KVM

From KVM

goal

start the tap network adapter and virtual machine with one command like: kvm-manager start similarly, stop or kill the virtual machine like: kvm-manager stop

how

having a directory containing everything about the virtual machine, for example:

/var/guest/my-workstation
conf
override
hda
hdb
/var/guest/my-workstation/run
monitor
pid

this form a convention. the script will look for your settings in the file called "conf", and will load additional overwriting settings in "override" file. hda is the first disk image, hdb is the second disk image. everything generated when the vm is running will put in "run" directory.

example

to be continued...

kvm-manager.sh

#!/bin/sh
### expected directory structure
DIR_BASE=`pwd $`
FILE_HDA=${DIR_BASE}/hda
FILE_CONF=${DIR_BASE}/conf
FILE_OVERRIDE=${DIR_BASE}/override
### run directory will be auto-created with following files
DIR_RUN=${DIR_BASE}/run
FILE_MONITOR=${DIR_RUN}/monitor
FILE_PID=${DIR_RUN}/pid
FILE_OUT=${DIR_RUN}/out
### user-defined variables in ./kvm.conf
#GUEST_ID       [required]      generate the mac and tap name
#GUEST_MEMORY   [optional]      in mega-bytes, default to 1024
GUEST_MEMORY=1024
if [ -f ${FILE_CONF} ]
then
        . ${FILE_CONF}
else
        echo "file ${FILE_CONF} not exists"
        exit 1
fi
### generated variables
TAP_NAME=tap${GUEST_ID}
MAC_ADDR=00:16:3e:${GUEST_ID}:00:01
VNC_DISPLAY=3${GUEST_ID}00
VNC_PORT=`expr ${VNC_DISPLAY} + 5900`
GUEST_IP=10.18.18.1${GUEST_ID}
### options for kvm
OPT_BOOT="-boot c"
OPT_CDROM=""
OPT_STD_VGA="-std-vga"
OPT_USBDEVICE="-usbdevice tablet"
OPT_NO_ACPI=""
OPT_CPU="-cpu qemu64"
OPT_NIC="-net nic,macaddr=${MAC_ADDR},model=rtl8139"
OPT_DRIVE=""
OPT_HDB=""
OPT_VNC="-vnc :${VNC_DISPLAY}"
OPT_HDA="-hda ${FILE_HDA}"
OPT_SMP="-smp 4"
OPT_SERIAL=""
if [ -f ${FILE_OVERRIDE} ]
then
        . ${FILE_OVERRIDE}
