From e50e99bb8b367dd0e07530f76b618fedcf764709 Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Mon, 3 Mar 2014 14:41:38 -0800 Subject: [PATCH 01/11] libcontainer/network: add netns strategy Docker-DCO-1.1-Signed-off-by: Johan Euphrosine (github: proppy) --- libcontainer/network/netns.go | 42 ++++++++++++++++++++++++++++++++ libcontainer/network/strategy.go | 2 ++ 2 files changed, 44 insertions(+) create mode 100644 libcontainer/network/netns.go diff --git a/libcontainer/network/netns.go b/libcontainer/network/netns.go new file mode 100644 index 0000000..3eb8ee5 --- /dev/null +++ b/libcontainer/network/netns.go @@ -0,0 +1,42 @@ +package network + +import ( + "fmt" + "os" + "syscall" + + "github.com/dotcloud/docker/pkg/libcontainer" + "github.com/dotcloud/docker/pkg/system" +) + +// crosbymichael: could make a network strategy that instead of returning veth pair names it returns a pid to an existing network namespace +type NetNS struct { +} + +func (v *NetNS) Create(n *libcontainer.Network, nspid int, context libcontainer.Context) error { + nsname, exists := n.Context["nsname"] + + if !exists { + return fmt.Errorf("nspath does not exist in network context") + } + + context["nspath"] = fmt.Sprintf("/var/run/netns/%s", nsname) + return nil +} + +func (v *NetNS) Initialize(config *libcontainer.Network, context libcontainer.Context) error { + nspath, exists := context["nspath"] + if !exists { + return fmt.Errorf("nspath does not exist in network context") + } + + f, err := os.OpenFile(nspath, os.O_RDONLY, 0) + if err != nil { + return fmt.Errorf("failed get network namespace fd: %v", err) + } + + if err := system.Setns(f.Fd(), syscall.CLONE_NEWNET); err != nil { + return fmt.Errorf("failed to setns current network namespace: %v", err) + } + return nil +} diff --git a/libcontainer/network/strategy.go b/libcontainer/network/strategy.go index 693790d..e41ecc3 100644 --- a/libcontainer/network/strategy.go +++ b/libcontainer/network/strategy.go @@ -2,6 +2,7 @@ package network import ( "errors" + "github.com/dotcloud/docker/pkg/libcontainer" ) @@ -12,6 +13,7 @@ var ( var strategies = map[string]NetworkStrategy{ "veth": &Veth{}, "loopback": &Loopback{}, + "netns": &NetNS{}, } // NetworkStrategy represents a specific network configuration for From 76d3c99530ab5b2bac27bc02f1e54789c5ad379e Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Mon, 3 Mar 2014 21:46:49 -0800 Subject: [PATCH 02/11] libcontainer/nsinit/init: move mount namespace after network Docker-DCO-1.1-Signed-off-by: Johan Euphrosine (github: proppy) --- libcontainer/nsinit/init.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libcontainer/nsinit/init.go b/libcontainer/nsinit/init.go index 117ae87..c39928d 100644 --- a/libcontainer/nsinit/init.go +++ b/libcontainer/nsinit/init.go @@ -4,6 +4,9 @@ package nsinit import ( "fmt" + "os" + "syscall" + "github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer/apparmor" "github.com/dotcloud/docker/pkg/libcontainer/capabilities" @@ -11,8 +14,6 @@ import ( "github.com/dotcloud/docker/pkg/libcontainer/utils" "github.com/dotcloud/docker/pkg/system" "github.com/dotcloud/docker/pkg/user" - "os" - "syscall" ) // Init is the init process that first runs inside a new namespace to setup mounts, users, networking, @@ -56,13 +57,13 @@ func (ns *linuxNs) Init(container *libcontainer.Container, uncleanRootfs, consol if err := system.ParentDeathSignal(uintptr(syscall.SIGTERM)); err != nil { return fmt.Errorf("parent death signal %s", err) } + if err := setupNetwork(container, context); err != nil { + return fmt.Errorf("setup networking %s", err) + } ns.logger.Println("setup mount namespace") if err := setupNewMountNamespace(rootfs, container.Mounts, console, container.ReadonlyFs, container.NoPivotRoot); err != nil { return fmt.Errorf("setup mount namespace %s", err) } - if err := setupNetwork(container, context); err != nil { - return fmt.Errorf("setup networking %s", err) - } if err := system.Sethostname(container.Hostname); err != nil { return fmt.Errorf("sethostname %s", err) } From fc0982872a1b7941f1c8c973a86be2e3ed6fe857 Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Mon, 3 Mar 2014 21:47:03 -0800 Subject: [PATCH 03/11] libcontainer: goimports Docker-DCO-1.1-Signed-off-by: Johan Euphrosine (github: proppy) --- libcontainer/nsinit/exec.go | 7 ++++--- libcontainer/nsinit/nsinit/main.go | 8 ++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/libcontainer/nsinit/exec.go b/libcontainer/nsinit/exec.go index 61286cc..6e902d1 100644 --- a/libcontainer/nsinit/exec.go +++ b/libcontainer/nsinit/exec.go @@ -3,12 +3,13 @@ package nsinit import ( - "github.com/dotcloud/docker/pkg/libcontainer" - "github.com/dotcloud/docker/pkg/libcontainer/network" - "github.com/dotcloud/docker/pkg/system" "os" "os/exec" "syscall" + + "github.com/dotcloud/docker/pkg/libcontainer" + "github.com/dotcloud/docker/pkg/libcontainer/network" + "github.com/dotcloud/docker/pkg/system" ) // Exec performes setup outside of a namespace so that a container can be diff --git a/libcontainer/nsinit/nsinit/main.go b/libcontainer/nsinit/nsinit/main.go index df32d0b..3725fb5 100644 --- a/libcontainer/nsinit/nsinit/main.go +++ b/libcontainer/nsinit/nsinit/main.go @@ -3,14 +3,18 @@ package main import ( "encoding/json" "flag" - "github.com/dotcloud/docker/pkg/libcontainer" - "github.com/dotcloud/docker/pkg/libcontainer/nsinit" "io" "io/ioutil" "log" "os" "path/filepath" "strconv" + + "github.com/dotcloud/docker/pkg/libcontainer" + "github.com/dotcloud/docker/pkg/libcontainer/nsinit" + + "github.com/dotcloud/docker/pkg/libcontainer" + "github.com/dotcloud/docker/pkg/libcontainer/nsinit" ) var ( From b00757fda634c5d90aa8556e84a0ef2ef3a5edfa Mon Sep 17 00:00:00 2001 From: Johan Euphrosine Date: Tue, 18 Mar 2014 16:25:26 -0700 Subject: [PATCH 04/11] libcontainer: remove duplicate imports Docker-DCO-1.1-Signed-off-by: Johan Euphrosine (github: proppy) --- libcontainer/nsinit/nsinit/main.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/libcontainer/nsinit/nsinit/main.go b/libcontainer/nsinit/nsinit/main.go index 3725fb5..37aa784 100644 --- a/libcontainer/nsinit/nsinit/main.go +++ b/libcontainer/nsinit/nsinit/main.go @@ -12,9 +12,6 @@ import ( "github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer/nsinit" - - "github.com/dotcloud/docker/pkg/libcontainer" - "github.com/dotcloud/docker/pkg/libcontainer/nsinit" ) var ( From f6a8719dd57f113c39169ae4418200e0cb18815c Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 20 Mar 2014 23:09:01 +0000 Subject: [PATCH 05/11] Dont use custom marshaling for caps and namespaces This also adds an enabled field to the types so that they can be easily toggled. Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- libcontainer/types.go | 77 +++++++++++-------------------------- libcontainer/types_linux.go | 12 +++--- 2 files changed, 28 insertions(+), 61 deletions(-) diff --git a/libcontainer/types.go b/libcontainer/types.go index 94fe876..8734634 100644 --- a/libcontainer/types.go +++ b/libcontainer/types.go @@ -1,7 +1,6 @@ package libcontainer import ( - "encoding/json" "errors" "github.com/syndtr/gocapability/capability" ) @@ -19,29 +18,30 @@ var ( namespaceList = Namespaces{} capabilityList = Capabilities{ - {Key: "SETPCAP", Value: capability.CAP_SETPCAP}, - {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE}, - {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO}, - {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT}, - {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN}, - {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE}, - {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE}, - {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME}, - {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG}, - {Key: "MKNOD", Value: capability.CAP_MKNOD}, - {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE}, - {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL}, - {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE}, - {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN}, - {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN}, + {Key: "SETPCAP", Value: capability.CAP_SETPCAP, Enabled: true}, + {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE, Enabled: true}, + {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO, Enabled: true}, + {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT, Enabled: true}, + {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN, Enabled: true}, + {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE, Enabled: true}, + {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE, Enabled: true}, + {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME, Enabled: true}, + {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG, Enabled: true}, + {Key: "MKNOD", Value: capability.CAP_MKNOD, Enabled: true}, + {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE, Enabled: true}, + {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL, Enabled: true}, + {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE, Enabled: true}, + {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN, Enabled: true}, + {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN, Enabled: true}, } ) type ( Namespace struct { - Key string - Value int - File string + Key string `json:"key,omitempty"` + Enabled bool `json:"enabled,omitempty"` + Value int `json:"value,omitempty"` + File string `json:"file,omitempty"` } Namespaces []*Namespace ) @@ -50,23 +50,6 @@ func (ns *Namespace) String() string { return ns.Key } -func (ns *Namespace) MarshalJSON() ([]byte, error) { - return json.Marshal(ns.Key) -} - -func (ns *Namespace) UnmarshalJSON(src []byte) error { - var nsName string - if err := json.Unmarshal(src, &nsName); err != nil { - return err - } - ret := GetNamespace(nsName) - if ret == nil { - return ErrUnkownNamespace - } - *ns = *ret - return nil -} - func GetNamespace(key string) *Namespace { for _, ns := range namespaceList { if ns.Key == key { @@ -89,8 +72,9 @@ func (n Namespaces) Contains(ns string) bool { type ( Capability struct { - Key string - Value capability.Cap + Key string `json:"key,omitempty"` + Enabled bool `json:"enabled"` + Value capability.Cap `json:"value,omitempty"` } Capabilities []*Capability ) @@ -99,23 +83,6 @@ func (c *Capability) String() string { return c.Key } -func (c *Capability) MarshalJSON() ([]byte, error) { - return json.Marshal(c.Key) -} - -func (c *Capability) UnmarshalJSON(src []byte) error { - var capName string - if err := json.Unmarshal(src, &capName); err != nil { - return err - } - ret := GetCapability(capName) - if ret == nil { - return ErrUnkownCapability - } - *c = *ret - return nil -} - func GetCapability(key string) *Capability { for _, capp := range capabilityList { if capp.Key == key { diff --git a/libcontainer/types_linux.go b/libcontainer/types_linux.go index c14531d..1f937e0 100644 --- a/libcontainer/types_linux.go +++ b/libcontainer/types_linux.go @@ -6,11 +6,11 @@ import ( func init() { namespaceList = Namespaces{ - {Key: "NEWNS", Value: syscall.CLONE_NEWNS, File: "mnt"}, - {Key: "NEWUTS", Value: syscall.CLONE_NEWUTS, File: "uts"}, - {Key: "NEWIPC", Value: syscall.CLONE_NEWIPC, File: "ipc"}, - {Key: "NEWUSER", Value: syscall.CLONE_NEWUSER, File: "user"}, - {Key: "NEWPID", Value: syscall.CLONE_NEWPID, File: "pid"}, - {Key: "NEWNET", Value: syscall.CLONE_NEWNET, File: "net"}, + {Key: "NEWNS", Value: syscall.CLONE_NEWNS, File: "mnt", Enabled: true}, + {Key: "NEWUTS", Value: syscall.CLONE_NEWUTS, File: "uts", Enabled: true}, + {Key: "NEWIPC", Value: syscall.CLONE_NEWIPC, File: "ipc", Enabled: true}, + {Key: "NEWUSER", Value: syscall.CLONE_NEWUSER, File: "user", Enabled: true}, + {Key: "NEWPID", Value: syscall.CLONE_NEWPID, File: "pid", Enabled: true}, + {Key: "NEWNET", Value: syscall.CLONE_NEWNET, File: "net", Enabled: true}, } } From 67a16257915b63cb8db82ba85c8964a803a7d4ff Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 21 Mar 2014 00:10:24 +0000 Subject: [PATCH 06/11] Allow caps to be toggled in native driver with plugin flag Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- libcontainer/capabilities/capabilities.go | 4 ++- libcontainer/types.go | 41 +++++++++++++---------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/libcontainer/capabilities/capabilities.go b/libcontainer/capabilities/capabilities.go index fbf7353..4b81e70 100644 --- a/libcontainer/capabilities/capabilities.go +++ b/libcontainer/capabilities/capabilities.go @@ -27,7 +27,9 @@ func DropCapabilities(container *libcontainer.Container) error { func getCapabilitiesMask(container *libcontainer.Container) []capability.Cap { drop := []capability.Cap{} for _, c := range container.CapabilitiesMask { - drop = append(drop, c.Value) + if !c.Enabled { + drop = append(drop, c.Value) + } } return drop } diff --git a/libcontainer/types.go b/libcontainer/types.go index 8734634..7751e85 100644 --- a/libcontainer/types.go +++ b/libcontainer/types.go @@ -18,21 +18,21 @@ var ( namespaceList = Namespaces{} capabilityList = Capabilities{ - {Key: "SETPCAP", Value: capability.CAP_SETPCAP, Enabled: true}, - {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE, Enabled: true}, - {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO, Enabled: true}, - {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT, Enabled: true}, - {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN, Enabled: true}, - {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE, Enabled: true}, - {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE, Enabled: true}, - {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME, Enabled: true}, - {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG, Enabled: true}, - {Key: "MKNOD", Value: capability.CAP_MKNOD, Enabled: true}, - {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE, Enabled: true}, - {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL, Enabled: true}, - {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE, Enabled: true}, - {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN, Enabled: true}, - {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN, Enabled: true}, + {Key: "SETPCAP", Value: capability.CAP_SETPCAP, Enabled: false}, + {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE, Enabled: false}, + {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO, Enabled: false}, + {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT, Enabled: false}, + {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN, Enabled: false}, + {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE, Enabled: false}, + {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE, Enabled: false}, + {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME, Enabled: false}, + {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG, Enabled: false}, + {Key: "MKNOD", Value: capability.CAP_MKNOD, Enabled: false}, + {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE, Enabled: false}, + {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL, Enabled: false}, + {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE, Enabled: false}, + {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN, Enabled: false}, + {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN, Enabled: false}, } ) @@ -86,7 +86,8 @@ func (c *Capability) String() string { func GetCapability(key string) *Capability { for _, capp := range capabilityList { if capp.Key == key { - return capp + cpy := *capp + return &cpy } } return nil @@ -95,10 +96,14 @@ func GetCapability(key string) *Capability { // Contains returns true if the specified Capability is // in the slice func (c Capabilities) Contains(capp string) bool { + return c.Get(capp) != nil +} + +func (c Capabilities) Get(capp string) *Capability { for _, cap := range c { if cap.Key == capp { - return true + return cap } } - return false + return nil } From 0114737132c1bd288389ced86847319254dbba14 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 21 Mar 2014 00:23:34 +0000 Subject: [PATCH 07/11] Add ability to work with individual namespaces Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- libcontainer/nsinit/command.go | 4 +++- libcontainer/types.go | 11 ++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/libcontainer/nsinit/command.go b/libcontainer/nsinit/command.go index 5546065..153a48a 100644 --- a/libcontainer/nsinit/command.go +++ b/libcontainer/nsinit/command.go @@ -39,7 +39,9 @@ func (c *DefaultCommandFactory) Create(container *libcontainer.Container, consol // flags on clone, unshare, and setns func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) { for _, ns := range namespaces { - flag |= ns.Value + if ns.Enabled { + flag |= ns.Value + } } return flag } diff --git a/libcontainer/types.go b/libcontainer/types.go index 7751e85..ffeb55a 100644 --- a/libcontainer/types.go +++ b/libcontainer/types.go @@ -53,7 +53,8 @@ func (ns *Namespace) String() string { func GetNamespace(key string) *Namespace { for _, ns := range namespaceList { if ns.Key == key { - return ns + cpy := *ns + return &cpy } } return nil @@ -62,12 +63,16 @@ func GetNamespace(key string) *Namespace { // Contains returns true if the specified Namespace is // in the slice func (n Namespaces) Contains(ns string) bool { + return n.Get(ns) != nil +} + +func (n Namespaces) Get(ns string) *Namespace { for _, nsp := range n { if nsp.Key == ns { - return true + return nsp } } - return false + return nil } type ( From a740cd779e939fafbd9d98308847e9a5a25b26da Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 21 Mar 2014 00:48:17 +0000 Subject: [PATCH 08/11] Allow containers to join the net namespace of other conatiners Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- libcontainer/network/netns.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/libcontainer/network/netns.go b/libcontainer/network/netns.go index 3eb8ee5..7e311f2 100644 --- a/libcontainer/network/netns.go +++ b/libcontainer/network/netns.go @@ -14,13 +14,7 @@ type NetNS struct { } func (v *NetNS) Create(n *libcontainer.Network, nspid int, context libcontainer.Context) error { - nsname, exists := n.Context["nsname"] - - if !exists { - return fmt.Errorf("nspath does not exist in network context") - } - - context["nspath"] = fmt.Sprintf("/var/run/netns/%s", nsname) + context["nspath"] = n.Context["nspath"] return nil } @@ -29,12 +23,10 @@ func (v *NetNS) Initialize(config *libcontainer.Network, context libcontainer.Co if !exists { return fmt.Errorf("nspath does not exist in network context") } - f, err := os.OpenFile(nspath, os.O_RDONLY, 0) if err != nil { return fmt.Errorf("failed get network namespace fd: %v", err) } - if err := system.Setns(f.Fd(), syscall.CLONE_NEWNET); err != nil { return fmt.Errorf("failed to setns current network namespace: %v", err) } From ea56bc461440a475a921e0026de559d2c2e24a13 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 21 Mar 2014 14:17:17 +0000 Subject: [PATCH 09/11] Change placement of readonly filesystem We need to change it to read only at the very end so that bound, copy dev nodes and other ops do not fail. Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- libcontainer/nsinit/mount.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libcontainer/nsinit/mount.go b/libcontainer/nsinit/mount.go index 61a9012..19dacfa 100644 --- a/libcontainer/nsinit/mount.go +++ b/libcontainer/nsinit/mount.go @@ -31,11 +31,6 @@ func setupNewMountNamespace(rootfs string, bindMounts []libcontainer.Mount, cons if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil { return fmt.Errorf("mouting %s as bind %s", rootfs, err) } - if readonly { - if err := system.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, ""); err != nil { - return fmt.Errorf("mounting %s as readonly %s", rootfs, err) - } - } if err := mountSystem(rootfs); err != nil { return fmt.Errorf("mount system %s", err) } @@ -81,6 +76,12 @@ func setupNewMountNamespace(rootfs string, bindMounts []libcontainer.Mount, cons } } + if readonly { + if err := system.Mount("/", "/", "bind", syscall.MS_BIND|syscall.MS_REMOUNT|syscall.MS_RDONLY|syscall.MS_REC, ""); err != nil { + return fmt.Errorf("mounting %s as readonly %s", rootfs, err) + } + } + system.Umask(0022) return nil From cb12e80969a652570ec15f42eaaf47843032f759 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 21 Mar 2014 14:53:47 +0000 Subject: [PATCH 10/11] Add cpuset.cpus to cgroups and native driver options Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- cgroups/cgroups.go | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/cgroups/cgroups.go b/cgroups/cgroups.go index b40e1a3..9d485d1 100644 --- a/cgroups/cgroups.go +++ b/cgroups/cgroups.go @@ -16,10 +16,11 @@ type Cgroup struct { Name string `json:"name,omitempty"` Parent string `json:"parent,omitempty"` - DeviceAccess bool `json:"device_access,omitempty"` // name of parent cgroup or slice - Memory int64 `json:"memory,omitempty"` // Memory limit (in bytes) - MemorySwap int64 `json:"memory_swap,omitempty"` // Total memory usage (memory + swap); set `-1' to disable swap - CpuShares int64 `json:"cpu_shares,omitempty"` // CPU shares (relative weight vs. other containers) + DeviceAccess bool `json:"device_access,omitempty"` // name of parent cgroup or slice + Memory int64 `json:"memory,omitempty"` // Memory limit (in bytes) + MemorySwap int64 `json:"memory_swap,omitempty"` // Total memory usage (memory + swap); set `-1' to disable swap + CpuShares int64 `json:"cpu_shares,omitempty"` // CPU shares (relative weight vs. other containers) + CpusetCpus string `json:"cpuset_cpus,omitempty"` // CPU to use } // https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt @@ -98,6 +99,7 @@ func (c *Cgroup) Cleanup(root string) error { get("memory"), get("devices"), get("cpu"), + get("cpuset"), } { os.RemoveAll(path) } @@ -150,6 +152,9 @@ func (c *Cgroup) Apply(pid int) error { if err := c.setupCpu(cgroupRoot, pid); err != nil { return err } + if err := c.setupCpuset(cgroupRoot, pid); err != nil { + return err + } return nil } @@ -248,3 +253,22 @@ func (c *Cgroup) setupCpu(cgroupRoot string, pid int) (err error) { } return nil } + +func (c *Cgroup) setupCpuset(cgroupRoot string, pid int) (err error) { + if c.CpusetCpus != "" { + dir, err := c.Join(cgroupRoot, "cpuset", pid) + if err != nil { + return err + } + defer func() { + if err != nil { + os.RemoveAll(dir) + } + }() + + if err := writeFile(dir, "cpuset.cpus", c.CpusetCpus); err != nil { + return err + } + } + return nil +} From ffa86e398a06646336c03689345a3caa2cc4765b Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 27 Mar 2014 08:25:01 +0000 Subject: [PATCH 11/11] Fix compile and unit test errors after merge Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- cgroups/apply_raw.go | 23 +++++++++++++++++++++++ cgroups/cgroups.go | 19 ------------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/cgroups/apply_raw.go b/cgroups/apply_raw.go index 47a2a00..5fe3179 100644 --- a/cgroups/apply_raw.go +++ b/cgroups/apply_raw.go @@ -49,6 +49,9 @@ func rawApply(c *Cgroup, pid int) (ActiveCgroup, error) { if err := raw.setupCpu(c, pid); err != nil { return nil, err } + if err := raw.setupCpuset(c, pid); err != nil { + return nil, err + } return raw, nil } @@ -170,6 +173,25 @@ func (raw *rawCgroup) setupCpu(c *Cgroup, pid int) (err error) { return nil } +func (raw *rawCgroup) setupCpuset(c *Cgroup, pid int) (err error) { + if c.CpusetCpus != "" { + dir, err := raw.join("cpuset", pid) + if err != nil { + return err + } + defer func() { + if err != nil { + os.RemoveAll(dir) + } + }() + + if err := writeFile(dir, "cpuset.cpus", c.CpusetCpus); err != nil { + return err + } + } + return nil +} + func (raw *rawCgroup) Cleanup() error { get := func(subsystem string) string { path, _ := raw.path(subsystem) @@ -180,6 +202,7 @@ func (raw *rawCgroup) Cleanup() error { get("memory"), get("devices"), get("cpu"), + get("cpuset"), } { if path != "" { os.RemoveAll(path) diff --git a/cgroups/cgroups.go b/cgroups/cgroups.go index cdf2687..5fe1034 100644 --- a/cgroups/cgroups.go +++ b/cgroups/cgroups.go @@ -101,22 +101,3 @@ func (c *Cgroup) Apply(pid int) (ActiveCgroup, error) { return rawApply(c, pid) } } - -func (c *Cgroup) setupCpuset(cgroupRoot string, pid int) (err error) { - if c.CpusetCpus != "" { - dir, err := c.Join(cgroupRoot, "cpuset", pid) - if err != nil { - return err - } - defer func() { - if err != nil { - os.RemoveAll(dir) - } - }() - - if err := writeFile(dir, "cpuset.cpus", c.CpusetCpus); err != nil { - return err - } - } - return nil -}