Skip to content

Commit

Permalink
Expand description of goroutine+netns problems
Browse files Browse the repository at this point in the history
  • Loading branch information
bboreham committed Nov 17, 2016
1 parent 61d3f45 commit 44ef109
Showing 1 changed file with 4 additions and 1 deletion.
5 changes: 4 additions & 1 deletion ns/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Go provides the `runtime.LockOSThread()` function to ensure a specific goroutine
For example, you cannot rely on the `ns.Set()` namespace being the current namespace after the `Set()` call unless you do two things. First, the goroutine calling `Set()` must have previously called `LockOSThread()`. Second, you must ensure `runtime.UnlockOSThread()` is not called somewhere in-between. You also cannot rely on the initial network namespace remaining the current network namespace if any other code in your program switches namespaces, unless you have already called `LockOSThread()` in that goroutine. Note that `LockOSThread()` prevents the Go scheduler from optimally scheduling goroutines for best performance, so `LockOSThread()` should only be used in small, isolated goroutines that release the lock quickly.

### Do() The Recommended Thing
The `ns.Do()` method provides control over network namespaces for you by implementing these strategies. All code dependent on a particular network namespace should be wrapped in the `ns.Do()` method to ensure the correct namespace is selected for the duration of your code. For example:
The `ns.Do()` method provides control over network namespaces for you by implementing these strategies. All code dependent on a particular network namespace (including the root namespace) should be wrapped in the `ns.Do()` method to ensure the correct namespace is selected for the duration of your code. For example:

```go
targetNs, err := ns.NewNS()
Expand All @@ -26,6 +26,9 @@ err = targetNs.Do(func(hostNs ns.NetNS) error {
})
```

Note this requirement to wrap every network call is very onerous - any libraries you call might call out to network services such as DNS, and all such calls need to be protected after you call `ns.Do()`. The CNI plugins all exit very soon after calling `ns.Do()` which helps to minimize the problem.

### Further Reading
- https://github.com/golang/go/wiki/LockOSThread
- http:https://morsmachine.dk/go-scheduler
- https://github.com/containernetworking/cni/issues/262

0 comments on commit 44ef109

Please sign in to comment.