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.
90 lines
4.3 KiB
Markdown
90 lines
4.3 KiB
Markdown
---
|
|
type: reference
|
|
description: "Dankserver's /mnt/entropy volume: the LUKS/array chain, the crypttab + fstab boot path, and the containers bound to it"
|
|
tags:
|
|
- dankserver
|
|
timestamp: 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
|
|
|
|
```text
|
|
/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.
|