Skip to content

Commit

Permalink
Fix race condition in GetCurrentNS temporarily (antrea-io#1131)
Browse files Browse the repository at this point in the history
In GetCurrentNS, If there is a context-switch between
getCurrentThreadNetNSPath and GetNS, another goroutine may execute in
the original thread and change its network namespace, then the original
goroutine would get the updated network namespace, which could lead to
unexpected behavior, especially when GetCurrentNS is used to get the
host network namespace in netNS.Do.

Instead of using the provided netns argument, this patch fixes it by
getting the hostNS in advance with the OS thread locked.
  • Loading branch information
tnqn authored and antoninbas committed Aug 21, 2020
1 parent 8b5d587 commit db7acd8
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion pkg/agent/cniserver/interface_configuration_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package cniserver
import (
"fmt"
"net"
"runtime"
"time"

"github.com/Mellanox/sriovnet"
Expand Down Expand Up @@ -194,7 +195,22 @@ func (ic *ifConfigurator) configureContainerLinkVeth(
hostIface := &current.Interface{Name: hostIfaceName}
containerIface := &current.Interface{Name: containerIfaceName, Sandbox: containerNetNS}
result.Interfaces = []*current.Interface{hostIface, containerIface}
if err := ns.WithNetNSPath(containerNetNS, func(hostNS ns.NetNS) error {

// This is a workaround for issue #1113, which is caused by https://github.com/containernetworking/plugins/issues/524.
// Instead of using the provided netns argument, which might not be the real hostNS, it fixes it by getting the
// hostNS in advance with the OS thread locked.
// TODO: remove this once the upstream issue is fixed.
hostNS, err := func() (ns.NetNS, error) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
return ns.GetCurrentNS()
}()
if err != nil {
return fmt.Errorf("failed to get host netns: %v", err)
}
defer hostNS.Close()

if err := ns.WithNetNSPath(containerNetNS, func(_ ns.NetNS) error {
klog.V(2).Infof("Creating veth devices (%s, %s) for container %s", containerIfaceName, hostIfaceName, containerID)
hostVeth, containerVeth, err := ip.SetupVethWithName(containerIfaceName, hostIfaceName, mtu, hostNS)
if err != nil {
Expand Down

0 comments on commit db7acd8

Please sign in to comment.