X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=functions;h=2c819fae3454b4ab96854aa508cb2c16a8657511;hb=7f766756c6d328a4a8d57a274a215f67376af68d;hp=67ea3ad51b143476c0ba5f3a82bfaa52d438c4ee;hpb=e167fa970f34adaeeac05db7e57c7d6b5307bb2d;p=rrq%2Foverlay-boot.git diff --git a/functions b/functions index 67ea3ad..2c819fa 100644 --- a/functions +++ b/functions @@ -1,18 +1,69 @@ -# This file implements common functions for all boot methods +# This file implements common functions for all boot scripts +# Rerun with sudo if needed +[ $(id -u) = 0 ] || exec sudo $0 $@ + +# Function to write a message and exit with error code die() { echo "$*" >&2 exit 1 } +# Function to setup subhost name and log file +subhost_name() { + CONFIG="$1" + [ -r "$CONFIG" ] || die "Cannot use $CONFIG" + config NAME "$(basename $CONFIG .conf)" + config LOG /tmp/oly-$NAME.log +} + +# Function to set up all subhost configuration +subhost_config() { + + config BASE + BASE="$(cd $(dirname $CONFIG); realpath $BASE)" + [ -z "$BASE" ] && die "BASE is unset; bogus $CONFIG ?" + [ -d "$BASE" ] || die "$BASE is not a directory; bogus $CONFIG ?" + cd "$BASE" || die "$BASE is inaccessible" + + config CABLES "" + config LIVE "$BASE/live" + config UPPER "$BASE/root" + config WORK "$BASE/work" + config LOWER "/" + config START "!networking ssh" + config PREMOUNT "$PROGRAMDIR/overlay-premount" + config POSTMOUNT "$PROGRAMDIR/overlay-postmount" + config INIT "$PROGRAMDIR/overlay-init" + config RAM_SIZE 50M +} + +# function to reverse the $* words +reverse() { + local OUT="" + for w in $* ; do OUT="$w $OUT" ; done + echo "${OUT% }" +} + # grab and set a configuration variable # $1 = variable, [ $2 = default .. error otherwise ] config() { - eval $1="'$(sed "/^$1=.*/{s|^$1=||;b};d" $CONFIG)'" - [ -z "$(eval echo "\$$1")" ] || return 0 - [ $# -lt 2 ] && die "Missing $1=... in $CONFIG" - eval $1="'$2'" - eval echo "$1=\$$1" + local V W + read V <&2 } # Install a default $1/etc/network/interfaces on the subhost root $1 @@ -57,67 +108,33 @@ setup_veth_cables() { done } -# (name live system root work) -# Set up an overlay fmr $name on $live, with a new tmpfs on its /run, +# Set up an overlay for $name on $live, with a new tmpfs on its /run, # and "install" a "reaper" as the upcoming pid 1 setup_overlay() { - local LIVE="$2" LOWER="$3" UPPER="$4" ROOT + local NAME="$1" LIVE="$2" LOWER="$3" UPPER="$4" WORK="$5" - if grep -q "$1 $2" /proc/mounts ; then - die "$1 is already mounted" - fi + echo setup_overlay "$NAME" "$LIVE" "$LOWER" "$UPPER" "$WORK" - if [ -f "${UPPER%% *}" ] ; then - if [ -x "${UPPER%% *}" ] ; then - echo "${UPPER%% *} appears to be executable" >&2 - # Giving a program/script as UPPER= asks for running this - # first, to make a root filesystem available. The script takes - # ACTION "setup" and "teardown", and on "setup" it must tell - # where the ROOT is set up. - ROOT="$(env ACTION=setup $UPPER)" - if [ ! -d "$ROOT" ] ; then - # setup failed - die "root setup failed: $UPPER" - fi - UPPER="$ROOT" - ## Now falling down to "normal overlay" setup - else - die "${UPPER%% *} (root setup program/script) is not executable" - fi + if grep -qE "^[^ ]+ $LIVE " /proc/mounts ; then + die "$LIVE already has a mount" fi - # LIVE is the same as LOWER then skip the overlay; just assume - # a proper chroot system exists at LIVE. - if [ "$LIVE" != "$LOWER" ] ; then + [ -d "$UPPER" ] || die "UPPER=$UPPER is not a directory" + [ -d "$LOWER" ] || die "LOWER=LOWPER is not a directory" + [ -d "$LIVE" ] || die "LOWER=LOWPER is not a directory" + [ -x "${PREMOUNT%% *}" ] || die "PREMOUNT=${PREMOUNT%% *} not executable" + [ -f "${PREMOUNT%% *}" ] || die "PREMOUNT='$PREMOUNT' is not a command" + [ -x "${POSTMOUNT%% *}" ] || \ + die "POSTMOUNT=${POSTMOUNT%% *} not executable" + [ -f "${POSTMOUNT%% *}" ] || \ + die "POSTMOUNT='$POSTMOUNT' is not a command" + + # UPPER is the same as LOWER then skip the overlay mount + if [ "$UPPER" != "$LOWER" ] ; then # sanity check [ -d "$WORK" ] || die "WORK=$WORK is not a directory" - [ -d "$UPPER" ] || die "UPPER=$UPPER is not a directory" - [ -d "$LOWER" ] || die "LOWER=LOWPER is not a directory" - [ -d "$LIVE" ] || die "LOWER=LOWPER is not a directory" - # setup $UPPER/dev - mkdir -p "$UPPER/dev" - mount -t tmpfs -osize=50M tmpfs "$UPPER/dev" - mknod -m 622 "$UPPER/dev/console" c 5 1 - mknod -m 666 "$UPPER/dev/null" c 1 3 - mknod -m 666 "$UPPER/dev/zero" c 1 5 - mknod -m 666 "$UPPER/dev/ptmx" c 5 2 - mknod -m 666 "$UPPER/dev/tty" c 5 0 - mknod -m 444 "$UPPER/dev/random" c 1 8 - mknod -m 444 "$UPPER/dev/urandom" c 1 9 - chown root:tty "$UPPER/dev/console" - chown root:tty "$UPPER/dev/ptmx" - chown root:tty "$UPPER/dev/tty" - ln -sTf /proc/self/fd "$UPPER/dev/fd" - ln -sTf /proc/self/fd/0 "$UPPER/dev/stdin" - ln -sTf /proc/self/fd/1 "$UPPER/dev/stdout" - ln -sTf /proc/self/fd/2 "$UPPER/dev/stderr" - ln -sTf /proc/kcore "$UPPER/dev/core" - mkdir "$UPPER/dev/shm" - mkdir "$UPPER/dev/pts" - chmod 1777 "$UPPER/dev/shm" - - # all good so far ; now avoid using the host's networking setup - setup_networking "$UPPER" + + env CONFIG="$CONFIG" $PREMOUNT "$UPPER" OLY="-olowerdir=$3,upperdir=$UPPER,workdir=$5" if ! mount -t overlay "$OLY" $1 $2 ; then @@ -125,36 +142,25 @@ setup_overlay() { umount "$UPPER/run" die "Cannot set up the overlay mount $2" fi + elif [ "$LIVE" != "$UPPER" ] ; then + # With UPPER = LOWER we rather make a bind mount to LIVE + env CONFIG="$CONFIG" $PREMOUNT "$UPPER" + mount --bind $UPPER $LOWER fi - echo "Installing $OVERLAYDIR/reaper to $LIVE/.reaper" - cp -p $OVERLAYDIR/reaper $LIVE/.reaper -} - -start_services() { - for S in "$@" ; do - service $S start - done + env CONFIG="$CONFIG" $POSTMOUNT "LIVE" "$UPPER" } -# find the upperdir option for an overlay mount line -getupper() { - sed 's/.*upperdir=\([^,]*\).*/\1/' -} - -# Check if $1 is "live" and echo the -# unshare and reaper process pids +# Find the "unshare" process for $1 and echo the its pid and the pids +# of its child processes. is_live() { local NAME=$1 local USPID="$(pgrep -f "unshare.* $NAME ")" [ -z "$USPID" ] && return 1 - echo $USPID $(pgrep -f ".reaper $NAME") + echo "$USPID $(ps -hopid --ppid=$USPID)" } +# Find all overlay-boot processes and list their config files list_running() { - for C in $(pgrep -a overlay-boot | awk '{print $4}') ; do - eval NAME="$(sed "/^NAME=.*/{s|^NAME=||;b};d" $C)" - [ -z "$NAME" ] && NAME=$(basename $C .conf) - echo $NAME - done + pgrep -a overlay-boot | awk '{print $4}' }