fi
### network
start_net() {
        echo "start network adapter ${TAP_NAME}"
        sudo tunctl -u twer -t ${TAP_NAME}
        sudo ifconfig ${TAP_NAME} 0.0.0.0 promisc up
        sudo brctl addif br0 ${TAP_NAME}
}
stop_net() {
        echo "stop network adapter ${TAP_NAME}"
        sudo tunctl -d ${TAP_NAME}
}
check_net_status() {
        NET_STATUS=`ifconfig | grep ${TAP_NAME}`
        if test "${NET_STATUS}" = ""
        then
                echo "network adapter ${TAP_NAME} has not been started"
        else
                echo "network adapter ${TAP_NAME} has been started"
        fi
}
## virtual machine
start_vm_sliently() {
        echo "start virtual machine"
        sudo modprobe kvm
        sudo modprobe kvm_intel
        if ! [ -d /dev/km ]
        then
                sleep 1
        fi
        sudo chmod 666 /dev/kvm
        sudo chmod 666 /dev/net/tun
        if ! [ -d ${DIR_RUN} ]
        then
                mkdir ${DIR_RUN}
        fi
        qemu-system-x86_64 \
                ${OPT_HDA} \
                ${OPT_HDB} \
                ${OPT_DRIVE} \
                ${OPT_CPU} \
                ${OPT_SMP} \
                ${OPT_CDROM} \
                -m ${GUEST_MEMORY} \
                ${OPT_BOOT} \
                ${OPT_USBDEVICE} \
                ${OPT_NIC} \
                ${OPT_SERIAL} \
                -net tap,ifname=${TAP_NAME} \
                -k en-us \
                ${OPT_STD_VGA} \
                -monitor unix:${FILE_MONITOR},server,nowait \
                -pidfile ${FILE_PID} \
                ${OPT_NO_ACPI} \
                ${OPT_VNC} &
        # check if the pid file created successfully
        if [ ! -f ${FILE_PID} ]
        then
                sleep 1
        fi
        if [ ! -f ${FILE_PID} ]
        then
                return 1
        fi
        # check if the process started successfully
        if [ ! -d /proc/`cat ${FILE_PID}` ]
        then
                return 1
        fi
}
start_vm() {
        start_vm_sliently

        # if start_vm_sliently return -1
        if test $? -eq -1
        then
                echo "startup failed. check ${FILE_OUT}"
                exit 1
        else
                echo "startup successfully"
        fi
}
send_cmd() {
        QEMU_MONITOR_COMMAND=$1
        echo "${QEMU_MONITOR_COMMAND}" | socat - UNIX-CONNECT:${FILE_MONITOR}
}
get_vm_pid_to() {
        ACTION_TO_DO=$1
        # check if pid file there
        if [ ! -f ${FILE_PID} ]
        then
                echo "${FILE_PID} not found, can not ${ACTION_TO_DO}"
                exit 1
        fi
        VM_PID=`cat ${FILE_PID}`
}
check_vm_status() {
        get_vm_pid_to "check vm status"
        if [ -d /proc/${VM_PID} ]
        then
                echo "vm is running at process id ${VM_PID}"
        else
                echo "vm is not running"
        fi
}
stop_vm() {
        echo "stop virtual machine"

        get_vm_pid_to "stop vm"
        # check if monitor file there
        if [ ! -e ${FILE_MONITOR} ]
        then
                echo "${FILE_MONITOR} not found, can not stop vm"
                exit 1
        fi
        # if the process is still running
        # send command quit to its monitor, and wait
        if [ -d /proc/${VM_PID} ]
        then
                send_cmd "quit"
        fi
        # check if the process is still running
        if [ -d /proc/${VM_PID} ]
        then
                sleep 1
        fi
        if [ ! -d /proc/${VM_PID} ]
        then
                # yes, done
                rm ${FILE_PID}
                rm ${FILE_MONITOR}
                echo "vm stopped successfully"
        else
                # no, something wrong there...
                echo "failed to stop vm"
                exit 1
        fi
}
kill_vm() {
        echo "kill virtual machine"

        get_vm_pid_to "kill vm"
        # if the process is still running, kill it
        if [ -d /proc/${VM_PID} ]
        then
                kill ${VM_PID}
        fi
        rm ${FILE_PID}
        rm ${FILE_MONITOR}
        echo "vm killed"
}
### Main switch
case "$1" in
start-net)
        start_net
        ;;
start-vm)
        start_vm
        ;;
start)
        start_net
        start_vm
        ;;
status)
        check_net_status
        check_vm_status
        ;;
cad)
        send_cmd "sendkey ctrl-alt-delete"
        ;;
vnc)
        vncviewer localhost:${VNC_PORT} &
        ;;
rdesktop)
        rdesktop $2 $3 ${GUEST_IP} &
        ;;
ssh)
        ssh ${GUEST_IP}
        ;;
ping)
        ping ${GUEST_IP}
        ;;
halt)
        ssh twer@${GUEST_IP} sudo halt
        ;;
reset)
        send_cmd "system_reset"
        ;;
stop-vm)
        stop_vm
        ;;
stop-net)
        stop_net
        ;;
stop)
        stop_vm
        stop_net
        ;;
kill)
        kill_vm
        sleep 1
        stop_net
        ;;
*)
        echo "You need to specify a action, available actions are:"
        echo "[start-net] start network of the virtual machine"
        echo "[start-vm] start virtual machine itself"
        echo "[start] start both"
        echo "[status] check the status of network and virtual machine"
        echo "[cad] ctrl-alt-delete"
        echo "[vnc] use vinagre to view the vnc of the guest"
        echo "[rdesktop] remote desktop to the guest"
        echo "[ssh] ssh to the guest"
        echo "[ping] ping guest"
        echo "[halt] ssh to the guest and halt the guest"
        echo "[reset] reset the virtual machine"
        echo "[stop-vm] power off vritual machine"
        echo "[stop-net] stop network of the virtual machine"
        echo "[stop] stop both"
        echo "[kill] kill the viritual machine and network"
        exit 1
        ;;
esac
exit

kvm-manager.sh for wireless interface

#!/bin/bash

######################
## Default settings ##
######################

## Directory and files
if ! [ -d $2 ]
then
	DIR_BASE=`pwd $`
else
	DIR_BASE=$2
fi
FILE_HDA=${DIR_BASE}/hda
FILE_CONF=${DIR_BASE}/conf

### run directory will be auto-created with following files
DIR_RUN=${DIR_BASE}/run
FILE_MONITOR=${DIR_RUN}/monitor
FILE_PID=${DIR_RUN}/pid
FILE_OUT=${DIR_RUN}/out

GUEST_ID=0
GUEST_MEMORY=1024
GUEST_IP=192.168.1.97
HOST_IP=192.168.1.90/24
HOST_INTERFACE=wlan0

