Files
serverAppConfigs/serverAppConfigs-docs/Dankserver/Entropy Volume.md
T
Frank 7cf388367e docs(media): the array's write doors, and why survivors are re-verified by size
A folder-rename pass ran on the media array with no journal anywhere: no
jsonl on the array, no bash history, no cron/timer/job artifact, no other
host ever authenticating. The door was GNOME Files mounting the array over
SFTP (gvfsd-sftp -> sftp-server as dank): rename() with no shell and no
journal, bumping only the renamed directory's ctime. Copyparty cannot do
this (its bind is ro at the mount) and the *arr stack has no route to the
array at all (no SMB, no NFS, mini asleep).

Two laws fall out for the prune pipeline: re-verify survivors by size
rather than by the path a stale artifact recorded, and Plex extras rows
naming a held path survive a second section pass.
2026-11-01 09:46:32 -08:00

4.3 KiB

type, description, tags, timestamp
type description tags timestamp
reference Dankserver's /mnt/entropy volume: the LUKS/array chain, the crypttab + fstab boot path, and the containers bound to it
dankserver
2026-10-31

Entropy Volume

/mnt/entropy is the ext4 filesystem on the LUKS container holding /dev/md0 (RAID6, seven disks). The media stack's data lives there, so the mount is a boot dependency for those containers rather than a convenience.

Chain

/dev/md0                     <- mdadm (its mdadm.conf ARRAY is what makes md0 exist at boot)
  -> LUKS UUID=cd86c728-459e-4f3a-bcc2-41ecf84685ec   keyfile: /etc/entropy
     -> /dev/mapper/entropy  <- systemd-cryptsetup@entropy.service
        -> ext4 at /mnt/entropy  <- mnt-entropy.mount, from /etc/fstab

Files that own it

Repo file Installs to Produces at boot
dankserver/host/crypttab /etc/crypttab systemd-cryptsetup@entropy.service → /dev/mapper/entropy
dankserver/host/fstab /etc/fstab mnt-entropy.mount (mountpoint dank:dankserver, 0755)

Deploy a change by copying the file onto the host, then systemctl daemon-reload && update-initramfs -u. The initramfs step is not optional: the cryptsetup hook bakes /etc/crypttab into the initrd, and the array is unlocked there, before the real root mounts. scripts/mount-entropy.sh (udisksctl unlock + mount) stays as the manual path for a volume that was never unlocked; on a correct boot it is redundant.

Law

crypttab's device field takes the LUKS UUID, never the md array UUID. blkid prints both on adjacent lines for a RAID-backed container, and the file shipped since 2025 carried the array UUID (61bd6eaf-…) where the LUKS container is cd86c728-…. The generator produced a perfectly valid unit pointing at a device that never appears, so the mapper came into existence only through a desktop udisks2 session — the volume looked mounted on every login while every boot failed to mount it. The matching fstab line named the same wrong UUID directly instead of the mapper.

A LUKS keyfile is hashed whole, so a trailing newline is a different passphrase. The shipped /etc/entropy was 27 bytes — 26 characters plus \n — and cryptsetup rejected it even after the UUID was corrected. Keyfiles stay 0600 with no trailing newline; prove it with cryptsetup open --test-passphrase --key-file /etc/entropy UUID=… before relying on it for a boot.

Prove a mount fix with the artifacts systemd generates, not with a live mount. The regenerated systemd-cryptsetup@entropy.service naming the right device, findmnt /mnt/entropy sourcing /dev/mapper/entropy, and a matching checksum between the repo copy and the host copy are the evidence. A mount that exists because someone logged in proves nothing about the boot path — that exactly describes the year this bug survived.

Consumers

jellyfin, copyparty, and plex bind paths under /mnt/entropy; with the volume absent they start active (healthy) against empty directories, which is how a missing 91 TiB volume hides. See Dankserver Stack for the stack and Storage Policy for what may be written here.

Write doors

Something renamed movie folders on this array with no journal in any of the /mnt/entropy/*.jsonl plans, no bash history, no cron, no timer, and no job artifact. The census of things that can mutate it:

  • A local process as dank or root. scripts/media-apply.py is the only one that journals; anything else (a hand mv, another session's script) is silent.
  • SFTP by a human. GNOME Files on a workstation mounts the array through gvfsd-sftp, which runs sftp-server on this host as dank. Renames and moves are direct rename() calls: no shell, no history, no journal. A folder rename bumps only that directory's ctime — its mtime and every child's ctime stay at their old values, so the files look untouched while their paths are gone. Diagnose it with pgrep -af gvfsd-sftp on the workstation and ss -tnp for the peer.
  • Copyparty is not a door: the bind is ro at the mount level, so no HTTP or WebDAV write reaches the array regardless of account flags (Copyparty).
  • No SMB or NFS server exists here — the *arr stack on FrankBook-Pro cannot reach the array at all, so it cannot rename, import, or rescan it.