Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rootless netns: recover from invalid netns #18024

Merged
merged 1 commit into from
Apr 4, 2023
Merged
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
19 changes: 15 additions & 4 deletions libpod/networking_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,15 +365,26 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
netnsName := fmt.Sprintf("%s-%x", rootlessNetNsName, hash[:10])

path := filepath.Join(nsDir, netnsName)
ns, err := ns.GetNS(path)
nsReference, err := ns.GetNS(path)
if err != nil {
if !new {
// return an error if we could not get the namespace and should no create one
return nil, fmt.Errorf("getting rootless network namespace: %w", err)
}

// When the netns is not valid but the file exists we have to remove it first,
// https://github.com/containers/common/pull/1381 changed the behavior from
// NewNSWithName()so it will now error whe the file already exists.
// https://github.com/containers/podman/issues/17903#issuecomment-1494329622
if errors.As(err, &ns.NSPathNotNSErr{}) {
logrus.Infof("rootless netns is no longer valid: %v", err)
// ignore errors, if something is wrong NewNSWithName() will fail below anyway
_ = os.Remove(path)
}

// create a new namespace
logrus.Debugf("creating rootless network namespace with name %q", netnsName)
ns, err = netns.NewNSWithName(netnsName)
nsReference, err = netns.NewNSWithName(netnsName)
giuseppe marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, fmt.Errorf("creating rootless network namespace: %w", err)
}
Expand Down Expand Up @@ -408,7 +419,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
}
// Note we do not use --exit-fd, we kill this process by pid
cmdArgs = append(cmdArgs, "-c", "-r", "3")
cmdArgs = append(cmdArgs, "--netns-type=path", ns.Path(), "tap0")
cmdArgs = append(cmdArgs, "--netns-type=path", nsReference.Path(), "tap0")

cmd := exec.Command(path, cmdArgs...)
logrus.Debugf("slirp4netns command: %s", strings.Join(cmd.Args, " "))
Expand Down Expand Up @@ -540,7 +551,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
// Important set rootlessNetNS as last step.
// Do not return any errors after this.
rootlessNetNS = &RootlessNetNS{
ns: ns,
ns: nsReference,
dir: rootlessNetNsDir,
Lock: lock,
}
Expand Down