fingerprintd/packaging/deploy-dev.sh
Jorijn van der Graaf a3d3dcb4af Print the trustlet's rc on every enrol press, and let deploy-dev.sh pass extra flags
A refused enrolment sample is one of two things: an image the algorithm saw and
turned down (rc=0, samples remaining unchanged) or an error the trustlet never
got past (a negative rc). The touch line printed the count and the fid but not
the rc, so a run of twenty-two refusals in a row said nothing about which it was.
It does now.

EXTRA=... on deploy-dev.sh appends daemon flags, so a diagnostic session can
come up with --ta-log without editing the script or the unit by hand.
2026-09-04 22:58:22 +02:00

109 lines
5.2 KiB
Shell
Executable file

#!/bin/sh
# deploy-dev.sh -- bring the dev phone back to a running daemon, from nothing.
#
# packaging/deploy-dev.sh [host] default: fp6usb4
#
# Run from the repo root on the workstation, after a cross build. Everything the
# daemon needs on the phone that does NOT survive a reboot is put back by this:
#
# /tmp/fingerprintd the cross-built binary
# /tmp/fpenrol.sh fptrial.sh the enrolment and labelled-trial scripts
# /tmp/fplearn.sh the template-learning protocol
# qcomtee.ko loaded /dev/tee0 does not exist until it is
# /dev/sda6 on /mnt/persist the real persist partition, read-write --
# the daemon's SFS root symlinks into it
# fingerprintd-test the transient unit, learning on
#
# What survives a reboot and is therefore NOT touched: /usr/lib/firmware/
# qcomtee.ko, /lib/firmware/fingerprintd.json (regenerate with
# fp6fpcfg.py --daemon --verbose and pass --config to refresh it), the SFS
# symlinks under /var/lib/fingerprintd/sfs, and the finger name map.
#
# WHY /tmp. Nothing here is packaged yet; /tmp is deliberate so a reboot leaves
# a stock phone rather than a half-installed daemon. The cost is exactly this
# script, run once after each reboot.
set -eu
HOST=${1:-fp6usb4}
CONFIG=${CONFIG:-} # optional: a fingerprintd.json to install
EXTRA=${EXTRA:-} # optional: extra daemon flags, e.g. EXTRA=--ta-log
SSH="ssh -o ConnectTimeout=8 -o BatchMode=yes $HOST"
cd "$(dirname "$0")/.."
BIN=$(ls -dt bin/fingerprintd-aarch64-alpine-linux-musl-*/ | head -1)fingerprintd
[ -x "$BIN" ] || { echo "no cross-built binary under bin/; build first" >&2; exit 1; }
echo ">> binary $BIN"
echo " $(sha256sum "$BIN" | cut -c1-16)"
# The binary goes in under a NEW name and is swapped into place on the phone
# after the unit stops: a running executable cannot be overwritten (ETXTBSY,
# which scp reports only as "dest open: Failure"), and a retry loop turns that
# into six identical failures instead of one clear one. mv replaces the inode,
# which is allowed while the old one is still executing.
#
# The phone also drops off the network transiently, which IS worth retrying.
cp "$BIN" /tmp/fingerprintd.new
i=0
until scp -o ConnectTimeout=8 -o BatchMode=yes -q \
/tmp/fingerprintd.new packaging/fpenrol.sh packaging/fptrial.sh packaging/fplearn.sh \
${CONFIG:+"$CONFIG"} "$HOST:/tmp/"; do
i=$((i+1)); [ $i -lt 6 ] || { echo "scp failed 6 times" >&2; rm -f /tmp/fingerprintd.new; exit 1; }
echo " scp retry $i"; sleep 5
done
rm -f /tmp/fingerprintd.new
echo ">> copied"
# EXTRA crosses into the single-quoted remote script as a prefixed assignment.
$SSH "EXTRA='$EXTRA'; "'set -e
# Stop before the swap so the new binary is what starts, not the old inode.
sudo systemctl stop fingerprintd-test 2>/dev/null || true
sudo mv /tmp/fingerprintd.new /tmp/fingerprintd
sudo chmod +x /tmp/fingerprintd /tmp/fpenrol.sh /tmp/fptrial.sh /tmp/fplearn.sh
if [ -f /tmp/fingerprintd.json ]; then
sudo cp /tmp/fingerprintd.json /lib/firmware/fingerprintd.json
echo ">> config installed"
fi
if ! lsmod | grep -q "^qcomtee"; then
sudo insmod /usr/lib/firmware/qcomtee.ko qseeflow=0
fi
[ -c /dev/tee0 ] || { echo "no /dev/tee0 after insmod" >&2; exit 1; }
echo ">> qcomtee loaded, /dev/tee0 present"
sudo mkdir -p /mnt/persist
if ! mount | grep -q " /mnt/persist "; then
sudo mount -o rw /dev/sda6 /mnt/persist
fi
mount | grep " /mnt/persist " | grep -q "rw," || { echo "persist not rw" >&2; exit 1; }
echo ">> persist mounted rw"
sudo systemctl stop fingerprintd-test 2>/dev/null || true
sleep 1
sudo systemd-run --unit=fingerprintd-test --collect \
/tmp/fingerprintd --daemon --verbose --edge-wake \
--sfs-root=/var/lib/fingerprintd/sfs --sfs-writable --rpmb-write $EXTRA >/dev/null
[ -z "$EXTRA" ] || echo ">> extra daemon flags: $EXTRA"
printf ">> daemon starting"
# Scope the readiness check to THIS invocation. The journal persists across
# restarts and reboots, so grepping the whole unit history matches the ready
# line of the PREVIOUS run and reports the daemon up while the session is
# still coming up on the worker thread -- which is how a first version of this
# script ran fprintd-list into "device is still starting".
# (No apostrophes in this block: the whole remote script is single-quoted.)
INV=$(systemctl show -p InvocationID --value fingerprintd-test)
log() { sudo journalctl "_SYSTEMD_INVOCATION_ID=$INV" --no-pager -o cat 2>/dev/null; }
i=0
while [ $i -lt 40 ]; do
if log | grep -q "fingerprintd: ready"; then echo " ready"; break; fi
if log | grep -q "StartFailed\|must run as root\|sensor power-up failed\|cannot open config"; then
echo " FAILED"; log | tail -15; exit 1
fi
printf "."; sleep 1; i=$((i+1))
done
[ $i -lt 40 ] || { echo " TIMED OUT"; log | tail -15; exit 1; }
echo ">> $(systemctl is-active fingerprintd-test), owning: $(busctl --system list 2>/dev/null | grep -c net.reactivated.Fprint)"
fprintd-list user 2>&1 | tail -n +2
echo ">> binary $(sha256sum /tmp/fingerprintd | cut -c1-16) config $(sha256sum /lib/firmware/fingerprintd.json | cut -c1-16)"
'
echo
echo "measurement:"
echo " ssh $HOST 'sudo /tmp/fplearn.sh enrol right-middle-finger'"
echo " ssh $HOST 'sudo /tmp/fplearn.sh base'"
echo " ssh $HOST 'sudo /tmp/fplearn.sh trend'"