summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app-emulation/qemu-init-scripts/files')
-rw-r--r--app-emulation/qemu-init-scripts/files/qemu-conf.example12
-rw-r--r--app-emulation/qemu-init-scripts/files/qemu-init-script157
-rw-r--r--app-emulation/qemu-init-scripts/files/qtap-manipulate118
3 files changed, 287 insertions, 0 deletions
diff --git a/app-emulation/qemu-init-scripts/files/qemu-conf.example b/app-emulation/qemu-init-scripts/files/qemu-conf.example
new file mode 100644
index 0000000..46f8274
--- /dev/null
+++ b/app-emulation/qemu-init-scripts/files/qemu-conf.example
@@ -0,0 +1,12 @@
+VMSOFTWARE=kvm
+MACADDR=52:54:1C:10:34:35
+DISKIMAGE=/mnt/kvm/gentoo64.qcow2
+MEMORY=1G
+SMP=4
+VNC=:24
+NIC_MODEL=virtio
+DRIVE_MODEL=virtio
+#OTHER_ARGS="-boot order=dc -cdrom /mnt/archive/gentoo/install-amd64-minimal-20100408.iso"
+OTHER_ARGS=" -boot order=cd -cdrom /mnt/archive/gentoo/systemrescuecd-x86-1.5.6.iso"
+#OTHER_ARGS="-vga std -boot order=dc -cdrom /dev/sdc"
+#TIMEOUT=60
diff --git a/app-emulation/qemu-init-scripts/files/qemu-init-script b/app-emulation/qemu-init-scripts/files/qemu-init-script
new file mode 100644
index 0000000..ba9aae3
--- /dev/null
+++ b/app-emulation/qemu-init-scripts/files/qemu-init-script
@@ -0,0 +1,157 @@
+#!/sbin/runscript
+# Copyright 2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# To use this, symlink a target kvm instance to this script.
+# Literally, ln -s qemu /etc/init.d/<vm-type>.<vmname>
+# then have a config named /etc/conf.d/<vm-type>.<vmname>
+#
+# Allowed vm-types are currently qemu and kvm.
+
+
+VMNAME=${SVCNAME#*.}
+VMTYPE=${SVCNAME%.*}
+VM_BINARY=
+PIDFILE=/var/run/vm/${SVCNAME}.pid
+MONITOR=/var/run/vm/${SVCNAME}.monitor
+QTAP_FILE=/var/run/vm/${SVCNAME}.qtap
+
+discern_vm_binary() {
+ case "$VMTYPE" in
+ kvm)
+ VM_BINARY=`type -p qemu-kvm`
+ [ -z "$VM_BINARY" ] && VM_BINARY=`type -p kvm`
+ ;;
+ qemu)
+ VM_BINARY=`type -p qemu`
+ ;;
+ *)
+ eerror "Failed to discern the binary for $VMTYPE"
+ ;;
+ esac
+ return 0
+}
+
+
+DROP_USER=${DROP_USER:-nobody}
+MEMORY=${MEMORY:-512M}
+TIMEOUT=${TIMEOUT:-300}
+SMP=${SMP:-1}
+export KVM_USER=${KVM_USER:-"root"}
+
+extra_commands="reboot"
+
+depend() {
+ need net.br0
+}
+
+send_command() {
+ local command="socat -u - UNIX-CONNECT:${MONITOR}"
+ type -p nc6 > /dev/null && command="nc6 -U ${MONITOR} --send-only"
+ echo "$@" | ${command} > /dev/null 2>&1
+}
+
+sanity_check() {
+ if [ "${VMNAME}" = "${SVCNAME}" ]; then
+ eerror "You have to create an init script for each vm:"
+ eerror " ln -s vm /etc/init.d/vm.vmname"
+ return 1
+ elif [ ! -f "${DISKIMAGE}" -a ! -b "${DISKIMAGE}" ]; then
+ eerror "couldn't find \$DISKIMAGE '$DISKIMAGE'"
+ return 1;
+ fi
+ discern_vm_binary
+}
+
+start() {
+ sanity_check || return 1
+
+ img=$(readlink -f "${DISKIMAGE}")
+ [ -z "$img" ] && {
+ eerror "couldn't find ${DISKIMAGE}"
+ return 1;
+ }
+
+ mkdir -p "${PIDFILE%/*}" "${MONITOR%/*}"
+ ebegin "creating qtap ${QTAP:-(auto allocating one)}"
+ if [ -n "$QTAP" ]; then
+ qtap-manipulate create_specific "${QTAP}" -u "${DROP_USER}"
+ else
+ QTAP=$(qtap-manipulate create -u "${DROP_USER}")
+ if [ 0 != $? ]; then
+ eerror "failed to create qtap interface"
+ return 1
+ fi
+ fi
+ echo "${QTAP}" > ${QTAP_FILE}
+ eend $?
+
+ ebegin "Starting ${VM_BINARY##*/} for ${VMNAME} at VNC port${VNC}"
+ start-stop-daemon --start "${VM_BINARY}" \
+ --pidfile ${PIDFILE} \
+ -- -daemonize -pidfile ${PIDFILE} -monitor unix:${MONITOR},server,nowait \
+ -runas ${DROP_USER} -name ${VMNAME} \
+ -drive file="$img",if=${DRIVE_MODEL:-virtio},cache=${DRIVE_CACHE:-none} \
+ -net nic,model=${NIC_MODEL:-virtio},macaddr=${MACADDR} -net tap,ifname=${QTAP},script=no \
+ ${DISABLE_KVM:---enable-kvm} \
+ ${MEMORY:+-m ${MEMORY}} ${SMP:+-smp ${SMP}} ${VNC:+-vnc ${VNC}} ${OTHER_ARGS}
+ ret=$?
+ if [ "0" != "${ret}" ]; then
+ qtap-manipulate destroy ${QTAP}
+ fi
+ eend ${ret}
+}
+
+reboot() {
+ if [ ${VMNAME} = ${SVCNAME} ]; then
+ eerror "You have to create an init script for each vm:"
+ eerror " ln -s vm /etc/init.d/vm.vmname"
+ return 1
+ fi
+
+ ebegin "Rebooting ${VMNAME}"
+ send_command system_reset
+ eend $?
+}
+
+stop() {
+ sanity_check || return 1
+
+ ebegin "Powering off ${VMNAME}"
+ send_command system_powerdown
+ eend $?
+
+ ebegin "waiting up to ${TIMEOUT:-60} seconds for it to die"
+ local pid
+ [ -s "${PIDFILE}" ] && pid=$(cat "${PIDFILE}")
+ if [ -z "$pid" ]; then
+ eerror "Couldn't find stored pid at '$PIDFILE'; user will have to manually kill kvm"
+ eerror "Will attempt to destroy qtap despite."
+ eend 1
+ else
+ local ret=1
+ for x in $(seq 0 ${TIMEOUT:-60}); do
+ if kill -0 "${pid}" > /dev/null 2>&1; then
+ sleep 1s
+ continue
+ fi
+ ret=0
+ break
+ done
+ eend $ret
+ fi
+
+ ebegin "Stopping ${VM_BINARY##*/} for ${VMNAME}"
+ start-stop-daemon --stop "${VM_BINARY}" \
+ --user "${DROP_USER}" \
+ --pidfile "${PIDFILE}" \
+ --quiet
+ eend $?
+ local qtap
+ [ -s "${QTAP_FILE}" ] && qtap=$(cat "${QTAP_FILE}")
+ if [ -n "$qtap" ]; then
+ ebegin "destroying qtap ${qtap}"
+ qtap-manipulate destroy ${qtap}
+ eend $?
+ fi
+}
diff --git a/app-emulation/qemu-init-scripts/files/qtap-manipulate b/app-emulation/qemu-init-scripts/files/qtap-manipulate
new file mode 100644
index 0000000..426bc78
--- /dev/null
+++ b/app-emulation/qemu-init-scripts/files/qtap-manipulate
@@ -0,0 +1,118 @@
+#!/bin/sh
+# Copyright 1999-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public Licens
+
+has() {
+ local desired=$1 x
+ shift
+ for x in "$@"; do
+ [ "$desired" = "$x" ] && return 0;
+ done
+ return 1
+}
+
+find_available_node() {
+ local val=$(ifconfig -a | grep -i ^qtap | cut -d ' ' -f1)
+ # Strip off ifconfig appended ':'
+ val="${val%:}"
+ local pos=0
+ while has qtap${pos} $val; do
+ pos=$(( $pos + 1 ))
+ done
+ echo qtap${pos}
+}
+
+create_node() {
+ local qtap="$1"
+ shift
+ tunctl -b -t "${qtap}" "$@" > /dev/null || die "tunctl failed"
+ brctl addif br0 "${qtap}" || die "brctl failed"
+ ifconfig "${qtap}" up 0.0.0.0 promisc || die "ifconfig failed"
+}
+
+destroy_node() {
+ issue=
+ ifconfig ${1} down || { echo "ifconfig failed";issue=1; }
+ brctl delif br0 ${1} || { echo "brctl failed";issue=2; }
+ tunctl -d ${1} > /dev/null || { echo "tunctl failed";issue=3;}
+ [ -n "${issue}" ] && exit $(( $issue ))
+}
+
+die() {
+ echo "$@" >&2
+ exit 1
+}
+
+usage() {
+ echo "commands available:"
+ echo "create-specific qtap-name [ -u user ] [ -g group ]"
+ echo "create [ -u user ] [ -g group ]"
+ echo "destroy qtap-name"
+ echo
+}
+
+usage_die() {
+ usage
+ die "$@"
+}
+
+create_user=
+create_group=
+
+parse_create_options() {
+ while [ $# -ne 0 ]; do
+ local x="$1"
+ case "$x" in
+ -u=*)
+ shift
+ set -- "-u" "${x#-u=}" "$@"
+ ;&
+ -u)
+ shift
+ [ -z "$1" ] && die "-u requires an argument"
+ create_user="$1"
+ shift
+ ;;
+ -g=*)
+ shift
+ set -- "-g" "${x#-u=}" "$@"
+ ;&
+ -g)
+ shift
+ [ -z "$1" ] && die "-g requires an argument"
+ create_group="$2"
+ shift
+ ;;
+ *)
+ die "unknown option $1"
+ esac
+ done
+}
+
+output_qtap=false
+case "$1" in
+ destroy)
+ shift
+ [ $# -eq 0 ] && usage_die "destroy requires a second argument"
+ [ $# -gt 1 ] && usage_die "no idea what to do with args: $@"
+ destroy_node "$1"
+ ;;
+ create)
+ output_qtap=true
+ qtap=$(find_available_node)
+ [ -z "$qtap" ] && die "failed to find a qtap node to use"
+ shift
+ set -- create_specific "${qtap}" "$@"
+ ;&
+ create_specific)
+ shift
+ qtap="$1"; shift
+ parse_create_options "$@"
+ create_node "$qtap"
+ $output_qtap && echo "$qtap"
+ ;;
+ *)
+ usage_die "Unknown command $1"
+ ;;
+esac
+exit 0