OpenRiot v7.9.69 — The Machine Copies Itself and Lives
“The construct tried to make a copy of itself and the whole street went dark. It read every file, one by one, and asked the encrypted disk for each one twice, and the disk — the same disk it was using for memory — stopped answering. The force-reboot came. The filesystem came back dirty. The Turing Police would call it a ‘thrashing induced I/O deadlock on a shared block device’ and bill you for the diagnosis. We call it a mirror that melted the thing it was standing on. So we stopped walking the files one at a time and taught the machine to read its own raw skin, straight through, top to bottom, and write it down somewhere else. The copy lives. The machine lives. That’s the whole trick.” — The OpenRiot Crew, v7.9.69
Release Overview
Backing up the whole system to a bootable mirror used to freeze the machine. It doesn’t anymore. The drive manager gains a second clone path that reads the raw filesystem sequentially instead of walking 3.2TB of inodes, the swap that turned out to be the murderer is taken out of the equation, the target is checked and repaired before it’s used, and the cancel key finally, actually, cancels.
Total changes: a sequential dump | restore clone, swap
discipline, a pre-mount fsck, a working cancel, and a
progress bar that moves.
📦 The Sequential Clone
dump 0af - /dev/rsd1a | (cd /mnt/backup && restore -rf -)
The Problem: The only clone path was rsync. rsync walks
the tree one inode at a time — millions of random seeks through
the softraid crypto layer. Sequential reads are cheap; random
reads are not. The crypto pipeline backs up, the disk stops
answering, the machine locks, the force-reboot arrives, and you
spend the morning in fsck.
The Fix: A second option under Full Backup — Clone to
/mnt/backup (dump | restore). dump reads the raw filesystem
cylinder-group by cylinder-group, in order, and pipes the stream
to restore, which writes the actual files into the target.
Same mirror as rsync. Sequential I/O instead of a random storm.
rsync stays for incremental runs — and it got harder to hurt
you: nice -n 20, --delete-delay, --prune-empty-dirs, and a
lower --bwlimit.
🔒 The Swap Was the Murderer
The Problem: Root, home, and swap all lived on one
softraid crypto volume. Under memory pressure the kernel paged
to swap — on the same encrypted disk rsync was already
saturating — and the crypto layer deadlocked on itself. nice
and --bwlimit only delayed it.
The Fix: The clone disables swap before it starts and
restores it when it’s done, on every exit path — success,
failure, or cancel. Without swap on the same device, the
feedback loop has nowhere to form. There’s no dmesg for this.
There is no error message. There is just a machine that doesn’t
freeze.
🧹 The Filesystem Was Not Clean
The Problem: After a force-reboot the backup disk came back
dirty — WARNING: R/W mount of /mnt/backup denied. Filesystem
is not clean - run fsck — and the clone would run against a
filesystem that refused to mount.
The Fix: Before cloning, if /mnt/backup isn’t already up,
the machine runs fsck -y /dev/sd3a, then mounts it. If it’s
already mounted, fsck is skipped — a clean reboot isn’t
punished with an unnecessary check.
⏹️ ESC Means Stop
The Problem: Pressing ESC set a flag and changed the message
to cancelled. It never touched the process. dump forks a
small army of children; restore holds the mount. The TUI said
“cancelled” while the disk kept grinding, and umount came back
Device busy.
The Fix: A watcher kills the whole tree — dump, restore,
rsync — the instant the flag is set. ESC means the machine
stops. umount means umount.
📊 A Bar That Tells the Truth
The Problem: The progress bar sat at 0.0% forever. dump
only reports its own percentage when it receives SIGINFO, which
nothing was sending; restore’s per-file chatter churned the
header; the number measured the root partition against a 3.4TB
total so it barely moved; and the sweep animation only re-ticked
on the other progress screen, so it froze after one frame. A
cancel with no error message dereferenced a nil and panicked.
The Fix: Progress is measured from the target’s own growth
against the partition being written, per partition — root
climbs 0→100%, then home climbs 0→100%. The sweep animates on
the clone screen too. The header keeps only the DUMP: lines,
so it reads dumping (Pass IV) [regular files] instead of
restore soup. And the cancel path no longer panics on a nil.
🧾 Files Changed
| File | Change |
|---|---|
source/migrate/clone.go |
dump | restore sequential clone; |
| swap disable/restore; pre-mount | |
fsck; process-tree cancel kill; |
|
| per-partition progress from disk use | |
source/migrate/model.go |
dump_clone routing; ESC kills the |
| tree; nil-guarded cancel; cylon | |
| animation on the dump-progress screen | |
source/migrate/screens/menus.go |
New “dump | restore” Full Backup entry |
source/migrate/ui.go |
Render the dump|restore clone correctly |
~/.local/bin/backup-4tb |
Standalone sequential clone script |
🗣️ Final Words
“The machine kept trying to copy itself and kept dying in the attempt, because it was reading its own skin one freckle at a time while breathing through the same wound. So we told it to read straight through, and to stop using its veins as its lungs, and to shut itself down when told. The copy boots. The original keeps running. The Turing Police will keep selling you a backup that phones home and a warranty that voids itself when you use it. We kept the mirror local and the machine awake.” — The OpenRiot Crew, v7.9.69