Merge pull request #523 from tnqn/ns-race

Fix race condition in GetCurrentNS
This commit is contained in:
Casey Callendrello 2020-08-26 17:41:51 +02:00 committed by GitHub
commit dacb671328
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 0 deletions

View File

@ -26,6 +26,11 @@ import (
// Returns an object representing the current OS thread's network namespace
func GetCurrentNS() (NetNS, error) {
// Lock the thread in case other goroutine executes in it and changes its
// network namespace after getCurrentThreadNetNSPath(), otherwise it might
// return an unexpected network namespace.
runtime.LockOSThread()
defer runtime.UnlockOSThread()
return GetNS(getCurrentThreadNetNSPath())
}

View File

@ -20,6 +20,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"sync"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
@ -118,6 +119,33 @@ var _ = Describe("Linux namespace operations", func() {
Expect(err).NotTo(HaveOccurred())
})
Context("when called concurrently", func() {
It("provides the original namespace as the argument to the callback", func() {
concurrency := 200
origNS, err := ns.GetCurrentNS()
Expect(err).NotTo(HaveOccurred())
origNSInode, err := getInodeNS(origNS)
Expect(err).NotTo(HaveOccurred())
var wg sync.WaitGroup
wg.Add(concurrency)
for i := 0; i < concurrency; i++ {
go func() {
defer wg.Done()
targetNetNS.Do(func(hostNS ns.NetNS) error {
defer GinkgoRecover()
hostNSInode, err := getInodeNS(hostNS)
Expect(err).NotTo(HaveOccurred())
Expect(hostNSInode).To(Equal(origNSInode))
return nil
})
}()
}
wg.Wait()
})
})
Context("when the callback returns an error", func() {
It("restores the calling thread to the original namespace before returning", func() {
err := originalNetNS.Do(func(ns.NetNS) error {