Keep Btrfs snapshots out of the locate index and put /home in it

The stock Arch updatedb.conf interacts badly with Omarchy's Btrfs
layout in both directions:

- Snapper snapshots under /.snapshots are nested subvolumes reached by
  plain directory traversal, so updatedb indexes the entire system once
  per snapshot. On machines that accumulated snapshots this means
  multi-hour updatedb runs at full CPU, gigabytes of RAM, and a
  multi-gigabyte plocate.db (observed: 18 GB db, 7.5 h runs at 96% CPU
  with 592 snapshots; 43 MB and ~1 min after the fix).
- PRUNE_BIND_MOUNTS="yes" treats Btrfs subvolume mounts like /home as
  bind mounts, so locate finds nothing in home directories at all.

Configure updatedb.conf at install time and migrate existing installs,
then rebuild the index in the background. Both settings are matched
tolerantly and appended when absent, so a hand-edited updatedb.conf is
fixed rather than silently skipped.
This commit is contained in:
Martin Bastien
2026-07-23 09:10:16 -04:00
parent 1b6ab15331
commit 8ef4eb24a2
4 changed files with 154 additions and 0 deletions
+1
View File
@@ -4,5 +4,6 @@ run_logged "$OMARCHY_INSTALL/config/lockscreen-pam.sh"
run_logged "$OMARCHY_INSTALL/config/fix-powerprofilesctl-shebang.sh"
run_logged "$OMARCHY_INSTALL/config/docker.sh"
run_logged "$OMARCHY_INSTALL/config/snapper.sh"
run_logged "$OMARCHY_INSTALL/config/locate.sh"
run_logged "$OMARCHY_INSTALL/config/enable-services.sh"
run_logged "$OMARCHY_INSTALL/config/firewall.sh"
+23
View File
@@ -0,0 +1,23 @@
UPDATEDB_CONF_PATH="${OMARCHY_UPDATEDB_CONF_PATH:-/etc/updatedb.conf}"
echo "Configuring locate to skip Btrfs snapshots and index Btrfs subvolumes"
[[ -f $UPDATEDB_CONF_PATH ]] || exit 0
# Btrfs subvolume mounts (like /home) look like bind mounts, so pruning
# bind mounts leaves them out of the index entirely.
if grep -qE '^PRUNE_BIND_MOUNTS[[:space:]]*=' "$UPDATEDB_CONF_PATH"; then
sed -i -E 's|^PRUNE_BIND_MOUNTS[[:space:]]*=.*|PRUNE_BIND_MOUNTS = "no"|' "$UPDATEDB_CONF_PATH"
else
printf '%s\n' 'PRUNE_BIND_MOUNTS = "no"' >>"$UPDATEDB_CONF_PATH"
fi
# Snapper snapshots are nested subvolumes reached by plain directory
# traversal, so without this updatedb indexes the system once per snapshot.
if ! grep -E '^PRUNEPATHS[[:space:]]*=' "$UPDATEDB_CONF_PATH" | grep -qF '/.snapshots'; then
if grep -qE '^PRUNEPATHS[[:space:]]*=[[:space:]]*"' "$UPDATEDB_CONF_PATH"; then
sed -i -E 's|^(PRUNEPATHS[[:space:]]*=[[:space:]]*")|\1/.snapshots |' "$UPDATEDB_CONF_PATH"
else
printf '%s\n' 'PRUNEPATHS = "/.snapshots"' >>"$UPDATEDB_CONF_PATH"
fi
fi