Skip to content

Instantly share code, notes, and snippets.

@mustafaturan
Last active September 18, 2026 04:12
Show Gist options
  • Select an option

  • Save mustafaturan/2cfdbb17ccec480200c65c3f2344360f to your computer and use it in GitHub Desktop.

Select an option

Save mustafaturan/2cfdbb17ccec480200c65c3f2344360f to your computer and use it in GitHub Desktop.
setup-10g-tmp.sh
#!/bin/bash
# Move /tmp from a RAM tmpfs (1.9G) to a disk-backed 10G ext4 image on /dev/sda2,
# keeping the "wiped on every boot" behaviour a tmpfs gave for free.
set -euo pipefail
IMG=/var/tmp-disk.img
SIZE=10G
[ "$(id -u)" -eq 0 ] || { echo "run as root"; exit 1; }
if [ ! -f "$IMG" ]; then
echo "==> Creating $SIZE image at $IMG"
fallocate -l "$SIZE" "$IMG"
mkfs.ext4 -q -m 0 -L tmpdisk "$IMG"
fi
chmod 600 "$IMG"
echo "==> Preparing filesystem (1777) and migrating current /tmp contents"
MNT=$(mktemp -d /root/tmpmig.XXXXXX)
mount -o loop "$IMG" "$MNT"
chmod 1777 "$MNT"
cp -a /tmp/. "$MNT"/ 2>/dev/null || true # sockets are skipped, that's expected
umount "$MNT"
rmdir "$MNT"
echo "==> Adding /etc/fstab entry"
# x-systemd.before=local-fs.target: nofail would otherwise drop the ordering that
# systemd-tmpfiles-setup.service (After=local-fs.target) relies on to see the
# mounted fs rather than the bare mountpoint underneath it.
if grep -qE '^[^#]*[[:space:]]/tmp[[:space:]]' /etc/fstab; then
echo " /tmp entry already present, leaving it alone"
else
cp /etc/fstab "/etc/fstab.bak.$(date +%Y%m%d%H%M%S)"
echo "$IMG /tmp ext4 loop,nofail,x-systemd.before=local-fs.target,noatime,nosuid,nodev 0 0" >> /etc/fstab
fi
echo "==> Installing boot-time wipe rule"
# Overrides /usr/lib/tmpfiles.d/tmp.conf wholesale (same filename), so the
# /var/tmp line has to be carried over too.
# D = create dir, and empty it when systemd-tmpfiles runs with --remove,
# which systemd-tmpfiles-setup.service does at every boot.
# 10d = additionally age out stale files on long-uptime systems (--clean).
cat > /etc/tmpfiles.d/tmp.conf <<'CONF'
# Local override of /usr/lib/tmpfiles.d/tmp.conf.
# /tmp is a disk-backed ext4 image, so it needs an explicit boot-time wipe
# to behave like the tmpfs it replaced.
D /tmp 1777 root root 10d
x /tmp/lost+found
q /var/tmp 1777 root root 30d
CONF
echo "==> Belt-and-braces ordering for the cleanup service"
mkdir -p /etc/systemd/system/systemd-tmpfiles-setup.service.d
cat > /etc/systemd/system/systemd-tmpfiles-setup.service.d/after-tmp.conf <<'CONF'
[Unit]
After=tmp.mount
CONF
echo "==> Activating"
systemctl daemon-reload
mount /tmp
echo
df -h /tmp
ls -ld /tmp
echo
echo "Dry-run of the boot-time wipe (nothing is deleted):"
systemd-tmpfiles --remove --boot --dry-run /etc/tmpfiles.d/tmp.conf || true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment