From ee60708880390559638bbd17b6e56af2eb952cdf Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Mon, 23 Oct 2023 11:02:17 -0400 Subject: [PATCH] Support size option when creating tmpfs volumes Fixes: https://github.com/containers/podman/issues/20449 Signed-off-by: Daniel J Walsh --- .../source/markdown/podman-volume-create.1.md | 7 +++-- libpod/runtime_volume_common.go | 29 ++++++++++--------- test/system/160-volumes.bats | 5 +++- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/docs/source/markdown/podman-volume-create.1.md b/docs/source/markdown/podman-volume-create.1.md index edbf1692bc..f2222b6105 100644 --- a/docs/source/markdown/podman-volume-create.1.md +++ b/docs/source/markdown/podman-volume-create.1.md @@ -55,7 +55,10 @@ The `o` option sets options for the mount, and is equivalent to the filesystem options (also `-o`) passed to **mount(8)** with the following exceptions: - The `o` option supports `uid` and `gid` options to set the UID and GID of the created volume that are not normally supported by **mount(8)**. - - The `o` option supports the `size` option to set the maximum size of the created volume, the `inodes` option to set the maximum number of inodes for the volume and `noquota` to completely disable quota support even for tracking of disk usage. Currently these flags are only supported on "xfs" file system mounted with the `prjquota` flag described in the **xfs_quota(8)** man page. + - The `o` option supports the `size` option to set the maximum size of the created volume, the `inodes` option to set the maximum number of inodes for the volume, and `noquota` to completely disable quota support even for tracking of disk usage. + The `size` option is supported on the "tmpfs" and "xfs[note]" file systems. + The `inodes` option is supported on the "xfs[note]" file systems. + Note: xfs filesystems must be mounted with the `prjquota` flag described in the **xfs_quota(8)** man page. Podman will throw an error if they're not. - The `o` option supports using volume options other than the UID/GID options with the **local** driver and requires root privileges. - The `o` options supports the `timeout` option which allows users to set a driver specific timeout in seconds before volume creation fails. For example, **--opt=o=timeout=10** sets a driver timeout of 10 seconds. @@ -75,7 +78,7 @@ $ podman volume create $ podman volume create --label foo=bar myvol -# podman volume create --opt device=tmpfs --opt type=tmpfs --opt o=nodev,noexec myvol +# podman volume create --opt device=tmpfs --opt type=tmpfs --opt o=size=2M,nodev,noexec myvol # podman volume create --opt device=tmpfs --opt type=tmpfs --opt o=uid=1000,gid=1000 testvol diff --git a/libpod/runtime_volume_common.go b/libpod/runtime_volume_common.go index c74a0f32a3..dca38a01ca 100644 --- a/libpod/runtime_volume_common.go +++ b/libpod/runtime_volume_common.go @@ -178,28 +178,31 @@ func (r *Runtime) newVolume(ctx context.Context, noCreatePluginVolume bool, opti if err := LabelVolumePath(fullVolPath, volume.config.MountLabel); err != nil { return nil, err } - if volume.config.DisableQuota { + switch { + case volume.config.DisableQuota: if volume.config.Size > 0 || volume.config.Inodes > 0 { return nil, errors.New("volume options size and inodes cannot be used without quota") } - } else { + case volume.config.Options["type"] == define.TypeTmpfs: + // tmpfs only supports Size + if volume.config.Inodes > 0 { + return nil, errors.New("volume option inodes not supported on tmpfs filesystem") + } + case volume.config.Inodes > 0 || volume.config.Size > 0: projectQuotaSupported := false q, err := quota.NewControl(r.config.Engine.VolumePath) if err == nil { projectQuotaSupported = true } - quota := quota.Quota{} - if volume.config.Size > 0 || volume.config.Inodes > 0 { - if !projectQuotaSupported { - return nil, errors.New("volume options size and inodes not supported. Filesystem does not support Project Quota") - } - quota.Size = volume.config.Size - quota.Inodes = volume.config.Inodes + if !projectQuotaSupported { + return nil, errors.New("volume options size and inodes not supported. Filesystem does not support Project Quota") } - if projectQuotaSupported { - if err := q.SetQuota(fullVolPath, quota); err != nil { - return nil, fmt.Errorf("failed to set size quota size=%d inodes=%d for volume directory %q: %w", volume.config.Size, volume.config.Inodes, fullVolPath, err) - } + quota := quota.Quota{ + Inodes: volume.config.Inodes, + Size: volume.config.Size, + } + if err := q.SetQuota(fullVolPath, quota); err != nil { + return nil, fmt.Errorf("failed to set size quota size=%d inodes=%d for volume directory %q: %w", volume.config.Size, volume.config.Inodes, fullVolPath, err) } } diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats index 4b863a0b66..b7092cb14f 100644 --- a/test/system/160-volumes.bats +++ b/test/system/160-volumes.bats @@ -431,11 +431,14 @@ EOF @test "podman volume type=tmpfs" { myvolume=myvol$(random_string) - run_podman volume create -o type=tmpfs -o device=tmpfs $myvolume + run_podman volume create -o type=tmpfs -o o=size=2M -o device=tmpfs $myvolume is "$output" "$myvolume" "should successfully create myvolume" run_podman run --rm -v $myvolume:/vol $IMAGE stat -f -c "%T" /vol is "$output" "tmpfs" "volume should be tmpfs" + + run_podman run --rm -v $myvolume:/vol $IMAGE sh -c "mount| grep /vol" + is "$output" "tmpfs on /vol type tmpfs.*size=2048k.*" "size should be set to 2048k" } # Named volumes copyup