diff options
author | Fabricio Voznika <fvoznika@google.com> | 2021-10-20 10:42:29 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-10-20 10:45:45 -0700 |
commit | c23d67f3c092176d0d5313f186d571d4067c1d57 (patch) | |
tree | 4bdbcbe30c61f5e5268c01bb358568376d9ebbdf /pkg/sentry/vfs | |
parent | bdf4e41c863ce025c67bfd30b5c52d15bdc54ced (diff) |
Report correct error when restore fails
When file corruption is detected, report vfs.ErrCorruption to
distinguish corruption error from other restore errors.
Updates #1035
PiperOrigin-RevId: 404588445
Diffstat (limited to 'pkg/sentry/vfs')
-rw-r--r-- | pkg/sentry/vfs/save_restore.go | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/pkg/sentry/vfs/save_restore.go b/pkg/sentry/vfs/save_restore.go index 8998a82dd..8a6ced365 100644 --- a/pkg/sentry/vfs/save_restore.go +++ b/pkg/sentry/vfs/save_restore.go @@ -15,7 +15,6 @@ package vfs import ( - "fmt" "sync/atomic" "gvisor.dev/gvisor/pkg/abi/linux" @@ -24,6 +23,18 @@ import ( "gvisor.dev/gvisor/pkg/waiter" ) +// ErrCorruption indicates a failed restore due to external file system state in +// corruption. +type ErrCorruption struct { + // Err is the wrapped error. + Err error +} + +// Error returns a sensible description of the restore error. +func (e ErrCorruption) Error() string { + return "restore failed due to external file system state in corruption: " + e.Err.Error() +} + // FilesystemImplSaveRestoreExtension is an optional extension to // FilesystemImpl. type FilesystemImplSaveRestoreExtension interface { @@ -37,38 +48,30 @@ type FilesystemImplSaveRestoreExtension interface { // PrepareSave prepares all filesystems for serialization. func (vfs *VirtualFilesystem) PrepareSave(ctx context.Context) error { - failures := 0 for fs := range vfs.getFilesystems() { if ext, ok := fs.impl.(FilesystemImplSaveRestoreExtension); ok { if err := ext.PrepareSave(ctx); err != nil { - ctx.Warningf("%T.PrepareSave failed: %v", fs.impl, err) - failures++ + fs.DecRef(ctx) + return err } } fs.DecRef(ctx) } - if failures != 0 { - return fmt.Errorf("%d filesystems failed to prepare for serialization", failures) - } return nil } // CompleteRestore completes restoration from checkpoint for all filesystems // after deserialization. func (vfs *VirtualFilesystem) CompleteRestore(ctx context.Context, opts *CompleteRestoreOptions) error { - failures := 0 for fs := range vfs.getFilesystems() { if ext, ok := fs.impl.(FilesystemImplSaveRestoreExtension); ok { if err := ext.CompleteRestore(ctx, *opts); err != nil { - ctx.Warningf("%T.CompleteRestore failed: %v", fs.impl, err) - failures++ + fs.DecRef(ctx) + return err } } fs.DecRef(ctx) } - if failures != 0 { - return fmt.Errorf("%d filesystems failed to complete restore after deserialization", failures) - } return nil } |