Skip to content

Commit b156b30

Browse files
committed
don't adjust rdma devchar duplicates
Change-Id: I9028ba278a99f3fd015b981106777ce4cacade2d
1 parent 1627d9e commit b156b30

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed

pkg/driver/nri_hooks.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
metav1apply "k8s.io/client-go/applyconfigurations/meta/v1"
3131
resourceapply "k8s.io/client-go/applyconfigurations/resource/v1beta1"
3232
"k8s.io/klog/v2"
33+
"k8s.io/utils/set"
3334
)
3435

3536
// NRI hooks into the container runtime, the lifecycle of the Pod seen here is local to the runtime
@@ -66,9 +67,15 @@ func (np *NetworkDriver) CreateContainer(_ context.Context, pod *api.PodSandbox,
6667
return nil, nil, nil
6768
}
6869
// Containers only cares about the RDMA char devices
70+
devPaths := set.Set[string]{}
6971
adjust := &api.ContainerAdjustment{}
7072
for _, config := range podConfig {
7173
for _, dev := range config.RDMADevice.DevChars {
74+
// do not insert the same path multiple times
75+
if devPaths.Has(dev.Path) {
76+
continue
77+
}
78+
devPaths.Insert(dev.Path)
7279
// TODO check the file permissions and uid and gid fields
7380
adjust.AddDevice(&api.LinuxDevice{
7481
Path: dev.Path,

pkg/driver/nri_hooks_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
Copyright 2024 Google LLC
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package driver
18+
19+
import (
20+
"context"
21+
"testing"
22+
23+
"github.com/containerd/nri/pkg/api"
24+
"k8s.io/apimachinery/pkg/types"
25+
)
26+
27+
func TestCreateContainerNoDuplicateDevices(t *testing.T) {
28+
np := &NetworkDriver{
29+
podConfigStore: NewPodConfigStore(),
30+
}
31+
32+
podUID := types.UID("test-pod")
33+
pod := &api.PodSandbox{
34+
Uid: string(podUID),
35+
Name: "test-pod",
36+
Namespace: "test-ns",
37+
}
38+
ctr := &api.Container{
39+
Name: "test-container",
40+
}
41+
42+
// Setup pod config with duplicate RDMA devices
43+
rdmaDevChars := []LinuxDevice{
44+
{Path: "/dev/infiniband/uverbs0", Type: "c", Major: 231, Minor: 192},
45+
}
46+
podConfig := PodConfig{
47+
RDMADevice: RDMAConfig{
48+
DevChars: rdmaDevChars,
49+
},
50+
}
51+
np.podConfigStore.Set(podUID, "eth0", podConfig)
52+
np.podConfigStore.Set(podUID, "eth1", podConfig)
53+
54+
adjust, _, err := np.CreateContainer(context.Background(), pod, ctr)
55+
if err != nil {
56+
t.Fatalf("CreateContainer failed: %v", err)
57+
}
58+
59+
if len(adjust.Linux.Devices) != 1 {
60+
t.Errorf("CreateContainer should not adjust the same device multiple times\n%v", adjust.Linux.Devices)
61+
}
62+
}

pkg/driver/pod_device_config_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,57 @@ func TestPodConfigStore_DeleteClaim(t *testing.T) {
292292
})
293293
}
294294
}
295+
296+
func TestPodConfigStore_NoDuplicateDevices(t *testing.T) {
297+
store := NewPodConfigStore()
298+
podUID := types.UID("test-pod-uid-1")
299+
deviceName1 := "eth0"
300+
config1 := PodConfig{
301+
Network: apis.NetworkConfig{
302+
Interface: apis.InterfaceConfig{Name: "eth0-pod"},
303+
},
304+
RDMADevice: RDMAConfig{
305+
LinkDev: "mlx5_0",
306+
DevChars: []LinuxDevice{{
307+
Path: "/dev/infiniband/rdma_cm",
308+
}, {
309+
Path: "/dev/infiniband/uverbs1",
310+
}},
311+
},
312+
}
313+
deviceName2 := "eth1"
314+
config2 := PodConfig{
315+
Network: apis.NetworkConfig{
316+
Interface: apis.InterfaceConfig{Name: "eth2-pod"},
317+
},
318+
RDMADevice: RDMAConfig{
319+
LinkDev: "mlx5_1",
320+
DevChars: []LinuxDevice{{
321+
Path: "/dev/infiniband/rdma_cm",
322+
}, {
323+
Path: "/dev/infiniband/uverbs2",
324+
}},
325+
},
326+
}
327+
328+
// Set the same device config multiple times
329+
store.Set(podUID, deviceName1, config1)
330+
store.Set(podUID, deviceName2, config2)
331+
store.Set(podUID, deviceName1, config1)
332+
333+
podConfigs, found := store.GetPodConfigs(podUID)
334+
if !found {
335+
t.Fatalf("GetPodConfigs() did not find configs for podUID, expected found")
336+
}
337+
338+
if len(podConfigs) != 2 {
339+
t.Errorf("Expected 2 device config, but got %d", len(podConfigs))
340+
}
341+
342+
if _, ok := podConfigs[deviceName1]; !ok {
343+
t.Errorf("Device %s not found in pod configs", deviceName2)
344+
}
345+
if _, ok := podConfigs[deviceName2]; !ok {
346+
t.Errorf("Device %s not found in pod configs", deviceName2)
347+
}
348+
}

0 commit comments

Comments
 (0)