mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
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:
@@ -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{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user