The objective of this project is to create a Dual Boot SLED workstation where the second Operating System (most likely Windows XP) can also be run within SLED as a virtual workstation. When companies try to migrate their workstations to SLED they run into a number of problems (both technical and political). However if the end-user were to have the option of “having your cake and eating it too” the migration would be much smoother. Being able to run both Windows and Linux at the same time would solve a nearly all of the technical and political issues surrounding the migration.
I have chosen VMware Player over XEN for two reasons:
There are a number of sites on the Internet that explain how to use different Virtualization products to run an OS from a partition rather than an image. However they all lack one thing, simplicity! These solutions are great if you are working on your own workstation, but if this solution is going to be rolled out to a large number of desktops, it is not feasible for the IT staff to spend a great deal of time on each workstation.
I have created a custom RPM to fix all these problems, which can be placed into your network repository and selected when building the SLED workstation. The RPMs (if anyone knows how to upload a RPM file to the wiki, please tell me!! :) ) are available for download and are licensed under GPL.
However there are a couple of points about this solution:
It has been my experience that the majority of workstations will already have Windows installed. This is either because it is an existing workstation where the user has been using Windows for some time, with all their applications and data already on it. Or it is because a new workstation coming from the factory has already been loaded with the default factory image or a specified corporate image.
If this is the rare situation where the the workstation is blank, build it as you normally would, however I would recommend building the image small since, only loading the programs that are necessary and not found in SLED. Remember, one of the objectives is to allow users to use Windows but slowly show the the benefits of Linux!
If your company uses Ghost (or any of the other multitude of imaging programs) it is possible to just create an empty partition on the drive and continue on. I have found that it is possible to image the partition while in Linux running VMware Player! (I would only do this after you have some experience though)
The analogy to running Windows natively then running it through VMware is like removing a hard disk with a windows installation from a Dell to into an HP. The visible devices Windows will see will be completely different when running under VMware.
To fix this in Windows we setup different Hardware Profiles. In Windows XP, the location to do this is under "System Properties" | "Hardware" tab | "Hardware Profiles" button.
A dialog will open showing a single existing hardware profile. What I do is rename it to "Physical" and make a copy called "Virtual".
Before your done, make sure that the "Virtual" Hardware Profile is on top (which means it will be the default).
There are numerous ways of installing SLED and a near infinite number of ways to configure it. Because of this I will not give you a blow by blow instruction on how to do it, but I will tell you how I do it.
I have a network repository which not only has the SLED10sp1 media, but also mirrors repositories from the internet and has a custom repository (which is where I loaded the RPMs)
I perform the installation by booting the workstation into a PXE boot server and use an AutoYaST script which helps standardize every installation. VMware Player and are automatically selected by the AutoYaST script.
From a command line run the command:
# vmware-config.pl
Accept all the defaults. The order of the questions is fairly standard, the only difference is when setting up the Networking Components. Because every workstation is different, it is not practical to script this.
A bridged network connection is one that piggybacks on an existing network connection. In this way, VMware allows you to use the physical network connection for both your physical and virtual workstation.
A NAT network connection is a Host-Only connection (A connection that is only visible within the physical machine) but allows NATed communication to the outside world through any available network connection. The physical Operating System is acting like a router between the virtual NAT network and the physical connections.
Although we did setup a bridged network connection, we will only be using the NAT network connection. This is because VMware is unable to bridge Wireless networks.
From a command line run the command:
# vmware-dualboot
vmware-dualboot is a custom script that modifies the VMware Configuration Files and other scripts. I will automatically search the drives for the Windows Partition and ask you to verify the selections. It will looks something like:
# vmware-dualboot Which partition is Windows installed on? [/dev/sda1]: Windows installed on #1 partition of /dev/sda (/dev/sda1) Adapter Type is scsi Total Sectors = 234441647 Cylinders = 14593 Heads = 255 Sectors = 63 Does this information look correct(y|n)? [n]: y Modifying /home/vmware/dualboot/dualboot.vmdk `/home/vmware/dualboot/dualboot.vmdk' -> `/home/vmware/dualboot/dualboot.vmdk.orig' # Disk Descriptor File version=1 CID=9c9136a6 parentCID=ffffffff createType="fullDevice" # Extent description RW 63 FLAT "dualboot.mbr" 0 RW 234441584 FLAT "/dev/sda" 63 # The Disk Data Base #DDB ddb.adapterType = "scsi" ddb.virtualHWVersion = "4" ddb.geometry.sectors = "63" ddb.geometry.heads = "255" ddb.geometry.cylinders = "14593"
The RPM comes with a custom made Application Icon named "Windows XP" which can be accessed via the Application Browser. You can also run the VMware session by running the command
# dualboot
You might be able to run VMware session by using the command
# vmplayer /home/vmware/dualboot/dualboot.vmx
Problem is that this does not address the permissions problems which the dualboot command does address.
While the Virtual Machine is booting up, watch to make sure that the correct hardware profile is selected and that there are no errors.
Once booted, the machine will start detecting all the new hardware that it sees. You will probably need to reboot the Virtual Machine a couple times.
Once everything comes down, you should install VMware Tools. These drivers are custom made to allow the Virtual Machine to operate smoother and faster. I obtained these tools by creating an ISO of the virtual CD-ROM that is created within VMware Server and Workstation when you select "Install VMware Tools", but since this option is not available within VMware Player, I have created a ZIP file available for download.
One problem with the solution is that the Windows VM has access to the entire disk, which of course includes the SLED installation. If a user is smart (i.e. dumb) enough, they could really create a mess!
To limit this possibility, go to the Disk Management applet ("Administrative Tools" | "Computer Management" | "Disk Management"). You should only see a C: drive on the Hard Drive, if there are more drive letters, remove ("Right-Click" | "Change Drive Letter and Paths.." | "Remove" Button)
My theory with users is, "What the monkey doesn't see he won't break"
The first part of the magic was to figure out how to format the VMware Configuration Files. The dualboot.vmdk file is the file that tells VMware how and where to find its virtual disks, in this case we are telling it to use the first 63 bytes of a file called dualboot.mbr and 64 byte and onward of the /dev/sdc device. Later on we will see how to create the dualboot.mbr file from the MBR of SDC and then how to manipulate it for our needs.
# Disk DescriptorFile version=1 CID=9c9136a6 parentCID=ffffffff createType="fullDevice" # Extent description RW 63 FLAT "dualboot.mbr" 0 RW 2004928 FLAT "/dev/sdc" 63 # The Disk Data Base #DDB ddb.adapterType = "scsi" ddb.virtualHWVersion = "4" ddb.geometry.sectors = "63" ddb.geometry.heads = "32" ddb.geometry.cylinders = "994"
The is the VMware Script that all the VMware products use. As you can see, it references the dualboot.vmdk file above as well specifies the hardware component VMware should expose to the Virtual Machine.
#!/usr/bin/vmplayer config.version = "8" virtualHW.version = "4" uuid.location = "56 4d 4f b5 b8 76 6f e9-8a a4 70 51 05 0b 3f a8" uuid.bios = "56 4d 4f b5 b8 76 6f e9-8a a4 70 51 05 0b 3f a8" uuid.action = "create" checkpoint.vmState = "" displayName = "Dual Boot" annotation = "Created by Bob Brandt (projects@brandt.ie)" guestinfo.vmware.product.long = "" guestinfo.vmware.product.url = "" guestOS = "winxppro" numvcpus = "1" memsize = "512" paevm = "TRUE" sched.mem.pshare.enable = "TRUE" MemAllowAutoScaleDown = "FALSE" MemTrimRate = "-1" nvram = "dualboot.nvram" mks.enable3d = "FALSE" vmmouse.present = "FALSE" vmmouse.fileName = "auto detect" tools.syncTime = "FALSE" tools.remindinstall = "FALSE" isolation.tools.hgfs.disable = "TRUE" isolation.tools.dnd.disable = "FALSE" isolation.tools.copy.enable = "TRUE" isolation.tools.paste.enabled = "TRUE" gui.restricted = "FALSE" ethernet0.present = "TRUE" ethernet0.connectionType = "NAT" usb.present = "TRUE" usb.generic.autoconnect = "FALSE" sound.present = "FALSE" sound.virtualdev = "sb16" ide0:0.present = "TRUE" ide0:0.fileName = "dualboot.vmdk" ide0:0.mode = "independent-persistent" ide0:0.deviceType = "rawDisk" ide0:0.redo = "" ide0:0.writeThrough = "FALSE" ide0:0.startConnected = "TRUE" ide1:0.present = "TRUE" ide1:0.fileName = "/dev/cdrom" ide1:0.deviceType = "atapi-cdrom" ide1:0.writeThrough = "FALSE" ide1:0.startConnected = "TRUE" floppy0.present = "TRUE" floppy0.startConnected = "FALSE" floppy0.autodetect = "TRUE" serial0.present = "FALSE" serial1.present = "FALSE" parallel0.present = "FALSE" virtualHW.productCompatibility = "hosted" tools.upgrade.policy = "manual" priority.grabbed = "normal" priority.ungrabbed = "normal" snapshot.disabled = "TRUE" gui.exitOnCLIHLT = "TRUE" usb.autoConnect.device0 = "" floppy0.fileName = "/dev/fd0" extendedConfigFile = "dualboot.vmxf"
Most of my scripts are pretty well documented (otherwise I woudl have no idea what is going on from one week to the next. But the jist of this script is to modify all the configuration files and the script files with the specific values for the machine it is running on.
This next part I am very proud of :)
The before leaving
#!/bin/bash
##############################################################################
##############################################################################
# #
# vmware-dualboot #
# #
# Details: Create custom VMWare Image files. #
# #
# This program was created to help administrators customize the vmdk file #
# used by vmware player. #
# #
# Comments can be used but must be preceeded by a hash symbol (#) #
# All Comments are to be preceded by a hash symbol (#) (Maximum of 78 chars) #
# #
# Created by Bob Brandt on 22 May 2007 #
# Web - http://www.brandt.ie/ #
# Email - projects@brandt.ie #
# #
# Licensed under GPL (just in case anyone askes) #
# #
##############################################################################
##############################################################################
vmdkfile="dualboot.vmdk"
vmxfile="dualboot.vmx"
mbrfile="dualboot.mbr"
filepath="/home/vmware/dualboot/"
filedepth=`echo "$filepath" | sed 's/[^\/]//g'`
filedepth=${#filedepth}
filedepth=$((filedepth+1))
version="0.7"
##############################################################################
# Below is the code responsible for producing asking a question #
# #
# USAGE: userinput Question DefaultAnswer #
# #
##############################################################################
function userinput {
echo -e -n "$1 [$2]: "
read value
if [ -z "$value" ]; then
value=$2
fi
echo
}
##############################################################################
# Below is the code responsible for modifying the mbr file. This is #
# necessary so the user will not need to manually select a boot option from #
# the GRUB menu. If the user were to miss it, they boot the default OS #
# again. (which is BAD) #
##############################################################################
function changebyte {
let byte=$1
echo -en $2 | dd conv=notrunc of="$filepath$mbrfile" bs=1 count=1 seek=$byte > /dev/null 2>&1
}
function modify_mbr {
# Copy the existing MBR from the specified device
dd if=$device of="$filepath$mbrfile" bs=512 count=63 > /dev/null 2>&1
# Change all the Partition Active Flags to 0x00
changebyte 0x1BE "\x00"
changebyte 0x1CE "\x00"
changebyte 0x1DE "\x00"
changebyte 0x1EE "\x00"
# Depending on the partition selected, mark the Partition Active Flag
# to 0x80
case "$partitionnumber" in
"2" ) changebyte 0x1CE "\x80" ;;
"3" ) changebyte 0x1DE "\x80" ;;
"4" ) changebyte 0x1EE "\x80" ;;
* ) changebyte 0x1BE "\x80" ;;
esac
}
##############################################################################
# Below is the code responsible for modifying the vmdk file. #
##############################################################################
function modify_vmdk {
# Make a copy of the old file and create a new file.
echo "Modifying $filepath$vmdkfile"
cp -vf "$filepath$vmdkfile" "$filepath$vmdkfile.orig"
echo -e "# Disk Descriptor File" > $filepath$vmdkfile
echo -e "version=1" >> $filepath$vmdkfile
echo -e "CID=9c9136a6" >> $filepath$vmdkfile
echo -e "parentCID=ffffffff" >> $filepath$vmdkfile
echo -e "createType=\"fullDevice\"\n" >> $filepath$vmdkfile
echo -e "# Extent description" >> $filepath$vmdkfile
echo -e "RW 63 FLAT \"$mbrfile\" 0" >> $filepath$vmdkfile
echo -e "RW $((totalsectors-63)) FLAT \"$device\" 63\n" >> $filepath$vmdkfile
echo -e "# The Disk Data Base" >> $filepath$vmdkfile
echo -e "#DDB\n" >> $filepath$vmdkfile
echo -e "ddb.adapterType = \"$adaptertype\"" >> $filepath$vmdkfile
echo -e "ddb.virtualHWVersion = \"4\"" >> $filepath$vmdkfile
echo -e "ddb.geometry.sectors = \"$sectors\"" >> $filepath$vmdkfile
echo -e "ddb.geometry.heads = \"$heads\"" >> $filepath$vmdkfile
echo -e "ddb.geometry.cylinders = \"$cylinders\"\n" >> $filepath$vmdkfile
# Display the new file to the user.
cat $filepath$vmdkfile
}
##############################################################################
# Below is the code responsible for modifying the sudoers file which will #
# allow users to run the permissions script above as root. #
##############################################################################
function modify_sudoers {
# This line will allow all users to run the vmplayer as root without
# entering a password.
sudoersline="%users ALL= NOPASSWD: $filepath""vmware-chmodgrp, /usr/bin/vmware-chmodgrp"
temp=`grep "^$sudoersline" /etc/sudoers`
if [ -z "$temp" ]; then
# We need to change the mod of the file so we can right to it.
chmod 0666 /etc/sudoers
echo -e "\n$sudoersline" >> /etc/sudoers
fi
# But before we leave we need to change the mod back to 0440. If we
# don't sudo won't work.
chmod 0440 /etc/sudoers
}
##############################################################################
# Below is the code responsible for modifying the script that changes the #
# permissions of the different files. #
##############################################################################
function modify_vmware-chmodgrp_script {
filename="$filepath"vmware-chmodgrp
searchtext="^filepath=\".*\""
replacetext="filepath=\"$filepath\""
sed 's~'"$searchtext"'~'"$replacetext"'~g' "$filename" > "$filename".temp
mv -f "$filename".temp "$filename"
searchtext="^device=\".*\""
replacetext="device=\"$device\""
sed 's~'"$searchtext"'~'"$replacetext"'~g' "$filename" > "$filename".temp
mv -f "$filename".temp "$filename"
}
##############################################################################
# Below is the code responsible for modifying the script that changes the #
# permissions of the different files. #
##############################################################################
function modify_dualboot_script {
filename="$filepath"dualboot
searchtext="^vmplayer .*"
replacetext="vmplayer $filepath$vmxfile"
sed 's~'"$searchtext"'~'"$replacetext"'~g' "$filename" > "$filename".temp
mv -f "$filename".temp "$filename"
}
##############################################################################
# Below is the code responsible for verifing that the values are correct. #
##############################################################################
function verify_values {
# Get the total number of sectors on the specified device.
temp=`parted $device unit s print | grep "Disk geometry for $device" | cut -d " " -f 7`
totalsectors=`echo $temp | cut -d "s" -f 1`
# Get the cylinder, head and sector information from the specified
# device.
temp=`parted $device unit cyl print | grep "BIOS cylinder,head,sector geometry:" | cut -d " " -f 4 | cut -d "." -f 1`
cylinders=`echo $temp | cut -d "," -f 1`
heads=`echo $temp | cut -d "," -f 2`
sectors=`echo $temp | cut -d "," -f 3`
# Figure out if the device is a SCSI, SATA or IDE device
if [ -z "`echo $device | sed 's/^\/dev\/hd.*//'`" ]; then
adaptertype="ide"
else
adaptertype="scsi"
fi
# From the Windows Partition variable, determine what the partition
# number is.
partitionnumber=`echo $windowspartition | sed 's/\/dev\/[h|s]da//'`
# Display the information to the user so he can verify it.
echo -e "\n\n\n\n"
echo "Windows installed on #$partitionnumber partition of $device ($windowspartition)"
echo "Adapter Type is $adaptertype"
echo "Total Sectors = $totalsectors"
echo "Cylinders = $cylinders"
echo "Heads = $heads"
echo "Sectors = $sectors"
userinput "\nDoes this information look correct(y|n)?" "n"
if [ "$value" = "n" ]; then
exit 1
fi
}
##############################################################################
# Below is the code responsible for modifying the vmdk file. #
##############################################################################
function execute {
modify_mbr
modify_vmdk
modify_sudoers
modify_vmware-chmodgrp_script
modify_dualboot_script
parentpath=`echo "$filepath" | sed 's|[^/]*/$||'`
# The permissions of the device need to be set in order for non-roots to be
# able to run the VM.
chmod -R 666 "$device"
# The permissions need to be changed on the files themselves to allow different
# users to be able run the VM. I may have gone overboard, but tough!
chgrp -R users "$parentpath"
chmod -R 7777 "$parentpath"
chmod -R 666 "$filepath"*
chmod 555 "$filepath"dualboot "$filepath"vmware-chmodgrp "$filepath"vmware-dualboot
}
##############################################################################
# Below is the code responsible for displaying the help screen. #
##############################################################################
function display_help
{
echo -e "\n ${0##*/} [Optional Options]\n"
echo -e " Optional Options:"
echo -e " -p, --partition = the partition windows is installed on."
echo -e " -h, --help = show this help."
echo -e " -v, --version = output version.\n"
exit 0
}
##############################################################################
# Below is the code responsible for displaying the version screen. #
##############################################################################
function display_version
{
echo -e "\nGNU ${0##*/} $version\n"
echo -e "This program is distributed in the hope that it will be useful,"
echo -e "but WITHOUT ANY WARRANTY; without even the implied warranty of"
echo -e "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
echo -e "GNU General Public License for more details.\n"
echo -e "Originally written by Bob Brandt <projects@brandt.ie>.\n"
exit 0
}
##############################################################################
# Everything below is the main code of the script, which processes the #
# parameters and runs the functions above. #
##############################################################################
windowspartition=
# Process all the parameters. Since we do not know what order the parameters
# will be given, we need to process all the parameters before we act upon
# them.
while [ "$1" != "" ]; do
case "$1" in
"-p" | "--partition" )
shift
windowspartition="$1"
;;
"-m" | "--mbr-file" )
shift
mbrfile="$1"
;;
"/?" | "/h" | "-?" | "-h" | "--help" )
display_help
exit 0
;;
"/v" | "-v" | "--version" )
display_version
exit 0
;;
* )
echo "Options Error: option $1 not recognized."
display_help
exit 1
;;
esac
shift
done
# Before anything is done, be sure to verify that the user is root.
if [ "`id -u`" != "0" ]; then
echo "You must be root to run this script" 2>&1
exit 1
fi
# Also make sure that the vmdk file is present and writeable.
if [ ! -w "$filepath$vmdkfile" ]; then
echo "$filepath$vmdkfile is not present or writeable" 2>&1
exit 1
fi
# If not specified, retrieve the windows partition from the user.
if [ -z "$windowspartition" ]; then
windowspartition=`fdisk -l 2>/dev/null | awk '/(HPFS|NTFS|FAT|W95)/{print $1}' | head -n 1`
userinput "Which partition is Windows installed on?" "$windowspartition"
windowspartition=`echo $value | awk '/^\/dev\/[s|h]d[a-z][0-9]*/'`
fi
if [ -z "$windowspartition" ]; then
echo "$value is not in a valid partition syntax. Try again" 2>&1
exit 1
fi
# Also specify the device based on the partition.
device=`echo $windowspartition | sed 's/[0-9]*$//'`
if [ -z "`fdisk -l 2>/dev/null | grep $device`" ]; then
echo "$windowspartition is not on a valid device. Try again" 2>&1
exit 1
fi
# Now that we have verified that all the parameters are correct, modify the
# vmdk file.
verify_values && execute
exit 0
The vmware-chmodgrp script is very basic. All it does is make sure that the necessary permissions are set on all the necessary files and scripts. Again the file is well documented.
#!/bin/bash ############################################################################## ############################################################################## # # # vmware-chmodgrp # # # # Details: Change the group membership and mod of the VMWare Image files. # # # # There is an ongoing issue with VMWare Player changing the permissions of # # the relevent files so non-root users are unable to run image. this script # # makes sure that the relevent files have the correct permissions for a # # non-root user to run the Dualboot image from disk. # # # # Comments can be used but must be preceeded by a hash symbol (#) # # All Comments are to be preceded by a hash symbol (#) (Maximum of 78 chars) # # # # Created by Bob Brandt on 22 May 2007 # # Web - http://www.brandt.ie/ # # Email - projects@brandt.ie # # # # Licensed under GPL (just in case anyone askes) # # # ############################################################################## ############################################################################## # These variables will be modified by the vmware-dualboot script filepath="/home/vmware/dualboot/" device="/dev/sda" # Before anything is done, be sure to verify that the user is root. if [ "`id -u`" != "0" ]; then echo "You must be root to run this script" 2>&1 exit 1 fi ############################################################################## # Below is the code responsible for modifying the permissions of the # # different files. # ############################################################################## parentpath=`echo "$filepath" | sed 's|[^/]*/$||'` # The permissions of the device need to be set in order for non-roots to be # able to run the VM. chmod -R 666 "$device" # The permissions need to be changed on the files themselves to allow different # users to be able run the VM. I may have gone overboard, but tough! chgrp -R users "$parentpath" chmod -R 7777 "$parentpath" chmod -R 666 "$filepath"* chmod 555 "$filepath"dualboot "$filepath"vmware-chmodgrp "$filepath"vmware-dualboot exit 0
The dulboot script is also very basic. All it does is launch the vmware-chmodgrp script using sudo, then it launches the vmplayer with the specified VMX file so the user is asked for absolutely NO imput whatsoever!
#!/bin/bash ############################################################################## ############################################################################## # # # dualboot # # # # Details: Launch a VMWare Player Dualboot VM Image # # # # All Comments are to be preceded by a hash symbol (#) # # Because of screen width limits, comments should be a Maximum of 78 chars # # # # # # Created by Bob Brandt on 22 May 2007 # # Web - http://www.brandt.ie/ # # Email - projects@brandt.ie # # # # Licensed under GPL (just in case anyone askes) # # # ############################################################################## ############################################################################## # Modify the permissions on the files since VMWare has a habit of changing # them so they only work with root sudo /usr/bin/vmware-chmodgrp # Run the VMWare Image vmplayer /path/to/vmware/file.vmx exit 0
Other than the files above, the RPM installes