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 <rodrigoca@microsoft.com>
This commit is contained in:
Rodrigo Campos
2023-04-03 15:43:21 +02:00
parent 0172016a53
commit 73b649705a
3 changed files with 23 additions and 14 deletions
+14 -5
View File
@@ -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{
+5 -5
View File
@@ -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 {
+4 -4
View File
@@ -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)
}
}