simple init script for controlling kvm
authorheiko
Fri, 24 Oct 2008 05:57:25 +0000
changeset 0 33b91fef5c76
child 1 e7bd8393f87b
simple init script for controlling kvm
kvmctl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kvmctl	Fri Oct 24 05:57:25 2008 +0000
@@ -0,0 +1,99 @@
+#! /bin/bash
+
+action="${1?}"; shift
+vm="$1";	shift
+
+# no user service able parts below
+
+unset ${!LC_*} LANG
+unset CDPATH
+PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+set +m		    # switch off job control
+
+DIR=$(dirname $0)
+ME=$(basename $0)
+
+KVM=$(command -v kvm)
+NC=$(command -v nc)
+FUSER=$(command -v fuser)
+VNCVIEWER=$(command -v vncviewer)
+
+die() { echo $ME: "$@" >&2; exit 1; }
+warn() { echo $ME: "$@" >&2; }
+
+### MAIN
+
+# sanity
+test "$NC"  || die "need nc (netcat)"
+test "$KVM" || die "need kvm"
+
+dups=$(cat $DIR/*/kvm/id | sort -n | uniq -c \
+    | egrep -v '^[[:space:]]+1 ' | tr -s ' ' | cut -f2 -d:)
+test "$dups" && die "duplicate ids (id: $dups)"
+
+for vm in ${vm:-$(echo $DIR/*)}; do
+    vm=$(basename $vm)
+    kvm=$DIR/$vm/kvm
+
+    test -d $kvm	 || continue
+    test -f $kvm/id	 || { warn "need id file (vm: $vm)" && continue; } 
+    test -f $kvm/cmdline || { warn "need cmdline file (vm: $vm)" && continue; }
+
+    id=$(cat $kvm/id)
+    monitor=$((4000 + id))
+    pid=$(cat $kvm/pid 2>/dev/null)
+
+    case "$action" in
+    start)
+	    echo "starting $vm"
+	    cmdline="$(cat $kvm/cmdline) \
+		-pidfile kvm/pid \
+		-name "$vm" \
+		-vnc :$id \
+		-usb -usbdevice tablet \
+		-monitor tcp:localhost:$monitor,server,nowait \
+		-daemonize \
+		$@"
+	    echo "$cmdline" > $kvm/.cmdline
+	    test -f $kvm/frozen && cmdline="$cmdline $(cat $kvm/frozen)"
+
+	    ( 
+		cd $DIR/$vm && $KVM $cmdline \
+		&& echo "started, display :$id, monitor tcp:127.0.0.1:$monitor" 
+	    )
+
+	    test "$DISPLAY" && test "$VNCVIEWER" && test -t \
+		&& ( $VNCVIEWER :$id &>/dev/null </dev/null & )
+
+	    ;;
+    stop)   echo "stopping (powerdown) $vm"
+	    {
+		( echo system_powerdown | $NC localhost $monitor ) & pid0=$!
+		( sleep 30; kill $pid0 &>/dev/null ) & pid1=$!
+		wait $pid0
+		kill $pid1 2>/dev/null
+		kill -0 $pid 2>/dev/null && $0 kill $vm
+	    } &
+	    ;;
+    quit)   echo "quit $vm"
+	    $FUSER -k $monitor/tcp
+	    echo quit | $NC 127.0.0.1 $monitor &
+	    ;;
+    kill)   echo "killing $vm"
+	    warn "killing vm $vm (id: $id, pid: $pid)"
+	    kill $pid &
+	    ;;
+    freeze) echo "freezing $vm"
+	    fuser -k $monitor/tcp
+	    echo -e "savevm HIBERNATE\nquit" | $NC localhost $monitor &
+	    echo "-loadvm HIBERNATE" >$kvm/frozen
+	    ;;
+    qemu)
+	    echo "DO *NOT* USE \"quit\", use ^C for exiting!"
+	    $NC localhost $monitor
+	    ;;
+    esac
+
+done
+
+wait