Files
moonarch/defaults/bin/moonarch-batsaver-restore
nevaforget 952776c4f9
Update PKGBUILD version / update-pkgver (push) Successful in 2s
batsaver: switch to pkexec helper, drop broken udev permission hack
The wheel-write-via-udev approach for charge_control_end_threshold has
been broken since 2026-04-08: the audit-remediation commit added
ACTION=="add" to the rule, but the threshold attribute doesn't exist
yet at the add event on Lenovo, so chmod fails silently and permissions
are never set. moonarch-batsaver-toggle has been returning Permission
denied since.

Replace the udev-rule approach with a pkexec helper:

  defaults/bin/moonarch-batsaver-apply    privileged: validate + write
  defaults/bin/moonarch-batsaver-toggle   user: read sysfs, dispatch via pkexec
  defaults/bin/moonarch-batsaver-restore  boot-time root restore (extracted
                                          from inline ExecStart for clarity)

Default Standard-pkexec prompt — password cached per session for the
~5min auth window; no polkit no-password rule, no privilege escalation
surface from misvalidated input. Same pattern Battery-Health-Charging
GNOME extension uses.

The boot-time restore service now skips the kernel write when the
sysfs value already matches the saved state (Lenovo drivers reject
same-value writes with EINVAL).

DECISIONS.md documents the failure analysis and trade-offs.
CLAUDE.md updated to describe the new flow.
moonarch-doctor: udev-effectiveness check removed.
2026-05-04 12:17:31 +02:00

24 lines
638 B
Bash
Executable File

#!/bin/sh
# ABOUTME: Restores the saved battery charge end threshold on boot.
# ABOUTME: Skips silently when the kernel already reports the same value (avoids EINVAL on some Lenovo drivers).
set -eu
STATE_FILE="/var/lib/moonarch/batsaver-threshold"
SYS_FILE="/sys/class/power_supply/BAT0/charge_control_end_threshold"
[ -f "$STATE_FILE" ] || exit 0
[ -f "$SYS_FILE" ] || exit 0
V=$(cat "$STATE_FILE")
case "$V" in
""|*[!0-9]*) exit 0 ;;
esac
[ "$V" -ge 1 ] && [ "$V" -le 100 ] || exit 0
# Some Lenovo drivers reject writing the same value with EINVAL.
C=$(cat "$SYS_FILE")
[ "$C" = "$V" ] && exit 0
printf %s "$V" > "$SYS_FILE"