minix/minix/llvm/clientctl
Lionel Sambuc 8933525b85 Fix default partition in clientctl.
The partition numbering has changed with the new image creation
framework.

Change-Id: I0644e5879913bee067bc31376f81bc5407f4c81f
2015-10-28 16:06:52 +01:00

466 lines
12 KiB
Bash
Executable file

#!/bin/bash
set -o errexit
cd $(dirname $0)
CMD=$(pwd)/$(basename $0)
mode=$1
shift || mode="no_action"
ROOT=../..
MYPWD=$( pwd )
IMAGE=$( readlink -f $ROOT/minix_x86.img )
DISK=$( readlink -f $ROOT/minix_x86.disk )
RC=$( readlink -f $ROOT/minix_x86.rc )
CONF=$( readlink -f $ROOT/minix_x86.conf )
MKFS=$( readlink -f $ROOT/../obj.i386/tooldir*/bin/nbmkfs.mfs )
MAKE=$( readlink -f $ROOT/../obj.i386/tooldir*/bin/nbmake-i386 )
ADDR2LINE=$( readlink -f $ROOT/../obj.i386/tooldir*/bin/i586-elf32-minix-addr2line )
BATCH=${BATCH:-0}
HYPER=${HYPER:-}
DISK_SIZE=${DISK_SIZE:-1024}
DISK_MNT=${DISK_MNT:-/media/minix-disk}
OUT=${OUT:-S} # S=STDOUT, F=FILE, C=CONSOLE, P=PTY
APPEND=${APPEND:-}
TIMEOUT=${TIMEOUT:-60}
BOOT_TIMEOUT=${BOOT_TIMEOUT:-45}
function rc_create {
cat <<EOF
#!/bin/sh
set -o errexit
[ -d /ext ] || mkdir /ext
mount /dev/c0d1 /ext
if [ -f /ext/etc/rc ]; then
sh /ext/etc/rc
fi
EOF
}
function rc_ext_default_create {
cat <<EOF
#!/bin/sh
echo "/ext/etc/rc: /ext mounted correctly."
EOF
}
function rc_ext_runcmd_create {
cat <<EOF
#!/bin/sh
echo "____runcmd_start"
$*
RET=\$?
echo "____runcmd_end \$RET status"
EOF
}
function minix_conf_create {
cat <<EOF
#!/bin/sh
GUEST_NIC=$guest_nic
HOST_FTP_USER=$host_ftp_user
HOST_FTP_PASS=$host_ftp_pass
HOST_FTP_PORT=$host_ftp_port
HOST_FTP_DIR=$host_ftp_dir
HOST_IP_ADDR=$host_ip_addr
EOF
}
#
# Configuration variables
#
CONF_VARS="guest_nic host_ftp_user host_ftp_pass host_ftp_port host_ftp_dir host_ip_addr"
function conf_init
{
for v in $CONF_VARS
do
if [ -z ${!v} ]; then
eval ${v}="NULL"
fi
done
}
function get_conf_value
{
local conf_var=$1
local msg="$2"
local default=$3
local values=""
[ ! -z $VALUES ] && values="$VALUES, "
line="$msg [${values}Default=$default]: "
(
echo -n "$line"
) 2>&1
if [ "${!conf_var}" == "NULL" ]; then
if [ $BATCH -eq 0 ]; then
read -r $conf_var
echo -en "\e[1A"
else
eval $conf_var=""
fi
fi
if [ "${!conf_var}" == "" ]; then
eval $conf_var=$default
fi
(
echo -en "\e[0K\r"
echo -n "$line"
echo ${!conf_var}
) 2>&1
RET=${!conf_var}
}
function get_conf_value_repeat
{
local check=$1
shift
local conf_var=$1
while true
do
get_conf_value "$@"
eval $check $RET || break
eval $conf_var="NULL"
done
}
function __get_conf_value_check_list
{
for v in $( echo $VALUES | sed "s/|/ /g" )
do
[ "$1" == "$v" ] && return 1
done
return 0
}
function get_conf_value_list
{
get_conf_value_repeat __get_conf_value_check_list "$@"
}
function get_conf_value_yn
{
VALUES="y|n" get_conf_value_list "$@"
}
function __get_conf_value_check_int_range
{
min=$( echo $VALUES | sed "s/|/ /g" | cut -d' ' -f 1 )
max=$( echo $VALUES | sed "s/|/ /g" | cut -d' ' -f 2 )
case $min in
''|*[!0-9]*) return 0 ;;
esac
case $max in
''|*[!0-9]*) return 0 ;;
esac
[ $1 -ge $min ] && [ $1 -le $max ] && return 1
return 0
}
function get_conf_value_int_range
{
get_conf_value_repeat __get_conf_value_check_int_range "$@"
}
function get_conf_value_nic
{
VALUES="0|13" get_conf_value_int_range "$@"
}
function __get_conf_value_check_string
{
return 1
}
function get_conf_value_string
{
get_conf_value_repeat __get_conf_value_check_string "$@"
}
function disk_mount {
local mnt=$1
echo "* Mounting ${DISK} to $mnt..."
[ -d $mnt ] || sudo mkdir -p $mnt
disk_umount &> /dev/null || true
sudo mount -o loop $DISK $mnt || true
}
function disk_umount {
echo "* Unmounting ${DISK}..."
sudo umount $DISK
}
function disk_build {
local size=$1
local tmp_mnt=$( mktemp -d /tmp/clientctl-XXXXX )
echo "* Building ${size} MB disk image..."
dd if=/dev/zero of=$DISK bs=1M count=$size
$MKFS $DISK
echo "* Setting up /ext/etc/rc file executed at startup..."
rc_create > $RC
disk_mount $tmp_mnt
[ -d $tmp_mnt/etc ] || mkdir -p $tmp_mnt/etc
rc_ext_default_create > $tmp_mnt/etc/rc
disk_umount
rm -rf $tmp_mnt
}
function minix_conf {
conf_init
nics="virbr0 virbr1 eth0 eth1 wlan0 wlan1"
for n in $nics
do
host_ip_addr_default=$( ifconfig $n 2> /dev/null | perl -nle'/dr:(\S+)/ && print $1' )
[ -z "$host_ip_addr_default" ] || break
done
get_conf_value_nic guest_nic "[NIC] Which nic do you want to use on MINIX (see MINIX' \`netconf -c\`)?" 7
get_conf_value_string host_ftp_user "[FTP] Username for FTP server running on the host?" ftptest
get_conf_value_string host_ftp_pass "[FTP] Password for FTP server running on the host?" ftptest
get_conf_value_string host_ftp_port "[FTP] Port for FTP server running on the host?" 21
get_conf_value_string host_ftp_dir "[FTP] Base directory for FTP server running on the host?" /home/$host_ftp_user
get_conf_value_string host_ip_addr "[HOSTS] Host ip address?" $host_ip_addr_default
echo ""
echo "* Setting up configuration settings in $CONF..."
minix_conf_create > $CONF
}
function wait_output {
RET=0
date
timeout $1 watch -n 1 -e \! grep -q "$2" $3 &> /dev/null < /dev/null || RET=$?
if [ $RET -eq 124 ]; then
echo "* Timed out after $1 seconds!" 1>&2
return 1
fi
echo "* Done." 1>&2
date
return 0
}
function run_cmd_exec {
echo "* Waiting for MINIX to boot..." 1>&2
wait_output $BOOT_TIMEOUT "__runcmd_start" runcmd.log || return 33
echo "* Waiting for command \"$*\"..." 1>&2
wait_output $TIMEOUT "__runcmd_end" runcmd.log || return 66
RET=$( grep __runcmd_end runcmd.log | cut -d' ' -f 2 )
return $RET
}
function run_cmd {
echo "* Setting up configuration..." 1>&2
[ -f $DISK ] || $CMD builddisk
[ -f $IMAGE ] || $CMD buildimage
$CMD mountdisk
[ ! -f $DISK_MNT/etc/rc ] || mv $DISK_MNT/etc/rc $DISK_MNT/etc/rc.bak
rc_ext_runcmd_create $* > $DISK_MNT/etc/rc
$CMD umountdisk
echo "* Starting up..." 1>&2
rm -f runcmd.*
OUT=S $CMD run &> runcmd.log &
PID=$!
RUNCMD_RET=0
run_cmd_exec $* || RUNCMD_RET=$?
cat runcmd.log | awk '/__runcmd_end/ {N=0;} { if (N==1) print; } /__runcmd_start/ {N=1;}' > runcmd.out
echo "* Shutting down..." 1>&2
for pid in $(ps ax -o pid,args --sort start_time | grep -e "$CMD run[^a-zA-Z]" -e qemu -e kvm | grep -v grep | cut -d' ' -f 1 | head -3 )
do
kill $pid &> /dev/null || true
done
$CMD mountdisk
[ ! -f $DISK_MNT/etc/rc.bak ] || mv $DISK_MNT/etc/rc.bak $DISK_MNT/etc/rc
echo "* COMMAND: \"$*\", RET: $RUNCMD_RET, OUTPUT:"
cat runcmd.out
return $RUNCMD_RET
}
function run {
if [ "$HYPER" == "" ]; then
if [ -e /dev/kvm ]; then
HYPER="qemu-system-i386 --enable-kvm"
else
HYPER=qemu-system-i386
fi
fi
opts="-m 256 -hda $IMAGE"
append="$APPEND rootdevname=c0d0p0"
[ ! -f $DISK ] || opts="$opts -hdb $DISK"
if [ "$OUT" == "F" ]; then
opts="$opts -curses -serial file:$MYPWD/serial.out"
append="$append cttyline=0"
echo "tail -f $MYPWD/serial.out" > $MYPWD/connect.cmd
elif [ "$OUT" == "C" ]; then
opts="$opts -curses -chardev socket,id=serial0,path=$MYPWD/serial.sock,server,nowait -serial chardev:serial0"
append="$append cttyline=0"
echo "(cd $MYPWD && minicom -D unix\#serial.sock)" > $MYPWD/connect.cmd
else
opts="$opts -nographic"
append="$append console=tty00"
if [ "$OUT" == "P" ]; then
opts="$opts -serial pty"
[ -z $PTS ] && PTS=$( $HYPER -serial pty 2>&1 | grep pts | sed "s/.* \([^ ]*pts[^ ]*\) .*/\1/g" )
echo "minicom -D $PTS" > $MYPWD/connect.cmd
else
echo "echo Cannot connect with OUT=S option." > $MYPWD/connect.cmd
fi
fi
(cd ../../../obj.i386/destdir.i386/boot/minix/.temp && $HYPER -kernel kernel -append "$append" $opts -initrd "mod01_ds,mod02_rs,mod03_pm,mod04_sched,mod05_vfs,mod06_memory,mod07_tty,mod08_mfs,mod09_vm,mod10_pfs,mod11_init")
}
function minix_connect {
echo "*****"
echo "***** Running: $( cat $MYPWD/connect.cmd )"
echo "*****"
eval $MYPWD/connect.cmd
}
function minix_unstack {
local service=$1
shift
if [ ! -f $ROOT/minix.mods.map ]; then
echo "$ROOT/minix.mods.map does not exist, run relink.llvm first!"
return 1
fi
path=$(grep "^$service=" $ROOT/minix.mods.map | cut -d= -f 2)
path=$ROOT/../obj.i386/$path/$service
$ADDR2LINE -p -f -e $path $*
}
function minix_test {
JOBS=${JOBS:-8}
RUNCMD=${RUNCMD:-ls}
C=${C:-full}
LOG=$(pwd)/test.log
if [ "$C" == "full" ]; then
cd $ROOT
JOBS=$JOBS BUILDVARS="-V MKBITCODE=yes" ./releasetools/x86_hdimage.sh -b 2>&1 | tee $LOG; test ${PIPESTATUS[0]} -eq 0 || exit 125
cd -
else
C=$C ./relink.llvm 2>&1 | tee $LOG; test ${PIPESTATUS[0]} -eq 0 || exit 125
./clientctl buildimage 2>&1 | tee -a $LOG; test ${PIPESTATUS[0]} -eq 0 || exit 125
fi
if [ "$RUNCMD" != "" ]; then
./clientctl runcmd $RUNCMD 2>&1 | tee -a $LOG; test ${PIPESTATUS[0]} -eq 0 || exit 2
fi
exit 0
}
function minix_bisect {
cd $ROOT
git bisect reset
echo " * Enter bad commit: "
read bad
echo " * Enter good commit: "
read good
git bisect start $bad $good
git bisect run minix/llvm/clientctl test
cd -
}
# Usage: [C=set] ./clientctl buildasr [num]
#
# Build 'num' sets of ASR-randomized service binaries for the 'set' set of
# services. Defaults to one set (in addition to the set used to boot) for
# all services. To be used after building the full system.
#
# The MINIX3 counterpart of the generation taking place here is the
# update_asr(8) command, which cycles through the generated binaries.
#
function minix_buildasr {
MINIXLLVMDIR=$ROOT/minix/llvm
ASRDIR=/usr/service/asr
. $MINIXLLVMDIR/common.inc # get DESTDIR
DESTDIR="$DESTDIR/destdir.i386" # correct DESTDIR
ASRDESTDIR="$DESTDIR$ASRDIR"
COUNT=${1:-1} # take count from command line, default to 1
C=${C:-"servers,fs,net,drivers"}
# start by relinking everything against the magic library
C=$C $MINIXLLVMDIR/relink.llvm magic
# we are replacing any previously made ASR binaries
rm -rf $ASRDESTDIR/*
# generate $COUNT number of sets of ASR-randomized service binaries
# TODO: do not use current time as random seed
N=1
while [ $N -le $COUNT ]; do
mkdir $ASRDESTDIR/$N
export BINDIR=$ASRDIR/$N
C=$C $MINIXLLVMDIR/build.llvm magic asr
sleep 1 # just to make sure they're guaranteed to be different
N=$(($N + 1))
done
# generate the initial set of service binaries, different as well
unset BINDIR
C=$C $MINIXLLVMDIR/build.llvm magic asr
# finally generate the image
# x86_hdimage will automatically add the binaries to the image set
$MINIXLLVMDIR/clientctl buildimage
}
case "$mode" in
'buildimage')
(cd $ROOT && CREATE_IMAGE_ONLY=1 releasetools/x86_hdimage.sh -b)
;;
'buildboot')
(cd $ROOT && $MAKE -C releasetools do-hdboot)
;;
'conf')
minix_conf
;;
'builddisk')
rm -f $DISK
disk_build $DISK_SIZE
;;
'mountdisk')
disk_mount $DISK_MNT
;;
'umountdisk')
disk_umount
;;
'runcmd')
run_cmd $*
;;
'run')
run
;;
'connect')
minix_connect
;;
'unstack')
minix_unstack $*
;;
'test')
minix_test
;;
'bisect')
minix_bisect
;;
'buildasr')
minix_buildasr $*
;;
*)
echo "Invalid action: $mode"
exit 1
;;
esac