### generated variables
TAP_NAME=tap${GUEST_ID}
#MAC_ADDR=00:16:3e:${GUEST_ID}:00:01
#VNC_DISPLAY=3${GUEST_ID}00
#VNC_PORT=`expr ${VNC_DISPLAY} + 5900`

### options for kvm
#OPT_BOOT="-boot c"
OPT_BOOT=""

#OPT_CDROM="-cdrom /media/cdrom"
OPT_CDROM=""

#OPT_STD_VGA="-std-vga"
OPT_STD_VGA=""

#OPT_USBDEVICE="-usbdevice tablet"
OPT_USBDEVICE=""

#OPT_NO_ACPI="-no-acpi"
OPT_NO_ACPI=""

#OPT_CPU="-cpu qemu64"
OPT_CPU=""

#OPT_NIC="-net nic,macaddr=${MAC_ADDR},model=rtl8139"
OPT_NIC="-net nic"

#OPT_DRIVE="-drive <drive>"
OPT_DRIVE=""

#OPT_HDB="-hdb <hdb>"
OPT_HDB=""

#OPT_VNC="-vnc :${VNC_DISPLAY}"
OPT_VNC=""

#OPT_HDA="-hda <hda>"
OPT_HDA="-hda ${FILE_HDA}"

#OPT_SMP="-smp 4"
OPT_SMP=""

OPT_SERIAL=""

OPT_OTHER=""

if [ -f ${FILE_CONF} ]
then
        . ${FILE_CONF}
fi

### wireless network
start_net() {
        echo "start network adapter ${TAP_NAME}"
        sysctl net.ipv4.ip_forward=1
        tunctl -b -t ${TAP_NAME} -u `whoami`
        ip link set ${TAP_NAME} up
        ip addr add ${HOST_IP} dev ${TAP_NAME}
        parprouted ${HOST_INTERFACE}  ${TAP_NAME}
        echo "network adapter ${TAP_NAME} is started with as ip ${GUEST_IP}"
}
stop_net() {
        echo "stop network adapter ${TAP_NAME}"
        tunctl -d ${TAP_NAME}
}
check_net_status() {
        NET_STATUS=`ifconfig | grep ${TAP_NAME}`
        if test "${NET_STATUS}" = ""
        then
                echo "network adapter ${TAP_NAME} has not been started"
        else
                echo "network adapter ${TAP_NAME} has been started"
        fi
}

## virtual machine
start_vm_sliently() {
        echo "start virtual machine"
        
        if ! [ -d ${DIR_RUN} ]
        then
                mkdir ${DIR_RUN}
        fi

        kvm \
                ${OPT_HDA} \
                ${OPT_HDB} \
                ${OPT_DRIVE} \
                ${OPT_CPU} \
                ${OPT_SMP} \
                ${OPT_CDROM} \
                -m ${GUEST_MEMORY} \
                ${OPT_BOOT} \
                ${OPT_USBDEVICE} \
                ${OPT_NIC} \
                ${OPT_SERIAL} \
                -net tap,ifname=${TAP_NAME},script=no \
                -k fr \
                ${OPT_STD_VGA} \
                -monitor unix:${FILE_MONITOR},server,nowait \
                -pidfile ${FILE_PID} \
                ${OPT_NO_ACPI} \
                ${OPT_VNC} \
                ${OPT_OTHER} &

        # check if the pid file created successfully
        if [ ! -f ${FILE_PID} ]
        then
                sleep 1
        fi

        if [ ! -f ${FILE_PID} ]
        then
                return 1
        fi

        # check if the process started successfully
        if [ ! -d /proc/`cat ${FILE_PID}` ]
        then
                return 1
        fi       
}
start_vm() {
        start_vm_sliently

        # if start_vm_sliently return -1
        if test $? -eq -1
        then
                echo "startup failed. check ${FILE_OUT}"
                exit 1
        else
                echo "startup successfully"
         fi
}
send_cmd() {
        QEMU_MONITOR_COMMAND=$1
        echo "${QEMU_MONITOR_COMMAND}" | socat - UNIX-CONNECT:${FILE_MONITOR}
}
get_vm_pid_to() {
        ACTION_TO_DO=$1
        # check if pid file there
        if [ ! -f ${FILE_PID} ]
        then
                echo "${FILE_PID} not found, can not ${ACTION_TO_DO}"
                exit 1
        fi
        
        VM_PID=`cat ${FILE_PID}`
}
check_vm_status() {
        get_vm_pid_to "check vm status"
        if [ -d /proc/${VM_PID} ]
        then
                echo "vm is running at process id ${VM_PID}"
        else
                echo "vm is not running"
        fi
}
kill_vm() {
        echo "kill virtual machine"
        
        get_vm_pid_to "kill vm"

        # if the process is still running, kill it
        if [ -d /proc/${VM_PID} ]
        then
                kill ${VM_PID}
        fi

        rm ${FILE_PID}
        rm ${FILE_MONITOR}
        echo "vm killed"
}
detect_module() {
. /lib/lsb/init-functions

# Figure out which module we need.
	if grep -q ^flags.*\\\<vmx\\\> /proc/cpuinfo
	then
		module=kvm_intel
	elif grep -q ^flags.*\\\<svm\\\> /proc/cpuinfo
	then
		module=kvm_amd
	else
		module=
	fi
}
start_kvm() {
	detect_module

	if [ -z "$module" ]
	then
		log_failure_msg "Your system does not have the CPU extensions required to use KVM. Not doing anything."
		exit 0
	fi
	if modprobe "$module" 
	then
		log_success_msg "Loading kvm module $module"
	else
		log_failure_msg "Module $module failed to load"
		exit 1
	fi
}
stop_kvm() {
	detect_module

	if [ -z "$module" ]
	then
		exit 0
	fi
	if lsmod | grep -q "$module"
	then
		if rmmod "$module" 
		then
			log_success_msg "Succesfully unloaded kvm module $module"
			rmmod kvm
		else
			log_failure_msg "Failed to remove $module"
			exit 1
		fi
	else
		log_failure_msg "Module $module not loaded"
	fi
}
### Main switch
case "$1" in

