From c96d2faaac4a831ed2d17194a7f6d93b4f2a8be3 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 4 May 2023 18:21:01 +0200 Subject: [PATCH] libpod: only mount netns when required When we run pasta or slirp4netns we do not have to mount the netns because we do not have to do any teardown. Signed-off-by: Paul Holzinger --- libpod/container_internal.go | 19 ----------- libpod/networking_linux.go | 55 +++++++++++++++++--------------- libpod/networking_slirp4netns.go | 3 +- 3 files changed, 31 insertions(+), 46 deletions(-) diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 6b3aaae0b650..d74f87a4d385 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -17,7 +17,6 @@ import ( "github.com/containers/buildah/pkg/overlay" butil "github.com/containers/buildah/util" "github.com/containers/common/libnetwork/etchosts" - "github.com/containers/common/libnetwork/resolvconf" "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/chown" "github.com/containers/common/pkg/config" @@ -984,7 +983,6 @@ func (c *Container) checkDependenciesRunning() ([]string, error) { } func (c *Container) completeNetworkSetup() error { - var nameservers []string netDisabled, err := c.NetworkDisabled() if err != nil { return err @@ -1001,30 +999,13 @@ func (c *Container) completeNetworkSetup() error { if err := c.save(); err != nil { return err } - state := c.state - // collect any dns servers that the network backend tells us to use - for _, status := range c.getNetworkStatus() { - for _, server := range status.DNSServerIPs { - nameservers = append(nameservers, server.String()) - } - } - nameservers = c.addSlirp4netnsDNS(nameservers) // add /etc/hosts entries if err := c.addHosts(); err != nil { return err } - // check if we have a bindmount for resolv.conf - resolvBindMount := state.BindMounts[resolvconf.DefaultResolvConf] - if len(nameservers) < 1 || resolvBindMount == "" || len(c.config.NetNsCtr) > 0 { - return nil - } - return c.addResolvConf() - - // write and return - return resolvconf.Add(resolvBindMount, nameservers) } // Initialize a container, creating it in the runtime diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 9b4585f35d60..13aa1c4145a5 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -617,39 +617,44 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS string) (status map[strin // Configure the network namespace using the container process func (r *Runtime) setupNetNS(ctr *Container) error { - nsProcess := fmt.Sprintf("/proc/%d/ns/net", ctr.state.PID) + netnsPath := fmt.Sprintf("/proc/%d/ns/net", ctr.state.PID) - b := make([]byte, 16) - - if _, err := rand.Reader.Read(b); err != nil { - return fmt.Errorf("failed to generate random netns name: %w", err) - } - nsPath, err := netns.GetNSRunDir() - if err != nil { - return err - } - nsPath = filepath.Join(nsPath, fmt.Sprintf("netns-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])) + // We only need to mount the netns for bridge because we need to call CNI/netavark + // with it to teardown after the process exits. For pasta and slirp it is fine to + // just use the /proc/$PID path + if ctr.config.NetMode.IsBridge() { + b := make([]byte, 16) + if _, err := rand.Reader.Read(b); err != nil { + return fmt.Errorf("failed to generate random netns name: %w", err) + } + nsPath, err := netns.GetNSRunDir() + if err != nil { + return err + } + nsPath = filepath.Join(nsPath, fmt.Sprintf("netns-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])) - if err := os.MkdirAll(filepath.Dir(nsPath), 0711); err != nil { - return err - } + if err := os.MkdirAll(filepath.Dir(nsPath), 0711); err != nil { + return err + } - mountPointFd, err := os.Create(nsPath) - if err != nil { - return err - } - if err := mountPointFd.Close(); err != nil { - return err - } + mountPointFd, err := os.Create(nsPath) + if err != nil { + return err + } + if err := mountPointFd.Close(); err != nil { + return err + } - if err := unix.Mount(nsProcess, nsPath, "none", unix.MS_BIND, ""); err != nil { - return fmt.Errorf("cannot mount %s: %w", nsPath, err) + if err := unix.Mount(netnsPath, nsPath, "none", unix.MS_BIND, ""); err != nil { + return fmt.Errorf("cannot mount %s: %w", nsPath, err) + } + netnsPath = nsPath } - networkStatus, err := r.configureNetNS(ctr, nsPath) + networkStatus, err := r.configureNetNS(ctr, netnsPath) // Assign NetNS attributes to container - ctr.state.NetNS = nsPath + ctr.state.NetNS = netnsPath ctr.state.NetworkStatus = networkStatus return err } diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go index c61e36736477..e103009a61c4 100644 --- a/libpod/networking_slirp4netns.go +++ b/libpod/networking_slirp4netns.go @@ -212,7 +212,7 @@ func createBasicSlirp4netnsCmdArgs(options *slirp4netnsNetworkOptions, features } // setupSlirp4netns can be called in rootful as well as in rootless -func (r *Runtime) setupSlirp4netns(ctr *Container, netns string) error { +func (r *Runtime) setupSlirp4netns(ctr *Container, netnsPath string) error { path := r.config.Engine.NetworkCmdPath if path == "" { var err error @@ -263,7 +263,6 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns string) error { } defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncR) defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncW) - netnsPath := fmt.Sprintf("/proc/%d/ns/net", ctr.state.PID) // we don't use --netns-path here (unavailable for slirp4netns < v0.4) cmdArgs = append(cmdArgs, fmt.Sprintf("%d", ctr.state.PID), "tap0")