X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;ds=sidebyside;f=control;h=f5831a267f8842a3d1090dece847d4d2501648c4;hb=e0808ddd112116c36fc3fceb65bea8589dff5647;hp=28a4d2c0d99d9fb2653b4c49d8e1d78d4100595a;hpb=90c8587c002a1f8dd0fb8213534cc84f5dddbea8;p=rrq%2Fsubhost.git diff --git a/control b/control index 28a4d2c..f5831a2 100755 --- a/control +++ b/control @@ -6,6 +6,8 @@ # $2 = the sub-host to start or stop # $3... = the optional chroot-ed command (/startup by default) +set -x + SCRIPT=$0 CMD=$1 NAME=$2 @@ -18,59 +20,102 @@ usage() { [ -z "$NAME" ] && usage -: ${ATTIC=/opt/srv} -: ${BRIDGE=srv_br} -: ${TARGET=/srv/$NAME} -: ${LOWER=$ATTIC/daedalus.fs} -: ${IMAGE=$ATTIC/$NAME/$NAME.img} -: ${UPPER=$ATTIC/$NAME/root} -: ${WORK=$ATTIC/$NAME/work} -: ${MOUNT=$ATTIC/$NAME/mnt} +: ${SUBHOST=/opt/subhost} +: ${OSROOT=} +: ${TOP=$SUBHOST/$NAME} +: ${TARGET=$TOP/live} +: ${IMAGE=$TOP/$NAME.img} +: ${UPPER=$TOP/root} +: ${WORK=$TOP/work} +: ${MOUNT=$TOP/mnt} : ${NSNAME=$NAME} -: ${NETH=1} +: ${BRIDGES=lan_br} +: ${CONFIG=$TOP/config} + +[ -e "$CONFIG" ] && . "$CONFIG" +cd "$SUBHOST" || exit 1 + +# Create a simple overlay subhost without its own image file create_subhost() { mkdir -p $TARGET $MOUNT $UPPER $WORK + [ -d "$OSROOT" ] || OSROOT=$SUBHOST/chimaera/base + [ -e $CONFIG ] || cat < "$CONFIG" +# Subhost $NAME is an autogenerated overlay subhost with shared filesystem +OSROOT="$OSROOT" +BRIDGES="$BRIDGES" +EOF } -setup_network() { - if [ -n "$BRIDGE" ] ; then - brctl show $BRIDGE >& /dev/null || brctl addbr $BRIDGE - fi +# map a string into a hexadecimal number with 10-digits by folding the given string into 9-digit ascii-code numbers and adding them +hexfoldsum() { + local V + V="$(b2sum -l 40 <<< "$1" | sed 's/\(..\)/\1:/g')" + echo "02:${V:0:14}" +} +# Generate a mac address for given interface by passing hostname, +# subhost name and interface through 40-bit b2sum and with 02: prefix. +macaddr() { + local V="$(b2sum -l 40 <<< "$(hostname)$NAME$1" | sed 's/\(..\)/\1:/g')" + echo "02:${V:0:14}" +} + +# setup the subhost network namespace and link up the host side +setup_network() { E=0 ip netns add $NSNAME - for I in $(eval echo "{1..$NETH}") ; do + for BRIDGE in ${BRIDGES[@]} ; do + brctl show $BRIDGE >& /dev/null || brctl addbr $BRIDGE IF=$NAME$E - ip link add $IF type veth peer name eth$E netns $NSNAME + MAC=$(macaddr $IF) + ip link add $IF type veth peer name eth$E address $MAC netns $NSNAME ip link set $IF up [ -n "$BRIDGE" ] && brctl addif $BRIDGE $IF E=$((E+1)) done } +# check if $1 is mounted +is_mounted() { + grep -qE "^[^ ]+ $1 " /proc/mounts +} + +# Setup or re-setup the subhost filesystem setup_rootfs() { - if [ -e "$IMAGE" ] ; then - mount $IMAGE $MOUNT || exit 1 - LOWER=$MOUNT/root - WORK=$MOUNT/work + if is_mounted $TARGET ; then + mount -oremount $TARGET + else + if [ -e "$IMAGE" ] ; then + # $IMAGE is either an image file or a link to a partition, + # with /root and /work in it. + is_mounted $MOUNT || mount $IMAGE $MOUNT || exit 1 + UPPER=$MOUNT/root + WORK=$MOUNT/work + fi + if [ -z "$OSROOT" ] ; then + # No overlay + mount --rbind $UPPER $TARGET + else + # overlay of $UPPER (+$WORK) over $OSROOT onto $TARGET + mount -t overlay $NAME \ + -olowerdir=$OSROOT,upperdir=$UPPER,workdir=$WORK \ + $TARGET + fi fi - mount -t overlay $NAME -olowerdir=$LOWER,upperdir=$UPPER,workdir=$WORK \ - $TARGET } case "$CMD" in start) - cd "$ATTIC" || exit 1 [ -e "/run/netns/$NSNAME" ] || setup_network [ -d "$MOUNT" ] || create_subhost - grep -q "^$NAME $TARGET overlay" /proc/mounts || setup_rootfs + setup_rootfs START=/bin/bash [ -x $TARGET/startup ] && START=/startup exec ip netns exec $NSNAME unshare \ --fork --pid --mount-proc --kill-child \ --uts --ipc --mount --cgroup \ - "--root=$TARGET" $START + chroot $TARGET $START ;; stop) umount $TARGET