Storage — proxfold¶
Storage architecture for proxfold: the boot mirror, the primary ZFS media pool, NFS export to arrstack, and the NAS used for Proxmox backups.
Boot mirror (rpool)¶
| Property | Value |
|---|---|
| Pool name | rpool |
| Layout | ZFS mirror (RAID1) |
| Disks | Samsung SM843T 960GB + Intel DC S4500 960GB (SATA) |
| Mount point | / (plus /rpool, /rpool/ROOT, /rpool/data, /var/lib/vz) |
| Usable capacity | ~888 GB |
| Current usage (sampled 2026-04-28) | ~25 GB allocated / ~836 GB free (2% full) |
| Proxmox storage IDs | local (dir on rootfs, ISO/template/vztmpl) + local-zfs (ZFS-backed disk images for VMs/CTs) |
Installed via the Proxmox auto-installer during the Phase 4C boot drive swap (2026-04-22). The disk filter in rebuild/answer.toml.j2 selects both drives via filter.ID_BUS="ata"; the installer builds the mirror as ashift=12 with the PVE 9 defaults (compression=on, atime=off, relatime=on).
Check mirror health:
zpool status rpool
proxmox-boot-tool status # both ESPs should show "uuid=... is configured with: grub"
ZFS Pool (stash)¶
| Property | Value |
|---|---|
| Pool name | stash |
| Layout | RAIDZ1 |
| Disks | 6x Samsung PM1633a 3.84TB SAS SSD (expanded from 4-wide 2026-04-20) |
| Mount point | /stash |
| Media path | /stash/rodneystash/ |
| Usable capacity | ~21 TB (RAIDZ1 on 6× 3.84 TB SSDs) |
| Current usage (sampled 2026-04-28) | ~13.1 TB allocated / ~7.9 TB free (62% full) |
| ZFS version | zfs-2.4.1-pve1 userland / zfs-kmod-2.3.4-pve1 — split is expected on PVE 9.1 and is backward-compatible |
Expansion parity ratio
Data written before the expansion keeps its original 4-wide parity ratio (3d+1p). Only new writes use the 6-wide ratio (5d+1p). Reported usage will slowly improve as old data is rewritten (replaced, moved, or re-encoded) — this is a cosmetic accounting quirk, not a real space loss.
No offsite or incremental backup
Media on stash/rodneystash/ is protected by RAIDZ1 only. There is no offsite copy and PBS does not back up bulk media. See Accepted Risks — Media library has no backup for the tradeoff and the conditions that would trigger a revisit.
Datasets¶
NAME USED AVAIL REFER QUOTA MOUNTPOINT
stash ~9.32T ~5.78T ~9.32T none /stash
stash/plex-data ~8.92G ~91.1G ~8.92G 100G /stash/plex-data
| Dataset | Purpose | Quota |
|---|---|---|
stash |
Root dataset — media files at /stash/rodneystash/ |
none |
stash/plex-data |
Plex data directory (metadata, databases, cache, logs) | 100G |
The plex-data child dataset was created to move Plex's data directory off the LXC rootfs. See Plex — data directory for full details.
Media directories¶
Check pool health¶
ZFS scrub¶
Scrubs run on an automatic schedule. To trigger manually:
ZFS ARC cap¶
By default ZFS will grow the ARC cache to consume most available RAM. With 48GB total RAM and both rpool + stash as ZFS pools, a cap is applied:
echo "options zfs zfs_arc_max=15032385536" > /etc/modprobe.d/zfs.conf
update-initramfs -u
# Takes effect after reboot
Current value: 14 GB (15032385536). Reference table:
| Desired max | Byte value |
|---|---|
| 4 GB | 4294967296 |
| 8 GB | 8589934592 |
| 12 GB | 12884901888 |
| 14 GB | 15032385536 |
| 16 GB | 17179869184 |
Verify after reboot:
Note
The stash pool workload is mostly sequential media reads (low ARC hit rate). 14 GB is the current cap on 48 GB total RAM, leaving headroom for VMs and containers.
zpool upgrade — completed 2026-04-20¶
zpool upgrade stash was run at the start of Phase 3 RAIDZ expansion (2026-04-20 13:54 ACST). Five feature flags were enabled: raidz_expansion, redaction_list_spill, fast_dedup, longname, large_microzap. This is irreversible — the pool now requires OpenZFS 2.3+ to import. Any rescue or recovery environment must boot a kernel with ZFS 2.3 or newer.
NFS Export¶
The ZFS pool is exported via NFS to the arrstack VM.
/etc/exports:
- Only
arrstack(192.168.1.252) is permitted to mount the export no_root_squashis used because containers run as PUID=0 on a trusted home network
To reload exports after a change:
NFS Mount (arrstack VM)¶
Configured in /etc/fstab on the arrstack VM:
Mounts at /stash inside the VM, matching the host path.
SMB Export¶
One read-write SMB share \\192.168.1.250\media from the dataset root for Windows client access (DaVinci Resolve clip ingest, Music drag-and-drop). Managed by the samba role.
| Property | Value |
|---|---|
| Share name | media |
| Path | /stash/rodneystash |
| Access | Authenticated, read-write |
| User | smbmedia (system user, nologin; password in vault) |
| Force user | root (traverses across mixed-PUID files from the arrstack containers) |
| Allowed network | 192.168.1.0/24 |
| Protocol minimum | SMB2 (SMB1 disabled) |
Connect from Windows: File Explorer → Map Network Drive → \\192.168.1.250\media, "Connect using different credentials", store in Credential Manager. Writes from Windows land as root:root 0644; Plex / Sonarr / Radarr keep consuming via the same dataset path.
Why not separate read-only and read-write shares?
The first cut of this share split read-only (Movies / TV Shows) from read-write (Music). It ran straight into Windows' SMB MUP limit: one credential set per server identity, even with identical creds. System error 1219 — "Multiple connections to a server or shared resource by the same user…" — per Microsoft's troubleshooting guide. Workarounds (DNS CNAME / hosts-file alias / NetBIOS hostname for one mount and IP for the other) work but add a moving part. The simpler call: drop the split, accept that Windows drag-delete can now hit Movies/ and TV Shows/. The arrstack containers already have full write access to those paths, so the read-only safety was never load-bearing — it just felt nice.
Proxmox Mount Points (Plex LXC)¶
The ZFS pool and Plex data dataset are mounted directly into the plex LXC via Proxmox mount points, bypassing NFS:
See Plex for how media paths and the data directory are exposed inside the container.
LXC rootfs reclamation¶
Since Phase 4C the rootfs for LXC containers lives on local-zfs (backed by rpool/data), not LVM-thin. ZFS reclaims freed blocks natively through copy-on-write, so the old weekly pct fstrim cron the host used to carry is no longer required and is not deployed on the rebuilt host.
Historical context
Pre-2026-04-22 the boot drive was a single 128GB Samsung 840 PRO in LVM-thin, and a weekly Sunday 03:00 pct fstrim cron ran on all running containers to reclaim space (LVM-thin does not auto-return freed blocks, and discard=on is not valid on LXC rootfs). If you roll back to an LVM-thin boot drive for any reason, re-add the cron.
NAS-backed backup storage¶
The QNAP TS-269L at 192.168.1.253 is the only second failure domain in the lab. Two Proxmox storage entries point at it, with different roles since Phase 5A:
| Storage ID | Type | Content | Status |
|---|---|---|---|
nas-primary |
PBS | VM/CT incremental backups via Proxmox Backup Server | Primary — pbs-daily runs nightly 02:00 ACST against this; managed via the pbs role and the proxmox role's pbs_client.yml task. Datastore lives on PBS CT 105 over NFSv3 from the QNAP. |
nasbackup |
CIFS | vzdump archives (legacy) | Transitional — kept registered through ~2026-05-23 for the 30-day PBS-only soak called out in Phase 5A. Slated for removal once the PBS path has run unattended through that window. Codified in the proxmox role for idempotent re-registration during the transition. |
QNAP details (applies to both):
| Property | Value |
|---|---|
| IP | 192.168.1.253 |
| Configuration | 2× drives, RAID 1 |
| Shares used | backup (CIFS for nasbackup; NFS export for nas-primary via PBS CT) |
| Firmware | QTS 4.3.4 (EOL — see Accepted Risks — QNAP firmware EOL) |
Equivalent manual nasbackup registration (for reference; the role handles this idempotently):
pvesm add cifs nasbackup --server 192.168.1.253 --share backup --username admin --password '<password>' --content backup --smbversion 2.0
PBS-side datastore mount and ACL detail live in the pbs role page.
Related¶
- Proxmox configuration
- Plex — how media paths are exposed inside the container
- Arrstack — NFS mount and Docker volume paths
- Backup & Restore runbook