Skip to content

Instantly share code, notes, and snippets.

@mpontillo
Last active March 3, 2017 21:58
Show Gist options
  • Save mpontillo/b930c629b2a42003165e6c43ffe80749 to your computer and use it in GitHub Desktop.
Save mpontillo/b930c629b2a42003165e6c43ffe80749 to your computer and use it in GitHub Desktop.
Script to start a virtual machine using virsh, and sample its $pc register until it seems to be idle.
#!/bin/bash -e
# Check if we believe the VM has started after this number of samples.
CHECK_EVERY=500
# Consider the machine to be idle if MIN_IDLE_PCT% of sampled program counters
# were identical after at least MIN_IDLE_SAMPLES.
#
MIN_IDLE_SAMPLES=450
MIN_IDLE_PCT=60
# Timeout (in seconds)
TIMEOUT=300
function monotonic_time_msecs {
now=$(awk '/^now/ {print $3; exit}' /proc/timer_list)
now_msecs="$(expr $now / 1000000)"
echo $now_msecs
}
# Check if the user supplied a valid virtual machine.
virsh dumpxml $1 > /dev/null 2>&1 || (echo "Required argument: virtual machine name." ; exit 1)
# If the virtual machine hasn't been started, start it now.
# If it's already started, no big deal.
virsh start $1 > /dev/null 2>&1 || true
TEMPFILE="$(mktemp)"
function finish {
rm -f "$TEMPFILE"
}
trap "finish \$?" EXIT
samples=0
start_time_msecs=$(monotonic_time_msecs)
while [ 1 ]; do
virsh qemu-monitor-command $1 --hmp --cmd 'print $pc' | tr '\r' '\n' | head -1 >> $TEMPFILE
let samples=$samples+1
if [ "$(expr $samples % $CHECK_EVERY)" == "0" ]; then
idle_info="$(cat $TEMPFILE | sort | uniq -c | sort -n | tail -1)"
idle_samples="$(echo $idle_info | awk '{ print $1 }')"
idle_pc="$(echo $idle_info | awk '{ print $2 }')"
idle_pct="$(expr \( 100 \* $idle_samples \) / $samples)"
now_msecs=$(monotonic_time_msecs)
elapsed="$(expr $now_msecs - $start_time_msecs)"
elapsed_secs="$(expr $elapsed / 1000)"
printf "Idle pc=%s idle_samples=%s samples=%s idle=%s%%\n" \
"$idle_pc" "$idle_samples" "$samples" "$idle_pct"
if [ $idle_pct -ge $MIN_IDLE_PCT -a $idle_samples -gt $MIN_IDLE_SAMPLES ]; then
printf "Virtual machine '%s' appears to be started after %d.%03ds.\n" \
"$1" "$elapsed_secs" "$(expr $elapsed % 1000)"
exit 0
fi
if [ $elapsed_secs -gt $TIMEOUT ]; then
echo "$0: aborted waiting for virtual machine '$1' after waiting $TIMEOUT seconds." 1>&2
exit 1
fi
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment