Generated by spec.rb at: Thu May 13 01:26:51 +0200 2010

How to boot via pygrub in Debian lenny Xen domUs (created using xen-tools)

Table of contents

Intro

This document explains how to setup xen-tools to generate Xen domU images for Debian lenny that will boot with pygrub.

I assume you have your dom0 running on lenny and that you have xen-tools (and other essentials) installed. If you don't, follow Dom0 part of this guide and then come back.

Step1: pygrub location fix

You should have pygrub by now, as part of xen-utils-3.2-1 package. Unfortunately it's in wrong place. This:

ln -s /usr/lib/xen-3.2-1/bin/pygrub /usr/bin/

will fix that.

Step2: xen-tools configuration

In order to boot with pygrub, you gotta have specific setup.

Your /etc/xen-tools/xen-tools.conf should look like this:

lvm = VOLUME_GROUP
install-method = debootstrap
size   = 100Gb    # Disk image size.
memory = 2Gb      # Memory size
swap   = 4Gb      # Swap size
fs     = ext3     # use the EXT3 filesystem for the disk image.
dist   = lenny    # Default distribution to install.
image  = sparse   # Specify sparse vs. full disk images.
gateway = GATEWAY_IP
netmask = 255.255.255.0
broadcast = BROADCAST_IP
arch=amd64
mirror = http://ftp.cz.debian.org/debian/
ext3_options   = noatime,nodiratime,errors=remount-ro
ext2_options   = noatime,nodiratime,errors=remount-ro
xfs_options    = defaults
reiser_options = defaults
serial_device = hvc0
disk_device = xvda

Absolutely crucial is the fact "kernel" and "initrd" are undefined.

In addition to that you have to have following script named /etc/xen-tools/role.d/pygrub:

#!/bin/sh
#
#  Configure the new image to be suitable for booting via pygrub
#
# Wejn
# --
# http://wejn.org/
#

prefix=$1


#
#  Source our common functions - this will let us install a Debian package.
#
if [ -e /usr/lib/xen-tools/common.sh ]; then
    . /usr/lib/xen-tools/common.sh
else
    echo "Installation problem"
fi


#
#  Update APT lists.
#
chroot ${prefix} /usr/bin/apt-get update


#
#  Install the packages
#
set -e
installDebianPackage ${prefix} perl
installDebianPackage ${prefix} libklibc
installDebianPackage ${prefix} klibc-utils
installDebianPackage ${prefix} initramfs-tools
installDebianPackage ${prefix} linux-image-2.6-xen-amd64

# Force initrd if none exists
echo ${prefix}/boot/initrd* | grep -q 2\\.6
if [ $? -ne 0 ]; then
        chroot ${prefix} update-initramfs -c -k `ls -1 ${prefix}/lib/modules/ | head -n 1`
fi

# Generate grub menu.lst
LNZ=`basename \`ls -1 ${prefix}/boot/vmlinuz*|tail -n 1\``
RD=`basename \`ls -1 ${prefix}/boot/initrd*|tail -n 1\``
mkdir -p ${prefix}/boot/grub
cat - <<-EOF > ${prefix}/boot/grub/menu.lst
default         0
timeout         5

title           Debian
root            (hd0,0)
kernel          /boot/$LNZ root=/dev/xvda2 ro 
initrd          /boot/$RD
EOF

with executable permissions.

You can install it via:

curl -s http://wejn.org/stuff/pygrub-role > /etc/xen-tools/role.d/pygrub
chmod a+x /etc/xen-tools/role.d/pygrub

or just download and install it yourself.

This role script will setup the pygrub boot environment within newly created guest.

Step3: new guest creation

To create pygrub-bootable guest, just create new image using pygrub and udev roles:

xen-create-image --hostname=HOSTNAME --ip=IP_ADDRESS --role=udev,pygrub

After guest creation finishes, you have to do one small change to the resulting config -- the root block device has to be listed first. By default xen-tools set swap first which breaks pygrub.

To automate you can use following script:

sed -i '/phy:.*swap/{h;d};/phy:.*root/G' /etc/xen/CONFIGNAME.cfg

Step4: launch

Now do a:

xm create hostname -c

and it should boot up just fine; using the kernel within guest's partition.

Conclusion

It wasn't that hard, was it?

Update: How to do the same on Ubuntu 10.04

Adarsh Carter sent me following how-to explaining steps to achieve the same result (and more) on Ubuntu 10.04.