libcontainer: fix a bug when setting shared rootfs propagation mode
So far when the input mount flags contain `MS_SHARED`, the flag has not been applied to the container rootfs. That's because we call `rootfsParentMountPrivate()` after applying the original mount flags. As a result, the original flags are overwritten. Though it's also true that we actually need to mount the container rootfs with `MS_PRIVATE`, to avoid failure from `pivot_root()` in the Linux kernel. Thus if the mount flags contain `MS_SHARED`, we need a special case handling. First do `pivotRoot()` (or `msMoveRoot`, `chroot`) with the rootfs with a mount flag `MS_PRIVATE`. Then after `pivotRoot()`, again mount the rootfs with `MS_SHARED`. With this fix, `validation/linux_rootfs_propagation.t` of runtime-tools works well with the shared mode finally. Fixes https://github.com/opencontainers/runc/issues/1755 Signed-off-by: Dongsu Park <dongsu@kinvolk.io>
This commit is contained in:
parent
dd56ece823
commit
da16461dc5
|
@ -110,6 +110,15 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
|
|||
return newSystemErrorWithCause(err, "jailing process inside rootfs")
|
||||
}
|
||||
|
||||
// mount with MS_SHARED flag does not work well with pivotRoot, because
|
||||
// of the checks in the Linux kernel. So we need to first pivotRoot with
|
||||
// a private rootfs, and after that make it shared.
|
||||
if config.RootPropagation&unix.MS_SHARED != 0 {
|
||||
if err := rootfsParentMountShared(config.Rootfs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if setupDev {
|
||||
if err := reOpenDevNull(); err != nil {
|
||||
return newSystemErrorWithCause(err, "reopening /dev/null inside container")
|
||||
|
@ -608,6 +617,31 @@ func rootfsParentMountPrivate(rootfs string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Make parent mount shared if it was not shared
|
||||
func rootfsParentMountShared(rootfs string) error {
|
||||
sharedMount := false
|
||||
|
||||
parentMount, optionalOpts, err := getParentMount(rootfs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
optsSplit := strings.Split(optionalOpts, " ")
|
||||
for _, opt := range optsSplit {
|
||||
if strings.HasPrefix(opt, "shared:") {
|
||||
sharedMount = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Make parent mount SHARED if it was not shared.
|
||||
if !sharedMount {
|
||||
return unix.Mount("", parentMount, "", unix.MS_SHARED, "")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func prepareRoot(config *configs.Config) error {
|
||||
flag := unix.MS_SLAVE | unix.MS_REC
|
||||
if config.RootPropagation != 0 {
|
||||
|
|
Loading…
Reference in New Issue