Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
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
38 changes: 29 additions & 9 deletions internal/config/nsmgr/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ type Namespace interface {
// Type returns the namespace type (net, ipc, user, pid or uts).
Type() NSType

// Remove ensures this namespace is closed and removed.
// Close ensures this namespace is closed.
Close() error

// Remove ensures this namespace is removed.
Remove() error
}

Expand Down Expand Up @@ -84,13 +87,13 @@ func (n *namespace) Type() NSType {
return n.nsType
}

// Remove ensures this namespace is closed and removed.
func (n *namespace) Remove() error {
// Close ensures this namespace is closed.
func (n *namespace) Close() error {
n.Lock()
defer n.Unlock()

if n.closed {
// Remove() can be called multiple
// Close() can be called multiple
// times without returning an error.
return nil
}
Expand All @@ -101,23 +104,40 @@ func (n *namespace) Remove() error {

n.closed = true

fp := n.Path()
if fp == "" {
if n.nsPath == "" {
return nil
}

// try to unmount, ignoring "not mounted" (EINVAL) error.
if err := unix.Unmount(fp, unix.MNT_DETACH); err != nil && err != unix.EINVAL {
return errors.Wrapf(err, "unable to unmount %s", fp)
if err := unix.Unmount(n.nsPath, unix.MNT_DETACH); err != nil && err != unix.EINVAL {
return errors.Wrapf(err, "unable to unmount %s", n.nsPath)
}
return nil
}

// Remove ensures this namespace is closed and removed.
func (n *namespace) Remove() error {
n.Lock()
defer n.Unlock()
if !n.closed {
return errors.New("Namespace must be closed before it can be removed")
}

if n.nsPath == "" {
return nil
}
return os.RemoveAll(fp)
return os.Remove(n.nsPath)
}

// GetNamespace takes a path and type, checks if it is a namespace, and if so
// returns an instance of the Namespace interface.
func GetNamespace(nsPath string, nsType NSType) (Namespace, error) {
ns, err := nspkg.GetNS(nsPath)
if err != nil {
// path exists but is not an NS, the namespace must have been closed
if _, ok := err.(nspkg.NSPathNotNSErr); ok {
return &namespace{nsType: nsType, nsPath: nsPath, closed: true}, nil
}
return nil, err
}

Expand Down
51 changes: 25 additions & 26 deletions internal/lib/container_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,26 +209,6 @@ func (c *ContainerServer) LoadSandbox(ctx context.Context, id string) (sb *sandb
}
}
}()
// We add an NS only if we can load a permanent one.
// Otherwise, the sandbox will live in the host namespace.
namespacesToJoin := []struct {
rspecNS rspec.LinuxNamespaceType
joinFunc func(string) error
}{
{rspecNS: rspec.NetworkNamespace, joinFunc: sb.NetNsJoin},
{rspecNS: rspec.IPCNamespace, joinFunc: sb.IpcNsJoin},
{rspecNS: rspec.UTSNamespace, joinFunc: sb.UtsNsJoin},
{rspecNS: rspec.UserNamespace, joinFunc: sb.UserNsJoin},
}
for _, namespaceToJoin := range namespacesToJoin {
path, err := configNsPath(&m, namespaceToJoin.rspecNS)
if err == nil {
if nsErr := namespaceToJoin.joinFunc(path); nsErr != nil {
return sb, nsErr
}
}
}

if err := c.AddSandbox(sb); err != nil {
return sb, err
}
Expand Down Expand Up @@ -293,6 +273,31 @@ func (c *ContainerServer) LoadSandbox(ctx context.Context, id string) (sb *sandb
scontainer = oci.NewSpoofedContainer(cID, cname, labels, id, created, sandboxPath)
}

if err := sb.SetInfraContainer(scontainer); err != nil {
return sb, err
}

sb.RestoreStopped()
// We add an NS only if we can load a permanent one.
// Otherwise, the sandbox will live in the host namespace.
namespacesToJoin := []struct {
rspecNS rspec.LinuxNamespaceType
joinFunc func(string) error
}{
{rspecNS: rspec.NetworkNamespace, joinFunc: sb.NetNsJoin},
{rspecNS: rspec.IPCNamespace, joinFunc: sb.IpcNsJoin},
{rspecNS: rspec.UTSNamespace, joinFunc: sb.UtsNsJoin},
{rspecNS: rspec.UserNamespace, joinFunc: sb.UserNsJoin},
}
for _, namespaceToJoin := range namespacesToJoin {
path, err := configNsPath(&m, namespaceToJoin.rspecNS)
if err == nil {
if nsErr := namespaceToJoin.joinFunc(path); nsErr != nil {
return sb, nsErr
}
}
}

if err := c.ContainerStateFromDisk(ctx, scontainer); err != nil {
return sb, fmt.Errorf("error reading sandbox state from disk %q: %v", scontainer.ID(), err)
}
Expand All @@ -303,17 +308,11 @@ func (c *ContainerServer) LoadSandbox(ctx context.Context, id string) (sb *sandb
return sb, fmt.Errorf("failed to write container %q state to disk: %v", scontainer.ID(), err)
}

if err := sb.SetInfraContainer(scontainer); err != nil {
return sb, err
}

sb.SetCreated()
if err := label.ReserveLabel(processLabel); err != nil {
return sb, err
}

sb.RestoreStopped()

if err := c.ctrIDIndex.Add(scontainer.ID()); err != nil {
return sb, err
}
Expand Down
43 changes: 24 additions & 19 deletions internal/lib/sandbox/namespaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,29 +91,34 @@ func (s *Sandbox) NamespacePaths() []*ManagedNamespace {
return typesAndPaths
}

// RemoveManagedNamespaces cleans up after managing the namespaces. It removes all of the namespaces
// and the parent directory in which they lived.
// CloseManagedNamespaces cleans up after managing the namespaces.
// It unmounts all of the namespaces, but does not remove their parent directory.
func (s *Sandbox) CloseManagedNamespaces() error {
return s.runFunctionOnNamespaces(func(ns nsmgr.Namespace) error {
return ns.Close()
})
}

// RemoveManagedNamespaces removes the formerly mounted namespace.
// Must be stopped first or this will fail.
func (s *Sandbox) RemoveManagedNamespaces() error {
return s.runFunctionOnNamespaces(func(ns nsmgr.Namespace) error {
if err := ns.Close(); err != nil {
return err
}
return ns.Remove()
})
}

func (s *Sandbox) runFunctionOnNamespaces(toRun func(nsmgr.Namespace) error) error {
errs := make([]error, 0)

// use a map as a set to delete each parent directory just once
if s.utsns != nil {
if err := s.utsns.Remove(); err != nil {
errs = append(errs, err)
}
}
if s.ipcns != nil {
if err := s.ipcns.Remove(); err != nil {
errs = append(errs, err)
}
}
if s.netns != nil {
if err := s.netns.Remove(); err != nil {
errs = append(errs, err)
allNamespaces := []nsmgr.Namespace{s.utsns, s.ipcns, s.netns, s.userns}
for _, ns := range allNamespaces {
if ns == nil {
continue
}
}
if s.userns != nil {
if err := s.userns.Remove(); err != nil {
if err := toRun(ns); err != nil {
errs = append(errs, err)
}
}
Expand Down
37 changes: 4 additions & 33 deletions internal/lib/sandbox/namespaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ func (s *spoofedIface) Type() nsmgr.NSType {
return s.nsType
}

func (s *spoofedIface) Close() error {
return nil
}

func (s *spoofedIface) Remove() error {
s.removed = true
return nil
Expand Down Expand Up @@ -211,39 +215,6 @@ var _ = t.Describe("SandboxManagedNamespaces", func() {
// When
err := testSandbox.UserNsJoin("/proc/self/ns/user")

// Then
Expect(err).NotTo(BeNil())
})
It("should fail when asked to join a non-namespace", func() {
// Given
// When
err := testSandbox.NetNsJoin("/tmp")

// Then
Expect(err).NotTo(BeNil())
})
It("should fail when asked to join a non-namespace", func() {
// Given

// When
err := testSandbox.IpcNsJoin("/tmp")

// Then
Expect(err).NotTo(BeNil())
})
It("should fail when asked to join a non-namespace", func() {
// Given
// When
err := testSandbox.UtsNsJoin("/tmp")

// Then
Expect(err).NotTo(BeNil())
})
It("should fail when asked to join a non-namespace", func() {
// Given
// When
err := testSandbox.UserNsJoin("/tmp")

// Then
Expect(err).NotTo(BeNil())
})
Expand Down
4 changes: 4 additions & 0 deletions server/sandbox_stop_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ func (s *Server) stopPodSandbox(ctx context.Context, sb *sandbox.Sandbox) error
}
}

if err := sb.CloseManagedNamespaces(); err != nil {
return errors.Wrap(err, "unable to close managed namespaces")
}

if err := sb.UnmountShm(); err != nil {
return err
}
Expand Down