#!/bin/bash # # Boot up subhost as if a vitual machine. # Allow CONFIG given as environment # #set -x : ${NAME=$1} : ${NSNAME=$NAME} : ${SUBHOST=/opt/subhost/$NAME} : ${TARGET=$SUBHOST/live} : ${CONFIG=$SUBHOST/config} # sets DISKS=( ... ) and BRIDGES=( ... ) [ -r "$CONFIG" ] && . $CONFIG if [ -z "$DISKS" ] ; then echo "Missing CONFIG" >&2 exit 1 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_cables() { E=0 [ -e /var/run/netns/$NSNAME ] || ip netns add $NSNAME for BRIDGE in ${BRIDGES[@]} ; do IF=$NAME$E 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 } # loopdev path -- Make a named device node for a loop device copyloop() { local MKNOD="mknod $(basename $2) b $(stat -c "%t %T" $1)" if [ -e "$2" ] ; then rm -f $2 else mkdir -p $(dirname $2) fi ( cd $(dirname $2) && $MKNOD ) } # diskid image partition# -- set up parition device node mkdevnode() { local LOOP="$(losetup -j "$3" | sed 's/:.*//')" [ -z "$LOOP" ] && LOOP="$(losetup -f --show "$3")" grep -q $TARGET /proc/mounts || \ mount ${LOOP}p$2 $TARGET copyloop $LOOP $TARGET/dev/$1 copyloop ${LOOP}p$2 $TARGET/dev/$1$2 } # Setup device nodes for VM loopbacks according to $DISKS setup_rootfs() { for DISK in ${DISKS[@]} ; do D=( $(echo $DISK | tr : ' ') ) case "${D[0]}" in vd*|sd*) mkdevnode "${D[@]}" ;; *) echo "Unknown disk type ${D[0]}" >&2 exit 1 ;; esac done } # Change $TARGET/dev/console setup_console() { local SCRIPT=$$ CONSOLE=$TARGET/dev/console rm -f $CONSOLE ln -s $(tty) $CONSOLE } #################### # Pretend boot setup_cables setup_rootfs setup_console ###################################################################### # Run the subhost init ip netns exec $NSNAME unshare --fork --pid --mount-proc --kill-child \ --uts --ipc --mount --cgroup chroot $TARGET /sbin/init ###################################################################### # Cleanup on exit umount $TARGET ip netns del $NSNAME true