106 lines
5 KiB
Shell
106 lines
5 KiB
Shell
|
|
#!/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
|
||
|
|
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"
|
||
|
|
|
||
|
|
$SSH '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 >/dev/null
|
||
|
|
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'"
|