diff options
author | Zhaozhong Ni <nzz@google.com> | 2018-05-08 11:36:11 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-05-08 11:36:59 -0700 |
commit | 174161013de22be6a42b02ee06611a9de9e20b18 (patch) | |
tree | b910f76ea3ba8b14a29df2d28010fd0af1db18bb /pkg/sentry/fs/gofer | |
parent | 3ac3ea1d6afea0b128112e6a46b8bf47b4b0e02a (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.go | 9 | ||||
-rw-r--r-- | pkg/sentry/fs/gofer/inode_state.go | 23 |
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)) } |