Buffer page metadata file I/O.

PiperOrigin-RevId: 666590672
This commit is contained in:
Jamie Liu
2024-08-22 19:55:11 -07:00
committed by gVisor bot
parent 26626ead8f
commit 87ec1007b4
2 changed files with 28 additions and 5 deletions
+3 -3
View File
@@ -624,7 +624,7 @@ func loadPrivateMFs(ctx context.Context, r io.Reader, pr *statefile.AsyncReader)
// SaveTo saves the state of k to w.
//
// Preconditions: The kernel must be paused throughout the call to SaveTo.
func (k *Kernel) SaveTo(ctx context.Context, w io.Writer, pagesMetadata, pagesFile *fd.FD, mfOpts pgalloc.SaveOpts) error {
func (k *Kernel) SaveTo(ctx context.Context, w, pagesMetadata io.Writer, pagesFile *fd.FD, mfOpts pgalloc.SaveOpts) error {
saveStart := time.Now()
// Do not allow other Kernel methods to affect it while it's being saved.
@@ -739,7 +739,7 @@ func (k *Kernel) invalidateUnsavableMappings(ctx context.Context) error {
}
// LoadFrom returns a new Kernel loaded from args.
func (k *Kernel) LoadFrom(ctx context.Context, r io.Reader, pagesMetadata, pagesFile *fd.FD, timeReady chan struct{}, net inet.Stack, clocks sentrytime.Clocks, vfsOpts *vfs.CompleteRestoreOptions) error {
func (k *Kernel) LoadFrom(ctx context.Context, r, pagesMetadata io.Reader, pagesFile *fd.FD, timeReady chan struct{}, net inet.Stack, clocks sentrytime.Clocks, vfsOpts *vfs.CompleteRestoreOptions) error {
loadStart := time.Now()
var (
@@ -837,7 +837,7 @@ func (k *Kernel) LoadFrom(ctx context.Context, r io.Reader, pagesMetadata, pages
return nil
}
func (k *Kernel) loadMemoryFiles(ctx context.Context, r io.Reader, pagesMetadata, pagesFile *fd.FD) error {
func (k *Kernel) loadMemoryFiles(ctx context.Context, r, pagesMetadata io.Reader, pagesFile *fd.FD) error {
// Load the memory files' state.
memoryStart := time.Now()
pmr := r
+25 -2
View File
@@ -16,6 +16,7 @@
package state
import (
"bufio"
"fmt"
"io"
@@ -98,8 +99,17 @@ func (opts SaveOpts) Save(ctx context.Context, k *kernel.Kernel, w *watchdog.Wat
if err != nil {
err = ErrStateFile{err}
} else {
var pagesMetadata io.Writer
if opts.PagesMetadata != nil {
// //pkg/state/wire writes one byte at a time; buffer these writes
// to avoid making one syscall per write. For the "main" state
// file, this buffering is handled by statefile.NewWriter() =>
// compressio.Writer or compressio.NewSimpleWriter().
pagesMetadata = bufio.NewWriter(opts.PagesMetadata)
}
// Save the kernel.
err = k.SaveTo(ctx, wc, opts.PagesMetadata, opts.PagesFile, opts.MemoryFileSaveOpts)
err = k.SaveTo(ctx, wc, pagesMetadata, opts.PagesFile, opts.MemoryFileSaveOpts)
// ENOSPC is a state file error. This error can only come from
// writing the state file, and not from fs.FileOperations.Fsync
@@ -111,6 +121,11 @@ func (opts SaveOpts) Save(ctx context.Context, k *kernel.Kernel, w *watchdog.Wat
if closeErr := wc.Close(); err == nil && closeErr != nil {
err = ErrStateFile{closeErr}
}
if pagesMetadata != nil {
if flushErr := pagesMetadata.(*bufio.Writer).Flush(); err == nil && flushErr != nil {
err = ErrStateFile{flushErr}
}
}
}
opts.Callback(err)
return err
@@ -140,9 +155,17 @@ func (opts LoadOpts) Load(ctx context.Context, k *kernel.Kernel, timeReady chan
if err != nil {
return ErrStateFile{err}
}
var pagesMetadata io.Reader
if opts.PagesMetadata != nil {
// //pkg/state/wire reads one byte at a time; buffer these reads to
// avoid making one syscall per read. For the "main" state file, this
// buffering is handled by statefile.NewReader() => compressio.Reader
// or compressio.NewSimpleReader().
pagesMetadata = bufio.NewReader(opts.PagesMetadata)
}
previousMetadata = m
// Restore the Kernel object graph.
return k.LoadFrom(ctx, r, opts.PagesMetadata, opts.PagesFile, timeReady, n, clocks, vfsOpts)
return k.LoadFrom(ctx, r, pagesMetadata, opts.PagesFile, timeReady, n, clocks, vfsOpts)
}