From a6a822268c637bc99ff5f7967e3a9d757e504ea0 Mon Sep 17 00:00:00 2001 From: Eugene Yakubovich Date: Tue, 19 May 2015 12:02:41 -0700 Subject: [PATCH] add DHCP IPAM plugin The plugin binary actually functions in two modes. The first mode is a regular CNI plugin. The second mode (when stared with "daemon" arg) runs a DHCP client daemon. When executed as a CNI plugin, it issues an RPC request to the daemon for actual processing. The daemon is required since a DHCP lease needs to be maintained by periodically renewing it. One instance of the daemon can server arbitrary number of containers/leases. --- ns/ns.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/ns/ns.go b/ns/ns.go index 82291f98..20548b9b 100644 --- a/ns/ns.go +++ b/ns/ns.go @@ -48,19 +48,30 @@ func SetNS(f *os.File, flags uintptr) error { // WithNetNSPath executes the passed closure under the given network // namespace, restoring the original namespace afterwards. -func WithNetNSPath(nspath string, f func(*os.File) error) error { +// Changing namespaces must be done on a goroutine that has been +// locked to an OS thread. If lockThread arg is true, this function +// locks the goroutine prior to change namespace and unlocks before +// returning +func WithNetNSPath(nspath string, lockThread bool, f func(*os.File) error) error { ns, err := os.Open(nspath) if err != nil { return fmt.Errorf("Failed to open %v: %v", nspath, err) } defer ns.Close() - - return WithNetNS(ns, f) + return WithNetNS(ns, lockThread, f) } // WithNetNS executes the passed closure under the given network // namespace, restoring the original namespace afterwards. -func WithNetNS(ns *os.File, f func(*os.File) error) error { +// Changing namespaces must be done on a goroutine that has been +// locked to an OS thread. If lockThread arg is true, this function +// locks the goroutine prior to change namespace and unlocks before +// returning +func WithNetNS(ns *os.File, lockThread bool, f func(*os.File) error) error { + if lockThread { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + } // save a handle to current (host) network namespace thisNS, err := os.Open("/proc/self/ns/net") if err != nil {