From 28c9d0252ca81c332004fcf020b9d06d9a9df839 Mon Sep 17 00:00:00 2001 From: Abin Shahab Date: Sun, 11 Oct 2015 22:30:41 +0000 Subject: [PATCH] Userns container in containers Enables launching userns containers by catching EPERM errors for writing to devices cgroups, and for mknod invocations. Signed-off-by: Abin Shahab --- libcontainer/rootfs_linux.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index 78beb038..990261e4 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -379,6 +379,17 @@ func createDevices(config *configs.Config) error { return nil } +func bindMountDeviceNode(dest string, node *configs.Device) error { + f, err := os.Create(dest) + if err != nil && !os.IsExist(err) { + return err + } + if f != nil { + f.Close() + } + return syscall.Mount(node.Path, dest, "bind", syscall.MS_BIND, "") +} + // Creates the device node in the rootfs of the container. func createDeviceNode(rootfs string, node *configs.Device, bind bool) error { dest := filepath.Join(rootfs, node.Path) @@ -387,18 +398,13 @@ func createDeviceNode(rootfs string, node *configs.Device, bind bool) error { } if bind { - f, err := os.Create(dest) - if err != nil && !os.IsExist(err) { - return err - } - if f != nil { - f.Close() - } - return syscall.Mount(node.Path, dest, "bind", syscall.MS_BIND, "") + return bindMountDeviceNode(dest, node) } if err := mknodDevice(dest, node); err != nil { if os.IsExist(err) { return nil + } else if os.IsPermission(err) { + return bindMountDeviceNode(dest, node) } return err } @@ -634,7 +640,6 @@ func remount(m *configs.Mount, rootfs string) error { if !strings.HasPrefix(dest, rootfs) { dest = filepath.Join(rootfs, dest) } - if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags|syscall.MS_REMOUNT), ""); err != nil { return err }