diff --git a/libpod/container_internal_freebsd.go b/libpod/container_internal_freebsd.go index cae11cd2ba..32e1f1a8d7 100644 --- a/libpod/container_internal_freebsd.go +++ b/libpod/container_internal_freebsd.go @@ -85,6 +85,9 @@ func (c *Container) prepare() error { wg.Wait() var createErr error + if createNetNSErr != nil { + createErr = createNetNSErr + } if mountStorageErr != nil { if createErr != nil { logrus.Errorf("Preparing container %s: %v", c.ID(), createErr) @@ -92,7 +95,23 @@ func (c *Container) prepare() error { createErr = mountStorageErr } + // Only trigger storage cleanup if mountStorage was successful. + // Otherwise, we may mess up mount counters. if createErr != nil { + if mountStorageErr == nil { + if err := c.cleanupStorage(); err != nil { + // createErr is guaranteed non-nil, so print + // unconditionally + logrus.Errorf("Preparing container %s: %v", c.ID(), createErr) + createErr = fmt.Errorf("unmounting storage for container %s after network create failure: %w", c.ID(), err) + } + } + // It's OK to unconditionally trigger network cleanup. If the network + // isn't ready it will do nothing. + if err := c.cleanupNetwork(); err != nil { + logrus.Errorf("Preparing container %s: %v", c.ID(), createErr) + createErr = fmt.Errorf("cleaning up container %s network after setup failure: %w", c.ID(), err) + } return createErr } diff --git a/libpod/networking_freebsd.go b/libpod/networking_freebsd.go index 230efc99d1..0c2168c96a 100644 --- a/libpod/networking_freebsd.go +++ b/libpod/networking_freebsd.go @@ -166,14 +166,23 @@ func (r *Runtime) createNetNS(ctr *Container) (n *jailNetNS, q map[string]types. jconf.Set("allow.raw_sockets", true) jconf.Set("allow.chflags", true) jconf.Set("securelevel", -1) - if _, err := jail.Create(jconf); err != nil { - logrus.Debugf("Failed to create vnet jail %s for container %s", ctrNS.Name, ctr.ID()) + j, err := jail.Create(jconf) + if err != nil { + return nil, nil, fmt.Errorf("Failed to create vnet jail %s for container %s: %w", ctrNS.Name, ctr.ID(), err) } logrus.Debugf("Created vnet jail %s for container %s", ctrNS.Name, ctr.ID()) var networkStatus map[string]types.StatusBlock networkStatus, err = r.configureNetNS(ctr, ctrNS) + if err != nil { + jconf := jail.NewConfig() + jconf.Set("persist", false) + if err := j.Set(jconf); err != nil { + // Log this error and return the error from configureNetNS + logrus.Errorf("failed to destroy vnet jail %s: %w", ctrNS.Name, err) + } + } return ctrNS, networkStatus, err }