Browse Source

tarting subhost almost as if booted

master
Ralph Rönnquist 4 months ago
parent
commit
1ac9828de4
  1. 106
      pretend-boot
  2. 39
      startup
  3. 37
      subhost-init

106
pretend-boot

@ -0,0 +1,106 @@
#!/bin/bash
#
# Boot up subhost as if a vitual machine.
#
# There is already an existing network namespace of the right name,
# and there are one or more disks at /opt/subhost/$NAME/disk$i
#set -x
: ${NAME=$1}
: ${NSNAME=$NAME}
: ${SUBHOST=/opt/subhost/$NAME}
: ${TARGET=$SUBHOST/live}
: ${INITRD=$SUBHOST/initrd.gz}
: ${CONFIG=$SUBHOST/config}
[ -r "$CONFIG" ] && . $CONFIG
# 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
}
setup_cables
setup_rootfs
setup_console || exit 1
# Install the current subhost-init startup script
cp -p $(realpath $(dirname $0))/subhost-init startup $TARGET/
######################################################################
# Run the subhost
ip netns exec $NSNAME unshare --fork --pid --mount-proc --kill-child \
--uts --ipc --mount --cgroup chroot $TARGET /startup
######################################################################
# Cleanup on exit
umount $TARGET
ip netns del $NSNAME
true

39
startup

@ -1,39 +0,0 @@
#!/bin/bash
#
# This is a script to run at startup of a bespoke sub-host
NOW=$(date +"%Y%m%d-%H%M%S")
{
echo "Startup at $NOW"
set -x
mkdir -p /dev/pts /dev/shm /run
[ -f /proc/mounts ] || mount -t proc proc /proc
if ! grep "^none /run tmpfs" /proc/mounts ; then
mount -t tmpfs -osize=80M none /run
mount -t tmpfs -osize=20M none /dev/shm
mount -t devpts none /dev/pts
mount -t sysfs none /sys
mkdir -p /run/lock /run/user
fi
{
# Restart auto interfaces
for IF in $(grep "^auto" /etc/network/interfaces) ; do
[ -e "/sys/class/net/$IF" ] || continue
ifdown $IF
ifup $IF
done
# Restart services
SERVICES=( )
for S in ${SERVICES[@]} ; do
service $S restart
done
} &
NETPID=$!
} |& tee /var/log/startup-$NOW.log
exec /bin/bash

37
subhost-init

@ -0,0 +1,37 @@
#!/bin/bash
#
# This is a script to run at startup of a bespoke sub-host
date +"subhost startup at %Y%m%d-%H%M%S"
mkdir -p /dev/pts /dev/shm /run
[ -f /proc/mounts ] || mount -t proc proc /proc
if ! grep "^none /run tmpfs" /proc/mounts ; then
mount -t tmpfs -osize=80M none /run
mount -t tmpfs -osize=20M none /dev/shm
mount -t devpts none /dev/pts
mount -t sysfs none /sys
mkdir -p /run/lock /run/user
fi
if grep -q ' / ext4 rw,' /proc/mounts ; then
##
## Here's the "pretend init"
##
zombie() {
wait
true # echo "zombie return $?" >&2
}
trap "zombie" 17 # SIGCHILD
/etc/init.d/rc S < /dev/null
/etc/init.d/rc 2 < /dev/null
SUBHOSTCTL=/run/initctl
mkfifo $SUBHOSTCTL
exec cat < $SUBHOSTCTL
#exec /bin/bash -i
else
echo "** The root filesystem is read-only; EXITING" >&2
exit 1
fi
Loading…
Cancel
Save