Tag-Archive for » kvm «

Wednesday, April 29th, 2009 | Author: viking

I have a couple of projects that are deployed on Windows, so I use a virtual Windows machine on my Ubuntu box for development. At first, I tried using Samba to mount a share to my virtual machine, but that ended up causing problems. If my virtual server went down and I forgot to unmount, bad things happened.

Googling around, I discovered a how-to on how to mount the virtual machine disk directly via loopback. I decided to write an init script for it:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          mount-windows-image
# Required-Start:    $remote_fs
# Required-Stop:     $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Mounts a KVM windows image
### END INIT INFO
 
# Author: Jeremy Stephens <viking415@gmail.com>
#
# Please remove the "Author" lines above and replace them
# with your own name if you copy and modify this script.
 
# Do NOT "set -e"
 
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/bin:/usr/bin
DESC="Mounts a KVM Windows image"
SCRIPTNAME=/etc/init.d/mount-windows-image
DEV_FILE=/var/run/mount-windows-image
 
MOUNT_DIR=/mnt/win
IMAGE_FILE=/etc/libvirt/qemu/xp.img
UID=1017
GID=1017
FMASK=0137
DMASK=0027
 
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
 
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
 
#
# Function that starts the daemon/service
#
do_start()
{
	# Return
	#   0 if daemon has been started
	#   1 if daemon was already running
	#   2 if daemon could not be started
        if [ `mount -l | grep $MOUNT_DIR | wc -l` -gt 0 ]; then
          return 1
        else
          DEV=`losetup -f`
          echo $DEV > $DEV_FILE
          losetup $DEV $IMAGE_FILE
          kpartx -a $DEV
          mount -t ntfs -o uid=$UID,gid=$GID,fmask=$FMASK,dmask=$DMASK \
            /dev/mapper/`echo $DEV | awk -F/ '{print $3}'`p1 $MOUNT_DIR
          if [ $? -eq 0 ]; then
            return 0
          else
            kpartx -d $DEV
            losetup -d $DEV
            rm -f $DEV_FILE
            return 2
          fi
        fi
}
 
#
# Function that stops the daemon/service
#
do_stop()
{
	# Return
	#   0 if daemon has been stopped
	#   1 if daemon was already stopped
	#   2 if daemon could not be stopped
	#   other if a failure occurred
        if [ `mount -l | grep $MOUNT_DIR | wc -l` -eq 0 ]; then
          return 1
        else
          umount $MOUNT_DIR
          if [ $? -eq 0 ]; then
            sleep 1
            DEV=`cat $DEV_FILE`
            kpartx -d $DEV
            losetup -d $DEV
            rm -f $DEV_FILE
            return 0
          else
            return 2
          fi
        fi
}
 
#
# Function that sends a SIGHUP to the daemon/service
#
#do_reload() {
#	#
#	# If the daemon can reload its configuration without
#	# restarting (for example, when it is sent a SIGHUP),
#	# then implement that here.
#	#
#	start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
#	return 0
#}
 
case "$1" in
  start)
	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
	do_start
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  stop)
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
	do_stop
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  #reload|force-reload)
	#
	# If do_reload() is not implemented then leave this commented out
	# and leave 'force-reload' as an alias for 'restart'.
	#
	#log_daemon_msg "Reloading $DESC" "$NAME"
	#do_reload
	#log_end_msg $?
	#;;
#  restart|force-reload)
#	#
#	# If the "reload" option is implemented then remove the
#	# 'force-reload' alias
#	#
#	log_daemon_msg "Restarting $DESC" "$NAME"
#	do_stop
#	case "$?" in
#	  0|1)
#		do_start
#		case "$?" in
#			0) log_end_msg 0 ;;
#			1) log_end_msg 1 ;; # Old process is still running
#			*) log_end_msg 1 ;; # Failed to start
#		esac
#		;;
#	  *)
#	  	# Failed to stop
#		log_end_msg 1
#		;;
#	esac
#	;;
  *)
	#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
	echo "Usage: $SCRIPTNAME {start|stop}" >&2
	exit 3
	;;
esac
 
:


Install the script in /etc/init.d and make it executable. Make sure you change the following variables in the script: UID, GID, MOUNT_DIR, IMAGE_FILE. You can add the script to the boot process via the update-rc.d command:

chmod +x /etc/init.d/mount-windows-image
update-rc.d mount-windows-image defaults

This script mounts the first partition on a Windows virtual image, and it assumes the disk is formatted as NTFS. Tweaking the script to fit your needs shouldn’t be too difficult. I use Ubuntu, although I imagine the script would work in Debian. Your mileage may vary.

Note: I believe this only works with raw virtual images. Also, It’s probably a good idea to at least skim the post I linked above for additional information and caveats.

» Download script

Category: linux  | Tags: ,  | Leave a Comment