3 # Control program for bespoke arbitrary services through unshared sub-hosts
5 # $1 = the command: start or stop
6 # $2 = the sub-host to start or stop
7 # $3... = the optional chroot-ed command (/startup by default)
17 echo "$SCRIPT (start|stop) <subhost>" >&2
21 [ -z "$NAME" ] && usage
23 : ${SUBHOST=/opt/subhost}
25 : ${TOP=$SUBHOST/$NAME}
27 : ${IMAGE=$TOP/$NAME.img}
33 : ${CONFIG=$TOP/config}
35 [ -e "$CONFIG" ] && . "$CONFIG"
37 cd "$SUBHOST" || exit 1
39 # Create a simple overlay subhost without its own image file
41 mkdir -p $TARGET $MOUNT $UPPER $WORK
42 [ -d "$OSROOT" ] || OSROOT=$SUBHOST/chimaera/base
43 [ -e $CONFIG ] || cat <<EOF > "$CONFIG"
44 # Subhost $NAME is an autogenerated overlay subhost with shared filesystem
50 # Generate a mac address for given arguments pass through 40-bit b2sum
51 # and with 02: prefix.
53 local V="$(b2sum -l 40 <<< "$*" )"
54 V="$( sed 's/\(..\)/\1:/g' <<< "${V}aaaaaaaaaa")"
58 # setup the subhost network namespace and link up the host side
62 for BRIDGE in ${BRIDGES[@]} ; do
67 [ -z "$MAC" ] && MAC="$(macaddr "$(hostname)" "$NAME" "$IF")"
68 brctl show $BRIDGE >& /dev/null || brctl addbr $BRIDGE
69 ip link add $IF type veth peer name eth$E address $MAC netns $NSNAME
71 [ -n "$BRIDGE" ] && brctl addif $BRIDGE $IF
76 # check if $1 is mounted
78 grep -qE "^[^ ]+ $1 " /proc/mounts
81 # Setup or re-setup the subhost filesystem
83 if is_mounted $TARGET ; then
84 mount -oremount $TARGET
86 if [ -e "$IMAGE" ] ; then
87 # $IMAGE is either an image file or a link to a partition,
88 # with /root and /work in it.
89 is_mounted $MOUNT || mount $IMAGE $MOUNT || exit 1
93 if [ -z "$OSROOT" ] ; then
95 mount --rbind $UPPER $TARGET
97 # overlay of $UPPER (+$WORK) over $OSROOT onto $TARGET
98 mount -t overlay $NAME \
99 -olowerdir=$OSROOT,upperdir=$UPPER,workdir=$WORK \
105 # Set up cgroup CPU accounting (cpuacct)
107 # 1-- once, system wide
108 grep -q "/sys/fs/cgroup cgroup" /proc/mounts || \
109 mount -t cgroup -ocpuacct none /sys/fs/cgroup
110 if [ -d /sys/fs/cgroup/$NAME ] ; then
113 mkdir /sys/fs/cgroup/$NAME
114 # the following fixes things that sometimes are broken?
115 for f in cpuset.mems cpuset.cpus ; do
116 [ -z "$(cat /sys/fs/cgroups/$NAME/$F)" ] && \
117 echo 0 > /sys/fs/cgroups/$NAME/$F
121 # Register this task for subhost accounting
122 echo $$ > /sys/fs/cgroup/$NAME/tasks
127 [ -e "/run/netns/$NSNAME" ] || setup_network
128 [ -d "$MOUNT" ] || create_subhost
131 [ -x $TARGET/startup ] && START=/startup
133 exec ip netns exec $NSNAME unshare \
134 --fork --pid --mount-proc --kill-child \
135 --uts --ipc --mount --cgroup \
136 chroot $TARGET $START
140 [ -e $IMAGE ] && umount $MOUNT
142 rmdir /sys/fs/cgroup/$NAME