Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
vc: error handling for bindUnmount functionalities
Browse files Browse the repository at this point in the history
Add error handling surrounding the syscall of unmounting the
container rootfs. Include a unit test to check that missing
files are not considered errors when attempting to unmount.

Fixes: #164

Signed-off-by: gabrielle beyer <[email protected]>
  • Loading branch information
gabrielle beyer committed Jun 11, 2019
1 parent 61fff89 commit e08f13e
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
8 changes: 6 additions & 2 deletions virtcontainers/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,9 @@ func TestStartSandboxKataAgentSuccessful(t *testing.T) {

// TODO: defaultSharedDir is a hyper var = /run/hyper/shared/sandboxes
// do we need to unmount sandboxes and containers?
bindUnmountAllRootfs(ctx, testDir, pImpl)
if err := bindUnmountAllRootfs(ctx, testDir, pImpl); err != nil {
t.Fatal(err)
}

}

Expand Down Expand Up @@ -535,7 +537,9 @@ func TestRunSandboxKataAgentSuccessful(t *testing.T) {
pImpl, ok := p.(*Sandbox)
assert.True(t, ok)

bindUnmountAllRootfs(ctx, testDir, pImpl)
if err := bindUnmountAllRootfs(ctx, testDir, pImpl); err != nil {
t.Fatal(err)
}
}

func TestRunSandboxFailing(t *testing.T) {
Expand Down
22 changes: 15 additions & 7 deletions virtcontainers/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import (
"path/filepath"
"strings"
"syscall"

merr "github.com/hashicorp/go-multierror"
"github.com/sirupsen/logrus"
)

// DefaultShmSize is the default shm size to be used in case host
Expand Down Expand Up @@ -330,23 +333,28 @@ func bindUnmountContainerRootfs(ctx context.Context, sharedDir, sandboxID, cID s
defer span.Finish()

rootfsDest := filepath.Join(sharedDir, sandboxID, cID, rootfsDir)
syscall.Unmount(rootfsDest, syscall.MNT_DETACH)

return nil
err := syscall.Unmount(rootfsDest, syscall.MNT_DETACH)
if err == syscall.ENOENT {
logrus.Warnf("%s: %s", err, rootfsDest)
return nil
}
return err
}

func bindUnmountAllRootfs(ctx context.Context, sharedDir string, sandbox *Sandbox) {
func bindUnmountAllRootfs(ctx context.Context, sharedDir string, sandbox *Sandbox) error {
span, _ := trace(ctx, "bindUnmountAllRootfs")
defer span.Finish()

var errors *merr.Error
for _, c := range sandbox.containers {
c.unmountHostMounts()
if c.state.Fstype == "" {
// Need to check for error returned by this call.
// See: https://github.com/containers/virtcontainers/issues/295
bindUnmountContainerRootfs(c.ctx, sharedDir, sandbox.id, c.id)
// even if error found, don't break out of loop until all mounts attempted
// to be unmounted, and collect all errors
errors = merr.Append(errors, bindUnmountContainerRootfs(c.ctx, sharedDir, sandbox.id, c.id))
}
}
return errors.ErrorOrNil()
}

const (
Expand Down
20 changes: 20 additions & 0 deletions virtcontainers/mount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,23 @@ func TestIsEphemeralStorage(t *testing.T) {
isHostEmptyDir = Isk8sHostEmptyDir(sampleEphePath)
assert.False(t, isHostEmptyDir)
}

// TestBindUnmountContainerRootfsENOENTNotError tests that if a file
// or directory attempting to be unmounted doesn't exist, then it
// is not considered an error
func TestBindUnmountContainerRootfsENOENTNotError(t *testing.T) {
testMnt := "/tmp/test_mount"
sID := "sandIDTest"
cID := "contIDTest"

// check to make sure the file doesn't exist
testPath := filepath.Join(testMnt, sID, cID, rootfsDir)
if _, err := os.Stat(testPath); !os.IsNotExist(err) {
if err := os.Remove(testPath); err != nil {
t.Fatalf("test mount file should not exist, and cannot be removed: %s", err)
}
}

err := bindUnmountContainerRootfs(context.Background(), testMnt, sID, cID)
assert.Nil(t, err)
}

0 comments on commit e08f13e

Please sign in to comment.