Skip to content

Commit

Permalink
rootless netns, one netns per libpod tmp dir
Browse files Browse the repository at this point in the history
The netns cleanup code is checking if there are running containers, this
can fail if you run several libpod instances with diffrent root/runroot.
To fix it we use one netns for each libpod instances. To prevent name
conflicts we use a hash from the static dir as part of the name.

Previously this worked because we would use the CNI files to check if
the netns was still in use. but this is no longer possible with netavark.

[NO NEW TESTS NEEDED]

Fixes containers#12306

Signed-off-by: Paul Holzinger <[email protected]>
  • Loading branch information
Luap99 committed Nov 18, 2021
1 parent 9b96494 commit 62d6b6b
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions libpod/networking_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package libpod

import (
"crypto/rand"
"crypto/sha1"
"fmt"
"io/ioutil"
"net"
Expand Down Expand Up @@ -400,10 +401,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
return nil, nil
}
var rootlessNetNS *RootlessNetNS
runDir, err := util.GetRuntimeDir()
if err != nil {
return nil, err
}
runDir := r.config.Engine.TmpDir

lfile := filepath.Join(runDir, "rootless-netns.lock")
lock, err := lockfile.GetLockfile(lfile)
Expand All @@ -429,16 +427,24 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
if err != nil {
return nil, err
}
path := filepath.Join(nsDir, rootlessNetNsName)

// create a hash from the static dir
// the cleanup will check if there are running containers
// if you run a several libpod instances with different root/runroot directories this check will fail
// we want one netns for each libpod static dir so we use the hash to prevent name collisions
hash := sha1.Sum([]byte(r.config.Engine.StaticDir))
netnsName := fmt.Sprintf("%s-%x", rootlessNetNsName, hash[:10])

path := filepath.Join(nsDir, netnsName)
ns, err := ns.GetNS(path)
if err != nil {
if !new {
// return a error if we could not get the namespace and should no create one
return nil, errors.Wrap(err, "error getting rootless network namespace")
}
// create a new namespace
logrus.Debug("creating rootless network namespace")
ns, err = netns.NewNSWithName(rootlessNetNsName)
logrus.Debugf("creating rootless network namespace with name %q", netnsName)
ns, err = netns.NewNSWithName(netnsName)
if err != nil {
return nil, errors.Wrap(err, "error creating rootless network namespace")
}
Expand Down

0 comments on commit 62d6b6b

Please sign in to comment.