Skip to content

Commit

Permalink
Merge pull request #69 from plumgrid/nsparalel
Browse files Browse the repository at this point in the history
Better NetNS parallel access
  • Loading branch information
msagheer authored Oct 1, 2016
2 parents 926d2f3 + 2734f2a commit 79b8a55
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 38 deletions.
17 changes: 10 additions & 7 deletions plugin/driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"os/exec"
"runtime"
"strings"
"time"

Log "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/drivers/remote/api"
Expand Down Expand Up @@ -352,20 +353,22 @@ func (driver *driver) joinEndpoint(w http.ResponseWriter, r *http.Request) {
}

objectResponse(w, res)
Log.Infof("Join endpoint %s:%s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)
Log.Infof("Join endpoint %s: %s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)

if auto_arp {
go func(net_ns_path string, pg_ifc_prefix string) {

// Disallow this goroutine to work on any other thread than this one
// since namespace ops (unshare, setns) are done for a single thread, we
// must ensure that the goroutine does not jump from OS thread to thread
runtime.LockOSThread()
defer runtime.UnlockOSThread()

err := RunContainerArping(net_ns_path, pg_ifc_prefix)
if err != nil {
Log.Printf("Error while running arping : %v", err)
for i := 0; i <= 4; i++ {
runtime.LockOSThread()
err := RunContainerArping(net_ns_path, pg_ifc_prefix)
if err != nil {
Log.Printf("Arping failed : %v", err)
}
runtime.UnlockOSThread()
time.Sleep(1 * time.Second)
}

}(j.SandboxKey, ifname.DstPrefix)
Expand Down
39 changes: 8 additions & 31 deletions plugin/driver/network_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"fmt"
"net"
"strings"
"time"

"github.com/google/gopacket"
"github.com/google/gopacket/layers"
Expand All @@ -32,27 +31,12 @@ import (
// that match with the prefix given to libnetwork
func RunContainerArping(net_ns_path string, pg_ifc_prefix string) error {

Log.Printf("Attempting to acces the container %s NetNS", net_ns_path)
var netns ns.NetNS
var err error
success := false

for attempts := 0; attempts <= 5; attempts++ {

netns, err = ns.GetNS(net_ns_path)

if err != nil {
Log.Printf("Attempt %d: failed to open netns %s: %v", attempts, net_ns_path, err)
time.Sleep(1 * time.Second)
} else {
success = true
break
}
attempts += 1
}

if !success {
return fmt.Errorf("Attempts exhaused, could not access %s, exiting", net_ns_path)
netns, err = ns.GetNS(net_ns_path)
if err != nil {
return fmt.Errorf("Failed to open netns %s: %v", net_ns_path, err)
}
defer netns.Close()

Expand All @@ -70,8 +54,6 @@ func RunContainerArping(net_ns_path string, pg_ifc_prefix string) error {
if strings.HasPrefix(ifc.Name, pg_ifc_prefix) {
// Valid PG-created ifc

// TODO we might want to add a retry here to make sure,
// in case the IFC is up but still has no IP, we retry
address_slice, err := ifc.Addrs()
if err != nil {
Log.Errorf("Failed to get Address slice for ifc %s: %v", ifc.Name, err)
Expand All @@ -83,7 +65,6 @@ func RunContainerArping(net_ns_path string, pg_ifc_prefix string) error {
continue
}

Log.Printf("Attempting raw socket open on %s", ifc.Name)
handle, err := pcap.OpenLive(ifc.Name, 65536, true, pcap.BlockForever)
if err != nil {
return fmt.Errorf("Failed to open raw socket %s : %v", ifc.Name, err)
Expand All @@ -105,18 +86,14 @@ func RunContainerArping(net_ns_path string, pg_ifc_prefix string) error {
// Get ARP packet
arp_pkt := getGratuitousArp(ifc.HardwareAddr, ip)

for i := 0; i <= 3; i++ {
Log.Printf("Sending %d GARP on %s : %s - %s",
i, ifc.Name, ifc.HardwareAddr.String(), ip.String())
Log.Printf("Sending %s GARP on %s : %s",
ifc.Name, ifc.HardwareAddr.String(), ip.String())

if err := handle.WritePacketData(arp_pkt); err != nil {
handle.Close()
return fmt.Errorf("Failed to write ARP packet data on %s : %v", ifc.Name, err)
}
time.Sleep(750 * time.Millisecond)
if err := handle.WritePacketData(arp_pkt); err != nil {
Log.Printf("Failed to write ARP packet data on %s : %v", ifc.Name, err)
continue
}
}

// Close the socket
handle.Close()
}
Expand Down

0 comments on commit 79b8a55

Please sign in to comment.