From 04c5ac3eb5df84b715dbe62ac3717205b9168c0f Mon Sep 17 00:00:00 2001 From: Cristiano Giuffrida Date: Mon, 22 Sep 2014 08:24:01 +0200 Subject: [PATCH] llvm: Extend clientctl with many features. Change-Id: I739eefa46458e956cb79c42a8cbf880428eec794 --- minix/llvm/clientctl | 351 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 328 insertions(+), 23 deletions(-) diff --git a/minix/llvm/clientctl b/minix/llvm/clientctl index 42fbf1607..a27cdb4ca 100755 --- a/minix/llvm/clientctl +++ b/minix/llvm/clientctl @@ -2,6 +2,9 @@ set -o errexit +cd $(dirname $0) + +CMD=$(pwd)/$(basename $0) mode=$1 shift || mode="no_action" @@ -10,12 +13,20 @@ 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} -SERIALOUT=${SERIALOUT:-0} +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 <&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 - umountdisk &> /dev/null || true - sudo mount -o loop $DISK $mnt + disk_umount &> /dev/null || true + sudo mount -o loop $DISK $mnt || true } function disk_umount { @@ -70,10 +218,171 @@ function disk_build { 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 which kvm2 > /dev/null; then + HYPER=kvm + elif [ -e /dev/kvm ]; then + HYPER="qemu-system-i386 --enable-kvm" + else + HYPER=qemu-system-i386 + fi + fi + opts="-hda $IMAGE" + append="$APPEND rootdevname=c0d0p1" + [ ! -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 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 - +} + case "$mode" in 'buildimage') (cd $ROOT && CREATE_IMAGE_ONLY=1 releasetools/x86_hdimage.sh) ;; + 'buildboot') + (cd $ROOT && $MAKE -C releasetools do-hdboot) + ;; + 'conf') + minix_conf + ;; 'builddisk') rm -f $DISK disk_build $DISK_SIZE @@ -84,27 +393,23 @@ case "$mode" in 'umountdisk') disk_umount ;; + 'runcmd') + run_cmd $* + ;; 'run') - if [ "$HYPER" == "" ]; then - if which kvm2 > /dev/null; then - HYPER=kvm - elif [ -e /dev/kvm ]; then - HYPER="qemu-system-i386 --enable-kvm" - else - HYPER=qemu-system-i386 - fi - fi - opts="-hda $IMAGE" - append="rootdevname=c0d0p1" - [ ! -f $DISK ] || opts="$opts -hdb $DISK" - if [ $SERIALOUT -eq 1 ]; then - opts="$opts -curses -serial file:$MYPWD/serial.out" - append="$append cttyline=0" - else - opts="$opts -nographic" - append="$append console=tty00" - 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") + run + ;; + 'connect') + minix_connect + ;; + 'unstack') + minix_unstack $* + ;; + 'test') + minix_test + ;; + 'bisect') + minix_bisect ;; *) echo "Invalid action: $mode"