Disk / filesystem monitoring¶
Sysadmin morning question: is anything full, and what's eating it?
This page documents the disk-related helpers and the tv disk channel.
For the dense reference table, see helpers.md.
Why care¶
Three failure modes that wake you up at 3am:
- Disk full (
No space left on device) — auditd panics the kernel ifdisk_full_action = halt. Most other daemons just stop accepting writes silently. - Inode exhaustion — disk shows free space, but
touch foofails because the inode table is full. Common with apps that create millions of tiny files (mail spools, badly-tuned caches). - Mount lost / mounted with wrong options — the same path
exists but isn't where you think it is, or is now
nosuid,nodevwhen it shouldn't be (security regression after a manual remount).
The helpers cover all three.
Quick CLI¶
disk-usage # per-mount df with green/yellow/red thresholds
disk-inodes # inode usage per mount
disk-largest /var # largest depth-1 children of /var
disk-largest /var/log --top 10 # classic /var/log triage
mount-info # active mounts + /etc/fstab
disk-watch / # live update of root mount usage
disk-largest auto-elevates via sudo -v when the path is root-owned
(e.g. disk-largest /var/lib/docker). Same gotcha as the audit
helpers: these are shell functions, so sudo disk-largest …
doesn't work; warm the sudo cache once with sudo -v and the helper
takes care of the rest.
Interactive: tv disk¶
Ctrl+S cycles 5 sources: per-mount df → inodes → largest dirs in
/var /home /tmp /opt /srv → active mounts → largest files >100M.
Preview is path-aware (uses du --max-depth=1 for dirs, ls -lh +
file for files). Enter opens dir in yazi or file in less. Alt+E
edits /etc/fstab. Alt+T tails dmesg -wT --color=always to catch
ENOSPC and I/O errors live.
Daily / weekly recipes¶
Morning sweep¶
If both are green you're done in 5 seconds. If disk-usage shows red:
disk-largest <red-mount> --top 20
# then drill into the offender
disk-largest <red-mount>/<biggest-subdir> --top 20
tv disk is faster for the drill phase because the path-aware preview
eliminates the second disk-largest call.
/var/log is full¶
Usual suspects:
journal/—sudo journalctl --vacuum-size=200Mto cap.*.log.1.gzaccumulating — logrotate misconfigured, or a service not signalled to reopen its log file.audit/— auditd; tunemax_log_file/num_logsper auditd.md.
Disk free but touch foo fails¶
Inode exhaustion:
Look for IUse% >= 95%. To find the culprit (millions of tiny files):
sudo find / -xdev -type d -exec sh -c 'echo "$(ls -A "$1" 2>/dev/null | wc -l) $1"' _ {} \; 2>/dev/null \
| sort -rn | head -20
(Slow on large filesystems; run during off-peak.)
Mount audit¶
Look for:
- A
/homemounted withoutnosuid,nodev— privilege-escalation surface. - A
/tmpmounted withoutnoexec,nosuid,nodev— common attacker drop site. - A drive in
/etc/fstabthat should mount but doesn't appear in the active list — mount failure at boot.
Caveats¶
- macOS doesn't have
df -hT— the helper templates emitdf -hon Darwin. du --max-depth=1is a GNU extension — macOS BSDduaccepts-d 1. The helper uses--max-depth=1(works because Homebrew installs GNU coreutils as the defaultduon most macOS hosts in this repo); pure macOS without coreutils will see the option flag rejected. Workaround: installcoreutilsviabrew install coreutils(already done if you're using this repo's Brewfile).disk-largestdoesn't follow mount boundaries unless you tell it to. By defaultduincludes mounted subdirs in the parent's total. For per-filesystem accounting usedu -x.dmesgrequires root on most modern kernels (kernel.dmesg_restrict=1).Alt+Tintv diskcalls it via sudo.
See also¶
- auditd framework —
disk_full_actionpolicy - Helpers in this repo
- Cookbook recipe 12 — combines disk + firewall + scheduled-jobs into one weekly pass