Skip to content

Commit ee9b60f

Browse files
committed
Mount host kernel modules in build pods for in-tree dependency resolution
Build pods now have access to /host/lib/modules and /host/usr/lib/modules, allowing depmod to resolve dependencies on in-tree kernel modules during the build phase. Worker pods updated to use the same paths for consistency.
1 parent 9ad4269 commit ee9b60f

File tree

7 files changed

+77
-19
lines changed

7 files changed

+77
-19
lines changed

docs/mkdocs/documentation/kmod_image.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,16 @@ Once the image is built, KMM proceeds with the `Module` reconciliation.
119119
### Depending on in-tree kernel modules
120120
121121
Some kernel modules depend on other kernel modules shipped with the node's distribution.
122-
To avoid copying those dependencies into the kmod image, KMM mounts `/usr/lib/modules` into both the build and the
123-
worker Pod's filesystems.
124-
By creating a symlink from `/opt/usr/lib/modules/[kernel-version]/[symlink-name]` to
125-
`/usr/lib/modules/[kernel-version]`, `depmod` can use the in-tree kmods on the building node's filesystem to resolve
122+
To avoid copying those dependencies into the kmod image, KMM mounts the host's `/lib/modules` and `/usr/lib/modules`
123+
directories into both the build and worker Pod's filesystems at `/host/lib/modules` and `/host/usr/lib/modules`.
124+
By creating a symlink from `/opt/lib/modules/[kernel-version]/[symlink-name]` to
125+
`/host/lib/modules/[kernel-version]`, `depmod` can use the in-tree kmods on the building node's filesystem to resolve
126126
dependencies.
127127
At runtime, the worker Pod extracts the entire image, including the `[symlink-name]` symbolic link.
128-
That link points to `/usr/lib/modules/[kernel-version]` in the worker Pod, which is mounted from the node's filesystem.
128+
That link points to `/host/lib/modules/[kernel-version]` in the worker Pod, which is mounted from the node's filesystem.
129129
`modprobe` can then follow that link and load the in-tree dependencies as needed.
130130

131-
In the example below, we use `host` as the symbolic link name under `/opt/usr/lib/modules/[kernel-version]`:
131+
In the example below, we use `host` as the symbolic link name under `/opt/lib/modules/[kernel-version]`:
132132

133133
```dockerfile
134134
FROM ubuntu as builder
@@ -146,8 +146,8 @@ RUN apt-get update && apt-get install -y kmod
146146
COPY --from=builder /usr/src/kernel-module-management/ci/kmm-kmod/kmm_ci_a.ko /opt/lib/modules/${KERNEL_FULL_VERSION}/
147147
COPY --from=builder /usr/src/kernel-module-management/ci/kmm-kmod/kmm_ci_b.ko /opt/lib/modules/${KERNEL_FULL_VERSION}/
148148
149-
# Create the symbolic link
150-
RUN ln -s /lib/modules/${KERNEL_FULL_VERSION} /opt/lib/modules/${KERNEL_FULL_VERSION}/host
149+
# Create the symbolic link to host modules (mounted at /host/lib/modules by KMM)
150+
RUN ln -s /host/lib/modules/${KERNEL_FULL_VERSION} /opt/lib/modules/${KERNEL_FULL_VERSION}/host
151151
152152
RUN depmod -b /opt ${KERNEL_FULL_VERSION}
153153
```
@@ -156,5 +156,5 @@ RUN depmod -b /opt ${KERNEL_FULL_VERSION}
156156
`depmod` will generate dependency files based on the kernel modules present on the node that runs the kmod image
157157
build.
158158
On the node on which KMM loads the kernel modules, `modprobe` will expect the files to be present under
159-
`/usr/lib/modules/[kernel-version]`, and the same filesystem layout.
159+
`/host/lib/modules/[kernel-version]`, and the same filesystem layout.
160160
It is highly recommended that the build and the target nodes share the same distribution and release.

internal/buildsign/resource/common_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,16 @@ var _ = Describe("makeBuildTemplate", func() {
142142
ReadOnly: true,
143143
MountPath: "/workspace",
144144
},
145+
{
146+
Name: "lib-modules",
147+
ReadOnly: true,
148+
MountPath: "/host/lib/modules",
149+
},
150+
{
151+
Name: "usr-lib-modules",
152+
ReadOnly: true,
153+
MountPath: "/host/usr/lib/modules",
154+
},
145155
},
146156
},
147157
},
@@ -162,6 +172,24 @@ var _ = Describe("makeBuildTemplate", func() {
162172
},
163173
},
164174
},
175+
{
176+
Name: "lib-modules",
177+
VolumeSource: v1.VolumeSource{
178+
HostPath: &v1.HostPathVolumeSource{
179+
Path: "/lib/modules",
180+
Type: ptr.To(v1.HostPathDirectory),
181+
},
182+
},
183+
},
184+
{
185+
Name: "usr-lib-modules",
186+
VolumeSource: v1.VolumeSource{
187+
HostPath: &v1.HostPathVolumeSource{
188+
Path: "/usr/lib/modules",
189+
Type: ptr.To(v1.HostPathDirectory),
190+
},
191+
},
192+
},
165193
},
166194
},
167195
}

