From c5f152a9dc851e0297f63a73c3e59890da135352 Mon Sep 17 00:00:00 2001 From: zhangsong34 Date: Fri, 19 Oct 2018 10:53:33 +0800 Subject: [PATCH 65/94] runc: support namespaced kernel params can be changed in system container reason:support namespaced kernel files can be written in container, when docker run a system container specify '--ns-change-opt' param, net or ipc namespaced kernel params can be changed in this container. Conflicts: libcontainer/rootfs_linux.go script/runc-euleros.spec Change-Id: I051b274117abd9745a27577e14a23c906ff7cca3 Signed-off-by: jingrui --- libcontainer/rootfs_linux.go | 26 ++++++++++++++++++++++++++ libcontainer/standard_init_linux.go | 8 ++++++++ 2 files changed, 34 insertions(+) diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index 7cf5edd..38bdd1b 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -160,6 +160,9 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error { switch m.Device { case "proc", "sysfs": + if strings.HasPrefix(m.Destination, "/proc/sys/") { + return nil + } if err := os.MkdirAll(dest, 0755); err != nil { return err } @@ -729,6 +732,29 @@ func readonlyPath(path string) error { return syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, "") } +// remountReadWrite will bind over the top of an existing path and ensure that it is read-write. +func remountReadWrite(path string) error { + for i := 0; i < 5; i++ { + if err := syscall.Mount("", path, "", syscall.MS_REMOUNT, ""); err != nil && !os.IsNotExist(err) { + switch err { + case syscall.EINVAL: + // Probably not a mountpoint, use bind-mount + if err := syscall.Mount(path, path, "", syscall.MS_BIND, ""); err != nil { + return err + } + return syscall.Mount(path, path, "", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_REC|defaultMountFlags, "") + case syscall.EBUSY: + time.Sleep(100 * time.Millisecond) + continue + default: + return err + } + } + return nil + } + return fmt.Errorf("unable to mount %s as readwrite max retries reached", path) +} + // remountReadonly will remount an existing mount point and ensure that it is read-only. func remountReadonly(m *configs.Mount) error { var ( diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index 484ba42..18506af 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "os/exec" + "strings" "syscall" "time" @@ -117,6 +118,13 @@ func (l *linuxStandardInit) Init() error { return err } } + for _, m := range l.config.Config.Mounts { + if m.Flags&syscall.MS_RDONLY == 0 && m.Device == "proc" && strings.HasPrefix(m.Destination, "/proc/sys/") { + if err := remountReadWrite(m.Destination); err != nil { + return err + } + } + } for _, path := range l.config.Config.MaskPaths { if err := maskPath(path); err != nil { return err -- 2.7.4.3