Skip to content

Commit 3b314aa

Browse files
ayushr2gvisor-bot
authored andcommitted
Update tmpfs to restore its MemoryFile using stateify tools.
PiperOrigin-RevId: 615233954
1 parent d432952 commit 3b314aa

File tree

3 files changed

+35
-56
lines changed

3 files changed

+35
-56
lines changed

pkg/sentry/fsimpl/tmpfs/save_restore.go

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,29 @@ import (
2323
"gvisor.dev/gvisor/pkg/sentry/vfs"
2424
)
2525

26-
// afterLoad is called by stateify.
27-
func (fs *filesystem) afterLoad(goContext.Context) {
28-
if !fs.privateMF {
29-
fs.mf = fs.mfp.MemoryFile()
26+
// saveMf is called by stateify.
27+
func (fs *filesystem) saveMf() string {
28+
if !fs.mf.IsSavable() {
29+
panic(fmt.Sprintf("Can't save tmpfs filesystem because its MemoryFile is not savable: %v", fs.mf))
3030
}
31+
return fs.mf.RestoreID()
32+
}
33+
34+
// loadMf is called by stateify.
35+
func (fs *filesystem) loadMf(ctx goContext.Context, restoreID string) {
36+
if restoreID == "" {
37+
fs.mf = pgalloc.MemoryFileFromContext(ctx)
38+
return
39+
}
40+
mfmap := pgalloc.MemoryFileMapFromContext(ctx)
41+
if mfmap == nil {
42+
panic("CtxMemoryFileMap was not provided")
43+
}
44+
mf, ok := mfmap[restoreID]
45+
if !ok {
46+
panic(fmt.Sprintf("Memory file for %q not found in CtxMemoryFileMap", restoreID))
47+
}
48+
fs.mf = mf
3149
}
3250

3351
// saveParent is called by stateify.
@@ -42,34 +60,23 @@ func (d *dentry) loadParent(_ goContext.Context, parent *dentry) {
4260

4361
// PrepareSave implements vfs.FilesystemImplSaveRestoreExtension.PrepareSave.
4462
func (fs *filesystem) PrepareSave(ctx context.Context) error {
45-
if !fs.privateMF {
63+
restoreID := fs.mf.RestoreID()
64+
if restoreID == "" {
4665
return nil
4766
}
4867
mfmap := pgalloc.MemoryFileMapFromContext(ctx)
4968
if mfmap == nil {
5069
return fmt.Errorf("CtxMemoryFileMap was not provided")
5170
}
52-
if _, ok := mfmap[fs.uniqueID.String()]; ok {
53-
return fmt.Errorf("memory file for %q already exists in CtxMemoryFileMap", fs.uniqueID)
71+
if _, ok := mfmap[restoreID]; ok {
72+
return fmt.Errorf("memory file for %q already exists in CtxMemoryFileMap", restoreID)
5473
}
55-
mfmap[fs.uniqueID.String()] = fs.mf
74+
mfmap[restoreID] = fs.mf
5675
return nil
5776
}
5877

5978
// CompleteRestore implements
6079
// vfs.FilesystemImplSaveRestoreExtension.CompleteRestore.
6180
func (fs *filesystem) CompleteRestore(ctx context.Context, opts vfs.CompleteRestoreOptions) error {
62-
if !fs.privateMF {
63-
return nil
64-
}
65-
mfmap := pgalloc.MemoryFileMapFromContext(ctx)
66-
if mfmap == nil {
67-
return fmt.Errorf("CtxMemoryFileMap was not provided")
68-
}
69-
mf, ok := mfmap[fs.uniqueID.String()]
70-
if !ok {
71-
return fmt.Errorf("memory file for %q not found in CtxMemoryFileMap", fs.uniqueID)
72-
}
73-
fs.mf = mf
7481
return nil
7582
}

pkg/sentry/fsimpl/tmpfs/tmpfs.go

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,8 @@ type filesystem struct {
6363
vfsfs vfs.Filesystem
6464

6565
// mf is used to allocate memory that stores regular file contents. mf is
66-
// immutable, except it may to changed during restore.
67-
mf *pgalloc.MemoryFile `state:"nosave"`
68-
69-
// privateMF indicates whether mf is private to this tmpfs mount. If so,
70-
// tmpfs takes ownership of mf. privateMF is immutable.
71-
privateMF bool
72-
73-
// uniqueID is an opaque string used to reassociate the filesystem with its
74-
// private MemoryFile during checkpoint and restore.
75-
uniqueID vfs.RestoreID
76-
77-
// mfp is used to provide mf, when privateMF == false. This is required to
78-
// re-provide mf on restore. mfp is immutable.
79-
mfp pgalloc.MemoryFileProvider
66+
// immutable, except it is changed during restore.
67+
mf *pgalloc.MemoryFile `state:".(string)"`
8068

8169
// clock is a realtime clock used to set timestamps in file operations.
8270
clock time.Clock
@@ -156,10 +144,6 @@ type FilesystemOpts struct {
156144
// AllowXattrPrefix is a set of xattr namespace prefixes that this
157145
// tmpfs mount will allow.
158146
AllowXattrPrefix []string
159-
160-
// If UniqueID is non-empty, it is an opaque string used to reassociate the
161-
// filesystem with its private MemoryFile during checkpoint and restore.
162-
UniqueID vfs.RestoreID
163147
}
164148

165149
// Default size limit mount option. It is immutable after initialization.
@@ -186,13 +170,10 @@ func getDefaultSizeLimit(disable bool) uint64 {
186170

187171
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
188172
func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, _ string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
189-
mfp := pgalloc.MemoryFileProviderFromContext(ctx)
190-
if mfp == nil {
191-
panic("MemoryFileProviderFromContext returned nil")
173+
mf := pgalloc.MemoryFileFromContext(ctx)
174+
if mf == nil {
175+
panic("CtxMemoryFile returned nil")
192176
}
193-
mf := mfp.MemoryFile()
194-
privateMF := false
195-
var uniqueID vfs.RestoreID
196177
rootFileType := uint16(linux.S_IFDIR)
197178
disableDefaultSizeLimit := false
198179
newFSType := vfs.FilesystemType(&fstype)
@@ -218,17 +199,11 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
218199
disableDefaultSizeLimit = tmpfsOpts.DisableDefaultSizeLimit
219200
if tmpfsOpts.MemoryFile != nil {
220201
mf = tmpfsOpts.MemoryFile
221-
privateMF = true
222202
}
223-
uniqueID = tmpfsOpts.UniqueID
224203
for _, xattr := range tmpfsOpts.AllowXattrPrefix {
225204
allowXattrPrefix[xattr] = struct{}{}
226205
}
227206
}
228-
if privateMF && len(uniqueID.Path) == 0 {
229-
ctx.Warningf("tmpfs.FilesystemType.GetFilesystem: privateMF requires uniqueID to be set")
230-
return nil, nil, linuxerr.EINVAL
231-
}
232207

233208
mopts := vfs.GenericParseMountOptions(opts.Data)
234209
rootMode := linux.FileMode(0777)
@@ -311,9 +286,6 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
311286
}
312287
fs := filesystem{
313288
mf: mf,
314-
privateMF: privateMF,
315-
uniqueID: uniqueID,
316-
mfp: mfp,
317289
clock: clock,
318290
devMinor: devMinor,
319291
mopts: opts.Data,
@@ -351,7 +323,9 @@ func (fs *filesystem) Release(ctx context.Context) {
351323
fs.root.releaseChildrenLocked(ctx)
352324
}
353325
fs.mu.Unlock()
354-
if fs.privateMF {
326+
if fs.mf.RestoreID() != "" {
327+
// If RestoreID is set, then this is a private MemoryFile which needs to be
328+
// destroyed since this tmpfs is the only user.
355329
fs.mf.Destroy()
356330
}
357331
}

runsc/boot/vfs.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,6 @@ func (c *containerMounter) configureOverlay(ctx context.Context, conf *config.Co
642642
return nil, nil, fmt.Errorf("failed to create memory file for overlay: %v", err)
643643
}
644644
tmpfsOpts.MemoryFile = mf
645-
tmpfsOpts.UniqueID = vfs.RestoreID{ContainerName: c.containerName, Path: dst}
646645
}
647646
upperOpts.GetFilesystemOptions.InternalData = tmpfsOpts
648647
upper, err := c.k.VFS().MountDisconnected(ctx, creds, "" /* source */, tmpfs.Name, &upperOpts)
@@ -903,7 +902,6 @@ func getMountNameAndOptions(spec *specs.Spec, conf *config.Config, m *mountInfo,
903902
}
904903
internalData = tmpfs.FilesystemOpts{
905904
MemoryFile: mf,
906-
UniqueID: vfs.RestoreID{ContainerName: containerName, Path: m.mount.Destination},
907905
// If a mount is being overlaid with tmpfs, it should not be limited by
908906
// the default tmpfs size limit.
909907
DisableDefaultSizeLimit: true,

0 commit comments

Comments
 (0)