Section 2.2 now reflects what shipped: auditoria + 22 bridges + 7 vars
+ man page + 7 phases all marked done. Open item left explicit: the
1625 hardcoded /storage refs in legacy scripts continue to work via
compat and refactor organically.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Three concrete Class Z migrations land via bridges in the archr meta-
package plus single-line script tweaks:
- /storage/jdk -> /opt/jdk (runemu.sh JAVA_HOME, freej2me.sh JDKDEST)
- /storage/.hatari -> /var/lib/archr/data/hatari (start_hatari.sh
HATARI_DIR_HOME; the pre-baked Atari-ST .cfg files keep working
through the symlink because both addresses resolve to the same
overlay dir).
- /storage/openbor -> /var/lib/archr/games/openbor (start_OpenBOR.sh
CONFIGDIR).
Other Class Z paths fall out cleanly:
- /storage/.opt was already covered by /opt -> /storage/.opt symlink
in virtual/image/package.mk.
- /storage/.emulationstation already gets redirected to
/storage/.config/emulationstation by emulationstation's autostart,
which is in turn covered by the umbrella bridge F5.
- /storage/psvita/vita3k/ux0/app and /storage/.nfs-mount are
low-traffic top-level paths; no bridge added.
docs/fhs-mapping.md: Fase 7 detail + system-wide audit summary. 17
umbrella bridges in archr meta-package + 5 modular (openssh, iwd,
bluez, connman, fontconfig). All seven ARCHR_* variables resolve to
Arch-friendly paths. The remaining 1625 hardcoded /storage refs in
projects/ArchR continue to work through compat (both paths reach the
same storage overlay); refactoring those is left as an organic
follow-up.
Status header marks the FHS migration complete. Section 2.2 of the
Arch-ification roadmap is now closed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Same playbook as F5, applied to user data. /storage/roms appears in
117 files in projects/ArchR and refactoring every reference in one
shot would be a huge diff over the directory where the user's games
library lives. Bad risk-reward.
Two new umbrella bridges in the archr meta-package:
/var/lib/archr/games -> /storage/roms
/var/lib/archr/backup -> /storage/backup
ARCHR_GAMES flipped to the FHS path; man page mirrors it.
The other Class E paths (screenshots, recordings, downloads, music,
pictures, videos, tvshows) audit as zero references in
projects/ArchR; they are LibreELEC top-level heritage and not used at
ArchR runtime.
/storage/.ssh stays as is. busybox/package.mk sets the root user's
HOME to /storage, so /storage/.ssh is literally $HOME/.ssh — FHS
already. Moving to /root/.ssh would require flipping the HOME of root
to /root first, which has knock-on effects (cd ~, every script that
assumes cwd at login, etc) outside the FHS scope.
No data migration script: nothing on disk moves. ROMs and saves keep
exactly the same bytes; the FHS path is just another way to address
them.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Original F5 plan was "one commit per emulator, refactor every
hardcoded /storage/.config/<emu> reference". Audit showed that path
appears across 22+ device quirk files, multiple start scripts and a
handful of compiled-in patches per emulator. Mass refactor would be a
huge diff with real regression risk and zero FHS gain on the running
system because, with the bridge installed, the FHS path already
resolves correctly.
Pivot: install two umbrella bridges in the archr meta-package:
/var/lib/archr/config -> /storage/.config
/var/lib/archr/data -> /storage/.local/share
Flip the ARCHR_CONFIG and ARCHR_DATA exports in 010-archr-fhs to the
FHS paths so downstream scripts that already use the variables get
the Arch-friendly surface for free. Update archr(7) ENVIRONMENT
section: both variables now describe the FHS location as the actual
address, with /storage/... noted as the rw-overlay substrate.
Net effect: every /var/lib/archr/config/<emu> and
/var/lib/archr/data/<emu> path exists at runtime and is writable.
Inspection tools see a normal Arch layout. Hardcoded /storage/.config
references in JELOS-inherited quirks and start scripts keep working
because the symlink resolves both ways — writes through either path
land in the same overlay file. Per-emulator refactors stay possible
later, as incremental PRs, without a single big-bang.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Fase 4 in fhs-mapping.md gets the breakdown: 9 state dirs bridged in
the four F4.x commits (ssh, iwd, bluez, services, samba, connman,
wireguard, tailscale, cron), pacman db/cache and rfkill noted as
no-op (already bridged upstream), .local/share moved to F5 (it is
per-emulator data and stays with each emulator's config migration),
overlayfs upperdirs documented as permanent no-op for the same
constraint that pinned the F3 workdirs, .pacman/build deferred to
section 2.1 when pacman gets wired into userland.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Class F (logs) and Class G (temp/update) reshuffled.
Logs:
- /var/log was already a mount from /storage/.cache/log via
packages/sysutils/busybox/system.d/var-log.mount, so journald already
writes to /var/log/journal in FHS terms. runemu.sh debug log moves
from /storage/.cache/log/runemu-debug.log to /var/log/runemu-debug.log
(same physical bytes, FHS surface).
- createlog (top-level busybox script) packs archive zips into
/var/log/archr/archive instead of /storage/logfiles. ArchR tmpfiles
z_01_archr.conf creates the backing dir under the storage overlay so
the path is writable on first boot.
Update:
- /var/cache/archr/update is a bridge symlink to /storage/.update added
by the archr meta-package. archr-update, automount and the [update]
samba share all flipped to the FHS path.
- factoryreset still preserves /storage/.update by its real name in
the find regex; that path is also what the pre-boot bootloader
scripts read, so the backing path is the canonical one and the
bridge is just the userland surface. Comment added so this is
obvious to future readers.
- busybox/scripts/init keeps UPDATE_ROOT=/storage/.update because it
runs in the initramfs before /var is even available.
Overlayfs workdirs (/storage/.tmp/*-workdir) and /storage/.boot.hint
documented as no-op in fhs-mapping.md: the overlayfs kernel layer
requires upperdir and workdir to share a filesystem, and the boot
hint is part of the U-Boot handshake.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Last Class C bridge: /var/cache/archr/fstrim.run -> /storage/.cache.
The stamp file does not exist at first boot; touch follows the symlink
and creates the file on the storage side, where future fstrim runs
read it to remember the last run.
docs/fhs-mapping.md updated:
- Fase 2 marked complete with the 5 caches actually migrated
(mesa, fontconfig, kernel-overlays, locpath, fstrim.run).
- Documents that the initial Class C bucket of 44 paths was a coarse
auto-classification: most of those paths are state (-> F4 / Class D),
logs (-> F3 / Class F) or already redirected upstream.
- Three already-no-op redirects called out: journald.conf.d,
systemd-machine-id, system_timezone (already symlinked by their
owning packages).
Next: F3 (Class F+G, logs and temp).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Audit of projects/ArchR/packages/sysutils/systemd/package.mk showed
the Class A paths are already FHS-correct at runtime: systemd creates
build-time symlinks from /etc/modules-load.d, /etc/sysctl.d,
/etc/tmpfiles.d, /etc/udev/{hwdb,rules}.d and /etc/systemd/*conf.d
pointing into /storage/.config/.
For any tool inspecting the running system, /etc/modules-load.d is a
real populated directory in /etc. The fact that the symlink target
lands on the storage overlay is internal plumbing required because
the rootfs is squashfs read-only.
Repointing those targets to /var/lib/archr/etc would be cosmetic in
exchange for adding a bind-mount in the init script. Not worth it.
hosts/resolv keep their existing template+render pipeline
(network-base-setup reads /storage/.config/{hosts,resolv}.conf and
writes /run/archr/{hosts,resolv}.conf at boot).
Fase 1 closed without code change. Fase 2 (Class C: cache) is next
and has actual work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
profile.d/010-archr-fhs exports seven variables (ARCHR_ETC,
ARCHR_CONFIG, ARCHR_CACHE, ARCHR_DATA, ARCHR_GAMES, ARCHR_LOG,
ARCHR_TMP) that future ArchR scripts should read instead of
hardcoding /storage/.config and siblings. Every variable defaults to
its current /storage location so behaviour is identical to today;
subsequent FHS phases will flip the right-hand side without touching
the callers.
archr(7) gains an ENVIRONMENT section describing each variable, its
current value and its FHS target so anyone writing a new script knows
which name to use.
docs/fhs-mapping.md: F0 marked complete; F1..F7 still pending.
Risk: zero. The new file is read at login but only sets variables.
No script reads them yet.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
docs/fhs-mapping.md: full audit (297 unique /storage paths classified
across 7 classes A-G + Z special cases), seven-phase plan, rules of
the road. Phase 0 introduces the vocabulary (vars in
/etc/profile.d/archr-fhs.sh) without moving any data. Each subsequent
phase ends in a commit with grep + boot validation before the next
one starts. User data (saves, ROMs) is phase 6, only after all other
phases survived at least one release on the stable channel.
.gitignore: whitelist docs/fhs-mapping.md so the plan stays tracked
alongside improvements.md and release-policy.md while the rest of
docs/ remains user-local.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
.gitignore had docs/* blocking everything; the rest of the directory
remains user-local notes, so whitelist only the two files that belong
to the project: improvements.md (Arch-ification roadmap, with the
architectural decision that LibreELEC overlay is by design) and
release-policy.md (semver-RC until v2.0, YYYY.MM.PATCH after, three
release channels mapped to updates.branch).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>