X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=control;h=304c93bd1400b6a310f17c8e90288d5594b3cc83;hb=HEAD;hp=28a4d2c0d99d9fb2653b4c49d8e1d78d4100595a;hpb=90c8587c002a1f8dd0fb8213534cc84f5dddbea8;p=rrq%2Fsubhost.git diff --git a/control b/control index 28a4d2c..304c93b 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,64 +20,126 @@ 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 +# Generate a mac address for given arguments pass through 40-bit b2sum +# and with 02: prefix. +macaddr() { + local V="$(b2sum -l 40 <<< "$*" )" + V="$( sed 's/\(..\)/\1:/g' <<< "${V}aaaaaaaaaa")" + 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 IF=$NAME$E - ip link add $IF type veth peer name eth$E netns $NSNAME + B=( ${BRIDGE/:/ } ) + BRIDGE="${B[0]}" + MAC="${B[1]}" + [ -z "$MAC" ] && MAC="$(macaddr "$(hostname)" "$NAME" "$IF")" + brctl show $BRIDGE >& /dev/null || brctl addbr $BRIDGE + 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 +} + +# Set up cgroup CPU accounting (cpuacct) +accounting() { + # 1-- once, system wide + grep -q "/sys/fs/cgroup cgroup" /proc/mounts || \ + mount -t cgroup -ocpuacct none /sys/fs/cgroup + if [ -d /sys/fs/cgroup/$NAME ] ; then + : # reset? + else + mkdir /sys/fs/cgroup/$NAME + # the following fixes things that sometimes are broken? + for f in cpuset.mems cpuset.cpus ; do + [ -z "$(cat /sys/fs/cgroups/$NAME/$F)" ] && \ + echo 0 > /sys/fs/cgroups/$NAME/$F + done + + fi + # Register this task for subhost accounting + echo $$ > /sys/fs/cgroup/$NAME/tasks } 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 + accounting 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 [ -e $IMAGE ] && umount $MOUNT ip netns del $NSNAME + rmdir /sys/fs/cgroup/$NAME ;; *) usage