#!/sbin/runscript # Copyright 2009 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 VMNAME=${SVCNAME#*.} PIDFILE=/var/run/vm/${VMNAME}.pid MONITOR=/var/run/vm/${VMNAME}.monitor QTAP_FILE=/var/run/vm/${VMNAME}.qtap # Default to qemu-kvm in the absense of a setting, failing back # to kvm if no binary is found, finally, back to qemu. [ -z "$VMSOFTWARE" ] && VMSOFTWARE=$(type -p qemu-kvm) [ -z "$VMSOFTWARE" ] && VMSOFTWARE=$(type -p kvm) [ -z "$VMSOFTWARE" ] && VMSOFTWARE=$(type -p qemu) 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 } start() { sanity_check 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 ${VMSOFTWARE##*/} for ${VMNAME} at VNC port${VNC}" start-stop-daemon --start "${VMSOFTWARE}" \ --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 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 ${VMSOFTWARE##*/} for ${VMNAME}" start-stop-daemon --stop "${VMSOFTWARE}" \ --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 }