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 <ashahab@altiscale.com>
This commit is contained in:
Abin Shahab 2015-10-11 22:30:41 +00:00
parent 48fdc50d09
commit 28c9d0252c
1 changed files with 14 additions and 9 deletions

View File

@ -379,14 +379,7 @@ func createDevices(config *configs.Config) error {
return nil return nil
} }
// Creates the device node in the rootfs of the container. func bindMountDeviceNode(dest string, node *configs.Device) error {
func createDeviceNode(rootfs string, node *configs.Device, bind bool) error {
dest := filepath.Join(rootfs, node.Path)
if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil {
return err
}
if bind {
f, err := os.Create(dest) f, err := os.Create(dest)
if err != nil && !os.IsExist(err) { if err != nil && !os.IsExist(err) {
return err return err
@ -396,9 +389,22 @@ func createDeviceNode(rootfs string, node *configs.Device, bind bool) error {
} }
return syscall.Mount(node.Path, dest, "bind", syscall.MS_BIND, "") 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)
if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil {
return err
}
if bind {
return bindMountDeviceNode(dest, node)
}
if err := mknodDevice(dest, node); err != nil { if err := mknodDevice(dest, node); err != nil {
if os.IsExist(err) { if os.IsExist(err) {
return nil return nil
} else if os.IsPermission(err) {
return bindMountDeviceNode(dest, node)
} }
return err return err
} }
@ -634,7 +640,6 @@ func remount(m *configs.Mount, rootfs string) error {
if !strings.HasPrefix(dest, rootfs) { if !strings.HasPrefix(dest, rootfs) {
dest = filepath.Join(rootfs, dest) dest = filepath.Join(rootfs, dest)
} }
if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags|syscall.MS_REMOUNT), ""); err != nil { if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags|syscall.MS_REMOUNT), ""); err != nil {
return err return err
} }