start-kvm)
	start_kvm
	;;
start-net)
        start_net
        ;;

start-vm)
        start_vm
        ;;

start)
        start_net
        start_vm
        ;;

status)
        check_net_status
        check_vm_status
        ;;

cad)
        send_cmd "sendkey ctrl-alt-delete"
        ;;

vnc)
        vncviewer localhost:${VNC_PORT} &
        ;;

rdesktop)
        rdesktop $2 $3 ${GUEST_IP} &
        ;;

ssh)
        ssh ${GUEST_IP}
        ;;

ping)
        ping ${GUEST_IP}
        ;;

halt)
        ssh root@${GUEST_IP} halt
        ;;

reset)
        send_cmd "system_reset"
        ;;

stop-vm)
        stop_vm
        ;;

stop-net)
        stop_net
        ;;

stop)
        stop_vm
        stop_net
        ;;
stop-kvm)
	stop_kvm
	;;
kill)
        kill_vm
        sleep 1
        stop_net
        ;;

*)
	echo "KVM manager version 0.1, Samuel Bally"
	echo "usage: kvm-manager [options] [path]"
	echo ""
	echo "Standard options:"      
	echo "You need to specify a action, available actions are:"
	echo "[start-kvm] start kvm module"
        echo "[start-net] start network of the virtual machine"
        echo "[start-vm] start virtual machine itself"
        echo "[start] start both"
        echo "[status] check the status of network and virtual machine"
        echo "[cad] ctrl-alt-delete"
        echo "[vnc] use vinagre to view the vnc of the guest"   
        echo "[rdesktop] remote desktop to the guest"
        echo "[ssh] ssh to the guest"
        echo "[ping] ping guest"        
        echo "[halt] ssh to the guest and halt the guest"
        echo "[reset] reset the virtual machine"
        echo "[stop-vm] power off vritual machine"
        echo "[stop-net] stop network of the virtual machine"
	echo "[stop-kvm] stop kvm module"
        echo "[stop] stop both"
        echo "[kill] kill the viritual machine and network"
	echo ""
	echo "Config file:"
	echo "create a conf file in your vm directory for change default settings"
	echo "conf varialbles:"
	echo "DIR_RUN"
	echo "FILE_MONITOR"
	echo "FILE_PID"
	echo "FILE_OUT"
	echo "GUEST_ID"
	echo "GUEST_MEMORY"
	echo "GUEST_IP"
	echo "HOST_IP"
	echo "HOST_INTERFACE"
	echo "OPT_BOOT"
	echo "OPT_CDROM"
	echo "OPT_STD_VGA"
	echo "OPT_USBDEVICE"
	echo "OPT_NO_ACPI"
	echo "OPT_CPU"
	echo "OPT_NIC"
	echo "OPT_DRIVE"
	echo "OPT_HDB"
	echo "OPT_VNC"
	echo "OPT_HDA"
	echo "OPT_SMP"
	echo "OPT_SERIAL"
	echo "OPT_OTHER"
        exit 1
        ;;

esac
exit


Views Article Discussion Edit History
Personal tools:  Log in / create account
Toolbox What links here Related changes Upload file Special pages Printable version