From f82d92777207ae3bc6b181a5553a6033acc825b3 Mon Sep 17 00:00:00 2001 From: Jamie Liu Date: Tue, 12 Mar 2024 15:46:40 -0700 Subject: [PATCH] Ensure that files created after save are visible after restore. PiperOrigin-RevId: 615197421 --- pkg/sentry/fsimpl/gofer/gofer.go | 16 +++++++++------- pkg/sentry/fsimpl/gofer/save_restore.go | 15 ++++++++++----- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/pkg/sentry/fsimpl/gofer/gofer.go b/pkg/sentry/fsimpl/gofer/gofer.go index d88f8dd2e..103daabc3 100644 --- a/pkg/sentry/fsimpl/gofer/gofer.go +++ b/pkg/sentry/fsimpl/gofer/gofer.go @@ -833,15 +833,17 @@ type dentry struct { children map[string]*dentry // If this dentry represents a directory, negativeChildrenCache cache - // names of negative children. + // names of negative children. negativeChildrenCache is not saved since + // dentry.prepareSaveRecursive() drops all negative children. // // +checklocks:childrenMu - negativeChildrenCache stringFixedCache - // If this dentry represents a directory, negativeChildren is the number - // of negative children cached in dentry.children + negativeChildrenCache stringFixedCache `state:"nosave"` + // If this dentry represents a directory, negativeChildren is the number of + // negative children cached in dentry.children. negativeChildren is not + // saved since dentry.prepareSaveRecursive() drops all negative children. // // +checklocks:childrenMu - negativeChildren int + negativeChildren int `state:"nosave"` // If this dentry represents a directory, syntheticChildren is the number // of child dentries for which dentry.isSynthetic() == true. @@ -857,9 +859,9 @@ type dentry struct { // childrenSet share the same lifecycle. // // +checklocks:childrenMu - dirents []vfs.Dirent + dirents []vfs.Dirent `state:"nosave"` // +checklocks:childrenMu - childrenSet map[string]struct{} + childrenSet map[string]struct{} `state:"nosave"` // Cached metadata; protected by metadataMu. // To access: diff --git a/pkg/sentry/fsimpl/gofer/save_restore.go b/pkg/sentry/fsimpl/gofer/save_restore.go index 742dcbfd3..9e8decba8 100644 --- a/pkg/sentry/fsimpl/gofer/save_restore.go +++ b/pkg/sentry/fsimpl/gofer/save_restore.go @@ -111,11 +111,16 @@ func (d *dentry) prepareSaveRecursive(ctx context.Context) error { } d.childrenMu.Lock() defer d.childrenMu.Unlock() - for _, child := range d.children { - if child != nil { - if err := child.prepareSaveRecursive(ctx); err != nil { - return err - } + for childName, child := range d.children { + if child == nil { + // Unsaved filesystem state may change across save/restore. Remove + // negative entries from d.children to ensure that files created + // after save are visible after restore. + delete(d.children, childName) + continue + } + if err := child.prepareSaveRecursive(ctx); err != nil { + return err } } return nil