--- /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