Paravirtualization in Xen: no loader anywhere

    Xen mascotPV-GRUB (not to be confused with obviously crutch pygrub ) is a boot loader for Xen paravirtual machines based on GRUB 0.9x, which allows loading the OS kernel directly from the DomU (guest) environment, which adds significant independence from the host system to the process of starting the guest system. One of the largest implementations is Amazon EC2 cloud hosting, which also uses the Xen hypervisor and provides customers with the ability to use PV-GRUB to download any customized kernels ( Use your own kernel with Amazon EC2 ) for paravirtual systems.

    Everything on this issue would be extremely positive if it weren’t for the usual problem for free software: the development of this GRUB branch has been completely stopped in favor of GRUB2 for several years, and the Xen development community, apparently, will be based on the current version of GRUB in the coming years Replacing the PV bootloader is not ready. PV-GRUB itself, although it is, in general, part of the official Xen distribution, is now already excluded from at least the corresponding packages in the Debian and Ubuntu repositories, while users who are accustomed to convenience require (Debian bug # 588839: Include pv-grub to securely boot guest kernels ) and require (Ubuntu bug # 798583: xen-utils-4.1 does not have pvgrub) ... Although for me personally the motivation of the Xen maintainers of packages referring to some obscure problems with dependencies is not very clear to me, while packages with GRUB 0.97 are still accessible and functional, and there are no complaints about the existing functionality.

    Here I will try to describe, perhaps, the most acceptable solution to the urgent problem at the moment - to independently build PV-GRUB and the necessary configuration of DomU to use it , since no supernatural efforts are required for this.

    For those interested in understanding the ins and outs of the implementation for the Xen paravirtual environment of an almost traditional bootloader, it would be appropriate to immediately throw some materials about the stub domains functionality that appeared in Xen 3.3. A brief introduction is on the Xen.org blog ( Xen 3.3 Feature: Stub Domains , Xen 3.3 Feature: HVM Device Model Domain ). The rest is to browse through the presentation ( PDF ) and listen to the report “Stub domains: A step towards Dom0 disaggregation” presented at Xen Summit North America.

    To build the bootloader, you need the Xen source code. It is best to take the version that is already used on your host system. Since I'm using Debian GNU / Linux "Wheezy", for me it will be Xen 4.1.4. You can build on any system with a minimum development kit (gcc + binutils + make). From the official site of Xen ( Xen 4.1 series , Xen 4.2 series ) download and unpack tarball with sources:
    $ wget http://bits.xensource.com/oss-xen/release/4.1.4/xen-4.1.4.tar.gz
    $ tar xzf xen-4.1.4.tar.gz

    Go to the directory stubdom. Run the bootloader build:
    $ make grub

    If you need to build a bootloader for an architecture that is different from the system architecture, you can set it using the XEN_TARGET_ARCH variable:
    $ XEN_TARGET_ARCH = x86_32 make grub

    The process is not complete without some pitfalls. The assembly of this component stops on banal errors of inclusion of some header files on nonexistent paths.
    In file included from xc_core.c: 69: 0:
    xc_core.h: 26: 35: fatal error: xen / libelf / elfstructs.h: There is no such file or directory
    compilation terminated.

    We are looking for the culprit:
    $ find .. -type f -name xc_core.h
    ../tools/libxc/xc_core.h

    Replace the string in it
    #include"xen/libelf/elfstructs.h"

    on
    #include"xen/elfstructs.h"

    When re-executing make grub, several more similar ones should follow:
    xc_dom.h: 17:31: fatal error: xen / libelf / libelf.h: There is no such file or directory
    xc_hvm_build.c: 34: 31: fatal error: xen / libelf / libelf.h: There is no such file or directory
    ../../xen/common/libelf/libelf-private.h:70:31: fatal error: xen / libelf / libelf.h: There is no such file or directory

    Everything is decided by replacement
    #include<xen/libelf/libelf.h>

    on
    #include<xen/libelf.h>

    The assembly should now complete successfully. The last lines of output that you are likely to see will be:
    gzip -f -9 -c /home/user/xen-4.1.4/stubdom/mini-os-x86_64-grub/mini-os> /home/user/xen-4.1.4/stubdom/mini-os-x86_64 -grub / mini-os.gz
    make [1]: Leaving directory `/home/user/xen-4.1.4/extras/mini-os'

    The resulting compressed file mini-os-x86_64-grub/mini-os.gzcan be renamed to a more understandable one pv-grub-x86_64.gz(or pv-grub-x86_32.gzif it was built under x86_32), and then put in the directory of /usr/lib/xen-4.1/bootyour Dom0, where it should be located (valid for Debian with the installed xen-utils-4.1 package , it is also located there hvmloader).

    Before directly switching to using the bootloader, you should do some preparatory procedures for your guest system.
    It is worth noting that the old GRUB is not directly friendly with modern file systems like Ext4, not to mention the less common. Therefore, you should first make sure that the section where you will place the kernel image, initrd, and GRUB configuration files (by default, everything is stored in the directory/boot), will be available to the bootloader for reading. In the process of completing the quest described here, I already stepped on a rake: despite the theoretically existing backward compatibility of Ext4 with Ext2, there are many different extensions (features) that completely exclude this compatibility, especially if you did not think about this when creating your Ext4 section. Before creating a separate section /bootfor me, there was no special need. Now, the solution may be just transferring the aforementioned starting trinity to the micro-partition (I think a double volume from the current content /bootwill be quite enough), formatted in Ext2. Remember to also edit /etc/fstabyour DomU by adding there/bootsection and changing the names of the block devices of the remaining sections, if necessary. The same applies to the disk configuration of the virtual machine itself.
    You can easily check how an existing partition is suitable for mounting in backward compatibility mode with Ext2 through mount -t ext2.

    On the virtual machine itself, you must install the old version of GRUB (the grub-legacy package in Debian or the most castrated grub-legacy-ec2 in Ubuntu). Inquiries about installing GRUB in the boot sector of any partition should be answered negatively - this does not make sense.
    After installation, make sure that the directory for storing the GRUB configuration exists and is writable. Launchupdate-grub It will create a bootloader menu file by adding the kernels installed in the system to the boot list.
    $ mkdir / boot / grub
    $ update-grub
    Searching for GRUB installation directory ... found: / boot / grub
    Probing devices to guess BIOS drives. This may take a long time.
    Searching for default file ... Generating / boot / grub / default file and setting the default boot entry to 0
    Searching for GRUB installation directory ... found: / boot / grub
    Testing for an existing GRUB menu.lst file ...
    Generating /boot/grub/menu.lst
    Searching for splash image ... none found, skipping ...
    Found kernel: /vmlinuz-3.2.0-4-amd64
    Updating /boot/grub/menu.lst ... done

    Let's look at the created /boot/grub/menu.lst:
    title Debian GNU / Linux, kernel 3.2.0-4-amd64
    root (/ dev / xvda1)
    kernel /vmlinuz-3.2.0-4-amd64 root = UUID = f5731cf7-420a-4094-acf7-bec5976a0b62 ro
    initrd /initrd.img-3.2.0-4-amd64
    title Debian GNU / Linux, kernel 3.2.0-4-amd64 (single-user mode)
    root (/ dev / xvda1)
    kernel /vmlinuz-3.2.0-4-amd64 root = UUID = f5731cf7-420a-4094-acf7-bec5976a0b62 ro single
    initrd /initrd.img-3.2.0-4-amd64

    It is striking here that the configurator incorrectly filled in the option root, substituting the disk name and partition for the file name of the block device instead of the understandable GRUB . When you select these menu items, GRUB will simply swear at the wrong option value.
    To fix the situation, we modify the generated one a bit by /boot/grub/menu.lstadding an option grootwith an explicit indication of the serial number of the boot "disk", which is subsequently mounted as /boot(since there are no full-fledged disks with a partition table in a paravirtual environment):
    groot = (hd0)

    You can immediately reduce the timeout before starting the download so as not to waste time in vain:
    ## timeout sec
    # Set a timeout, in SEC seconds, before automatically booting the default entry
    # (normally the first entry defined).
    timeout 1

    In order for the value to be grootcorrectly perceived by the configuration generator update-grub, we will additionally create a file /boot/grub/device.mapwhere we will enter a single line regarding the mentioned boot partition:
    (hd0) / dev / xvda1

    Now it update-grubshould generate the correct menu file, the operability of which will also not be affected if you want to update the version of the main kernel or add additional ones.
    title Debian GNU / Linux, kernel 3.2.0-4-amd64
    root (hd0)
    kernel /vmlinuz-3.2.0-4-amd64 root = UUID = f5731cf7-420a-4094-acf7-bec5976a0b62 ro
    initrd /initrd.img-3.2.0-4-amd64
    title Debian GNU / Linux, kernel 3.2.0-4-amd64 (single-user mode)
    root (hd0)
    kernel /vmlinuz-3.2.0-4-amd64 root = UUID = f5731cf7-420a-4094-acf7-bec5976a0b62 ro single
    initrd /initrd.img-3.2.0-4-amd64

    If it is necessary to pass to the kernel any additional parameters that were previously set directly in the virtual machine configuration via an option extra, then this can be done by modification koptin the same /boot/grub/menu.lst.

    As a final chord, it remains to reconfigure the DomU startup process: the bootloader file name must be specified in the option kernel. If the bootloader image is in the default directory (in the same place as hvmloader), then the full path is optional. The option extraspecifies the section and path to the GRUB menu file.
    kernel = 'pv-grub-x86_64.gz'
    extra = '(hd0) /grub/menu.lst'

    It is ramdiskalso rootnecessary to get rid of the previous options .
    To make sure that the new configuration is fully operational, the first start of DomU should be done in the mode of automatic connection to the console ( xm start -c). If everything is done correctly, then you will see the GRUB menu and the subsequent kernel boot process with mounting the root partition.

    Note : The most likely reason for the lack of PV-GRUB in Xen packages of various distributions is announced on the xen-users mailing list .
    The Gentoo Xen ebuilds do not support building stubdom because it downloads external packages during the built process which is not acceptable / compatible with the portage ebuild system, perhaps it is not included in the Debian package for similar reasons.

    Also popular now: