renamed directory
[rrq/overlay-boot.git] / functions
1 # This file implements common functions for all boot methods
2
3 die() {
4     echo "$*" >&2
5     exit 1
6 }
7
8 # grab and set a configuration variable
9 # $1 = variable, [ $2 = default .. error otherwise ]
10 config() {
11     eval $1="$(sed "/^$1=.*/{s|^$1=||;b};d" $CONFIG)"
12     [ -z "$(eval echo "\$$1")" ] || return 0
13     [ $# -lt 2 ] && die "Missing $1=... in $CONFIG"
14     eval $1="'$2'"
15     eval echo "$1=\$$1"
16 }
17
18 # Unless the subhost already has a private /etc/network/interfaces,
19 # install an "empty" one
20 setup_networking() {
21     [ -r $UPPER/etc/network/interfaces ] && return 0
22     [ "$UPPER/etc/network" = "/etc/network" ] && exit 1
23     mkdir -p $UPPER/etc/network
24     cat <<EOF > $UPPER/etc/network/interfaces
25 # Generated for $NAME subhost
26 auto lo
27 iface lo inet loopback
28 EOF
29     return 1
30 }
31
32 # Setup the network namespace for the given $CABLES
33 # $1=netns ( $2="br=mac" .. )
34 setup_veth_cables() {
35     local NETNS BR IF MAC C i ADD
36     NETNS="$1"
37     shift 1
38     i=0
39     ADD=false
40     setup_networking || ADD=true
41     for C in "$@" ; do
42         IF=$NETNS$i
43         MAC="${C#*=}"
44         [ -z "$MAC" ] || MAC="address $MAC"
45         ip link add $IF type veth peer name eth$i $MAC netns $NETNS
46         ip link set $IF up
47         $ADD && cat <<EOF >> $UPPER/etc/network/interfaces
48
49 auto eth$i
50 iface eth$i inet manual
51 EOF
52         BR="${C%=*}"
53         [ -z "$BR" ] || brctl addif $BR $IF
54         i=$((i+1))
55     done
56 }
57
58 REAPER=$(dirname $(realpath $0))/reaper
59 # (name live system root work)
60 # Set up an overlay fmr $name on $live, with a new tmpfs on its /run,
61 # and "install" a "reaper" as the upcoming pid 1
62 setup_overlay() {
63     local ROOT="$4"
64     local LIVE="$2"
65
66     if grep -q "$1 $2" /proc/mounts ; then
67         die "$1 is already mounted"
68     fi
69
70     # setup $ROOT/run
71     mkdir -p "$ROOT/run"
72     mount -t tmpfs -osize=100M tmpfs "$ROOT/run"
73     mkdir -p "$ROOT/run/lock"
74     # setup $ROOT/dev
75     mkdir -p "$ROOT/dev"
76     mount -t tmpfs -osize=100M tmpfs "$ROOT/dev"
77     mknod -m 622 "$ROOT/dev/console" c 5 1
78     mknod -m 666 "$ROOT/dev/null" c 1 3
79     mknod -m 666 "$ROOT/dev/zero" c 1 5
80     mknod -m 666 "$ROOT/dev/ptmx" c 5 2
81     mknod -m 666 "$ROOT/dev/tty" c 5 0
82     mknod -m 444 "$ROOT/dev/random" c 1 8
83     mknod -m 444 "$ROOT/dev/urandom" c 1 9
84     chown root:tty "$ROOT/dev/console"
85     chown root:tty "$ROOT/dev/ptmx"
86     chown root:tty "$ROOT/dev/tty"
87     ln -sTf /proc/self/fd "$ROOT/dev/fd"
88     ln -sTf /proc/self/fd/0 "$ROOT/dev/stdin"
89     ln -sTf /proc/self/fd/1 "$ROOT/dev/stdout"
90     ln -sTf /proc/self/fd/2 "$ROOT/dev/stderr"
91     ln -sTf /proc/kcore "$ROOT/dev/core"
92     mkdir "$ROOT/dev/shm"
93     mkdir "$ROOT/dev/pts"
94     chmod 1777 "$ROOT/dev/shm"
95
96     if mount -t overlay -olowerdir=$3,upperdir=$4,workdir=$5 $1 $2 ; then
97         : # all good
98     else
99         umount -R "$ROOT/dev"
100         umount "$ROOT/run"
101         die "Cannot set up the overlay mount $2"
102     fi
103     cp -p $REAPER $LIVE/.reaper
104 }
105
106 start_services() {
107     for S in "$@" ; do
108         service $S start
109     done
110 }
111
112 # find the upperdir option for an overlay mount line
113 getupper() {
114     sed 's/.*upperdir=\([^,]*\).*/\1/'
115 }
116
117 # Check if $1 is "live" and echo the
118 # unshare and reaper process pids
119 is_live() {
120     local NAME=$1
121     local USPID="$(pgrep -f "unshare.* $NAME ")"
122     [ -z "$USPID" ] && return 1
123     echo $USPID $(pgrep -f ".reaper $NAME")
124 }
125
126 list_running() {
127     for C in $(pgrep -a overlay-boot | awk '{print $4}') ; do
128         eval NAME="$(sed "/^NAME=.*/{s|^NAME=||;b};d" $C)"
129         [ -z "$NAME" ] && NAME=$(basename $C .conf)
130         echo $NAME
131     done
132 }