From d71f14f8128477c0ae533612896fbe2990d73eae Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Mon, 18 Apr 2016 23:47:06 -0400 Subject: init --- notes.txt | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 notes.txt (limited to 'notes.txt') diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..1e4f296 --- /dev/null +++ b/notes.txt @@ -0,0 +1,176 @@ +initramfs-tools launches, as pid 1, a script called /init which is used to call +all of the various configured scripts which are installed into +'/etc/initramfs-tools/scripts'. + +Some of this scripts are executed in subshells, thus they cannot contain the +final 'pivot_root' (or actually 'switch_root' now), but some of the scripts are +sourced from the pid1 'sh' process. + +There is an environment variable called 'BOOT' which is set to 'local' by +default and which can be overriden on the kernel command line. The pid1 process +will source a file named with the value of the 'BOOT' variable: + + # Always load local and nfs (since these might be needed for /etc or + # /usr, irrespective of the boot script used to mount the rootfs). + . /scripts/local + . /scripts/nfs + . /scripts/${BOOT} + +The BOOT script is used to define functions that will be called within pid1; +particularly (from '/scripts/local', for example): + + + mountroot() + { + local_mount_root + } + + mount_top() + { + # Note, also called directly in case it's overridden. + local_top + } + + mount_premount() + { + # Note, also called directly in case it's overridden. + local_premount + } + + mount_bottom() + { + # Note, also called directly in case it's overridden. + local_bottom + } + + +Thus, it should be possible to add a script '/script/samizdat' which overrides +one of these functions, and then add a BOOT=samizdat parameter. + +(Note: the 'local' versions of these scripts merely call 'run_scripts' on +directories named like '/scripts/local-premount' etc. -- 'run_scripts' runs +scripts in new processes, it does not source them from pid 1. But see below.) + +Almost certainly, the samizdat script should simply define the function 'mountroot'. + +Note: if it was desired not to have to set a kernel parameter, it would also be +possible to 'trick' the system into executing code as pid1 through any script +called with 'run_scripts' (such as a file placed in '/scripts/local-bottom'). + +A script called with 'run_scripts' will run in a separate process, but after +each script is called, pid1 will source the file '/conf/param.conf'. + +Thus, to overwrite the mountroot() function, something like this should suffice: + + cat > /conf/mountroot-override <> /conf/param.conf + +Or even just: + + echo BOOT=samizdat >> /conf/mountroot-override + + + + + + +This is probably the approach to take: + + Create two scripts: + + /etc/initramfs-tools/scripts/local-bottom/samizdat + /etc/initramfs-tools/scripts/samizdat + + The first script just does: + + echo BOOT=samizdat >> /conf/param.conf + + The second script calls out to the existing samizdat initrd code. It can even + 'exec' the original samizdat 'init', although it probably shouldn't. + + + + + + +Another idea: + + + The first script waits for a samizdat read-only ISO, then configures the rest + of the boot process: + + * Find the btrfs seed filesystem on the ISO + * Mount it as a loop device + * Add a ramfs to it, making it read-write + * Chroot into this system and run code to interact with the user and determine what to do: + * Find existing encrypted LUKS partitions + * Find existing encrypted GPG keys + * Allow the user to decrypt GPG keys -- saving the password in order to restart GPG agent + * Allow the user to create a new LUKS partition or choose an existing one + * If successful: + + echo BOOT=samizdat >> /conf/param.conf + echo SAMIZDAT_LUKS_DEV=... >> /conf/param.conf # unencrypted dm dev + echo SAMIZDAT_GPG_ID=... >> /conf/param.conf # record the user we've authenticated as + + The second script does the rest of the work: + + * ... + + + + + + + + + + + + + + + +grepping for param.conf: + +/usr/share/initramfs-tools/scripts/local-top/cryptroot: # Apparently ROOT is already set in /conf/param.conf for +/usr/share/initramfs-tools/scripts/local-top/cryptroot: if [ -f /conf/param.conf ] && grep -q "^ROOT=" /conf/param.conf; then +/usr/share/initramfs-tools/scripts/local-top/cryptroot: NEWROOT=$(sed -n 's/^ROOT=//p' /conf/param.conf) +/usr/share/initramfs-tools/scripts/local-top/cryptroot: echo "ROOT=$NEWROOT" >>/conf/param.conf +/usr/share/initramfs-tools/hook-functions: echo "[ -e /conf/param.conf ] && . /conf/param.conf" >> ${initdir}/ORDER +/usr/share/initramfs-tools/hook-functions: if [ -e /conf/param.conf ]; then +/usr/share/initramfs-tools/hook-functions: . /conf/param.conf + +Relevant instances of 'run_scripts': + + Definition: + + /usr/share/initramfs-tools/scripts/functions:run_scripts() + + Uses in pid1: + + /usr/share/initramfs-tools/init:run_scripts /scripts/init-top + /usr/share/initramfs-tools/init:run_scripts /scripts/init-premount + /usr/share/initramfs-tools/init:run_scripts /scripts/init-bottom + + Uses in 'local': + + /usr/share/initramfs-tools/scripts/local: run_scripts /scripts/local-top + /usr/share/initramfs-tools/scripts/local: run_scripts /scripts/local-block "$@" + /usr/share/initramfs-tools/scripts/local: run_scripts /scripts/local-premount + /usr/share/initramfs-tools/scripts/local: run_scripts /scripts/local-bottom + + Note that 'local' is unconditionally executed in init: + + + + Panic hooks: + + /usr/share/initramfs-tools/scripts/functions: run_scripts /scripts/panic -- cgit v1.2.3