Skip to content

Commit 03e051a

Browse files
authored
[snapshot] Add config option for volatile overlayfs (#731)
Add `enable_overlayfs_volatile` to the snapshot config so operators can globally enable the volatile overlayfs mount option on all writable layers without needing to inject snapshot labels through the container runtime stack. The volatile option skips sync on the upper layer, improving write performance for ephemeral container filesystems. This is a safe trade-off for most workloads where the writable layer does not need to survive a crash.
1 parent 1b11fc9 commit 03e051a

File tree

4 files changed

+79
-22
lines changed

4 files changed

+79
-22
lines changed

config/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ type SnapshotConfig struct {
181181
NydusOverlayFSPath string `toml:"nydus_overlayfs_path"`
182182
EnableKataVolume bool `toml:"enable_kata_volume"`
183183
SyncRemove bool `toml:"sync_remove"`
184+
// EnableOverlayfsVolatile globally enables the "volatile" overlayfs mount option
185+
// on all writable snapshots. This skips sync on the upper layer, improving
186+
// write performance for ephemeral container filesystems at the cost of crash consistency.
187+
EnableOverlayfsVolatile bool `toml:"enable_overlayfs_volatile"`
184188
}
185189

186190
// Configure cache manager that manages the cache files lifecycle

misc/snapshotter/config.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ nydus_overlayfs_path = "nydus-overlayfs"
100100
enable_kata_volume = false
101101
# Whether to remove resources when a snapshot is removed
102102
sync_remove = false
103+
# Globally enable the "volatile" overlayfs mount option on all writable snapshots.
104+
# This skips sync on the upper layer, improving write performance for ephemeral
105+
# container filesystems. Safe for most workloads where the writable layer does not
106+
# need to survive a crash.
107+
enable_overlayfs_volatile = false
103108

104109
[cache_manager]
105110
# Disable or enable recyclebin

snapshot/snapshot.go

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,17 @@ import (
5252
var _ snapshots.Snapshotter = &snapshotter{}
5353

5454
type snapshotter struct {
55-
root string
56-
nydusdPath string
57-
ms *storage.MetaStore // Storing snapshots' state, parentage and other metadata
58-
fs *filesystem.Filesystem
59-
cgroupManager *cgroup.Manager
60-
enableNydusOverlayFS bool
61-
nydusOverlayFSPath string
62-
enableKataVolume bool
63-
syncRemove bool
64-
cleanupOnClose bool
55+
root string
56+
nydusdPath string
57+
ms *storage.MetaStore // Storing snapshots' state, parentage and other metadata
58+
fs *filesystem.Filesystem
59+
cgroupManager *cgroup.Manager
60+
enableNydusOverlayFS bool
61+
nydusOverlayFSPath string
62+
enableKataVolume bool
63+
syncRemove bool
64+
cleanupOnClose bool
65+
enableOverlayfsVolatile bool
6566
}
6667

6768
func NewSnapshotter(ctx context.Context, cfg *config.SnapshotterConfig) (snapshots.Snapshotter, error) {
@@ -302,16 +303,17 @@ func NewSnapshotter(ctx context.Context, cfg *config.SnapshotterConfig) (snapsho
302303
}
303304

304305
return &snapshotter{
305-
root: cfg.Root,
306-
nydusdPath: cfg.DaemonConfig.NydusdPath,
307-
ms: ms,
308-
syncRemove: syncRemove,
309-
fs: nydusFs,
310-
cgroupManager: cgroupMgr,
311-
enableNydusOverlayFS: cfg.SnapshotsConfig.EnableNydusOverlayFS,
312-
nydusOverlayFSPath: cfg.SnapshotsConfig.NydusOverlayFSPath,
313-
enableKataVolume: cfg.SnapshotsConfig.EnableKataVolume,
314-
cleanupOnClose: cfg.CleanupOnClose,
306+
root: cfg.Root,
307+
nydusdPath: cfg.DaemonConfig.NydusdPath,
308+
ms: ms,
309+
syncRemove: syncRemove,
310+
fs: nydusFs,
311+
cgroupManager: cgroupMgr,
312+
enableNydusOverlayFS: cfg.SnapshotsConfig.EnableNydusOverlayFS,
313+
nydusOverlayFSPath: cfg.SnapshotsConfig.NydusOverlayFSPath,
314+
enableKataVolume: cfg.SnapshotsConfig.EnableKataVolume,
315+
enableOverlayfsVolatile: cfg.SnapshotsConfig.EnableOverlayfsVolatile,
316+
cleanupOnClose: cfg.CleanupOnClose,
315317
}, nil
316318
}
317319

@@ -1098,7 +1100,7 @@ func (o *snapshotter) mountProxy(ctx context.Context, s storage.Snapshot) ([]mou
10981100
// `s` and `id` can represent a different layer, it's useful when View an image
10991101
func (o *snapshotter) mountRemote(ctx context.Context, labels map[string]string, s storage.Snapshot, id, key string) ([]mount.Mount, error) {
11001102
var overlayOptions []string
1101-
if _, ok := labels[label.OverlayfsVolatileOpt]; ok {
1103+
if _, ok := labels[label.OverlayfsVolatileOpt]; ok || o.enableOverlayfsVolatile {
11021104
overlayOptions = append(overlayOptions, "volatile")
11031105
}
11041106

@@ -1168,7 +1170,7 @@ func (o *snapshotter) mountNative(ctx context.Context, labels map[string]string,
11681170
fmt.Sprintf("workdir=%s", o.workPath(s.ID)),
11691171
fmt.Sprintf("upperdir=%s", o.upperPath(s.ID)),
11701172
)
1171-
if _, ok := labels[label.OverlayfsVolatileOpt]; ok {
1173+
if _, ok := labels[label.OverlayfsVolatileOpt]; ok || o.enableOverlayfsVolatile {
11721174
options = append(options, "volatile")
11731175
}
11741176
} else if len(s.ParentIDs) == 1 {

snapshot/snapshot_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,49 @@ func TestMountNative(t *testing.T) {
224224
})
225225
}
226226
}
227+
228+
func TestMountNativeConfigVolatile(t *testing.T) {
229+
snapshotterRoot := "/var/lib/containerd/snapshotter"
230+
s := &snapshotter{
231+
root: snapshotterRoot,
232+
enableOverlayfsVolatile: true,
233+
}
234+
235+
ctx := context.Background()
236+
237+
t.Run("active snapshot gets volatile from config", func(t *testing.T) {
238+
snap := storage.Snapshot{
239+
ID: "snap1",
240+
Kind: snapshots.KindActive,
241+
ParentIDs: []string{"parent1", "parent2"},
242+
}
243+
mounts, err := s.mountNative(ctx, nil, snap)
244+
require.NoError(t, err)
245+
require.Len(t, mounts, 1)
246+
assert.Contains(t, mounts[0].Options, "volatile")
247+
})
248+
249+
t.Run("view snapshot does not get volatile from config", func(t *testing.T) {
250+
snap := storage.Snapshot{
251+
ID: "snap2",
252+
Kind: snapshots.KindView,
253+
ParentIDs: []string{"parent1", "parent2"},
254+
}
255+
mounts, err := s.mountNative(ctx, nil, snap)
256+
require.NoError(t, err)
257+
require.Len(t, mounts, 1)
258+
assert.NotContains(t, mounts[0].Options, "volatile")
259+
})
260+
261+
t.Run("committed snapshot does not get volatile from config", func(t *testing.T) {
262+
snap := storage.Snapshot{
263+
ID: "snap3",
264+
Kind: snapshots.KindCommitted,
265+
ParentIDs: []string{"parent1", "parent2"},
266+
}
267+
mounts, err := s.mountNative(ctx, nil, snap)
268+
require.NoError(t, err)
269+
require.Len(t, mounts, 1)
270+
assert.NotContains(t, mounts[0].Options, "volatile")
271+
})
272+
}

0 commit comments

Comments
 (0)