Treat ENOSPC as a state-file error during save.

PiperOrigin-RevId: 241028806
Change-Id: I770bf751a2740869a93c3ab50370a727ae580470
This commit is contained in:
Nicolas Lacasse 2019-03-29 12:25:17 -07:00 committed by Shentubot
parent 45c54b1f4e
commit ed23f54709
3 changed files with 18 additions and 2 deletions

View File

@ -365,6 +365,11 @@ func (ts *TaskSet) flushWritesToFiles(ctx context.Context) error {
syncErr := desc.file.Fsync(ctx, 0, fs.FileMaxOffset, fs.SyncAll) syncErr := desc.file.Fsync(ctx, 0, fs.FileMaxOffset, fs.SyncAll)
if err := fs.SaveFileFsyncError(syncErr); err != nil { if err := fs.SaveFileFsyncError(syncErr); err != nil {
name, _ := desc.file.Dirent.FullName(nil /* root */) 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) return fmt.Errorf("%q was not sufficiently synced: %v", name, err)
} }
} }

View File

@ -18,5 +18,6 @@ go_library(
"//pkg/sentry/kernel", "//pkg/sentry/kernel",
"//pkg/sentry/watchdog", "//pkg/sentry/watchdog",
"//pkg/state/statefile", "//pkg/state/statefile",
"//pkg/syserror",
], ],
) )

View File

@ -24,18 +24,20 @@ import (
"gvisor.googlesource.com/gvisor/pkg/sentry/kernel" "gvisor.googlesource.com/gvisor/pkg/sentry/kernel"
"gvisor.googlesource.com/gvisor/pkg/sentry/watchdog" "gvisor.googlesource.com/gvisor/pkg/sentry/watchdog"
"gvisor.googlesource.com/gvisor/pkg/state/statefile" "gvisor.googlesource.com/gvisor/pkg/state/statefile"
"gvisor.googlesource.com/gvisor/pkg/syserror"
) )
var previousMetadata map[string]string 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 { type ErrStateFile struct {
err error err error
} }
// Error implements error.Error(). // Error implements error.Error().
func (e ErrStateFile) Error() string { 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. // SaveOpts contains save-related options.
@ -76,6 +78,14 @@ func (opts SaveOpts) Save(k *kernel.Kernel, w *watchdog.Watchdog) error {
} else { } else {
// Save the kernel. // Save the kernel.
err = k.SaveTo(wc) 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 { if closeErr := wc.Close(); err == nil && closeErr != nil {
err = ErrStateFile{closeErr} err = ErrStateFile{closeErr}
} }