Table of Contents

EVE-OS Volume Provisioning: Pool Layer vs. Per-App Layer

Companion page to EVE-OS / ZEDEDA Application Volumes. That page covers the controller/app-instance config layer (maxsize, preserve, drvtype). This page covers the storage backend layer underneath it — what actually happens on the edge node's disks, and why those two layers must not be conflated.

The core distinction

There are two completely different things that can both reasonably be called “a zvol,” configured at two different times, by two different actors:

Pool layer Per-app volume layer
What it is The ZFS pool's RAID topology across physical disks (mirror / raidz1 / raidz2) One zvol (or qcow2 file) per individual app volume, sized from that volume's maxsize
Set via grub.cfg on the CONFIG partition, eve_install_zfs_with_raid_level=… Controller app-instance config (maxsize), read by volumemgr on the node
When Once, at install or reinstall Dynamically, every time an app instance with a volume is deployed, purged, or resized
Who acts on it The EVE installer The volumemgr pillar agent
Covered on EVE-OS Partitioning / ZFS wiki page This page, and EVE-OS / ZEDEDA Application Volumes

The install-time grub.cfg RAID setting decides only the physical pool topology. It does not create, size, or reserve space for any individual app's disk. Every app volume's actual backing object is created later, per app, by volumemgr, driven entirely by that app's maxsize — the same way qcow2 files are created per app on an ext4-persist node. Setting raid1 at install time tells EVE “mirror these two physical disks”; it says nothing about how big any given app's disk will be or whether it's a zvol or a file.

What volumemgr actually creates per app volume

Source: EVE's pillar/docs/volumemgr.md, pillar/types (ZVolDevicePrefix = “/dev/zvol”, ZFSBinary, ZPoolBinary), and EVE release notes referencing zvol support for ZFS persist.

Either way, the app-instance config layer doesn't know or care which of these it gets — maxsize is the same field regardless of backend, and volumemgr is what translates it.

Does maxsize fully provision the disk immediately?

qcow2 (ext4 persist): No — thin-provisioned by default. A maxsize of 100 GB on an 8 GB image creates a qcow2 file with a virtual size of 100 GB; actual bytes on /persist start near the image size and grow only as the guest writes new data. qemu-img info would show virtual size: 100 GiB but a much smaller disk size: until filled in. This changes only if preallocation is explicitly forced to metadata/falloc/full, which none of the GUI/TF/zcli fields covered in the companion page do.

zvol (ZFS persist), if per-app zvols are in use: Depends on whether volumemgr creates the zvol sparse or thick:

Can a per-app zvol be resized after the fact?

Yes, mechanically — this is a normal, well-supported ZFS operation. Growing a zvol's volsize (zfs set volsize=<new size> pool/vol) is safe and routine; shrinking is the risky/restricted direction, not growing. So a maxsize increase on a ZFS-persist app volume, combined with allow_storage_resize=true on the companion page, should translate to volumemgr issuing the equivalent of a zfs set volsize call on that specific app's zvol.

Not yet confirmed: the exact volumehandlers code path that performs this translation on the ZFS side. Treat this as mechanically plausible and consistent with how ZFS works, but not verified against EVE source line-by-line. Same Purge & Update lifecycle from the companion page still applies regardless — this is not a live resize while the app instance is running.

Why this matters practically