Building a Debian or Ubuntu Xen Guest Root Filesystem using debootstrap
In earlier chapters of this book we looked at populating the root filesystem of a Xen domU guest system by copying the root filesystem from the host operating system. While this is a workable approach it has the draw back that it provides little or no control over which packages get installed in the guest system. It is also possible that the operating system required to run in the guest domain is a different Linux distribution to that running on the host.
A cleaner way to install the operating system files on a guest root filesystem on Debian or Ubuntu is to use the debrootstrap tool to install the packages from the distribution repositories. In this chapter we will work step by step through the process of creating a bootable Ubuntu Xen guest system using debootstrab to populate the root filesystem.
One point to note is that the steps provided in this chapter can be automated to a large extent using Xen-Tools (a process which is described in detail in the Building a Xen Guest Domain using Xen-Tools chapter). If you are currently learning Xen, however, we recommend that you perform the configuration at least once using the steps below before switching to using Xen-Tools. This will provide a better understanding of how Xen guest domains are configured, knowledge which will be invaluable when things go wrong.
Creating the Xen Guest Root Filesystem
For the purposes of this chapter the root filesystem for the guest domain will reside in a disk image file (as opposed to a physical partition of logical volume). The first step therefore is to create the image file:
dd if=/dev/zero of=UbuntuXen.img bs=1024k seek=6144 count=0
The above command creates a 3Gb image file to which will contain the root filesystem. Having generated the image the next step is to create a filesystem on it:
mkfs -t ext3 UbuntuXen.img mke2fs 1.40.2 (12-Jul-2007) UbuntuXen.img is not a block special device. Proceed anyway? (y,n) y Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) 393216 inodes, 786432 blocks 39321 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=805306368 24 block groups 32768 blocks per group, 32768 fragments per group 16384 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912 Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 32 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.
The guest root filesystem image file is now ready.
Creating Swap for the Xen Guest Domain
The next key requirement for a Xen guest domain is swap space. Once again for the purposes of this chapter we will use a disk image file for this purpose. The following command creates a 1Gb disk image file for swap:
dd if=/dev/zero of=UbuntuXen.swap bs=1024k seek=1024 count=0
Having created the an image file to act as the swap device the next task is to format the image as swap space using the mkswap command as follows:
mkswap UbuntuXen.swap Setting up swapspace version 1, size = 1073737 kB
Installing the Base Ubuntu/Debian System using debootstrap
Before the base Linux system can be installed on the root filesystem the disk image must first be mounted. This is achieved using the mount command and the loopback interface. The following example creates a temporary directory as a mount point and mounts the root filesystem image at this location:
mkdir xenloop mount -o loop UbuntuXen.img /tmp/xenloop
Now that the root filesytem disk image is mounted the base Ubuntu operating system can be be installed debootstrap. The tool takes two command-line arguments, the release of Ubuntu or Debian to be installed (for example gutsy or edgy) following by the location of the filesystem into which the packages are to be installed. The following shows an excerpt of the output:
debootstrap gutsy /tmp/xenloop I: Retrieving Release I: Retrieving Packages I: Validating Packages I: Resolving dependencies of required packages... I: Resolving dependencies of base packages... I: Checking component main on http://archive.ubuntu.com/ubuntu... I: Retrieving adduser I: Validating adduser I: Retrieving alsa-base I: Validating alsa-base I: Retrieving alsa-utils . . . I: Configuring libc6... I: Configuring initramfs-tools... I: Base system installed successfully.
The debootstrap tool will now download and install the base packages necessary for the Xen Guest system to boot. Note that this may take some time to complete.
Once the installation is complete the appropriate modules need to be copied from the host operating system to the guest root fileystem:
cp -r /lib/modules/* /tmp/xenloop/lib/modules
Configuring the root Password
When a system is created using the debrootstrap tool it is configured with no root password. Whilst it is possible to boot the system and set the root password once it is up and running a safer option is to set the root password immediately after the debootstrap process has completed. This is achieved using the chroot command using the path to the mounted guest root filesystem as a command-line argument:
chroot /tmp/xenloop /usr/bin/passwd Enter new UNIX password:
Enter the desired root password when prompted.
Creating a Configuration File for the Guest Domain
All that remains before booting up the guest domain (domU) is to create a suitable Xen configuration file. For the purposes of this example we will load the initial RAM filesystem and kernel images from the host operating system. These are typically located in the /boot directory. The kernel file typically begins with the name vmlinuz and the initial RAM disk begins with initrd. These two images are defined in the Xen configuration file using the kernel = and ramdisk = directives. For example:
kernel = "/boot/vmlinuz-2.6.22-14-xen" ramdisk = "/boot/initrd.img-2.6.22-14-xen"
Next, the amount of memory to be allocated to the guest system is defined using the memory = directive. The following assigned 512Mb to the guest:
memory = 256
Each guest domain needs to have a name by which it can be referenced when using the Xen management tools. This is assigned using name = :
name = "UbuntuXen"
Now we specify network configuration options. The following lines indicate to Xen that the IP address of the system will be assigned using DHCP and the empty vif line instructs Xen to use the default values for the network interface configuration:
vif = [ '' ] dhcp = "dhcp"
Next, we need to add an extra directive to specify a console device:
extra = 'xencons=tty'
Finally the disk = directive is used to map the disk images we have created with guest operating system devices. The following lines map the root and swap images to /dev/xvda1 and /dev/xvda2 respectively and define the root filesystem as /dev/xvda:
disk = ['tap:aio:/xen/UbuntuXen.img,xvda1,w', 'tap:aio:/xen/UbuntuXen.swap,xvda2,w'] root = "/dev/xvda1 ro"
Note that these device mappings will be needed when the fstab file is configured later in this chapter.
Bringing all these configuration lines together should result in the following configuration file which we will name UbuntuXen.cfg:
kernel = "/boot/vmlinuz-2.6.18-53.1.14.el5xen" ramdisk = "/boot/initrd-2.6.18-53.1.14.el5xen.img" memory = 256 name = "UbuntuXen" vif = [ '' ] dhcp = "dhcp" extra = 'xencons=tty' disk = ['tap:aio:/xen/XenGuest1.img,xvda1,w', 'tap:aio:/xen/XenGuest1.swap,xvda2,w'] root = "/dev/xvda1 ro"
Configuring System Files for the Guest Operating System
It is important to keep in mind that at this point in the process we have copied all of the system files from our host operating system onto the disk image for our guest operating system. It is vital at this point, therefore, that we change any system configuration files to meet the requirements of our guest domain. Typical settings that will need to be changed are:
- /etc/fstab - This file contains the mappings between physical and network devices and filesystems. This will need to be changed to reflect the disk configuiration used by the guest system.
- /etc/passwd - Contains password information for all user and application accounts on the host system. It is important to remove the entries for any accounts which will not be required on the guest system.
- /etc/group - This file contains information about user and application groups and, as with the passd file, should be modified to remove any groups not required in the guest system.
- /etc/hosts - Contains information about the local host and other hosts on the network. Be sure to change the name of the local host to match the name to be used by the guest operating system.
- /etc/sysconfig/network or /etc/network/interfaces - Depending on which Linux distribution you are using, one of these files will contain networking information such as the host name and possibly a static IP address. Be sure to modify this file to remove any conflicts between the host and guest operating systems.
- /etc/exports - Contains information about any filesystems local to the host operating system which are exported for NFS access to remote systems. This should be modified to reflect any exports needed for the guest OS.
Modifying /etc/fstab for the Guest System
In the preceding section we talked about the system configuration files which may need to be modified in the root filesystem of the guest operating system. One file which needs particular attention is the etc/fstab file. The file currently present in the guest root filesystem is a direct replica of the file used by the host operating system. It is almost certain that this file will not be configured to work with the disk represented by our root filesystem and swap images. The following shows a typical empty /etc/fstab file from an Ubuntu system immediately after it has been created as part of the debootstrap process:
# UNCONFIGURED FSTAB FOR BASE SYSTEM
Clearly, this doesn't match the disk configuration we have set up using disk images for the root filesystem and the swap device. The guest OS copy of the fstab file needs to be modified to reflect the device mappings in the Xen configuration file created above (recall that the root filesystem was mapped to /dev/xvda1 and swap to /dev/xvda2). For example:
# <file system> <mount point> <type> <options> <dump> <pass> proc /proc proc defaults 0 0 /dev/xvda1 / ext3 defaults,errors=remount-ro 0 1 /dev/xvda2 none swap sw 0 0
Booting the Guest OS
Now all that remains is to boot the guest operating system. before issuing the command to do so it is important to note that the system may not boot for a number of reasons.
If the system fails to boot be sure to read the Xen Guest Boot Problems section at the end of this chapter.
With the set up and configuration complete we are now ready to start up the guest OS. If the root filesystem image is still mounted be sure to unmount before proceeding using the umount command:
Start the Xen guest domain using the xm create command:
xm create UbuntuXen.cfg -c
The -c flag above instructs Xen to attach a console to the guest system so that we see output as the system boots.
Xen Guest Boot Problems
A number of different problems can occur during the boot process of the Xen guest system. Solutions to a number of Xen problems are available at Linuxtopia.org.
Solutions to common Xen problems are as follows:
- OS fails to boot with a "switchroot: mount failed: No such file or directory error message" error message.
- Guest OS fails to boot with a "Xen Guest OS Fails to Boot with Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)" error message.