<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dotfiles/.gitignore, branch master</title>
<subtitle>My linux config and rc files</subtitle>
<id>https://git.sommerfeld.dev/dotfiles/atom/.gitignore?h=master</id>
<link rel='self' href='https://git.sommerfeld.dev/dotfiles/atom/.gitignore?h=master'/>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/'/>
<updated>2026-05-29T10:18:15Z</updated>
<entry>
<title>refactor(suspend): gate suspend on AC, drop bespoke zellij inhibit</title>
<updated>2026-05-29T10:18:15Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-29T10:18:15Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=ec3734c5ef9fcfe97c21cd19f198ec779ab5f052'/>
<id>urn:sha1:ec3734c5ef9fcfe97c21cd19f198ec779ab5f052</id>
<content type='text'>
New, simpler suspend policy:

  AC plugged in   -&gt; never auto-suspends (lid close ignored, idle no-op)
  On battery only -&gt; lid close suspends, swayidle suspends at 30 min idle

This replaces the SSH/zellij-aware inhibit machinery with a rule that
matches the user's mental model: if you don't want the machine to
sleep, plug it in. Long-running tasks (builds, downloads, SSH
sessions, headless services) just need AC.

Changes:

* etc/systemd/logind.conf.d/20-lid-ac.conf: set
  HandleLidSwitchExternalPower=ignore so logind itself handles the AC
  case at the source. No userspace daemon, no race, no rate-limit risk.
* dot_local/bin/on-battery-suspend: tiny POSIX wrapper that exits 0
  when any /sys/class/power_supply/{AC,ADP}*/online == 1, else execs
  `systemctl suspend`.
* dot_config/systemd/user/swayidle.service: add
  `timeout 1800 on-battery-suspend`. Idle suspend now exists, but only
  when on battery.
* Delete zellij-inhibit-suspend.{path,service} + watcher script and
  remove the entry from systemd-units/user.txt. The .path
  re-trigger storm bug is moot because the whole mechanism is gone.

Manual suspends (sway XF86Sleep keybind, sway power submode `s`,
`systemctl suspend` over SSH) still always work regardless of AC --
explicit user intent wins.

Also drop /migrate-podman-to-btrfs.sh from .gitignore; the one-off
migration script has been deleted now that the user has switched their
podman storage to the btrfs driver.

On-host steps to apply:

  chezmoi apply -v
  systemctl --user daemon-reload
  systemctl --user reset-failed zellij-inhibit-suspend.service zellij-inhibit-suspend.path || true
  systemctl --user stop zellij-inhibit-suspend.path zellij-inhibit-suspend.service || true
  systemctl --user disable zellij-inhibit-suspend.path || true
  systemctl --user restart swayidle.service
  # logind drop-in is reloaded automatically by the etc deploy script.

Verify:

  systemctl status systemd-logind | grep -i lid
  loginctl show-session $XDG_SESSION_ID | grep -i lid
  # Unplug AC -&gt; close lid -&gt; should suspend.
  # Plug AC   -&gt; close lid -&gt; nothing happens.
</content>
</entry>
<entry>
<title>feat(suspend): re-enable suspend on s2idle, drop diagnostic scaffolding</title>
<updated>2026-05-29T10:18:15Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-29T10:18:15Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=6e0c5c33438e5e898bd075c33a45b3abf9d1b26b'/>
<id>urn:sha1:6e0c5c33438e5e898bd075c33a45b3abf9d1b26b</id>
<content type='text'>
Confirmed root cause: this hardware's S3 (deep) firmware path triggers a
fatal wake-from-suspend hang only on linux-hardened. INIT_ON_FREE + slab
hardening + tighter locking turn a latent driver race that stock linux
gets away with into an unrecoverable panic so early the journal isn't
even flushed. mem_sleep_default=s2idle bypasses the BIOS S3 path
entirely (s0ix is a pure-kernel low-power state) and suspends/resumes
reliably under hardened.

This is a widespread Lenovo S3 firmware issue across post-2018
ThinkPads (see Ubuntu T560, X1C9/10/11 reports). Lenovo themselves
moved newer firmwares to s2idle-only. Not a linux-hardened bug per se;
just hardened being a strict enough kernel to make the bug fatal.

Keep:
* mem_sleep_default=s2idle in etc/kernel/cmdline-linux-hardened.tmpl
  (only the hardened UKI; stock linux keeps unchanged shared cmdline)

Revert (all the diagnostic / speculative scaffolding from the last
few commits):
* MODULES=(intel_lpss_pci) → MODULES=()  — Arch wiki touchpad fix was
  not the cause here
* nmi_watchdog=panic softlockup_panic=1 panic=10 — only needed to
  auto-reboot during diagnosis
