From 73b649705a33c0cb6862042826eeb5115ec32b03 Mon Sep 17 00:00:00 2001 From: Rodrigo Campos Date: Mon, 3 Apr 2023 15:43:21 +0200 Subject: [PATCH] libcontainer: Add mountFds struct We will need to pass more slices of fds to these functions in future patches. Let's add a struct that just contains them all, instead of adding lot of parameters to these functions. Signed-off-by: Rodrigo Campos --- libcontainer/init_linux.go | 19 ++++++++++++++----- libcontainer/rootfs_linux.go | 10 +++++----- libcontainer/standard_init_linux.go | 8 ++++---- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go index ed84ab59e..4f6ed61c0 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -47,6 +47,15 @@ type network struct { TempVethPeerName string `json:"temp_veth_peer_name"` } +type mountFds struct { + // Fds to use as source when mounting + // Size should be the same as container mounts, as it will be paired. + // The value -1 is used when no fd is needed for the mount. + // Can't have a valid fd in the same position that other slices in this struct. + // We need to use only one of these fds on any single mount. + sourceFds []int +} + // initConfig is used for transferring parameters from Exec() to Init() type initConfig struct { Args []string `json:"args"` @@ -128,7 +137,7 @@ func StartInitialization() (retErr error) { } // Get mount files (O_PATH). - mountFds, err := parseMountFds() + mountSrcFds, err := parseFdsFromEnv("_LIBCONTAINER_MOUNT_FDS") if err != nil { return err } @@ -148,10 +157,10 @@ func StartInitialization() (retErr error) { }() // If init succeeds, it will not return, hence none of the defers will be called. - return containerInit(it, pipe, consoleSocket, fifofd, logPipeFd, mountFds) + return containerInit(it, pipe, consoleSocket, fifofd, logPipeFd, mountFds{sourceFds: mountSrcFds}) } -func containerInit(t initType, pipe *os.File, consoleSocket *os.File, fifoFd, logFd int, mountFds []int) error { +func containerInit(t initType, pipe *os.File, consoleSocket *os.File, fifoFd, logFd int, mountFds mountFds) error { var config *initConfig if err := json.NewDecoder(pipe).Decode(&config); err != nil { return err @@ -162,8 +171,8 @@ func containerInit(t initType, pipe *os.File, consoleSocket *os.File, fifoFd, lo switch t { case initSetns: // mountFds must be nil in this case. We don't mount while doing runc exec. - if mountFds != nil { - return errors.New("mountFds must be nil; can't mount from exec") + if mountFds.sourceFds != nil { + return errors.New("mount source fds must be nil; can't mount from exec") } i := &linuxSetnsInit{ diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index 00e84e791..d93f9246f 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -63,14 +63,14 @@ func needsSetupDev(config *configs.Config) bool { // prepareRootfs sets up the devices, mount points, and filesystems for use // inside a new mount namespace. It doesn't set anything as ro. You must call // finalizeRootfs after this function to finish setting up the rootfs. -func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig, mountFds []int) (err error) { +func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig, mountFds mountFds) (err error) { config := iConfig.Config if err := prepareRoot(config); err != nil { return fmt.Errorf("error preparing rootfs: %w", err) } - if mountFds != nil && len(mountFds) != len(config.Mounts) { - return fmt.Errorf("malformed mountFds slice. Expected size: %v, got: %v. Slice: %v", len(config.Mounts), len(mountFds), mountFds) + if mountFds.sourceFds != nil && len(mountFds.sourceFds) != len(config.Mounts) { + return fmt.Errorf("malformed mountFds slice. Expected size: %v, got: %v. Slice: %v", len(config.Mounts), len(mountFds.sourceFds), mountFds.sourceFds) } mountConfig := &mountConfig{ @@ -84,8 +84,8 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig, mountFds []int) (err entry := mountEntry{Mount: m} // Just before the loop we checked that if not empty, len(mountFds) == len(config.Mounts). // Therefore, we can access mountFds[i] without any concerns. - if mountFds != nil && mountFds[i] != -1 { - entry.srcFD = "/proc/self/fd/" + strconv.Itoa(mountFds[i]) + if mountFds.sourceFds != nil && mountFds.sourceFds[i] != -1 { + entry.srcFD = "/proc/self/fd/" + strconv.Itoa(mountFds.sourceFds[i]) } if err := mountToRootfs(mountConfig, entry); err != nil { diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index a4c01953a..b22b37ecd 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -25,7 +25,7 @@ type linuxStandardInit struct { parentPid int fifoFd int logFd int - mountFds []int + mountFds mountFds config *initConfig } @@ -86,15 +86,15 @@ func (l *linuxStandardInit) Init() error { // initialises the labeling system selinux.GetEnabled() - // We don't need the mountFds after prepareRootfs() nor if it fails. + // We don't need the mountFds.SourceFds after prepareRootfs() nor if it fails. err := prepareRootfs(l.pipe, l.config, l.mountFds) - for _, m := range l.mountFds { + for _, m := range l.mountFds.sourceFds { if m == -1 { continue } if err := unix.Close(m); err != nil { - return fmt.Errorf("Unable to close mountFds fds: %w", err) + return fmt.Errorf("unable to close mount sourceFds: %w", err) } }