internal/buildsign/resource/volumes.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
func makeBuildResourceVolumesAndVolumeMounts(buildConfig kmmv1beta1.Build,
1212
imageRepoSecret *v1.LocalObjectReference) ([]v1.Volume, []v1.VolumeMount) {
1313

14+
hostPathDirectory := v1.HostPathDirectory
15+
1416
volumes := []v1.Volume{
1517
{
1618
Name: dockerfileVolumeName,
@@ -26,6 +28,24 @@ func makeBuildResourceVolumesAndVolumeMounts(buildConfig kmmv1beta1.Build,
2628
},
2729
},
2830
},
31+
{
32+
Name: "lib-modules",
33+
VolumeSource: v1.VolumeSource{
34+
HostPath: &v1.HostPathVolumeSource{
35+
Path: "/lib/modules",
36+
Type: &hostPathDirectory,
37+
},
38+
},
39+
},
40+
{
41+
Name: "usr-lib-modules",
42+
VolumeSource: v1.VolumeSource{
43+
HostPath: &v1.HostPathVolumeSource{
44+
Path: "/usr/lib/modules",
45+
Type: &hostPathDirectory,
46+
},
47+
},
48+
},
2949
}
3050

3151
for _, secretRef := range buildConfig.Secrets {
@@ -46,6 +66,16 @@ func makeBuildResourceVolumesAndVolumeMounts(buildConfig kmmv1beta1.Build,
4666
ReadOnly: true,
4767
MountPath: "/workspace",
4868
},
69+
{
70+
Name: "lib-modules",
71+
ReadOnly: true,
72+
MountPath: "/host/lib/modules",
73+
},
74+
{
75+
Name: "usr-lib-modules",
76+
ReadOnly: true,
77+
MountPath: "/host/usr/lib/modules",
78+
},
4979
}
5080

5181
for _, secretRef := range buildConfig.Secrets {

internal/pod/workerpodmanager.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,12 +388,12 @@ func (wpmi *workerPodManagerImpl) baseWorkerPod(ctx context.Context, nmc client.
388388
},
389389
{
390390
Name: volNameLibModules,
391-
MountPath: "/lib/modules",
391+
MountPath: "/host/lib/modules",
392392
ReadOnly: true,
393393
},
394394
{
395395
Name: volNameUsrLibModules,
396-
MountPath: "/usr/lib/modules",
396+
MountPath: "/host/usr/lib/modules",
397397
ReadOnly: true,
398398
},
399399
{

internal/pod/workerpodmanager_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,12 +548,12 @@ cp -R /firmware-path/* /tmp/firmware-path;
548548
},
549549
{
550550
Name: volNameLibModules,
551-
MountPath: "/lib/modules",
551+
MountPath: "/host/lib/modules",
552552
ReadOnly: true,
553553
},
554554
{
555555
Name: volNameUsrLibModules,
556-
MountPath: "/usr/lib/modules",
556+
MountPath: "/host/usr/lib/modules",
557557
ReadOnly: true,
558558
},
559559
{

internal/worker/worker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func (w *worker) LoadKmod(ctx context.Context, cfg *kmmv1beta1.ModuleConfig, fir
4949
w.logger.Info("Unloading in-tree modules", "names", inTreeModulesToRemove)
5050
modulesToUnload := make([]string, 0, len(inTreeModulesToRemove))
5151
for _, module := range inTreeModulesToRemove {
52-
exists, err := w.fh.FileExists("/lib/modules", fmt.Sprintf("^%s.ko", module))
52+
exists, err := w.fh.FileExists("/host/lib/modules", fmt.Sprintf("^%s.ko", module))
5353
if err != nil {
5454
w.logger.Info(utils.WarnString(
5555
fmt.Sprintf("failed to check if module file %s present on the host", module)), "error", err)

internal/worker/worker_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ var _ = Describe("worker_LoadKmod", func() {
8282
}
8383

8484
gomock.InOrder(
85-
fh.EXPECT().FileExists("/lib/modules", "^intree1.ko").Return(true, nil),
86-
fh.EXPECT().FileExists("/lib/modules", "^intree2.ko").Return(false, nil),
87-
fh.EXPECT().FileExists("/lib/modules", "^intree3.ko").Return(true, nil),
88-
fh.EXPECT().FileExists("/lib/modules", "^intree4.ko").Return(false, fmt.Errorf("some error")),
85+
fh.EXPECT().FileExists("/host/lib/modules", "^intree1.ko").Return(true, nil),
86+
fh.EXPECT().FileExists("/host/lib/modules", "^intree2.ko").Return(false, nil),
87+
fh.EXPECT().FileExists("/host/lib/modules", "^intree3.ko").Return(true, nil),
88+
fh.EXPECT().FileExists("/host/lib/modules", "^intree4.ko").Return(false, fmt.Errorf("some error")),
8989
mr.EXPECT().Run(ctx, "-rv", "intree1", "intree3"),
9090
mr.EXPECT().Run(ctx, "-vd", filepath.Join(sharedFilesDir, dirName), moduleName),
9191
)
@@ -109,7 +109,7 @@ var _ = Describe("worker_LoadKmod", func() {
109109
}
110110

111111
gomock.InOrder(
112-
fh.EXPECT().FileExists("/lib/modules", "^intreeToRemove.ko").Return(true, nil),
112+
fh.EXPECT().FileExists("/host/lib/modules", "^intreeToRemove.ko").Return(true, nil),
113113
mr.EXPECT().Run(ctx, "-rv", "intreeToRemove"),
114114
mr.EXPECT().Run(ctx, "-vd", filepath.Join(sharedFilesDir, dirName), moduleName),
115115
)

0 commit comments

Comments
 (0)