diff options
Diffstat (limited to 'qemu-init-scripts/qemu-init-script')
-rwxr-xr-x | qemu-init-scripts/qemu-init-script | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/qemu-init-scripts/qemu-init-script b/qemu-init-scripts/qemu-init-script new file mode 100755 index 0000000..2d3ce95 --- /dev/null +++ b/qemu-init-scripts/qemu-init-script @@ -0,0 +1,263 @@ +#!/sbin/runscript +# Copyright 2009-2013 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +# You are not supposed to run this script directly. Create a symlink +# for the qemu instance you want to run as well as a copy of the +# configuration file and modify it appropriately like so... +# +# ln -s qemu /etc/init.d/kvm.myserver +# cp /etc/conf.d/qemu /etc/conf.d/kvm.myserver +# nano /etc/conf.d/kvm.myserver +# +# where 'kvm' is the virtual machine type ('qemu' and 'kvm' allowed) +# and 'myserver' is the name of your instance. + +VERSION="0.3.0" + +VMNAME=${SVCNAME#*.} +VMTYPE=${SVCNAME%.*} +VM_BINARY= +PIDFILE=/run/vm/${SVCNAME}.pid +MONITOR=/run/vm/${SVCNAME}.monitor +QTAP_FILE=/run/vm/${SVCNAME}.qtap +ENABLE_SDL= + +discern_vm_binary() { + case "$VMTYPE" in + kvm) + VM_BINARY=$(which "qemu-system-${QEMU_TYPE}") + [ -z "$VM_BINARY" ] && eerror "Failed to find the binary for qemu-system-${QEMU_TYPE}" + ;; + qemu) + VM_BINARY=$(which "qemu-${QEMU_TYPE}") + [ -z "$VM_BINARY" ] && eerror "Failed to find the binary for qemu-${QEMU_TYPE}" + ;; + *) + eerror "Failed to discern the binary for $VMTYPE" + ;; + esac + return 0 +} + +discern_foreground() { + if [ -n "$VNC" ]; then + ewarn "VNC option is going away; set FOREGROUND=\"vnc=${VNC}\" instead" + FOREGROUND="vnc=${VNC}" + fi + case "${FOREGROUND:-none}" in + vnc*) + VNC=${FOREGROUND#*=} + if [ -z "$VNC" ]; then + eerror "FOREGROUND vnc is incorrectly set; must specify an address (:1 for example)" + return 1 + fi + ;; + sdl*) + ENABLE_SDL=${FOREGROUND#*=} + if [ -z "${ENABLE_SDL}" ]; then + eerror "FOREGROUND sdl is incorrectly set; must specify a DISPLAY address" + return 1 + fi + ;; + none) + ;; + *) + eerror "Unknown FOREGROUND setting: $FOREGROUND" + return 1 + ;; + 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 version" + +depend() { + if [ "$VMNAME" = "$SVCNAME" ]; then + return 0 + fi + + sanity_check || return 1 + + case "$NIC_TYPE" in + br) + need ${NIC_NET_DEPS-net.br0} + ;; + esac +} + +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 +} + +symlink_check() { + if [ "${VMNAME}" = "${SVCNAME}" ]; then + eerror "You are not supposed to run this script directly. Create a symlink" + eerror "for the qemu instance you want to run as well as a copy of the" + eerror "configuration file and modify it appropriately like so..." + eerror + eerror " ln -s qemu /etc/init.d/kvm.myserver" + eerror " cp /etc/conf.d/qemu /etc/conf.d/kvm.myserver" + eerror " `basename "${EDITOR:-nano}"` /etc/conf.d/kvm.myserver" + eerror + eerror "where 'kvm' is the virtual machine type ('qemu' and 'kvm' allowed)" + eerror "and 'myserver' is the name of your instance." + return 1 + fi +} + +sanity_check() { + symlink_check || return 1 + + DISKIMAGE=$(readlink -f "${DISKIMAGE}") + if [ ! -f "${DISKIMAGE}" -a ! -b "${DISKIMAGE}" ]; then + eerror "couldn't find \$DISKIMAGE '$DISKIMAGE'" + return 1; + fi + discern_vm_binary || return 1 + NIC_TYPE=${NIC_TYPE:-nat} + + discern_foreground || return 1 +} + +start_pre() { + checkpath -d --owner root:root --mode 0644 "${PIDFILE%/*}" \ + "${MONITOR%/*}" +} + +start() { + sanity_check || return 1 + + local NIC_COMMAND=( -net "nic,model=${NIC_MODEL:-virtio},macaddr=${MACADDR}" -net ) + + if [ "${NIC_TYPE}" = "br" ]; then + if [ -n "$QTAP" ]; then + ebegin "using specified QTAP: ${QTAP}" + qtap-manipulate create_specific "${QTAP}" -u "${DROP_USER}" + else + ebegin "creating qtap ${QTAP:-(auto allocating one)}" + 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 $? + NIC_COMMAND[${#NIC_COMMAND[@]}]="tap,ifname=${QTAP},script=no" + elif [ "${NIC_TYPE}" = "none" ]; then + NIC_COMMAND=( -net none ) + else + NIC_COMMAND[${#NIC_COMMAND[@]}]=user + fi + + local ss_args=( ) + local vm_args=( -daemonize ) + + if [ -n "${ENABLE_SDL}" ]; then + ss_args[${#ss_args[@]}]=--env + ss_args[${#ss_args[@]}]="DISPLAY=${ENABLE_SDL}" + ss_args[${#ss_args[@]}]=--env + local user_home=`getent passwd ${DROP_USER:-root} | cut -d: -f6` + ss_args[${#ss_args[@]}]="XAUTHORITY=$user_home/.Xauthority" + vm_args[${#vm_args[@]}]=-display + vm_args[${#vm_args[@]}]=sdl + elif [ -n "$VNC" ]; then + vm_args[${#vm_args[@]}]=-display + vm_args[${#vm_args[@]}]="vnc=${VNC}" + else + vm_args[${#vm_args[@]}]=-display + vm_args[${#vm_args[@]}]=none + fi + + ebegin "Starting ${VM_BINARY##*/} for ${VMNAME} ${FOREGROUND:+at ${FOREGROUND}}" + set -- start-stop-daemon \ + --start "${VM_BINARY}" \ + --pidfile ${PIDFILE} \ + "${ss_args[@]}" \ + -- \ + "${vm_args[@]}" \ + -pidfile ${PIDFILE} -monitor unix:${MONITOR},server,nowait \ + -runas ${DROP_USER} -name ${VMNAME} \ + -drive file="${DISKIMAGE//,/,,}",if=${DRIVE_MODEL:-virtio},cache=${DRIVE_CACHE:-none}${DRIVE_FORMAT:+,format=${DRIVE_FORMAT}} \ + "${NIC_COMMAND[@]}" \ + ${ENABLE_KVM:+--enable-kvm} ${CPU:+-cpu ${CPU}} \ + ${MACHINE:+-M ${MACHINE}} \ + ${MEMORY:+-m ${MEMORY}} ${SMP:+-smp ${SMP}} \ + ${OTHER_ARGS} + einfo "invoking ${@}" + "${@}" + ret=$? + if [ "0" != "${ret}" -a -n "${QTAP}" ]; then + qtap-manipulate destroy ${QTAP} + fi + + eend ${ret} +} + +reboot() { + symlink_check || return 1 + + 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} 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}); 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}" + if kill -0 "${pid}" > /dev/null 2>&1; then + start-stop-daemon --stop "${VM_BINARY}" \ + --user "${DROP_USER}" \ + --pidfile "${PIDFILE}" \ + --quiet + eend $? + else + eend 0 # no need to kill process if it is dead :P + fi + local qtap + [ -s "${QTAP_FILE}" ] && qtap=$(cat "${QTAP_FILE}") + if [ -n "$qtap" ]; then + ebegin "destroying qtap ${qtap}" + qtap-manipulate destroy ${qtap} + eend $? + fi +} + +version() { + echo "qemu-init-scripts version: ${VERSION}" +} + |