diff --git a/install/hardware/fix-synaptic-touchpad.sh b/install/hardware/fix-synaptic-touchpad.sh index d30dd271..00b3396c 100644 --- a/install/hardware/fix-synaptic-touchpad.sh +++ b/install/hardware/fix-synaptic-touchpad.sh @@ -1,6 +1,25 @@ # Enable Synaptics InterTouch for confirmed touchpads if not already loaded - -if grep -qi synaptics /proc/bus/input/devices \ - && ! lsmod | grep -q '^psmouse'; then - modprobe psmouse synaptics_intertouch=1 +# +# Only when modprobe can resolve psmouse for the running kernel, and never +# fatally. Installs run this under arch-chroot, where uname -r still names the +# live ISO's kernel while /lib/modules holds the target's -- the two differ on +# every machine that is not a T2 Mac, so modprobe failed with "Module psmouse +# not found in directory /lib/modules/" and took the whole install +# down with it. Asking modprobe itself first (-qn resolves a module without +# loading it) keeps that mismatch quiet, and the warning below covers every +# other reason it declines. An optional touchpad improvement must not be able to +# halt an install. +# +# Loading a module into the live kernel does nothing for the installed system +# either way, so this only takes effect when it runs on the booted machine. +# Persisting the switch instead would mean writing options psmouse +# synaptics_intertouch=1 to /etc/modprobe.d, which forces the SMBus transport +# past the kernel's own allowlist on every touchpad merely named "synaptics" in +# /proc/bus/input/devices -- a wider change than this one, and not one to make +# blind. +if grep -qi synaptics "${OMARCHY_SYNAPTIC_INPUT_DEVICES:-/proc/bus/input/devices}" \ + && ! lsmod | grep -q '^psmouse' \ + && modprobe -qn psmouse; then + modprobe psmouse synaptics_intertouch=1 || + echo "Warning: could not enable Synaptics InterTouch on psmouse" >&2 fi diff --git a/test/shell.d/synaptic-touchpad-test.sh b/test/shell.d/synaptic-touchpad-test.sh new file mode 100755 index 00000000..df4828e6 --- /dev/null +++ b/test/shell.d/synaptic-touchpad-test.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +leaf="$ROOT/install/hardware/fix-synaptic-touchpad.sh" +all="$ROOT/install/hardware/all.sh" + +grep -q 'run_logged .*hardware/fix-synaptic-touchpad.sh' "$all" || + fail "the synaptic touchpad quirk runs during hardware setup" +pass "the synaptic touchpad quirk runs during hardware setup" + +test_tmp=$(mktemp -d) +trap 'rm -rf "$test_tmp"' EXIT + +mkdir -p "$test_tmp/bin" +modprobe_log="$test_tmp/modprobe.log" + +# Only a real load is logged, so a case that expects nothing to happen can say +# so with an empty log even though the leaf always asks modprobe first whether +# psmouse resolves against the running kernel. +cat >"$test_tmp/bin/modprobe" <<'SH' +#!/bin/bash + +if [[ $1 == "-qn" ]]; then + exit "${TEST_MODPROBE_RESOLVES:-0}" +fi + +printf '%s\n' "$*" >>"$MODPROBE_LOG" +exit "${TEST_MODPROBE_STATUS:-0}" +SH + +cat >"$test_tmp/bin/lsmod" <<'SH' +#!/bin/bash + +printf '%s\n' 'Module Size Used by' +printf '%s\n' "${TEST_LOADED_MODULES:-}" +SH + +chmod +x "$test_tmp/bin"/* + +printf '%s\n' 'N: Name="SynPS/2 Synaptics TouchPad"' >"$test_tmp/devices" + +# Sourced under errexit the way run_logged runs it, so a failing modprobe would +# fail the run rather than be swallowed here. +run_fix() { + : >"$modprobe_log" + + MODPROBE_LOG="$modprobe_log" \ + PATH="$test_tmp/bin:$PATH" \ + OMARCHY_SYNAPTIC_INPUT_DEVICES="$test_tmp/devices" \ + TEST_LOADED_MODULES="${1:-}" \ + TEST_MODPROBE_STATUS="${2:-0}" \ + TEST_MODPROBE_RESOLVES="${3:-0}" \ + bash -eE -c 'source "$1"' bash "$leaf" +} + +run_fix +grep -q 'psmouse synaptics_intertouch=1' "$modprobe_log" || + fail "the synaptic touchpad quirk enables InterTouch on a booted machine" +pass "the synaptic touchpad quirk enables InterTouch on a booted machine" + +# The install-breaking case: under arch-chroot the live kernel's modules are not +# the ones on disk, so psmouse does not resolve and there is nothing to load. +run_fix "" 0 1 +if [[ -s $modprobe_log ]]; then + fail "the synaptic touchpad quirk skips a kernel that cannot resolve psmouse" +fi +pass "the synaptic touchpad quirk skips a kernel that cannot resolve psmouse" + +run_fix psmouse +if [[ -s $modprobe_log ]]; then + fail "the synaptic touchpad quirk leaves an already-loaded psmouse alone" +fi +pass "the synaptic touchpad quirk leaves an already-loaded psmouse alone" + +# An optional touchpad improvement never gets to halt an install, whatever the +# reason the module declines to load. +run_fix "" 1 2>/dev/null || + fail "the synaptic touchpad quirk survives a failing modprobe" +pass "the synaptic touchpad quirk survives a failing modprobe"