diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2019-03-29 12:25:17 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-03-29 12:26:25 -0700 |
commit | ed23f547093e705ba3d6f82b2ce49592180f9a5a (patch) | |
tree | 973becebd4992b41a0d5791a93e3a36745052d82 | |
parent | 45c54b1f4e2bb6fcad14b8b7734d6a1847329901 (diff) |
Treat ENOSPC as a state-file error during save.
PiperOrigin-RevId: 241028806
Change-Id: I770bf751a2740869a93c3ab50370a727ae580470
-rw-r--r-- | pkg/sentry/kernel/kernel.go | 5 | ||||
-rw-r--r-- | pkg/sentry/state/BUILD | 1 | ||||
-rw-r--r-- | pkg/sentry/state/state.go | 14 |
3 files changed, 18 insertions, 2 deletions
diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go index 3533fd8f7..d9f3f4e24 100644 --- a/pkg/sentry/kernel/kernel.go +++ b/pkg/sentry/kernel/kernel.go @@ -365,6 +365,11 @@ func (ts *TaskSet) flushWritesToFiles(ctx context.Context) error { syncErr := desc.file.Fsync(ctx, 0, fs.FileMaxOffset, fs.SyncAll) if err := fs.SaveFileFsyncError(syncErr); err != nil { name, _ := desc.file.Dirent.FullName(nil /* root */) + // Wrapping this error not only allows + // for a more useful message, but is + // required to distinguish Fsync errors + // from state file errors in + // state.Save. return fmt.Errorf("%q was not sufficiently synced: %v", name, err) } } diff --git a/pkg/sentry/state/BUILD b/pkg/sentry/state/BUILD index 69385e23c..cee18f681 100644 --- a/pkg/sentry/state/BUILD +++ b/pkg/sentry/state/BUILD @@ -18,5 +18,6 @@ go_library( "//pkg/sentry/kernel", "//pkg/sentry/watchdog", "//pkg/state/statefile", + "//pkg/syserror", ], ) diff --git a/pkg/sentry/state/state.go b/pkg/sentry/state/state.go index 67db78a56..224f8b709 100644 --- a/pkg/sentry/state/state.go +++ b/pkg/sentry/state/state.go @@ -24,18 +24,20 @@ import ( "gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/watchdog" "gvisor.googlesource.com/gvisor/pkg/state/statefile" + "gvisor.googlesource.com/gvisor/pkg/syserror" ) var previousMetadata map[string]string -// ErrStateFile is returned when the state file cannot be opened. +// ErrStateFile is returned when an error is encountered writing the statefile +// (which may occur during open or close calls in addition to write). type ErrStateFile struct { err error } // Error implements error.Error(). func (e ErrStateFile) Error() string { - return fmt.Sprintf("failed to open statefile: %v", e.err) + return fmt.Sprintf("statefile error: %v", e.err) } // SaveOpts contains save-related options. @@ -76,6 +78,14 @@ func (opts SaveOpts) Save(k *kernel.Kernel, w *watchdog.Watchdog) error { } else { // Save the kernel. err = k.SaveTo(wc) + + // ENOSPC is a state file error. This error can only come from + // writing the state file, and not from fs.FileOperations.Fsync + // because we wrap those in kernel.TaskSet.flushWritesToFiles. + if err == syserror.ENOSPC { + err = ErrStateFile{err} + } + if closeErr := wc.Close(); err == nil && closeErr != nil { err = ErrStateFile{closeErr} } |