/rw/config/rc.local-early
is like /rw/config/rc.local
with two important differences:
- It runs much earlier in the qube startup process
- It blocks until complete. This means that until the
rc.local-early
script exits, the qube is not considered to have started up, and subsequent systemd units and user gui apps will not run.
Even though it is described in QubesOS’s live documentation, rc.local-early
is not available in QubesOS’s current release at time of writing (that being version 4.2-- and it remains to be seen if it will be backported to 4.2 at some point).
That said, you can plug in the functionality for rc.local-early
yourself, and you don’t even need to modify any templates; it can be done within /rw
of your app qube, by creating two additional files:
mkdir -p /rw/bind-dirs/usr/lib/qubes/init
- Create file
/rw/bind-dirs/usr/lib/qubes/init/qubes-early-vm-config.sh
with contents:
#!/usr/bin/bash
EARLY_SH=/usr/lib/qubes/init/qubes-early-vm-config.sh
# undo bind mount
umount -l "$EARLY_SH"
# run rc.local-early scripts, but only if the original qubes-early-vm.config.sh
# script doesn't provide this functionality
grep -q -e "rc.local-early" "$EARLY_SH" || {
for rc in /rw/config/rc.local-early.d/*.rc /rw/config/rc.local-early; do
[ -f "$rc" ] || continue
[ -x "$rc" ] || continue
"$rc"
done
unset rc
}
# this clause not strictly necessary but can avoid some foot-shooting
# with certain misconfigurations
[ `findmnt -n -o MAJ:MIN -T "$EARLY_SH"` = `findmnt -n -o MAJ:MIN -T /` ] || {
echo "file resides on unexpected block device: $EARLY_SH" >&2
exit 1
}
# run original script (that the current one replaced)
"$EARLY_SH"
chmod +x /rw/bind-dirs/usr/lib/qubes/init/qubes-early-vm-config.sh
mkdir -p /rw/config/qubes-bind-dirs.d
- Create file
/rw/config/qubes-bind-dirs.d/rc-local-early.conf
with contents:
binds+=( '/usr/lib/qubes/init/qubes-early-vm-config.sh' )
That’s it! You can now include your rc.local-early
script.