vc: error handling for bindUnmount functionalities

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 <gabrielle.n.beyer@intel.com>
This commit is contained in:
gabrielle beyer 2019-06-11 16:57:20 +00:00
parent 61fff8959c
commit e08f13ea31
3 changed files with 41 additions and 9 deletions

View File

@ -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)
}
}
@ -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) {

View File

@ -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
@ -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 (

View File

@ -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)
}