A Pi 5 NAS, Five Failure Modes, and One Ethernet Cable

I wanted Time Machine backups. My Mac had been living dangerously without them for longer than I care to admit, and the fix seemed straightforward: Raspberry Pi 5, a 1TB SSD, Samba with Apple's Time Machine extensions. An afternoon's work, maybe two. A small, quiet box that would sit next to the router and silently save me from myself.
That was the plan. What actually happened was a thorough tour of the Linux storage stack, several kernel panics, and an eventual resolution that involved plugging in an ethernet cable I should have reached for on day one.
The stack, and why it matters
Before anything went wrong, I had to understand what I was building. The storage side of a Linux NAS isn't one thing — it's four separate layers, each completely ignorant of the ones above and below it.
At the bottom: LUKS encryption, provided by cryptsetup and the kernel's dm-crypt module. LUKS sees a raw block device and produces an encrypted one. It doesn't know what you'll put inside it.
On top of that: LVM, the Logical Volume Manager. lvm2 in userspace, the device mapper kernel module underneath. LVM takes one or more Physical Volumes (in this case, the decrypted LUKS volume) and presents them as a single pool of storage — a Volume Group — from which you carve Logical Volumes of whatever size you like. It doesn't know what filesystem lives inside them.
On top of that: ext4. A filesystem. It sees a Logical Volume as a contiguous block device. It doesn't know about LUKS or LVM beneath it.
On top of that: Samba, serving ext4 directories over the network as SMB shares with Apple's vfs_fruit extension bolted on for Time Machine compatibility. Samba doesn't know there's a filesystem underneath, let alone encryption or volume management.
Both LUKS and LVM use the kernel's device mapper as their plumbing, which is why /dev/mapper/nasvault and /dev/mapper/nasvg-phi appear in lsblk, and why the dmsetup command surfaces when things go catastrophically wrong. It's the lowest-level interface to device mapper, and it becomes your best friend during an incident.
The composability of these layers is the point. You can resize a Logical Volume without touching LUKS. You can add a second SSD, LUKS-encrypt it separately, add it to the Volume Group, and extend an existing Logical Volume across both physical drives — all without reformatting the filesystem or reconfiguring Samba. Each layer does one thing and delegates everything else.
One ordering constraint
The first non-obvious lesson: install Samba before lvm2/cryptsetup, not after.
Installing the LVM and cryptsetup packages regenerates the initramfs. If /etc/crypttab isn't fully configured at that point, the Pi boots into a state where it's waiting for LUKS volumes it can't unlock, which blocks the network from coming up. Since the Pi has no monitor attached, you're left with a box that's on, appears to have booted, and accepts no SSH connections. The fix is to pull the SD card, mount it on another machine, and sort out the initramfs by hand — which is exactly as annoying as it sounds.
The safe sequence: install and verify Samba, take an SD card image as a checkpoint, then install lvm2 and cryptsetup. The checkpoint is particularly important because the next steps are destructive — LUKS-formatting a drive is not something you undo.

