Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions common/libnetwork/internal/rootlessnetns/netns_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,17 @@ func (n *Netns) getPath(path string) string {

// getOrCreateNetns returns the rootless netns, if it created a new one the
// returned bool is set to true.
func (n *Netns) getOrCreateNetns() (netns.NetNS, bool, error) {
func (n *Netns) getOrCreateNetns(create bool) (netns.NetNS, bool, error) {
nsPath := n.getPath(rootlessNetnsDir)
nsRef, err := netns.GetNS(nsPath)
if err == nil {
if !create {
if err := n.deserializeInfo(); err != nil {
return nil, false, wrapError("deserialize info", err)
}
return nsRef, false, nil
}

pidPath := n.getPath(rootlessNetNsConnPidFile)
pid, err := readPidFile(pidPath)
if err == nil {
Expand All @@ -133,6 +140,10 @@ func (n *Netns) getOrCreateNetns() (netns.NetNS, bool, error) {
}
// In case of errors continue and setup the network cmd again.
} else {
if !create {
return nil, false, err
}

// Special case, the file might exist already but is not a valid netns.
// One reason could be that a previous setup was killed between creating
// the file and mounting it. Or if the file is not on tmpfs (deleted on boot)
Expand Down Expand Up @@ -539,8 +550,8 @@ func (n *Netns) setupMounts() error {
return nil
}

func (n *Netns) runInner(toRun func() error, cleanup bool) (err error) {
nsRef, newNs, err := n.getOrCreateNetns()
func (n *Netns) runInner(toRun func() error, cleanup bool, create bool) (err error) {
nsRef, newNs, err := n.getOrCreateNetns(create)
if err != nil {
return err
}
Expand Down Expand Up @@ -568,7 +579,7 @@ func (n *Netns) runInner(toRun func() error, cleanup bool) (err error) {
}

func (n *Netns) Setup(nets int, toRun func() error) error {
err := n.runInner(toRun, true)
err := n.runInner(toRun, true, true)
if err != nil {
return err
}
Expand All @@ -577,7 +588,7 @@ func (n *Netns) Setup(nets int, toRun func() error) error {
}

func (n *Netns) Teardown(nets int, toRun func() error) error {
err := n.runInner(toRun, true)
err := n.runInner(toRun, true, false)
if err != nil {
return err
}
Expand Down Expand Up @@ -614,7 +625,7 @@ func (n *Netns) Run(lock *lockfile.LockFile, toRun func() error) error {
return err
}

inErr := n.runInner(inner, false)
inErr := n.runInner(inner, false, true)
// make sure to always reset the ref counter afterwards
count, err := refCount(n.dir, -1)
if err != nil {
Expand Down
30 changes: 30 additions & 0 deletions common/libnetwork/internal/rootlessnetns/netns_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"go.podman.io/common/pkg/config"
)

func Test_refCount(t *testing.T) {
Expand Down Expand Up @@ -75,3 +76,32 @@ func Test_refCount(t *testing.T) {
})
}
}

func Test_getOrCreateNetnsNoCreateDoesNotRestartHelper(t *testing.T) {
dir := t.TempDir()

conf, err := config.Default()
assert.NoError(t, err)

n, err := New(dir, conf)
assert.NoError(t, err)

nsPath := n.getPath(rootlessNetnsDir)
err = os.Symlink("/proc/self/ns/net", nsPath)
assert.NoError(t, err)

err = os.WriteFile(
n.getPath(rootlessNetNsConnPidFile),
[]byte("99999999"),
0o600,
)
assert.NoError(t, err)

ns, created, err := n.getOrCreateNetns(false)
assert.NoError(t, err)
assert.False(t, created)

if ns != nil {
assert.NoError(t, ns.Close())
}
}