summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/vfs
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2021-10-20 10:42:29 -0700
committergVisor bot <gvisor-bot@google.com>2021-10-20 10:45:45 -0700
commitc23d67f3c092176d0d5313f186d571d4067c1d57 (patch)
tree4bdbcbe30c61f5e5268c01bb358568376d9ebbdf /pkg/sentry/vfs
parentbdf4e41c863ce025c67bfd30b5c52d15bdc54ced (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.go29
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
}