summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/gofer
diff options
context:
space:
mode:
authorZhaozhong Ni <nzz@google.com>2018-05-08 11:36:11 -0700
committerShentubot <shentubot@google.com>2018-05-08 11:36:59 -0700
commit174161013de22be6a42b02ee06611a9de9e20b18 (patch)
treeb910f76ea3ba8b14a29df2d28010fd0af1db18bb /pkg/sentry/fs/gofer
parent3ac3ea1d6afea0b128112e6a46b8bf47b4b0e02a (diff)
Capture restore file system corruption errors in exit error.
PiperOrigin-RevId: 195850822 Change-Id: I4d7bdd8fe129c5ed461b73e1d7458be2cf5680c2
Diffstat (limited to 'pkg/sentry/fs/gofer')
-rw-r--r--pkg/sentry/fs/gofer/file_state.go9
-rw-r--r--pkg/sentry/fs/gofer/inode_state.go23
2 files changed, 19 insertions, 13 deletions
diff --git a/pkg/sentry/fs/gofer/file_state.go b/pkg/sentry/fs/gofer/file_state.go
index 1d63e33ec..715af8f16 100644
--- a/pkg/sentry/fs/gofer/file_state.go
+++ b/pkg/sentry/fs/gofer/file_state.go
@@ -15,13 +15,15 @@
package gofer
import (
+ "fmt"
+
"gvisor.googlesource.com/gvisor/pkg/sentry/context"
"gvisor.googlesource.com/gvisor/pkg/sentry/fs"
)
// afterLoad is invoked by stateify.
func (f *fileOperations) afterLoad() {
- load := func() {
+ load := func() error {
f.inodeOperations.fileState.waitForLoad()
// Manually load the open handles.
@@ -29,9 +31,10 @@ func (f *fileOperations) afterLoad() {
// TODO: Context is not plumbed to save/restore.
f.handles, err = newHandles(context.Background(), f.inodeOperations.fileState.file, f.flags)
if err != nil {
- panic("failed to re-open handle: " + err.Error())
+ return fmt.Errorf("failed to re-open handle: %v", err)
}
f.inodeOperations.fileState.setHandlesForCachedIO(f.flags, f.handles)
+ return nil
}
- fs.Async(load)
+ fs.Async(fs.CatchError(load))
}
diff --git a/pkg/sentry/fs/gofer/inode_state.go b/pkg/sentry/fs/gofer/inode_state.go
index 997a7d1c1..82d1dd4da 100644
--- a/pkg/sentry/fs/gofer/inode_state.go
+++ b/pkg/sentry/fs/gofer/inode_state.go
@@ -15,6 +15,7 @@
package gofer
import (
+ "errors"
"fmt"
"strings"
@@ -83,7 +84,7 @@ func (i *inodeFileState) loadLoading(_ struct{}) {
// afterLoad is invoked by stateify.
func (i *inodeFileState) afterLoad() {
- load := func() {
+ load := func() error {
// See comment on i.loading().
defer i.loading.Unlock()
@@ -92,14 +93,14 @@ func (i *inodeFileState) afterLoad() {
if !ok {
// This should be impossible, see assertion in
// beforeSave.
- panic(fmt.Sprintf("failed to find path for inode number %d. Device %s contains %s", i.sattr.InodeID, i.s.connID, fs.InodeMappings(i.s.inodeMappings)))
+ return fmt.Errorf("failed to find path for inode number %d. Device %s contains %s", i.sattr.InodeID, i.s.connID, fs.InodeMappings(i.s.inodeMappings))
}
// TODO: Context is not plumbed to save/restore.
ctx := &dummyClockContext{context.Background()}
var err error
_, i.file, err = i.s.attach.walk(ctx, strings.Split(name, "/"))
if err != nil {
- panic(fmt.Sprintf("failed to walk to %q: %v", name, err))
+ return fmt.Errorf("failed to walk to %q: %v", name, err)
}
// Remap the saved inode number into the gofer device using the
@@ -107,10 +108,10 @@ func (i *inodeFileState) afterLoad() {
// environment.
qid, mask, attrs, err := i.file.getAttr(ctx, p9.AttrMaskAll())
if err != nil {
- panic(fmt.Sprintf("failed to get file attributes of %s: %v", name, err))
+ return fmt.Errorf("failed to get file attributes of %s: %v", name, err)
}
if !mask.RDev {
- panic(fmt.Sprintf("file %s lacks device", name))
+ return fs.ErrCorruption{fmt.Errorf("file %s lacks device", name)}
}
i.key = device.MultiDeviceKey{
Device: attrs.RDev,
@@ -118,24 +119,26 @@ func (i *inodeFileState) afterLoad() {
Inode: qid.Path,
}
if !goferDevice.Load(i.key, i.sattr.InodeID) {
- panic(fmt.Sprintf("gofer device %s -> %d conflict in gofer device mappings: %s", i.key, i.sattr.InodeID, goferDevice))
+ return fs.ErrCorruption{fmt.Errorf("gofer device %s -> %d conflict in gofer device mappings: %s", i.key, i.sattr.InodeID, goferDevice)}
}
if i.sattr.Type == fs.RegularFile {
env, ok := fs.CurrentRestoreEnvironment()
if !ok {
- panic("missing restore environment")
+ return errors.New("missing restore environment")
}
uattr := unstable(ctx, mask, attrs, i.s.mounter, i.s.client)
if env.ValidateFileSize && uattr.Size != i.savedUAttr.Size {
- panic(fmt.Errorf("file size has changed for %s: previously %d, now %d", i.s.inodeMappings[i.sattr.InodeID], i.savedUAttr.Size, uattr.Size))
+ return fs.ErrCorruption{fmt.Errorf("file size has changed for %s: previously %d, now %d", i.s.inodeMappings[i.sattr.InodeID], i.savedUAttr.Size, uattr.Size)}
}
if env.ValidateFileTimestamp && uattr.ModificationTime != i.savedUAttr.ModificationTime {
- panic(fmt.Errorf("file modification time has changed for %s: previously %v, now %v", i.s.inodeMappings[i.sattr.InodeID], i.savedUAttr.ModificationTime, uattr.ModificationTime))
+ return fs.ErrCorruption{fmt.Errorf("file modification time has changed for %s: previously %v, now %v", i.s.inodeMappings[i.sattr.InodeID], i.savedUAttr.ModificationTime, uattr.ModificationTime)}
}
i.savedUAttr = nil
}
+
+ return nil
}
- fs.Async(load)
+ fs.Async(fs.CatchError(load))
}