|
1 #! /bin/bash |
|
2 |
|
3 action="${1?}"; shift |
|
4 vm="$1"; shift |
|
5 |
|
6 # no user service able parts below |
|
7 |
|
8 unset ${!LC_*} LANG |
|
9 unset CDPATH |
|
10 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
|
11 set +m # switch off job control |
|
12 |
|
13 DIR=$(dirname $0) |
|
14 ME=$(basename $0) |
|
15 |
|
16 KVM=$(command -v kvm) |
|
17 NC=$(command -v nc) |
|
18 FUSER=$(command -v fuser) |
|
19 VNCVIEWER=$(command -v vncviewer) |
|
20 |
|
21 die() { echo $ME: "$@" >&2; exit 1; } |
|
22 warn() { echo $ME: "$@" >&2; } |
|
23 |
|
24 ### MAIN |
|
25 |
|
26 # sanity |
|
27 test "$NC" || die "need nc (netcat)" |
|
28 test "$KVM" || die "need kvm" |
|
29 |
|
30 dups=$(cat $DIR/*/kvm/id | sort -n | uniq -c \ |
|
31 | egrep -v '^[[:space:]]+1 ' | tr -s ' ' | cut -f2 -d:) |
|
32 test "$dups" && die "duplicate ids (id: $dups)" |
|
33 |
|
34 for vm in ${vm:-$(echo $DIR/*)}; do |
|
35 vm=$(basename $vm) |
|
36 kvm=$DIR/$vm/kvm |
|
37 |
|
38 test -d $kvm || continue |
|
39 test -f $kvm/id || { warn "need id file (vm: $vm)" && continue; } |
|
40 test -f $kvm/cmdline || { warn "need cmdline file (vm: $vm)" && continue; } |
|
41 |
|
42 id=$(cat $kvm/id) |
|
43 monitor=$((4000 + id)) |
|
44 pid=$(cat $kvm/pid 2>/dev/null) |
|
45 |
|
46 case "$action" in |
|
47 start) |
|
48 echo "starting $vm" |
|
49 cmdline="$(cat $kvm/cmdline) \ |
|
50 -pidfile kvm/pid \ |
|
51 -name "$vm" \ |
|
52 -vnc :$id \ |
|
53 -usb -usbdevice tablet \ |
|
54 -monitor tcp:localhost:$monitor,server,nowait \ |
|
55 -daemonize \ |
|
56 $@" |
|
57 echo "$cmdline" > $kvm/.cmdline |
|
58 test -f $kvm/frozen && cmdline="$cmdline $(cat $kvm/frozen)" |
|
59 |
|
60 ( |
|
61 cd $DIR/$vm && $KVM $cmdline \ |
|
62 && echo "started, display :$id, monitor tcp:127.0.0.1:$monitor" |
|
63 ) |
|
64 |
|
65 test "$DISPLAY" && test "$VNCVIEWER" && test -t \ |
|
66 && ( $VNCVIEWER :$id &>/dev/null </dev/null & ) |
|
67 |
|
68 ;; |
|
69 stop) echo "stopping (powerdown) $vm" |
|
70 { |
|
71 ( echo system_powerdown | $NC localhost $monitor ) & pid0=$! |
|
72 ( sleep 30; kill $pid0 &>/dev/null ) & pid1=$! |
|
73 wait $pid0 |
|
74 kill $pid1 2>/dev/null |
|
75 kill -0 $pid 2>/dev/null && $0 kill $vm |
|
76 } & |
|
77 ;; |
|
78 quit) echo "quit $vm" |
|
79 $FUSER -k $monitor/tcp |
|
80 echo quit | $NC 127.0.0.1 $monitor & |
|
81 ;; |
|
82 kill) echo "killing $vm" |
|
83 warn "killing vm $vm (id: $id, pid: $pid)" |
|
84 kill $pid & |
|
85 ;; |
|
86 freeze) echo "freezing $vm" |
|
87 fuser -k $monitor/tcp |
|
88 echo -e "savevm HIBERNATE\nquit" | $NC localhost $monitor & |
|
89 echo "-loadvm HIBERNATE" >$kvm/frozen |
|
90 ;; |
|
91 qemu) |
|
92 echo "DO *NOT* USE \"quit\", use ^C for exiting!" |
|
93 $NC localhost $monitor |
|
94 ;; |
|
95 esac |
|
96 |
|
97 done |
|
98 |
|
99 wait |