]> Zhao Yanbai Git Server - minix.git/commitdiff
llvm: Extend clientctl with many features. 31/3131/1
authorCristiano Giuffrida <giuffrida@cs.vu.nl>
Mon, 22 Sep 2014 06:24:01 +0000 (08:24 +0200)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 17 Sep 2015 13:49:03 +0000 (13:49 +0000)
Change-Id: I739eefa46458e956cb79c42a8cbf880428eec794

minix/llvm/clientctl

index 42fbf1607770e8ca3b9628c520e3c176c62d74c8..a27cdb4cac986de0c1fc07707fd64d2a52b81bab 100755 (executable)
@@ -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 <<EOF
@@ -42,12 +53,149 @@ 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
-    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,21 +218,77 @@ function disk_build {
     rm -rf $tmp_mnt
 }
 
-case "$mode" in
-  'buildimage')
-    (cd $ROOT && CREATE_IMAGE_ONLY=1 releasetools/x86_hdimage.sh)
-    ;;
-  'builddisk')
-    rm -f $DISK
-    disk_build $DISK_SIZE
-    ;;
-  'mountdisk')
-    disk_mount $DISK_MNT
-    ;;
-  'umountdisk')
-    disk_umount
-    ;;
-  'run')
+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
@@ -95,16 +299,117 @@ case "$mode" in
         fi
     fi
     opts="-hda $IMAGE"
-    append="rootdevname=c0d0p1"
+    append="$APPEND rootdevname=c0d0p1"
     [ ! -f $DISK ] || opts="$opts -hdb $DISK"
-    if [ $SERIALOUT -eq 1 ]; then
+    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
+    ;;
+  '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
     ;;
   *)
     echo "Invalid action: $mode"