The SSD falls off the bus (first time)
With the storage stack assembled — LUKS UUID in /etc/crypttab, Logical Volumes in /etc/fstab with nofail on both entries — everything came up cleanly on first boot.
Then, thirty-seven seconds later, it didn't.
Apr 12 18:24:20 nasbox systemd-cryptsetup[1366]: Underlying device for crypt device nasvault disappeared.
The SSD had vanished from the USB bus. LUKS still had nasvault, nasvg-phi, and nasvg-cs registered in device mapper, but they were ghosts — active entries pointing at a device that no longer existed. Any attempt to read from /mnt/timemachine/phi returned Input/output error. And crucially, because Samba held open file handles on those ghost devices, even dmsetup remove refused to clean them up until Samba was stopped first.
Initial suspicion: USB autosuspend. Linux suspends USB devices after two seconds of inactivity by default, and the Crucial X9 SSD was a plausible candidate for not waking reliably. I added a udev rule to disable autosuspend for the specific vendor/product ID. This turned out to be correct reasoning applied to the wrong problem.
The hub was resetting
A closer look at the kernel log around the thirty-seven second mark:
usb 3-1: USB disconnect, device number 2
usb 3-1.2: USB disconnect, device number 3
usb 3-1: new high-speed USB device number 7 using xhci-hcd
...
usb 3-1: can't set config #1, error -71
Not the SSD. The entire USB hub. 3-1 is the VIA Labs hub that the SSD was connected through, and it was resetting — taking all downstream devices, including the SSD, with it. The hub had Billboard devices attached (2109:8822), indicating USB Power Delivery negotiation. The PD contract completing at around thirty-seven seconds post-boot was causing the hub to reset.
The SSD's autosuspend setting was irrelevant. The hub was the problem.
The SSD falls off the bus (second time, third time, fourth time)
The obvious fix: bypass the hub and plug the SSD directly into one of the Pi's blue USB 3.0 ports. No hub, no hub reset.
This worked for about eleven minutes — until the backup started writing in earnest and the SSD disappeared again:
usb 2-1: USB disconnect, device number 10
sd 0:0:0:0: [sda] Synchronize Cache(10) failed: Result: hostbyte=0x01
This time it was power. The Crucial X9 draws up to 900mA during writes. The Pi's USB port, even with usb_max_current_enable=1 set in config.txt, couldn't sustain that under heavy load. And checking the USB tree revealed something else: when connected directly to the Pi's USB 3.0 port, the SSD was being claimed by the UAS (USB Attached SCSI) driver rather than the standard usb-storage driver. UAS is higher-performance, queuing multiple IO streams simultaneously — which means it draws more current.
/: Bus 002.Port 001: Dev 001, Class=root_hub, Driver=xhci-hcd/1p, 5000M
|__ Port 001: Dev 002, If 0, Class=Mass Storage, Driver=uas, 5000M
The fix for UAS is a kernel boot parameter. In /boot/firmware/cmdline.txt, appended to the single existing line:
usb-storage.quirks=0634:5606:u
The format is vendorid:productid:u where :u means "UAS blacklist". The SSD still runs at USB 3.0 speed; it just uses Bulk Only Transport instead of SCSI command queuing. Less aggressive IO, more stable power draw.
This helped. But the SSD was still dropping. Repeatedly, within minutes of the backup starting.
Back to the hub, on purpose
The powered hub has a useful property I'd been thinking of as a liability: it powers downstream devices from its own PSU, not from the Pi's USB port. The SSD doesn't care where its current comes from; it just needs enough of it. Through the hub, the SSD draws from the hub's power supply. The Pi's USB port never sees that load.
The hub reset at boot remains, but it's predictable — it happens once, around thirty-odd seconds after boot, and then the hub is stable for as long as the Pi runs. The right answer was to put the SSD back through the hub and build an automatic recovery mechanism for the one-time reset.
A udev rule fires when the SSD's block device re-appears after any disconnection:
ACTION=="add", SUBSYSTEM=="block", DEVTYPE=="disk", ENV{ID_USB_VENDOR_ID}=="0634", ENV{ID_USB_MODEL_ID}=="5606", RUN+="/usr/bin/systemctl --no-block start nas-recovery.service"
A oneshot systemd service waits up to thirty seconds for the LUKS device to settle (the hub reconnects in fits and starts), tears down any stale device mapper entries, re-opens LUKS by UUID, re-activates the Volume Group, mounts both filesystems, and restarts Samba. The whole recovery takes under a minute and is invisible to Time Machine — by the time it tries to connect, the shares are up.
The ethernet cable
With the SSD stable and the recovery service tested, I started a backup. It ran. It made progress — forty percent in twenty-four minutes. And then:
Apr 12 22:21:19 nasbox NetworkManager: device (wlan0): supplicant interface state: associating -> 4way_handshake
Apr 12 22:21:21 nasbox NetworkManager: dhcp4 (wlan0): state changed new lease, address=172.29.0.25
The WiFi dropped and reconnected. Samba lost its connection. Time Machine declared the backup failed and gave up.
Samba with Time Machine is uniquely unforgiving about dropped connections — there's no retry, no resumption, just failure. A PlayStation losing WiFi for two seconds reconnects and carries on. Time Machine sees the share disappear mid-backup and calls it done.
The Pi was three feet from the router. The WiFi was, by every other measure, excellent. But the Pi's onboard antenna is small, the board runs warm, and a sustained large transfer is a different proposition to browsing the web. The fix was a single ethernet cable.
With the cable in place: forty percent complete, about an hour remaining, transfer rate solid throughout. It finished.
What I'd do differently
Wire it from the start. The WiFi failure was the last one but it was also the most avoidable. A NAS is infrastructure; infrastructure gets a cable.
Read the kernel log before assuming the cause. The autosuspend diagnosis was plausible and wrong. journalctl -k with the right grep would have shown the hub resetting in the first five minutes. I spent longer than I should chasing a theory before looking at the evidence.
Enable persistent journaling immediately. By default, systemd's journal doesn't survive reboots on Raspberry Pi OS. When the Pi froze — which it did, twice, while the storage stack was in a broken state — the logs reset. sudo mkdir -p /var/log/journal and a restart of systemd-journald fixes this permanently. Do it before anything else.
The storage stack itself — LUKS, LVM, ext4, Samba — worked exactly as designed throughout. Each layer did its job and stayed out of the others' business. The problems were all physical: a hub that resets, a USB port that can't sustain a write workload, a WiFi connection that drops at the worst possible moment. The software was fine. The world was the problem.
Martin Harris writes about connecting real hardware to abstract cloud infrastructure. If you've ever diagnosed a kernel panic caused by an SSD, a hub, and a WiFi chip all failing in sequence, you've arrived at the right blog.
If you find this blog useful, please consider a donation.
