From b6a9bdb38fc000dce0edbf82e3b7f79b3a6a3060 Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Sat, 27 Sep 2014 06:24:03 -0400 Subject: [PATCH] Allow IPC namespace to be shared between containers or with the host Some workloads rely on IPC for communications with other processes. We would like to split workloads between two container but still allow them to communicate though shared IPC. This patch allows us to mimic the --net code to allow --ipc=host to not split off the IPC Namespace. ipc=container:CONTAINERID to share ipc between containers Docker-DCO-1.1-Signed-off-by: Dan Walsh (github: rhatdan) --- Makefile | 4 ++-- config.go | 3 +++ ipc/ipc.go | 31 +++++++++++++++++++++++++++++++ namespaces/init.go | 4 ++++ 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 ipc/ipc.go diff --git a/Makefile b/Makefile index 0ec995fc..0c4dda7c 100644 --- a/Makefile +++ b/Makefile @@ -12,10 +12,10 @@ sh: GO_PACKAGES = $(shell find . -not \( -wholename ./vendor -prune -o -wholename ./.git -prune \) -name '*.go' -print0 | xargs -0n1 dirname | sort -u) direct-test: - go test -cover -v $(GO_PACKAGES) + go test $(TEST_TAGS) -cover -v $(GO_PACKAGES) direct-test-short: - go test -cover -test.short -v $(GO_PACKAGES) + go test $(TEST_TAGS) -cover -test.short -v $(GO_PACKAGES) direct-build: go build -v $(GO_PACKAGES) diff --git a/config.go b/config.go index 1fb377dc..57ea5c69 100644 --- a/config.go +++ b/config.go @@ -47,6 +47,9 @@ type Config struct { // Networks specifies the container's network setup to be created Networks []*Network `json:"networks,omitempty"` + // Ipc specifies the container's ipc setup to be created + IpcNsPath string `json:"ipc,omitempty"` + // Routes can be specified to create entries in the route table as the container is started Routes []*Route `json:"routes,omitempty"` diff --git a/ipc/ipc.go b/ipc/ipc.go new file mode 100644 index 00000000..3681d013 --- /dev/null +++ b/ipc/ipc.go @@ -0,0 +1,31 @@ +package ipc + +import ( + "fmt" + "os" + "syscall" + + "github.com/docker/libcontainer/system" +) + +// Join the IPC Namespace of specified ipc path if it exists. +// If the path does not exist then you are not joining a container. +func Initialize(nsPath string) error { + + if nsPath == "" { + return nil + } + f, err := os.OpenFile(nsPath, os.O_RDONLY, 0) + if err != nil { + return fmt.Errorf("failed get IPC namespace fd: %v", err) + } + + err = system.Setns(f.Fd(), syscall.CLONE_NEWIPC) + f.Close() + + if err != nil { + return fmt.Errorf("failed to setns current IPC namespace: %v", err) + } + + return nil +} diff --git a/namespaces/init.go b/namespaces/init.go index 4c2b3327..879ac21e 100644 --- a/namespaces/init.go +++ b/namespaces/init.go @@ -11,6 +11,7 @@ import ( "github.com/docker/libcontainer" "github.com/docker/libcontainer/apparmor" "github.com/docker/libcontainer/console" + "github.com/docker/libcontainer/ipc" "github.com/docker/libcontainer/label" "github.com/docker/libcontainer/mount" "github.com/docker/libcontainer/netlink" @@ -66,6 +67,9 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn return fmt.Errorf("setctty %s", err) } } + if err := ipc.Initialize(container.IpcNsPath); err != nil { + return fmt.Errorf("setup IPC %s", err) + } if err := setupNetwork(container, networkState); err != nil { return fmt.Errorf("setup networking %s", err) }