Skip to content

Commit b7aa6b1

Browse files
committed
libct/rootfs: introduce and use mountEntry
Adding fd field to mountConfig was not a good thing since mountConfig contains data that is not specific to a particular mount, while fd is a mount entry attribute. Introduce mountEntry structure, which embeds configs.Mount and adds srcFd to replace the removed mountConfig.fd. Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent c12b091 commit b7aa6b1

File tree

2 files changed

+36
-43
lines changed

2 files changed

+36
-43
lines changed

libcontainer/container_linux.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,9 +1274,8 @@ func (c *Container) makeCriuRestoreMountpoints(m *configs.Mount) error {
12741274
case "bind":
12751275
// The prepareBindMount() function checks if source
12761276
// exists. So it cannot be used for other filesystem types.
1277-
// TODO: pass something else than nil? Not sure if criu is
1278-
// impacted by issue #2484
1279-
if err := prepareBindMount(m, c.config.Rootfs, nil); err != nil {
1277+
// TODO: pass srcFD? Not sure if criu is impacted by issue #2484.
1278+
if err := prepareBindMount(mountEntry{Mount: m}, c.config.Rootfs); err != nil {
12801279
return err
12811280
}
12821281
default:

libcontainer/rootfs_linux.go

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,19 @@ import (
2828

2929
const defaultMountFlags = unix.MS_NOEXEC | unix.MS_NOSUID | unix.MS_NODEV
3030

31+
// mountConfig contains mount data not specific to a mount point.
3132
type mountConfig struct {
3233
root string
3334
label string
3435
cgroup2Path string
3536
rootlessCgroups bool
3637
cgroupns bool
37-
fd *int
38+
}
39+
40+
// mountEntry contains mount data specific to a mount point.
41+
type mountEntry struct {
42+
*configs.Mount
43+
srcFD string
3844
}
3945

4046
// needsSetupDev returns true if /dev needs to be set up.
@@ -67,21 +73,20 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig, mountFds []int) (err
6773
rootlessCgroups: iConfig.RootlessCgroups,
6874
cgroupns: config.Namespaces.Contains(configs.NEWCGROUP),
6975
}
70-
setupDev := needsSetupDev(config)
7176
for i, m := range config.Mounts {
77+
entry := mountEntry{Mount: m}
7278
// Just before the loop we checked that if not empty, len(mountFds) == len(config.Mounts).
7379
// Therefore, we can access mountFds[i] without any concerns.
7480
if mountFds != nil && mountFds[i] != -1 {
75-
mountConfig.fd = &mountFds[i]
76-
} else {
77-
mountConfig.fd = nil
81+
entry.srcFD = "/proc/self/fd/" + strconv.Itoa(mountFds[i])
7882
}
7983

80-
if err := mountToRootfs(m, mountConfig); err != nil {
84+
if err := mountToRootfs(mountConfig, entry); err != nil {
8185
return fmt.Errorf("error mounting %q to rootfs at %q: %w", m.Source, m.Destination, err)
8286
}
8387
}
8488

89+
setupDev := needsSetupDev(config)
8590
if setupDev {
8691
if err := createDevices(config); err != nil {
8792
return fmt.Errorf("error creating device nodes: %w", err)
@@ -201,10 +206,10 @@ func cleanupTmp(tmpdir string) {
201206
_ = os.RemoveAll(tmpdir)
202207
}
203208

204-
func prepareBindMount(m *configs.Mount, rootfs string, mountFd *int) error {
209+
func prepareBindMount(m mountEntry, rootfs string) error {
205210
source := m.Source
206-
if mountFd != nil {
207-
source = "/proc/self/fd/" + strconv.Itoa(*mountFd)
211+
if m.srcFD != "" {
212+
source = m.srcFD
208213
}
209214

210215
stat, err := os.Stat(source)
@@ -252,7 +257,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
252257
PropagationFlags: m.PropagationFlags,
253258
}
254259

255-
if err := mountToRootfs(tmpfs, c); err != nil {
260+
if err := mountToRootfs(c, mountEntry{Mount: tmpfs}); err != nil {
256261
return err
257262
}
258263

@@ -280,7 +285,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
280285
return err
281286
}
282287
} else {
283-
if err := mountToRootfs(b, c); err != nil {
288+
if err := mountToRootfs(c, mountEntry{Mount: b}); err != nil {
284289
return err
285290
}
286291
}
@@ -328,7 +333,7 @@ func mountCgroupV2(m *configs.Mount, c *mountConfig) error {
328333
})
329334
}
330335

331-
func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
336+
func doTmpfsCopyUp(m mountEntry, rootfs, mountLabel string) (Err error) {
332337
// Set up a scratch dir for the tmpfs on the host.
333338
tmpdir, err := prepareTmp("/tmp")
334339
if err != nil {
@@ -345,7 +350,7 @@ func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
345350
// m.Destination since we are going to mount *on the host*.
346351
oldDest := m.Destination
347352
m.Destination = tmpDir
348-
err = mountPropagate(m, "/", mountLabel, nil)
353+
err = mountPropagate(m, "/", mountLabel)
349354
m.Destination = oldDest
350355
if err != nil {
351356
return err
@@ -373,10 +378,9 @@ func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
373378
})
374379
}
375380

376-
func mountToRootfs(m *configs.Mount, c *mountConfig) error {
381+
func mountToRootfs(c *mountConfig, m mountEntry) error {
377382
rootfs := c.root
378383
mountLabel := c.label
379-
mountFd := c.fd
380384
dest, err := securejoin.SecureJoin(rootfs, m.Destination)
381385
if err != nil {
382386
return err
@@ -400,12 +404,12 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
400404
return err
401405
}
402406
// Selinux kernels do not support labeling of /proc or /sys
403-
return mountPropagate(m, rootfs, "", nil)
407+
return mountPropagate(m, rootfs, "")
404408
case "mqueue":
405409
if err := os.MkdirAll(dest, 0o755); err != nil {
406410
return err
407411
}
408-
if err := mountPropagate(m, rootfs, "", nil); err != nil {
412+
if err := mountPropagate(m, rootfs, ""); err != nil {
409413
return err
410414
}
411415
return label.SetFileLabel(dest, mountLabel)
@@ -420,7 +424,7 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
420424
if m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP {
421425
err = doTmpfsCopyUp(m, rootfs, mountLabel)
422426
} else {
423-
err = mountPropagate(m, rootfs, mountLabel, nil)
427+
err = mountPropagate(m, rootfs, mountLabel)
424428
}
425429

426430
if err != nil {
@@ -434,17 +438,17 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
434438
}
435439
return nil
436440
case "bind":
437-
if err := prepareBindMount(m, rootfs, mountFd); err != nil {
441+
if err := prepareBindMount(m, rootfs); err != nil {
438442
return err
439443
}
440-
if err := mountPropagate(m, rootfs, mountLabel, mountFd); err != nil {
444+
if err := mountPropagate(m, rootfs, mountLabel); err != nil {
441445
return err
442446
}
443447
// bind mount won't change mount options, we need remount to make mount options effective.
444448
// first check that we have non-default options required before attempting a remount
445449
if m.Flags&^(unix.MS_REC|unix.MS_REMOUNT|unix.MS_BIND) != 0 {
446450
// only remount if unique mount options are set
447-
if err := remount(m, rootfs, mountFd); err != nil {
451+
if err := remount(m, rootfs); err != nil {
448452
return err
449453
}
450454
}
@@ -460,19 +464,19 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
460464
}
461465
case "cgroup":
462466
if cgroups.IsCgroup2UnifiedMode() {
463-
return mountCgroupV2(m, c)
467+
return mountCgroupV2(m.Mount, c)
464468
}
465-
return mountCgroupV1(m, c)
469+
return mountCgroupV1(m.Mount, c)
466470
default:
467471
if err := checkProcMount(rootfs, dest, m.Source); err != nil {
468472
return err
469473
}
470474
if err := os.MkdirAll(dest, 0o755); err != nil {
471475
return err
472476
}
473-
return mountPropagate(m, rootfs, mountLabel, mountFd)
477+
return mountPropagate(m, rootfs, mountLabel)
474478
}
475-
if err := setRecAttr(m, rootfs); err != nil {
479+
if err := setRecAttr(m.Mount, rootfs); err != nil {
476480
return err
477481
}
478482
return nil
@@ -1036,15 +1040,10 @@ func writeSystemProperty(key, value string) error {
10361040
return os.WriteFile(path.Join("/proc/sys", keyPath), []byte(value), 0o644)
10371041
}
10381042

1039-
func remount(m *configs.Mount, rootfs string, mountFd *int) error {
1040-
srcFD := ""
1041-
if mountFd != nil {
1042-
srcFD = "/proc/self/fd/" + strconv.Itoa(*mountFd)
1043-
}
1044-
1043+
func remount(m mountEntry, rootfs string) error {
10451044
return utils.WithProcfd(rootfs, m.Destination, func(dstFD string) error {
10461045
flags := uintptr(m.Flags | unix.MS_REMOUNT)
1047-
err := mountViaFDs(m.Source, srcFD, m.Destination, dstFD, m.Device, flags, "")
1046+
err := mountViaFDs(m.Source, m.srcFD, m.Destination, dstFD, m.Device, flags, "")
10481047
if err == nil {
10491048
return nil
10501049
}
@@ -1058,13 +1057,13 @@ func remount(m *configs.Mount, rootfs string, mountFd *int) error {
10581057
}
10591058
// ... and retry the mount with ro flag set.
10601059
flags |= unix.MS_RDONLY
1061-
return mountViaFDs(m.Source, srcFD, m.Destination, dstFD, m.Device, flags, "")
1060+
return mountViaFDs(m.Source, m.srcFD, m.Destination, dstFD, m.Device, flags, "")
10621061
})
10631062
}
10641063

10651064
// Do the mount operation followed by additional mounts required to take care
10661065
// of propagation flags. This will always be scoped inside the container rootfs.
1067-
func mountPropagate(m *configs.Mount, rootfs string, mountLabel string, mountFd *int) error {
1066+
func mountPropagate(m mountEntry, rootfs string, mountLabel string) error {
10681067
var (
10691068
data = label.FormatMountLabel(m.Data, mountLabel)
10701069
flags = m.Flags
@@ -1077,17 +1076,12 @@ func mountPropagate(m *configs.Mount, rootfs string, mountLabel string, mountFd
10771076
flags &= ^unix.MS_RDONLY
10781077
}
10791078

1080-
srcFD := ""
1081-
if mountFd != nil {
1082-
srcFD = "/proc/self/fd/" + strconv.Itoa(*mountFd)
1083-
}
1084-
10851079
// Because the destination is inside a container path which might be
10861080
// mutating underneath us, we verify that we are actually going to mount
10871081
// inside the container with WithProcfd() -- mounting through a procfd
10881082
// mounts on the target.
10891083
if err := utils.WithProcfd(rootfs, m.Destination, func(dstFD string) error {
1090-
return mountViaFDs(m.Source, srcFD, m.Destination, dstFD, m.Device, uintptr(flags), data)
1084+
return mountViaFDs(m.Source, m.srcFD, m.Destination, dstFD, m.Device, uintptr(flags), data)
10911085
}); err != nil {
10921086
return err
10931087
}

0 commit comments

Comments
 (0)