diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-10-20 17:50:34 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-10-20 17:50:34 +0000 |
commit | 18e785d536d7af375fcdd741c79e5815e8ce54bf (patch) | |
tree | 8b68be739ff2b528975e79702d9f8ebe1b30cb73 /pkg | |
parent | 5fa08793a628d59f29ebe23950f12bfee7c072b9 (diff) | |
parent | c23d67f3c092176d0d5313f186d571d4067c1d57 (diff) |
Merge release-20211011.0-37-gc23d67f3c (automated)
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/sentry/fsimpl/gofer/save_restore.go | 16 | ||||
-rw-r--r-- | pkg/sentry/vfs/save_restore.go | 29 |
2 files changed, 24 insertions, 21 deletions
diff --git a/pkg/sentry/fsimpl/gofer/save_restore.go b/pkg/sentry/fsimpl/gofer/save_restore.go index 475322527..82878c056 100644 --- a/pkg/sentry/fsimpl/gofer/save_restore.go +++ b/pkg/sentry/fsimpl/gofer/save_restore.go @@ -277,18 +277,18 @@ func (d *dentry) restoreFile(ctx context.Context, file p9file, qid p9.QID, attrM if d.isRegularFile() { if opts.ValidateFileSizes { if !attrMask.Size { - return fmt.Errorf("gofer.dentry(%q).restoreFile: file size validation failed: file size not available", genericDebugPathname(d)) + return vfs.ErrCorruption{fmt.Errorf("gofer.dentry(%q).restoreFile: file size validation failed: file size not available", genericDebugPathname(d))} } if d.size != attr.Size { - return fmt.Errorf("gofer.dentry(%q).restoreFile: file size validation failed: size changed from %d to %d", genericDebugPathname(d), d.size, attr.Size) + return vfs.ErrCorruption{fmt.Errorf("gofer.dentry(%q).restoreFile: file size validation failed: size changed from %d to %d", genericDebugPathname(d), d.size, attr.Size)} } } if opts.ValidateFileModificationTimestamps { if !attrMask.MTime { - return fmt.Errorf("gofer.dentry(%q).restoreFile: mtime validation failed: mtime not available", genericDebugPathname(d)) + return vfs.ErrCorruption{fmt.Errorf("gofer.dentry(%q).restoreFile: mtime validation failed: mtime not available", genericDebugPathname(d))} } if want := dentryTimestampFromP9(attr.MTimeSeconds, attr.MTimeNanoSeconds); d.mtime != want { - return fmt.Errorf("gofer.dentry(%q).restoreFile: mtime validation failed: mtime changed from %+v to %+v", genericDebugPathname(d), linux.NsecToStatxTimestamp(d.mtime), linux.NsecToStatxTimestamp(want)) + return vfs.ErrCorruption{fmt.Errorf("gofer.dentry(%q).restoreFile: mtime validation failed: mtime changed from %+v to %+v", genericDebugPathname(d), linux.NsecToStatxTimestamp(d.mtime), linux.NsecToStatxTimestamp(want))} } } } @@ -326,18 +326,18 @@ func (d *dentry) restoreFileLisa(ctx context.Context, inode *lisafs.Inode, opts if d.isRegularFile() { if opts.ValidateFileSizes { if inode.Stat.Mask&linux.STATX_SIZE != 0 { - return fmt.Errorf("gofer.dentry(%q).restoreFile: file size validation failed: file size not available", genericDebugPathname(d)) + return vfs.ErrCorruption{fmt.Errorf("gofer.dentry(%q).restoreFile: file size validation failed: file size not available", genericDebugPathname(d))} } if d.size != inode.Stat.Size { - return fmt.Errorf("gofer.dentry(%q).restoreFile: file size validation failed: size changed from %d to %d", genericDebugPathname(d), d.size, inode.Stat.Size) + return vfs.ErrCorruption{fmt.Errorf("gofer.dentry(%q).restoreFile: file size validation failed: size changed from %d to %d", genericDebugPathname(d), d.size, inode.Stat.Size)} } } if opts.ValidateFileModificationTimestamps { if inode.Stat.Mask&linux.STATX_MTIME != 0 { - return fmt.Errorf("gofer.dentry(%q).restoreFile: mtime validation failed: mtime not available", genericDebugPathname(d)) + return vfs.ErrCorruption{fmt.Errorf("gofer.dentry(%q).restoreFile: mtime validation failed: mtime not available", genericDebugPathname(d))} } if want := dentryTimestampFromLisa(inode.Stat.Mtime); d.mtime != want { - return fmt.Errorf("gofer.dentry(%q).restoreFile: mtime validation failed: mtime changed from %+v to %+v", genericDebugPathname(d), linux.NsecToStatxTimestamp(d.mtime), linux.NsecToStatxTimestamp(want)) + return vfs.ErrCorruption{fmt.Errorf("gofer.dentry(%q).restoreFile: mtime validation failed: mtime changed from %+v to %+v", genericDebugPathname(d), linux.NsecToStatxTimestamp(d.mtime), linux.NsecToStatxTimestamp(want))} } } } 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 } |