diff options
| author | Craig Jennings <c@cjennings.net> | 2026-04-12 22:55:02 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-04-12 22:55:02 -0400 |
| commit | 64260df38906e68b3d75169b8cae3b69715f5bc6 (patch) | |
| tree | 33c05ad4ac015fd09296baf40a7b6369e29a53d6 | |
| parent | 77b9caac5a6bb5c338f691fdadd2f781557a9d7b (diff) | |
| download | archangel-64260df38906e68b3d75169b8cae3b69715f5bc6.tar.gz archangel-64260df38906e68b3d75169b8cae3b69715f5bc6.zip | |
fix: drop zroot/tmp dataset and dedup pacman snapshot hook
- /tmp on ZFS breaks systemd-tmpfiles-clean (statx ENOLINK on
PrivateTmp paths). Use tmpfs via fstab instead; keep zroot/var/tmp.
- zfs-pre-snapshot gains a 60s lockfile in /run so burst transactions
(archsetup produced 357 snapshots in one run) collapse to one.
Both fixes mirrored in installer/archangel and installer/lib/zfs.sh.
Already applied and verified on velox.
| -rwxr-xr-x | installer/archangel | 30 | ||||
| -rw-r--r-- | installer/lib/zfs.sh | 24 |
2 files changed, 46 insertions, 8 deletions
diff --git a/installer/archangel b/installer/archangel index 814f12b..9c6da97 100755 --- a/installer/archangel +++ b/installer/archangel @@ -893,10 +893,14 @@ create_datasets() { zfs create -o mountpoint=/var/lib/pacman "$POOL_NAME/var/lib/pacman" zfs create -o mountpoint=/var/lib/docker "$POOL_NAME/var/lib/docker" - # Temp directories - excluded from snapshots + # /var/tmp - ZFS-backed, persists across reboots, excluded from snapshots zfs create -o mountpoint=/var/tmp -o com.sun:auto-snapshot=false "$POOL_NAME/var/tmp" - zfs create -o mountpoint=/tmp -o com.sun:auto-snapshot=false "$POOL_NAME/tmp" - chmod 1777 /mnt/tmp /mnt/var/tmp + chmod 1777 /mnt/var/tmp + + # /tmp - tmpfs via fstab (not ZFS: ZFS statx() returns ENOLINK on + # systemd PrivateTmp paths, breaking systemd-tmpfiles-clean every boot) + mkdir -p /mnt/tmp + chmod 1777 /mnt/tmp info "Datasets created:" zfs list -r "$POOL_NAME" -o name,mountpoint,compression @@ -1003,10 +1007,13 @@ install_base_btrfs() { configure_system() { step "Configuring System" - # fstab (only for EFI - /boot is on ZFS root) + # fstab (EFI + tmpfs /tmp; /boot is on ZFS root) info "Generating fstab..." echo "# /efi - EFI System Partition (ZFSBootMenu binary)" > /mnt/etc/fstab echo "UUID=$(blkid -s UUID -o value "${EFI_PARTS[0]}") /efi vfat defaults,noatime 0 2" >> /mnt/etc/fstab + echo "" >> /mnt/etc/fstab + echo "# /tmp - tmpfs (avoids ZFS statx ENOLINK on systemd PrivateTmp paths)" >> /mnt/etc/fstab + echo "tmpfs /tmp tmpfs defaults,nosuid,nodev,mode=1777 0 0" >> /mnt/etc/fstab # Timezone info "Setting timezone to $TIMEZONE..." @@ -1318,15 +1325,28 @@ EOF #!/bin/bash POOL="zroot" DATASET="$POOL/ROOT/default" +LOCKFILE="/run/zfs-pre-snapshot.lock" +MIN_INTERVAL=60 + +# Dedup bursts of back-to-back pacman transactions (e.g. archsetup runs) +# into a single snapshot. Lockfile on tmpfs — clears on reboot. +if [ -f "$LOCKFILE" ]; then + last=$(stat -c %Y "$LOCKFILE" 2>/dev/null || echo 0) + now=$(date +%s) + if (( now - last < MIN_INTERVAL )); then + exit 0 + fi +fi + TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) SNAPSHOT_NAME="pre-pacman_$TIMESTAMP" if zfs snapshot "$DATASET@$SNAPSHOT_NAME"; then echo "Created snapshot: $DATASET@$SNAPSHOT_NAME" + touch "$LOCKFILE" else echo "Warning: Failed to create snapshot" >&2 fi - EOF chmod +x /mnt/usr/local/bin/zfs-pre-snapshot diff --git a/installer/lib/zfs.sh b/installer/lib/zfs.sh index feda91d..bf8af35 100644 --- a/installer/lib/zfs.sh +++ b/installer/lib/zfs.sh @@ -133,10 +133,14 @@ create_zfs_datasets() { zfs create -o mountpoint=/var/lib/pacman "$POOL_NAME/var/lib/pacman" zfs create -o mountpoint=/var/lib/docker "$POOL_NAME/var/lib/docker" - # Temp directories - excluded from snapshots + # /var/tmp - ZFS-backed, persists across reboots, excluded from snapshots zfs create -o mountpoint=/var/tmp -o com.sun:auto-snapshot=false "$POOL_NAME/var/tmp" - zfs create -o mountpoint=/tmp -o com.sun:auto-snapshot=false "$POOL_NAME/tmp" - chmod 1777 /mnt/tmp /mnt/var/tmp + chmod 1777 /mnt/var/tmp + + # /tmp - tmpfs via fstab (not ZFS: ZFS statx() returns ENOLINK on + # systemd PrivateTmp paths, breaking systemd-tmpfiles-clean every boot) + mkdir -p /mnt/tmp + chmod 1777 /mnt/tmp info "Datasets created:" zfs list -r "$POOL_NAME" -o name,mountpoint,compression @@ -266,11 +270,25 @@ EOF #!/bin/bash POOL="zroot" DATASET="$POOL/ROOT/default" +LOCKFILE="/run/zfs-pre-snapshot.lock" +MIN_INTERVAL=60 + +# Dedup bursts of back-to-back pacman transactions (e.g. archsetup runs) +# into a single snapshot. Lockfile on tmpfs — clears on reboot. +if [ -f "$LOCKFILE" ]; then + last=$(stat -c %Y "$LOCKFILE" 2>/dev/null || echo 0) + now=$(date +%s) + if (( now - last < MIN_INTERVAL )); then + exit 0 + fi +fi + TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) SNAPSHOT_NAME="pre-pacman_$TIMESTAMP" if zfs snapshot "$DATASET@$SNAPSHOT_NAME"; then echo "Created snapshot: $DATASET@$SNAPSHOT_NAME" + touch "$LOCKFILE" else echo "Warning: Failed to create snapshot" >&2 fi |
