mirror of
https://github.com/containers/podman.git
synced 2025-12-02 02:58:03 +08:00
vendor latest c/common main
Includes several rootless-netns fixes. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
103
vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go
generated
vendored
103
vendor/github.com/containers/common/libnetwork/internal/rootlessnetns/netns_linux.go
generated
vendored
@@ -100,18 +100,37 @@ func (n *Netns) getOrCreateNetns() (ns.NetNS, bool, error) {
|
||||
nsPath := n.getPath(rootlessNetnsDir)
|
||||
nsRef, err := ns.GetNS(nsPath)
|
||||
if err == nil {
|
||||
// TODO check if slirp4netns is alive
|
||||
return nsRef, false, nil
|
||||
}
|
||||
logrus.Debugf("Creating rootless network namespace at %q", nsPath)
|
||||
// We have to create the netns dir again here because it is possible
|
||||
// that cleanup() removed it.
|
||||
if err := os.MkdirAll(n.dir, 0o700); err != nil {
|
||||
return nil, false, wrapError("", err)
|
||||
}
|
||||
netns, err := netns.NewNSAtPath(nsPath)
|
||||
if err != nil {
|
||||
return nil, false, wrapError("create netns", err)
|
||||
pidPath := n.getPath(rootlessNetNsConnPidFile)
|
||||
pid, err := readPidFile(pidPath)
|
||||
if err == nil {
|
||||
// quick check if pasta/slirp4netns are still running
|
||||
err := unix.Kill(pid, 0)
|
||||
if err == nil {
|
||||
// All good, return the netns.
|
||||
return nsRef, false, nil
|
||||
}
|
||||
// Print warnings in case things went wrong, we might be able to recover
|
||||
// but maybe not so make sure to leave some hints so we can figure out what went wrong.
|
||||
if errors.Is(err, unix.ESRCH) {
|
||||
logrus.Warn("rootless netns program no longer running, trying to start it again")
|
||||
} else {
|
||||
logrus.Warnf("failed to check if rootless netns program is running: %v, trying to start it again", err)
|
||||
}
|
||||
} else {
|
||||
logrus.Warnf("failed to read rootless netns program pid: %v", err)
|
||||
}
|
||||
// In case of errors continue and setup the network cmd again.
|
||||
} else {
|
||||
logrus.Debugf("Creating rootless network namespace at %q", nsPath)
|
||||
// We have to create the netns dir again here because it is possible
|
||||
// that cleanup() removed it.
|
||||
if err := os.MkdirAll(n.dir, 0o700); err != nil {
|
||||
return nil, false, wrapError("", err)
|
||||
}
|
||||
nsRef, err = netns.NewNSAtPath(nsPath)
|
||||
if err != nil {
|
||||
return nil, false, wrapError("create netns", err)
|
||||
}
|
||||
}
|
||||
switch strings.ToLower(n.config.Network.DefaultRootlessNetworkCmd) {
|
||||
case "", slirp4netns.BinaryName:
|
||||
@@ -121,7 +140,17 @@ func (n *Netns) getOrCreateNetns() (ns.NetNS, bool, error) {
|
||||
default:
|
||||
err = fmt.Errorf("invalid rootless network command %q", n.config.Network.DefaultRootlessNetworkCmd)
|
||||
}
|
||||
return netns, true, err
|
||||
// If pasta or slirp4netns fail here we need to get rid of the netns again to not leak it,
|
||||
// otherwise the next command thinks the netns was successfully setup.
|
||||
if err != nil {
|
||||
if nerr := netns.UnmountNS(nsPath); nerr != nil {
|
||||
logrus.Error(nerr)
|
||||
}
|
||||
_ = nsRef.Close()
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return nsRef, true, nil
|
||||
}
|
||||
|
||||
func (n *Netns) cleanup() error {
|
||||
@@ -165,11 +194,7 @@ func (n *Netns) setupPasta(nsPath string) error {
|
||||
|
||||
if systemd.RunsOnSystemd() {
|
||||
// Treat these as fatal - if pasta failed to write a PID file something is probably wrong.
|
||||
pidfile, err := os.ReadFile(pidPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to open pasta PID file: %w", err)
|
||||
}
|
||||
pid, err := strconv.Atoi(strings.TrimSpace(string(pidfile)))
|
||||
pid, err := readPidFile(pidPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to decode pasta PID: %w", err)
|
||||
}
|
||||
@@ -245,16 +270,12 @@ func (n *Netns) setupSlirp4netns(nsPath string) error {
|
||||
|
||||
func (n *Netns) cleanupRootlessNetns() error {
|
||||
pidFile := n.getPath(rootlessNetNsConnPidFile)
|
||||
b, err := os.ReadFile(pidFile)
|
||||
pid, err := readPidFile(pidFile)
|
||||
if err == nil {
|
||||
var i int
|
||||
i, err = strconv.Atoi(strings.TrimSpace(string(b)))
|
||||
if err == nil {
|
||||
// kill the slirp process so we do not leak it
|
||||
err = unix.Kill(i, unix.SIGTERM)
|
||||
if err == unix.ESRCH {
|
||||
err = nil
|
||||
}
|
||||
// kill the slirp/pasta process so we do not leak it
|
||||
err = unix.Kill(pid, unix.SIGTERM)
|
||||
if err == unix.ESRCH {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
return err
|
||||
@@ -294,6 +315,13 @@ func (n *Netns) setupMounts() error {
|
||||
return wrapError("create new mount namespace", err)
|
||||
}
|
||||
|
||||
// Ensure we mount private in our mountns to prevent accidentally
|
||||
// overwriting the host mounts in case the default propagation is shared.
|
||||
err = unix.Mount("", "/", "", unix.MS_PRIVATE|unix.MS_REC, "")
|
||||
if err != nil {
|
||||
return wrapError("make tree private in new mount namespace", err)
|
||||
}
|
||||
|
||||
xdgRuntimeDir, err := homedir.GetRuntimeDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not get runtime directory: %w", err)
|
||||
@@ -301,7 +329,7 @@ func (n *Netns) setupMounts() error {
|
||||
newXDGRuntimeDir := n.getPath(xdgRuntimeDir)
|
||||
// 1. Mount the netns into the new run to keep them accessible.
|
||||
// Otherwise cni setup will fail because it cannot access the netns files.
|
||||
err = mountAndMkdirDest(xdgRuntimeDir, newXDGRuntimeDir, none, unix.MS_BIND|unix.MS_SHARED|unix.MS_REC)
|
||||
err = mountAndMkdirDest(xdgRuntimeDir, newXDGRuntimeDir, none, unix.MS_BIND|unix.MS_REC)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -556,15 +584,12 @@ func (n *Netns) Run(lock *lockfile.LockFile, toRun func() error) error {
|
||||
logrus.Errorf("Failed to decrement ref count: %v", err)
|
||||
return inErr
|
||||
}
|
||||
if count == 0 {
|
||||
// runInner() already cleans up the netns when it created a new one on errors
|
||||
// so we only need to do that if there was no error.
|
||||
if inErr == nil && count == 0 {
|
||||
err = n.cleanup()
|
||||
if err != nil {
|
||||
err = wrapError("cleanup", err)
|
||||
if inErr == nil {
|
||||
return err
|
||||
}
|
||||
logrus.Errorf("Failed to cleanup rootless netns: %v", err)
|
||||
return inErr
|
||||
return wrapError("cleanup", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,3 +624,11 @@ func refCount(dir string, inc int) (int, error) {
|
||||
|
||||
return currentCount, nil
|
||||
}
|
||||
|
||||
func readPidFile(path string) (int, error) {
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.Atoi(strings.TrimSpace(string(b)))
|
||||
}
|
||||
|
||||
8
vendor/github.com/containers/common/libnetwork/netavark/network.go
generated
vendored
8
vendor/github.com/containers/common/libnetwork/netavark/network.go
generated
vendored
@@ -135,7 +135,11 @@ func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) {
|
||||
}
|
||||
|
||||
var netns *rootlessnetns.Netns
|
||||
if unshare.IsRootless() {
|
||||
// Do not use unshare.IsRootless() here. We only care if we are running re-exec in the userns,
|
||||
// IsRootless() also returns true if we are root in a userns which is not what we care about and
|
||||
// causes issues as this slower more complicated rootless-netns logic should not be used as root.
|
||||
_, useRootlessNetns := os.LookupEnv(unshare.UsernsEnvName)
|
||||
if useRootlessNetns {
|
||||
netns, err = rootlessnetns.New(conf.NetworkRunDir, rootlessnetns.Netavark, conf.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -147,7 +151,7 @@ func NewNetworkInterface(conf *InitConfig) (types.ContainerNetwork, error) {
|
||||
networkRunDir: conf.NetworkRunDir,
|
||||
netavarkBinary: conf.NetavarkBinary,
|
||||
aardvarkBinary: conf.AardvarkBinary,
|
||||
networkRootless: unshare.IsRootless(),
|
||||
networkRootless: useRootlessNetns,
|
||||
ipamDBPath: filepath.Join(conf.NetworkRunDir, "ipam.db"),
|
||||
firewallDriver: conf.Config.Network.FirewallDriver,
|
||||
defaultNetwork: defaultNetworkName,
|
||||
|
||||
Reference in New Issue
Block a user