ns: fix reading net namespace in multi-threaded processes
/proc/self/ns/net gives the main thread's namespace, not necessarily
the namespace of the thread that's running the testcases. This causes
sporadic failures of the tests.
For example, with a testcase reading inodes after switching netns:
/proc/27686/task/27689/ns/net 4026532565
/proc/self/ns/net 4026531969
/proc/27686/task/27689/ns/net 4026532565
See also:
008d17ae00
Running Suite: pkg/ns Suite
===========================
Random Seed: 1459953577
Will run 6 of 6 specs
• Failure [0.028 seconds]
Linux namespace operations
/cni/gopath/src/github.com/appc/cni/pkg/ns/ns_test.go:167
WithNetNS
/cni/gopath/src/github.com/appc/cni/pkg/ns/ns_test.go:166
executes the callback within the target network namespace [It]
/cni/gopath/src/github.com/appc/cni/pkg/ns/ns_test.go:97
Expected
<uint64>: 4026531969
to equal
<uint64>: 4026532565
/cni/gopath/src/github.com/appc/cni/pkg/ns/ns_test.go:96
------------------------------
•••••
Summarizing 1 Failure:
[Fail] Linux namespace operations WithNetNS [It] executes the callback within the target network namespace
/cni/gopath/src/github.com/appc/cni/pkg/ns/ns_test.go:96
Ran 6 of 6 Specs in 0.564 seconds
FAIL! -- 5 Passed | 1 Failed | 0 Pending | 0 Skipped --- FAIL: TestNs (0.56s)
FAIL
This commit is contained in:
@ -27,6 +27,16 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func getCurrentThreadNetNSPath() string {
|
||||
pid := unix.Getpid()
|
||||
tid := unix.Gettid()
|
||||
return fmt.Sprintf("/proc/%d/task/%d/ns/net", pid, tid)
|
||||
}
|
||||
|
||||
func GetInodeCurNetNS() (uint64, error) {
|
||||
return GetInode(getCurrentThreadNetNSPath())
|
||||
}
|
||||
|
||||
func GetInode(path string) (uint64, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
@ -68,9 +78,7 @@ func MakeNetworkNS(containerID string) string {
|
||||
defer GinkgoRecover()
|
||||
|
||||
// capture current thread's original netns
|
||||
pid := unix.Getpid()
|
||||
tid := unix.Gettid()
|
||||
currentThreadNetNSPath := fmt.Sprintf("/proc/%d/task/%d/ns/net", pid, tid)
|
||||
currentThreadNetNSPath := getCurrentThreadNetNSPath()
|
||||
originalNetNS, err := unix.Open(currentThreadNetNSPath, unix.O_RDONLY, 0)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer unix.Close(originalNetNS)
|
||||
|
Reference in New Issue
Block a user