* no_console_suspend — diagnostic-only
* etc/systemd/logind.conf.d/20-no-suspend.conf  — masking workaround
* sleep-target masking block in run_onchange_after_deploy-etc.sh.tmpl,
  replaced with a one-shot cleanup that removes any leftover
  /dev/null symlinks from systems that ran the previous version
* systemd-pstore.service from systemd-units/system.txt — added only to
  catch the diagnostic panic
* diagnose-suspend.sh helper (and its .gitignore/.chezmoiignore entries)
* sway suspend → lock-session keybind workaround
* power-menu.sh Suspend entry restoration
* KEYBINDS.md docs
</content>
</entry>
<entry>
<title>feat(suspend): hardened-only init_on_free=0 + hang-detection cmdline</title>
<updated>2026-05-29T10:18:14Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-29T10:18:14Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=e2a7a2fdb9ba66e777ec1a8c0d3c9301cc21bdab'/>
<id>urn:sha1:e2a7a2fdb9ba66e777ec1a8c0d3c9301cc21bdab</id>
<content type='text'>
Split the hardened UKI cmdline off the shared etc/kernel/cmdline.tmpl
so we can carry workarounds without poking the stock linux build.

Daily-driving linux-hardened on this hardware has reliably hung on
resume from S3: black screen, blinking caps-lock + power LED, only
the power button helps. The kernel journal stops at 'PM: suspend
entry (deep)' with nothing after, so the freeze is below the level
where logs can flush — characteristic of a hard hang inside a device
driver's suspend/resume callback rather than a userspace bug.

linux-hardened defaults init_on_free=1, which zeroes pages on free.
On Intel + iwlwifi/i915/nvme stacks this routinely surfaces latent
UAFs as suspend hangs that are invisible on stock linux. Drop that
knob to 0 for the hardened cmdline as the working hypothesis.

Add nmi_watchdog=panic, softlockup_panic=1, panic=10 so if the next
attempt still wedges, a stuck CPU self-panics and auto-reboots
within ~10s, giving us a 'journalctl -b -1 -k' trace to look at
instead of having to force-power-off blindly.

Stock linux is untouched.
</content>
</entry>
<entry>
<title>feat(podman): switch rootless storage driver to btrfs</title>
<updated>2026-05-29T10:18:13Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-05-29T10:18:13Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=aabcdc206246aa935790908f2ab7e7edcc88b3b9'/>
<id>urn:sha1:aabcdc206246aa935790908f2ab7e7edcc88b3b9</id>
<content type='text'>
fuse-overlayfs is dog-slow on `podman commit` (and noticeably slower
than native overlay/btrfs for layer extraction in general) because every
read/write round-trips through a FUSE daemon. The kernel overlay driver
does not support btrfs as a lowerdir, so on a btrfs root fs the choices
were:

  - fuse-overlayfs  (slow, but works)
  - btrfs           (native subvolume + CoW snapshot per layer; fast)

Switching graph drivers is destructive — the on-disk layout is
incompatible, so a one-time `podman system reset --force` is required.
A migration helper script lives at the repo root (gitignored,
chezmoiignored) that snapshots stateful containers, exports images and
volumes, runs the reset, and restores everything on the new driver.

Drops fuse-overlayfs from meta/base.txt — no longer needed and pulls
in libfuse3 transitively for nothing. (Flatpak still depends on it for
its own sandbox; pacman won't actually uninstall the binary while
flatpak is around — that's fine.)

VM (nix/vm.nix) is unaffected: it sets its own storage.conf inline
with driver=overlay since its rootfs is ext4.
</content>
</entry>
<entry>
<title>chore: remove webtorrent mpv hook; gitignore caches</title>
<updated>2026-04-21T00:24:38Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-04-21T00:24:38Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=edc5e6070f23c02a45635a1e0180e998fd6c4fb2'/>
<id>urn:sha1:edc5e6070f23c02a45635a1e0180e998fd6c4fb2</id>
<content type='text'>
</content>
</entry>
<entry>
<title>chore: gitignore .worktrees/ for chezmoi migration</title>
<updated>2026-04-21T00:23:18Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2026-04-21T00:23:18Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=288f0dd4757f373a4ef7293020d2be94c983f502'/>
<id>urn:sha1:288f0dd4757f373a4ef7293020d2be94c983f502</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Add .lldbinit</title>
<updated>2025-10-24T10:46:59Z</updated>
<author>
<name>sommerfeld</name>
<email>sommerfeld@sommerfeld.dev</email>
</author>
<published>2025-10-24T10:46:59Z</published>
<link rel='alternate' type='text/html' href='https://git.sommerfeld.dev/dotfiles/commit/?id=2f4b0c7f048575fe641c08d046b5a4d6d6872cad'/>
<id>urn:sha1:2f4b0c7f048575fe641c08d046b5a4d6d6872cad</id>
<content type='text'>
</content>
</entry>
</feed>
