# This file implements common functions for all boot methods die() { echo "$*" >&2 exit 1 } # 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" } # Unless the subhost already has a private /etc/network/interfaces, # install an "empty" one setup_networking() { [ -r $UPPER/etc/network/interfaces ] && return 0 [ "$UPPER/etc/network" = "/etc/network" ] && exit 1 mkdir -p $UPPER/etc/network cat < $UPPER/etc/network/interfaces # Generated for $NAME subhost auto lo iface lo inet loopback EOF return 1 } # Setup the network namespace for the given $CABLES # $1=netns ( $2="br=mac" .. ) setup_veth_cables() { local NETNS BR IF MAC C i ADD NETNS="$1" shift 1 i=0 ADD=false setup_networking || ADD=true for C in "$@" ; do IF=$NETNS$i MAC="${C#*=}" [ -z "$MAC" ] || MAC="address $MAC" ip link add $IF type veth peer name eth$i $MAC netns $NETNS ip link set $IF up $ADD && cat <> $UPPER/etc/network/interfaces auto eth$i iface eth$i inet manual EOF BR="${C%=*}" [ -z "$BR" ] || brctl addif $BR $IF i=$((i+1)) done } REAPER=$(dirname $(realpath $0))/reaper # (name live system root work) # Set up an overlay fmr $name on $live, with a new tmpfs on its /run, # and "install" a "reaper" as the upcoming pid 1 setup_overlay() { local ROOT="$4" local LIVE="$2" if grep -q "$1 $2" /proc/mounts ; then die "$1 is already mounted" fi # setup $ROOT/run mkdir -p "$ROOT/run" mount -t tmpfs -osize=100M tmpfs "$ROOT/run" mkdir -p "$ROOT/run/lock" # setup $ROOT/dev mkdir -p "$ROOT/dev" mount -t tmpfs -osize=100M tmpfs "$ROOT/dev" mknod -m 622 "$ROOT/dev/console" c 5 1 mknod -m 666 "$ROOT/dev/null" c 1 3 mknod -m 666 "$ROOT/dev/zero" c 1 5 mknod -m 666 "$ROOT/dev/ptmx" c 5 2 mknod -m 666 "$ROOT/dev/tty" c 5 0 mknod -m 444 "$ROOT/dev/random" c 1 8 mknod -m 444 "$ROOT/dev/urandom" c 1 9 chown root:tty "$ROOT/dev/console" chown root:tty "$ROOT/dev/ptmx" chown root:tty "$ROOT/dev/tty" ln -sTf /proc/self/fd "$ROOT/dev/fd" ln -sTf /proc/self/fd/0 "$ROOT/dev/stdin" ln -sTf /proc/self/fd/1 "$ROOT/dev/stdout" ln -sTf /proc/self/fd/2 "$ROOT/dev/stderr" ln -sTf /proc/kcore "$ROOT/dev/core" mkdir "$ROOT/dev/shm" mkdir "$ROOT/dev/pts" chmod 1777 "$ROOT/dev/shm" if mount -t overlay -olowerdir=$3,upperdir=$4,workdir=$5 $1 $2 ; then : # all good else umount -R "$ROOT/dev" umount "$ROOT/run" die "Cannot set up the overlay mount $2" fi cp -p $REAPER $LIVE/.reaper } start_services() { for S in "$@" ; do service $S start done } # 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 is_live() { local NAME=$1 local USPID="$(pgrep -f "unshare.* $NAME ")" [ -z "$USPID" ] && return 1 echo $USPID $(pgrep -f ".reaper $NAME") }