From 98c2593cdcdcb8694516dcdd96738171779b4cd3 Mon Sep 17 00:00:00 2001 From: Vishnu Kannan Date: Wed, 25 Jun 2014 22:51:28 +0000 Subject: [PATCH] Refactores network Interface a bit to use NetworkState struct instead of a map for passing runtime information around. Docker-DCO-1.1-Signed-off-by: Vishnu Kannan (github: vishh) --- namespaces/exec.go | 12 ++++++------ namespaces/init.go | 8 ++++---- namespaces/sync_pipe.go | 14 ++++++++------ network/loopback.go | 4 ++-- network/netns.go | 13 ++++++------- network/state.go | 25 ------------------------- network/strategy.go | 4 ++-- network/types.go | 11 +++++++++++ network/veth.go | 18 ++++++------------ 9 files changed, 45 insertions(+), 64 deletions(-) delete mode 100644 network/state.go diff --git a/namespaces/exec.go b/namespaces/exec.go index e5e2575db..5eeda61d2 100644 --- a/namespaces/exec.go +++ b/namespaces/exec.go @@ -69,7 +69,8 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string defer cleaner.Cleanup() } - if err := InitializeNetworking(container, command.Process.Pid, syncPipe, dataPath); err != nil { + var networkState network.NetworkState + if err := InitializeNetworking(container, command.Process.Pid, syncPipe, &networkState); err != nil { command.Process.Kill() command.Wait() return -1, err @@ -78,7 +79,7 @@ func Exec(container *libcontainer.Config, term Terminal, rootfs, dataPath string state := &libcontainer.State{ InitPid: command.Process.Pid, InitStartTime: started, - NetworkState: *network.NetworkStateImpl.GetNetworkState(), + NetworkState: networkState, } if err := libcontainer.SaveState(dataPath, state); err != nil { @@ -157,18 +158,17 @@ func SetupCgroups(container *libcontainer.Config, nspid int) (cgroups.ActiveCgro // InitializeNetworking creates the container's network stack outside of the namespace and moves // interfaces into the container's net namespaces if necessary -func InitializeNetworking(container *libcontainer.Config, nspid int, pipe *SyncPipe, dataPath string) error { - context := map[string]string{} +func InitializeNetworking(container *libcontainer.Config, nspid int, pipe *SyncPipe, networkState *network.NetworkState) error { for _, config := range container.Networks { strategy, err := network.GetStrategy(config.Type) if err != nil { return err } - if err := strategy.Create((*network.Network)(config), nspid, context, dataPath); err != nil { + if err := strategy.Create((*network.Network)(config), nspid, networkState); err != nil { return err } } - return pipe.SendToChild(context) + return pipe.SendToChild(networkState) } // GetNamespaceFlags parses the container's Namespaces options to set the correct diff --git a/namespaces/init.go b/namespaces/init.go index b0b32750d..6c4745142 100644 --- a/namespaces/init.go +++ b/namespaces/init.go @@ -40,7 +40,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn } // We always read this as it is a way to sync with the parent as well - context, err := syncPipe.ReadFromParent() + networkState, err := syncPipe.ReadFromParent() if err != nil { syncPipe.Close() return err @@ -60,7 +60,7 @@ func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syn return fmt.Errorf("setctty %s", err) } } - if err := setupNetwork(container, context); err != nil { + if err := setupNetwork(container, networkState); err != nil { return fmt.Errorf("setup networking %s", err) } if err := setupRoute(container); err != nil { @@ -165,14 +165,14 @@ func SetupUser(u string) error { // setupVethNetwork uses the Network config if it is not nil to initialize // the new veth interface inside the container for use by changing the name to eth0 // setting the MTU and IP address along with the default gateway -func setupNetwork(container *libcontainer.Config, context map[string]string) error { +func setupNetwork(container *libcontainer.Config, networkState *network.NetworkState) error { for _, config := range container.Networks { strategy, err := network.GetStrategy(config.Type) if err != nil { return err } - err1 := strategy.Initialize((*network.Network)(config), context) + err1 := strategy.Initialize((*network.Network)(config), networkState) if err1 != nil { return err1 } diff --git a/namespaces/sync_pipe.go b/namespaces/sync_pipe.go index 210ee5fbd..57851c5c6 100644 --- a/namespaces/sync_pipe.go +++ b/namespaces/sync_pipe.go @@ -5,6 +5,8 @@ import ( "fmt" "io/ioutil" "os" + + "github.com/docker/libcontainer/network" ) // SyncPipe allows communication to and from the child processes @@ -43,8 +45,8 @@ func (s *SyncPipe) Parent() *os.File { return s.parent } -func (s *SyncPipe) SendToChild(context map[string]string) error { - data, err := json.Marshal(context) +func (s *SyncPipe) SendToChild(networkState *network.NetworkState) error { + data, err := json.Marshal(networkState) if err != nil { return err } @@ -52,18 +54,18 @@ func (s *SyncPipe) SendToChild(context map[string]string) error { return nil } -func (s *SyncPipe) ReadFromParent() (map[string]string, error) { +func (s *SyncPipe) ReadFromParent() (*network.NetworkState, error) { data, err := ioutil.ReadAll(s.child) if err != nil { return nil, fmt.Errorf("error reading from sync pipe %s", err) } - var context map[string]string + var networkState *network.NetworkState if len(data) > 0 { - if err := json.Unmarshal(data, &context); err != nil { + if err := json.Unmarshal(data, &networkState); err != nil { return nil, err } } - return context, nil + return networkState, nil } diff --git a/network/loopback.go b/network/loopback.go index fbc4878bc..46a1fa8c8 100644 --- a/network/loopback.go +++ b/network/loopback.go @@ -10,11 +10,11 @@ import ( type Loopback struct { } -func (l *Loopback) Create(n *Network, nspid int, context map[string]string, _ string) error { +func (l *Loopback) Create(n *Network, nspid int, networkState *NetworkState) error { return nil } -func (l *Loopback) Initialize(config *Network, context map[string]string) error { +func (l *Loopback) Initialize(config *Network, networkState *NetworkState) error { if err := SetMtu("lo", config.Mtu); err != nil { return fmt.Errorf("set lo mtu to %d %s", config.Mtu, err) } diff --git a/network/netns.go b/network/netns.go index 4dd195b6e..64544476b 100644 --- a/network/netns.go +++ b/network/netns.go @@ -14,17 +14,16 @@ import ( type NetNS struct { } -func (v *NetNS) Create(n *Network, nspid int, context map[string]string, _ string) error { - context["nspath"] = n.NsPath +func (v *NetNS) Create(n *Network, nspid int, networkState *NetworkState) error { + networkState.NsPath = n.NsPath return nil } -func (v *NetNS) Initialize(config *Network, context map[string]string) error { - nspath, exists := context["nspath"] - if !exists { - return fmt.Errorf("nspath does not exist in network context") +func (v *NetNS) Initialize(config *Network, networkState *NetworkState) error { + if networkState.NsPath == "" { + return fmt.Errorf("nspath does is not specified in NetworkState") } - f, err := os.OpenFile(nspath, os.O_RDONLY, 0) + f, err := os.OpenFile(networkState.NsPath, os.O_RDONLY, 0) if err != nil { return fmt.Errorf("failed get network namespace fd: %v", err) } diff --git a/network/state.go b/network/state.go deleted file mode 100644 index 71ee012e9..000000000 --- a/network/state.go +++ /dev/null @@ -1,25 +0,0 @@ -package network - -// Struct describing the network specific runtime state that will be maintained by libcontainer for all running containers -// Do not depend on it outside of libcontainer. -type NetworkState struct { - // The name of the veth interface on the Host. - VethHost string `json:"veth_host,omitempty"` - // The name of the veth interface created inside the container for the child. - VethChild string `json:"veth_child,omitempty"` -} - -type networkStateIntImpl struct{} - -var ( - networkState = &NetworkState{} - NetworkStateImpl = &networkStateIntImpl{} -) - -func (networkStateIntImpl) GetNetworkState() *NetworkState { - return networkState -} - -func (networkStateIntImpl) updateNetworkState(n *NetworkState) { - networkState = n -} diff --git a/network/strategy.go b/network/strategy.go index 5c27382fa..be5ec93b7 100644 --- a/network/strategy.go +++ b/network/strategy.go @@ -19,8 +19,8 @@ var strategies = map[string]NetworkStrategy{ // NetworkStrategy represents a specific network configuration for // a container's networking stack type NetworkStrategy interface { - Create(*Network, int, map[string]string, string) error - Initialize(*Network, map[string]string) error + Create(*Network, int, *NetworkState) error + Initialize(*Network, *NetworkState) error } // GetStrategy returns the specific network strategy for the diff --git a/network/types.go b/network/types.go index 14463ab71..0f1df30e8 100644 --- a/network/types.go +++ b/network/types.go @@ -27,3 +27,14 @@ type Network struct { // container's interfaces if a pair is created, specifically in the case of type veth Mtu int `json:"mtu,omitempty"` } + +// Struct describing the network specific runtime state that will be maintained by libcontainer for all running containers +// Do not depend on it outside of libcontainer. +type NetworkState struct { + // The name of the veth interface on the Host. + VethHost string `json:"veth_host,omitempty"` + // The name of the veth interface created inside the container for the child. + VethChild string `json:"veth_child,omitempty"` + // Net namespace path. + NsPath string `json:"ns_path,omitempty"` +} diff --git a/network/veth.go b/network/veth.go index e2167a523..fcafd85cc 100644 --- a/network/veth.go +++ b/network/veth.go @@ -16,7 +16,7 @@ type Veth struct { const defaultDevice = "eth0" -func (v *Veth) Create(n *Network, nspid int, context map[string]string, dataPath string) error { +func (v *Veth) Create(n *Network, nspid int, networkState *NetworkState) error { var ( bridge = n.Bridge prefix = n.VethPrefix @@ -31,8 +31,6 @@ func (v *Veth) Create(n *Network, nspid int, context map[string]string, dataPath if err != nil { return err } - context["veth-host"] = name1 - context["veth-child"] = name2 if err := SetInterfaceMaster(name1, bridge); err != nil { return err } @@ -45,20 +43,16 @@ func (v *Veth) Create(n *Network, nspid int, context map[string]string, dataPath if err := SetInterfaceInNamespacePid(name2, nspid); err != nil { return err } - networkState := NetworkStateImpl.GetNetworkState() networkState.VethHost = name1 networkState.VethChild = name2 - NetworkStateImpl.updateNetworkState(networkState) + return nil } -func (v *Veth) Initialize(config *Network, context map[string]string) error { - var ( - vethChild string - exists bool - ) - if vethChild, exists = context["veth-child"]; !exists { - return fmt.Errorf("vethChild does not exist in network context") +func (v *Veth) Initialize(config *Network, networkState *NetworkState) error { + var vethChild = networkState.VethChild + if vethChild == "" { + return fmt.Errorf("vethChild is not specified") } if err := InterfaceDown(vethChild); err != nil { return fmt.Errorf("interface down %s %s", vethChild, err)