diff --git a/snapshots/devmapper/config.go b/snapshots/devmapper/config.go index 3c491df99..9e5ed7d84 100644 --- a/snapshots/devmapper/config.go +++ b/snapshots/devmapper/config.go @@ -50,6 +50,9 @@ type Config struct { // Defines file system to use for snapshout device mount. Defaults to "ext4" FileSystemType fsType `toml:"fs_type"` + + // Defines optional file system options passed through config file + FsOptions string `toml:"fs_options"` } // LoadConfig reads devmapper configuration file from disk in TOML format diff --git a/snapshots/devmapper/snapshotter.go b/snapshots/devmapper/snapshotter.go index a6d6dd28f..4a504ac7c 100644 --- a/snapshots/devmapper/snapshotter.go +++ b/snapshots/devmapper/snapshotter.go @@ -403,6 +403,7 @@ func (s *Snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k } if len(snap.ParentIDs) == 0 { + fsOptions := "" deviceName := s.getDeviceName(snap.ID) log.G(ctx).Debugf("creating new thin device '%s'", deviceName) @@ -412,7 +413,14 @@ func (s *Snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k return nil, err } - if err := mkfs(ctx, s.config.FileSystemType, dmsetup.GetFullDevicePath(deviceName)); err != nil { + if s.config.FileSystemType == fsTypeExt4 && s.config.FsOptions == "" { + // Explicitly disable lazy_itable_init and lazy_journal_init in order to enable lazy initialization. + fsOptions = "nodiscard,lazy_itable_init=0,lazy_journal_init=0" + } else { + fsOptions = s.config.FsOptions + } + log.G(ctx).Debugf("Creating file system of type: %s with options: %s for thin device %q", s.config.FileSystemType, fsOptions, deviceName) + if err := mkfs(ctx, s.config.FileSystemType, fsOptions, dmsetup.GetFullDevicePath(deviceName)); err != nil { status, sErr := dmsetup.Status(s.pool.poolName) if sErr != nil { multierror.Append(err, sErr) @@ -448,7 +456,7 @@ func (s *Snapshotter) createSnapshot(ctx context.Context, kind snapshots.Kind, k // mkfs creates filesystem on the given devmapper device based on type // specified in config. -func mkfs(ctx context.Context, fs fsType, path string) error { +func mkfs(ctx context.Context, fs fsType, fsOptions string, path string) error { mkfsCommand := "" var args []string @@ -457,8 +465,7 @@ func mkfs(ctx context.Context, fs fsType, path string) error { mkfsCommand = "mkfs.ext4" args = []string{ "-E", - // We don't want any zeroing in advance when running mkfs on thin devices (see "man mkfs.ext4") - "nodiscard,lazy_itable_init=0,lazy_journal_init=0", + fsOptions, path, } case fsTypeXFS: diff --git a/snapshots/devmapper/snapshotter_test.go b/snapshots/devmapper/snapshotter_test.go index d8bb73e0e..819a555d4 100644 --- a/snapshots/devmapper/snapshotter_test.go +++ b/snapshots/devmapper/snapshotter_test.go @@ -142,12 +142,26 @@ func testUsage(t *testing.T, snapshotter snapshots.Snapshotter) { func TestMkfsExt4(t *testing.T) { ctx := context.Background() - err := mkfs(ctx, "ext4", "") + // We test the default setting which is lazy init is disabled + err := mkfs(ctx, "ext4", "nodiscard,lazy_itable_init=0,lazy_journal_init=0", "") + assert.ErrorContains(t, err, `mkfs.ext4 couldn't initialize ""`) +} + +func TestMkfsExt4NonDefault(t *testing.T) { + ctx := context.Background() + // We test a non default setting where we enable lazy init for ext4 + err := mkfs(ctx, "ext4", "nodiscard", "") assert.ErrorContains(t, err, `mkfs.ext4 couldn't initialize ""`) } func TestMkfsXfs(t *testing.T) { ctx := context.Background() - err := mkfs(ctx, "xfs", "") + err := mkfs(ctx, "xfs", "", "") + assert.ErrorContains(t, err, `mkfs.xfs couldn't initialize ""`) +} + +func TestMkfsXfsNonDefault(t *testing.T) { + ctx := context.Background() + err := mkfs(ctx, "xfs", "noquota", "") assert.ErrorContains(t, err, `mkfs.xfs couldn't initialize ""`) }