Skip to content

Commit 1f029e1

Browse files
Fix collision between sofdep unloading and hard symbol dependency
scenario: 1.KMM Modules needs to load module_a, module_b, module_c 2. module_a has a hard symbol dependency on module_b. 3. modulesLoadingOrder defined as: [module_a, module_b, module_c] There is no problems when loading. When unloading using softdep, the following happens 1. module_a is unloaded first 2. module_b is unloaded automatically, due to hard symbol dependency 3. modprobe looks at softdep, sees that module_b is unloaded, and does not continue to module_c This commit changes the Unload flow: 1. no softdep is created. 2. modprobe -r ocmmand is provided with the list of modules defined in the modulesLoadingOrder This way it will go over every module in the command and try to unload it Upstream-Commit: f17d16db0c5f7f7aefa5ec2bfcd46725afe43c8f
1 parent fbf4c8f commit 1f029e1

4 files changed

Lines changed: 59 additions & 31 deletions

File tree

internal/pod/workerpodmanager.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ func (wpmi *workerPodManagerImpl) LoaderPodTemplate(ctx context.Context, nmc cli
165165
return nil, fmt.Errorf("could not create the base Pod: %v", err)
166166
}
167167

168-
if nms.Config.Modprobe.ModulesLoadingOrder != nil {
168+
if len(nms.Config.Modprobe.ModulesLoadingOrder) > 0 {
169169
if err = setWorkerSofdepConfig(pod, nms.Config.Modprobe.ModulesLoadingOrder); err != nil {
170170
return nil, fmt.Errorf("could not set software dependency for mulitple modules: %v", err)
171171
}
@@ -237,11 +237,7 @@ func (wpmi *workerPodManagerImpl) UnloaderPodTemplate(ctx context.Context, nmc c
237237
return nil, fmt.Errorf("could not set the worker Pod's security context: %v", err)
238238
}
239239

240-
if nms.Config.Modprobe.ModulesLoadingOrder != nil {
241-
if err = setWorkerSofdepConfig(pod, nms.Config.Modprobe.ModulesLoadingOrder); err != nil {
242-
return nil, fmt.Errorf("could not set software dependency for mulitple modules: %v", err)
243-
}
244-
}
240+
// we skip the softdep configuration, since in unload we will do it with one "modprobe -r" call
245241

246242
if nms.Config.Modprobe.FirmwarePath != "" {
247243
firmwareHostPath := wpmi.workerCfg.FirmwareHostPath

internal/pod/workerpodmanager_test.go

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,13 @@ cp -R /firmware-path/* /tmp/firmware-path;
485485
configAnnotationValue = strings.ReplaceAll(configAnnotationValue, "firmwarePath: /firmware-path\n ", "")
486486
}
487487
tolerationAnotationValue := "- effect: NoExecute\n key: test-key\n value: test-value\n"
488+
annotations := map[string]string{
489+
configAnnotationKey: configAnnotationValue,
490+
tolerationsAnnotationKey: tolerationAnotationValue,
491+
}
492+
if isLoaderPod {
493+
annotations[modulesOrderKey] = modulesOrderValue
494+
}
488495
pod := v1.Pod{
489496
ObjectMeta: metav1.ObjectMeta{
490497
Name: WorkerPodName(nmcName, moduleName),
@@ -496,11 +503,7 @@ cp -R /firmware-path/* /tmp/firmware-path;
496503
actionLabelKey: string(action),
497504
constants.ModuleNameLabel: moduleName,
498505
},
499-
Annotations: map[string]string{
500-
configAnnotationKey: configAnnotationValue,
501-
modulesOrderKey: modulesOrderValue,
502-
tolerationsAnnotationKey: tolerationAnotationValue,
503-
},
506+
Annotations: annotations,
504507
},
505508
Spec: v1.PodSpec{
506509
Tolerations: []v1.Toleration{
@@ -555,11 +558,6 @@ cp -R /firmware-path/* /tmp/firmware-path;
555558
MountPath: sharedFilesDir,
556559
ReadOnly: true,
557560
},
558-
{
559-
Name: "modules-order",
560-
ReadOnly: true,
561-
MountPath: "/etc/modprobe.d",
562-
},
563561
},
564562
},
565563
},
@@ -597,21 +595,31 @@ cp -R /firmware-path/* /tmp/firmware-path;
597595
EmptyDir: &v1.EmptyDirVolumeSource{},
598596
},
599597
},
600-
{
601-
Name: "modules-order",
602-
VolumeSource: v1.VolumeSource{
603-
DownwardAPI: &v1.DownwardAPIVolumeSource{
604-
Items: []v1.DownwardAPIVolumeFile{
605-
{
606-
Path: "softdep.conf",
607-
FieldRef: &v1.ObjectFieldSelector{FieldPath: fmt.Sprintf("metadata.annotations['%s']", modulesOrderKey)},
608-
},
609-
},
598+
},
599+
},
600+
}
601+
602+
if isLoaderPod {
603+
softDepVolumeMount := v1.VolumeMount{
604+
Name: "modules-order",
605+
ReadOnly: true,
606+
MountPath: "/etc/modprobe.d",
607+
}
608+
pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, softDepVolumeMount)
609+
softdepVolume := v1.Volume{
610+
Name: "modules-order",
611+
VolumeSource: v1.VolumeSource{
612+
DownwardAPI: &v1.DownwardAPIVolumeSource{
613+
Items: []v1.DownwardAPIVolumeFile{
614+
{
615+
Path: "softdep.conf",
616+
FieldRef: &v1.ObjectFieldSelector{FieldPath: fmt.Sprintf("metadata.annotations['%s']", modulesOrderKey)},
610617
},
611618
},
612619
},
613620
},
614-
},
621+
}
622+
pod.Spec.Volumes = append(pod.Spec.Volumes, softdepVolume)
615623
}
616624

617625
if withFirmware {

internal/worker/worker.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,19 @@ func (w *worker) UnloadKmod(ctx context.Context, cfg *kmmv1beta1.ModuleConfig, f
146146
if cfg.Modprobe.Args != nil {
147147
args = append(args, cfg.Modprobe.Args.Unload...)
148148
}
149-
150-
args = append(args, moduleName)
149+
if len(cfg.Modprobe.ModulesLoadingOrder) > 0 {
150+
w.logger.Info("Preparing to unload multiple modules", "modules", cfg.Modprobe.ModulesLoadingOrder)
151+
args = append(args, cfg.Modprobe.ModulesLoadingOrder...)
152+
} else {
153+
w.logger.Info("Preparing to unload single module", "moduleName", moduleName)
154+
args = append(args, moduleName)
155+
}
151156
}
152157

153-
w.logger.Info("Unloading module", "name", moduleName)
158+
w.logger.Info("Starting unloading", "args", args)
154159

155160
if err := w.mr.Run(ctx, args...); err != nil {
156-
return fmt.Errorf("could not unload module %s: %v", moduleName, err)
161+
return fmt.Errorf("failed to unload module %q: %v", args, err)
157162
}
158163

159164
//remove firmware files only (no directories)

internal/worker/worker_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,25 @@ var _ = Describe("worker_UnloadKmod", func() {
332332
)
333333
})
334334

335+
It("should use ModulesLoadingOrder when set", func() {
336+
cfg := v1beta1.ModuleConfig{
337+
ContainerImage: imageName,
338+
Modprobe: v1beta1.ModprobeSpec{
339+
ModuleName: moduleName,
340+
DirName: dirName,
341+
ModulesLoadingOrder: []string{"a", "b", "c"},
342+
},
343+
}
344+
345+
mr.EXPECT().Run(ctx, "-rvd", filepath.Join(sharedFilesDir, dirName), "a", "b", "c")
346+
347+
Expect(
348+
w.UnloadKmod(ctx, &cfg, ""),
349+
).NotTo(
350+
HaveOccurred(),
351+
)
352+
})
353+
335354
It("should remove all firmware file only", func() {
336355
cfg := v1beta1.ModuleConfig{
337356
ContainerImage: imageName,

0 commit comments

Comments
 (0)