Category: xenserver

Booting Linux ISOs with Memdisk and iPXE

There are a number of distributions out there that provide proper support for booting the distribution over the network. A lot of the more popular distributions usually provide a installer kernels that can be easily downloaded for use. You point at the vmlinuz and the initrd and can them immediately proceed with the install streaming down packages as needed. These distributions make it great for tools like netboot.xyz to install using iPXE.

There are some distributions out there that don’t have this functionality and typically only produce the ISO without any repositories that provide installer kernels or the rootfs.

In those cases, occasionally you can use memdisk and iPXE to boot those ISOs but they don’t always work. In doing some research, I ran across one of the major issues as to why.

Syslinux – Memdisk

The following was taken from syslinux – memdisk.

The majority of Linux based CD images will also fail to work with MEMDISK ISO emulation. Linux distributions require kernel and initrd files to be specified, as soon as these files are loaded the protected mode kernel driver(s) take control and the virtual CD will no longer be accessible. If any other files are required from the CD/DVD they will be missing, resulting in boot error(s). Linux distributions that only require kernel and initrd files function fully via ISO emulation, as no other data needs accessing from the virtual CD/DVD drive once they have been loaded. The boot loader has read all necessary files to memory by using INT 13h, before booting the kernel.

There is also another solution, which requires the phram and mtdblock kernel module and memdiskfind utility of the Syslinux package (utils/memdiskfind). memdiskfind will detect the MEMDISK mapped image and will print the start and length of the found MEMDISK mapped image in a format phram understands:

modprobe phram phram=memdisk,$(memdiskfind)
modprobe mtdblock

This will create a /dev/mtdblock0 device, which should be the .ISO image, and should be mountable.

If your image is bigger than 128MiB and you have a 32-bit OS, then you have to increase the maximum memory usage of vmalloc, by adding:

vmalloc=<at_least_size_of_your_image_in_mib>Mi</at_least_size_of_your_image_in_mib>

Example: vmalloc=256Mi to your kernel parameters.

memdiskfind can be compiled with the klibc instead of with the glibc C library to get a much smaller binary for use in the initramfs:

cd ./syslinux-4.04/utils/
make spotless
make CC=klcc memdiskfind

Implementations of phram and mtdblock

ArchLinux has implemented the above concept here and here.

Debian Live used it here.

It’s also been implemented in Clonezilla and GParted.

Antergos Linux based on Arch Linux works great with memdisk using the phram module.

Conclusion

I think it would be great for more distributions to attempt to implement something like this so that iPXE tools can be used to load the ISOs instead of actually having to burn or look for the location of the latest ISO every time.

Some of the distributions I’d love to see network support or better memdisk support are:

Linux Mint
Manjaro
Elementary
Solus Project

There are also many other new distributions being released all the time. I typically use DistroWatch to determine the most popular distributions to attempt to add to netboot.xyz. I’d love to get a lot of these added to make it really easy to install anything on the fly.

I’d also love to see some of the hypervisors out there crack open the ISOs, pull them outside of their paywalls, and host the bits on their servers so that it’s much easier to immediately boot an install to test something out without having to jump through many hoops. I have working installs for VMware ESX and Citrix XenServer but I’d need to have them host the bits or allow permission to do so for a public facing installer menu.

Creating Custom Security Updates In XenServer

Some of you may have heard about the latest vulnerability affecting QEMU codenamed VENOM.

Sometimes security vulnerabilities are released faster than the vendor can qualify a valid hot fix. In this post, I’ll walk you through how to generate your own XenServer hotfix in order to rapidly patch the issue.

How XenServer Patching Works

The sources for XenServer are provided each release, usually in a binpkg.iso. Here’s are some links for the latest version of XenServer 6.5:

XenServer Primary Download Page

XenServer 6.5 Hypervisor

XenServer 6.5 Sources

XenServer 6.5 DDK

Creating your Own Custom Patch

The first thing you’ll need to do is to download the DDK for the affected version. The DDKs are released for each version of XenServer and also released anytime the kernel revs within the major release. The DDK provides the same environment that the SRPMs were created under, so it makes it really easy to rebuild the RPMs. It comes packaged as an appliance, so you’ll want to import that appliance into a build of XenServer and boot it up

Determine What Needs to be Patched

If QEMU needs patching, more than likely it’s the qemu-dm binary (/usr/lib64/xen/bin/qemu-dm). To determine which packages sources you need to retrieve, run a rpm query on that binary:

[root@hostname /]# rpm -qf /usr/lib64/xen/bin/qemu-dm
xen-device-model-1.9.0-199.7656

Now we know that we need to make the changes to the xen-device-model.

If we needed to patch Xen:

[root@hostname boot]# rpm -qf xen-4.4.1-xs100346.gz
xen-hypervisor-4.4.1-1.9.0.462.28802

And so on. Once you know what the package is, then we can go about finding the source rpm.

Obtaining the Source RPM

Assuming the version of XenServer you’re using is up to date on patches, you’ll want to grab either the latest deployed patch to your environment, or grab the latest patch that contained the version you want to update. Each xsupdate contains updated RPMs, so you might need to run through all of the latest patches to find the right one.

Anytime a hotfix is released, the hotfix will include the sources that were changed as part of the update release. For example, within the zip of a hotfixed release, 6.5SP1 in this case, you’ll have two files:

  • the xsupdate that is used to apply to the server, XS65ESP1.xsupdate
  • the sources package, XS65ESP1-src-pkgs.tar.bz2

The sources package includes all of the SRPMs that were used to create the latest xsupdate.

Extracting the Sources

We’ll want to take the latest available sources, grab the Source RPM, and install it to the DDK server. We’ll use the one out of this hotfix to simulate updating QEMU for VENOM:

wget http://downloadns.citrix.com.edgesuite.net/10325/XS62ESP1021.zip
unzip XS62ESP1021.zip
bunzip2 XS62ESP1021-src-pkgs.tar.bz2
tar xvf XS62ESP1021-src-pkgs.tar 

Create .rpmmacros so that the sources extract to a known location:

# ~/.rpmmacros
%packager %(echo "$USER")
%_topdir %(echo "$HOME")/rpmbuild

Make directories:

mkdir ~/rpmbuild ~/rpmbuild/SOURCES ~/rpmbuild/RPMS ~/rpmbuild/BUILD ~/rpmbuild/SRPMS ~/rpmbuild/SPECS 

Install the sources:

rpm -i xen-device-model-1.8.0-105.7582.i686.src.rpm

Copy the patch file to ~/rpmbuild/SOURCES/:

cp xsa133-qemut.patch ~/rpmbuild/SOURCES/

Update the SPEC file to include the new patch and bump the release from 105.7582 to 105.7582.1custom. We do this so we can prevent conflicts from future versions but still differentiate which version we’re on:

[root@localhost]# diff -u xen-device-model.spec xen-device-model.spec.mod
--- xen-device-model.spec   2015-03-17 12:02:05.000000000 -0400
+++ xen-device-model.spec.mod   2015-05-12 19:35:53.000000000 -0400
@@ -1,11 +1,12 @@ 
 Summary: qemu-dm device model
 Name: xen-device-model
 Version: 1.8.0
-Release: 105.7582
+Release: 105.7582.1custom
 License: GPL
 Group: System/Hypervisor 
 Source0: xen-device-model-%{version}.tar.bz2
 Patch0: xen-device-model-development.patch
+Patch1: xsa133-qemut.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
 BuildRequires: SDL-devel, zlib-devel, xen-devel, ncurses-devel, pciutils-devel
@@ -14,6 +15,7 @@
 %prep
 %setup -q
 %patch0 -p1
+%patch1 -p1
 %build
 ./xen-setup --disable-opengl --disable-vnc-tls --disable-blobs
@@ -37,6 +39,9 @@
 %dir /var/xen/qemu
 %changelog
+* Tue Mar 17 2015 MyPatch <www.mypatch.com> [1.8.0 105.7582.1custom]
+- xsa133-qemu
+
 * Tue Mar 17 2015 Citrix Systems, Inc. <www.citrix.com> [1.8.0 105.7582]
 - Build ioemu.

Regenerate the RPM from the sources, and watch for errors.

rpmbuild -ba xen-device-model.spec

Make sure your patches apply cleanly and if they do, after the compile has completed, the fresh RPMs will be present in ~/RPMS:

ls ~/rpmbuild/RPMS/i386/xen-device-model* 
xen-device-model-1.8.0-105.7582.1custom.i386
xen-device-model-debuginfo-1.8.0-105.7582.1custom.i386.rpm 

Deploying the RPMs to XenServer

You’ll want to take the new RPM and deploy it using:

rpm -Uvh xen-device-model-1.8.0-105.7582.1custom.i386 

If you need to revert to the original version, you can run

rpm --force -Uvh xen-device-model-1.8.0-105.7582.i386

Depending on the type of patching you’re doing, you’ll need to determine your reload strategy. If it’s Xen or a kernel for instance, you’ll know you’ll have to reboot. If it QEMU, you know that you’ll have to detach the disks and reload them so that they get the newly patched process.

Developing boot.rackspace.com

When I started down the path of building osimag.es, I started realizing that it could be really useful for others, especially in a cloud environment. Since my main focus has been working on Rackspace Cloud Servers for a number of years, I decided to see how feasible it would be to put together a menu driven installer for any Operating System working in a Infrastructure as a Service type of environment. I figured there’s probably a number of power users who might not want to start out with the default images provided, but possibly would want the opportunity to create their own custom image from scratch.

Will it even work?

I started testing out the XenServer boot from ISO code in Openstack to see if someone might have already gotten that working for another use case. To my delight, the boot from ISO code worked out pretty well. I was able to upload the iPXE 1MB iso into Glance and boot from that image type.

The next problem to solve was the fact that Rackspace Cloud Servers assigns static IP addresses and does not currently run a DHCP service to assign out the networking. iPXE usually works best when DHCP is used as the network stack gets set up automatically. Because of this, a customer launching a cloud server could boot the iPXE image but would have to specify the networking manually of the instance in order to chain load boot.rackspace.com.

We started thinking about how to automate this, and with the help of a few developers came up with a solution. The solution retrieves an iPXE image on boot, brings it down to the hypervisor, extracts the iPXE kernel, and regenerates the ISO with a new iPXE startup script that contains the networking information of the instance. Then when the instance is started, iPXE is able to get on the network and load up boot.rackspace.com automatically. Once iPXE has those values, they can then be passed to kernel command line for distributions that support network options. This allows for the user to not have to worry about any networking input during installation.

Hosting the Menu

Because boot.rackspace.com is just a bunch of iPXE scripts, they are hosted on Cloud Files in a container. The domain is a CNAME to the containers URL and then hosted on the Akamai CDN. The source is deployed from Github to the Cloud Files container when new commits are checked in via a Jenkins job. This makes it very lightweight and very scalable to run. The next thing I’m probably going to look at is seeing if I can remove the Jenkins server completely and just run the deploy out of Github. I was also able to enable CDN logs within the container and I’m using a service called Qloudstat to parse those logs and provide metrics on the usage of the scripts.

Delete those old ISOs
Having a small 1MB image is really nice for those times when you need to deploy an OS onto a remote server, or just need to install something into Virtual Box or VMware. There’s really no point in storing tons of ISOs on your machine if you can just stream the packages you need.

What’s Next?
I have a few ideas about some new features that I’d like to add. I’d like to add a menu of experimental items and I’d also like to have the ability to generate a new version of the menu from a pull request so that new changes can be quickly validated before being merged into the main code base. If you haven’t tried out boot.rackspace.com yet, I encourage you to check it out. You can get a quick overview from my Rackspace blog post.

Citrix XenServer 6.1 Automated Installer for Openstack

I’ve put my Openstack XenServer 6.1 (Tampa) installer onto Github here: https://github.com/amesserl/xs-tampa-openstack.

It has all of the modifications to get it running with the XenAPI Openstack Nova code and also includes the latest hotfixes. All you need to do is snag the latest CD and drop it in. I’ll continue to publish repos for new versions as they come out (Clearwater should be released soon). You can also boot it from osimag.es as well.

Deploying XenServer with Puppet Razor

If you’ve never heard of Puppet Razor, it’s a useful tool for provisioning bare metal servers. The servers netboot a microkernel that allows the server to be inventoried and remotely controlled by the Razor server so that the servers can be provisioned automatically. You can follow the instructions on how to install it here: https://github.com/puppetlabs/Razor/wiki/Installation

If you’re looking to install XenServer via Razor here’s a quick guide on doing so. After setting up your Razor server, you’ll want to snag the latest Citrix XenServer ISO. They have a free download that provides full functionality.

First we’ll add the iso to the image library:

[root@razor ~]# razor image add -t xenserver -p /root/XenServer-6.1-install-cd.iso -n xenserver_tampa -v 6.1.0
 
Attempting to add, please wait…
 
New image added successfully
 
Added Image:
UUID => 1xE9oYTH0Zc9FqgPBItVuO
Type => XenServer Hypervisor Install
ISO Filename => XenServer-6.1-install-cd.iso
Path => /opt/razor/image/xenserver/1xE9oYTH0Zc9FqgPBItVuO
Status => Valid
Version => 6.1.0

Then we’ll create a model that will hold all of the generic settings we’ll want to set for each node. It also lets us define the range of IPs that we want to assign to all servers that are being provisioned.

[root@razor ~]# razor model add -t xenserver_tampa -l xenserver_tampa_example -i 1xE9oYTH0Zc9FqgPBItVuO
--- Building Model (xenserver_tampa):
 
Please enter IP Subnet (example: 255.255.255.0)
default: 255.255.255.0
(QUIT to cancel)
 > 255.255.255.0
Please enter NTP server for node (example: ntp.razor.example.local)
(QUIT to cancel)
 > pool.ntp.org
Please enter Gateway for node (example: 192.168.1.1)
(QUIT to cancel)
 > 192.168.1.1.
Value (192.168.1.1.) is invalid
Please enter Gateway for node (example: 192.168.1.1)
(QUIT to cancel)
 > 192.168.1.1
Please enter IP Network for hosts (example: 192.168.10)
(QUIT to cancel)
 > 12.168.1
Please enter root password (> 8 characters) (example: P@ssword!)
default: test1234
(QUIT to cancel)
 > test1234
Please enter Starting IP address (1-254) (example: 1)
(QUIT to cancel)
 > 5
Please enter Nameserver for node (example: 192.168.10.10)
(QUIT to cancel)
 > 4.4.4.4
Please enter Ending IP address (2-255) (example: 50)
(QUIT to cancel)
 > 20
Please enter Prefix for naming node (example: xs-node)
(QUIT to cancel)
 > xs-node
Model created
 Label =>  xenserver_tampa_example
 Template =>  xenserver_hypervisor
 Description =>  Citrix XenServer 6.1 (tampa) Deployment
 UUID =>  3BYDqVasC4g0GFikNJYCdA
 Image UUID =>  1xE9oYTH0Zc9FqgPBItVuO

Once the model has been created, now would be a good time to boot up your node into the microkernel and have it discover the hardware if you haven’t already. If you type:

[root@razor ~]# razor node
Discovered Nodes
         UUID           Last Checkin  Status                 Tags
6z2AodeElhhYdd3yR7juE0  33 sec        A       [nics_3,HP,cpus_4,memsize_32GiB]

you can see the servers that have booted up and reported into Razor. If you want to further look at the attributes of the server, you can run:

razor node get 6z2AodeElhhYdd3yR7juE0 -f attrib

which will show you all of the facter attributes of that node. Now you’ll want to add that node to a policy so that we can start provisioning the node. Using the tags above, you can utilize those to apply the policy to nodes of that type.

[root@razor ~]# razor policy add --template xenserver_hypervisor --label tampa --model-uuid 3BYDqVasC4g0GFikNJYCdA --tags nics_3,HP,cpus_4,memsize_32GiB --enabled true
Policy created
 UUID =>  5luw9q3cPYhruPgCILRFOe
 Line Number =>  3
 Label =>  tampa
 Enabled =>  true
 Template =>  xenserver_hypervisor
 Description =>  Policy for deploying a XenServer hypervisor.
 Tags =>  [nics_3, HP, cpus_4, memsize_32GiB]
 Model Label =>  xenserver_tampa_example
 Broker Target =>  none
 Currently Bound =>  0
 Maximum Bound =>  0
 Bound Counter =>  0

Once you’ve added the policy and enabled it, any server that’s reported in should pick up the new policy and start the provisioning process. Razor will tell the microkernel to reboot and start provisioning on the next netboot. If you need to make additional changes to the installation, you can modify this file for the first phase of the install:

/opt/razor/lib/project_razor/model/xenserver/tampa/postinstall.erb

and this file for any changes you want to occur on the second phase of the installation, or firstboot:

/opt/razor/lib/project_razor/model/xenserver/tampa/os_boot.erb

Note: This applies to Citrix XenServer 6.1 (Tampa)

XenServer Auto Patcher

I put together a little script that might come in handy to get Citrix XenServer fully up to date after doing a factory install. You can find it here:

https://github.com/amesserl/xs_patcher

It will detect the version of XenServer you are running and install all of the latest Citrix XenServer hotfixes that are available in sequential order. It will also detect any previous patches and install anything that might not be present. If you don not have the hotfixes on the machine, it will retrieve them for you. After running the script, all you will need to do is reboot so it will pick up the latest kernel.

To install it automatically during an install, you will need to put the patcher script on the disk with the cache prepropulated with all of the patches to avoid the script retrieving them each time. It’s usually best to put this in place during the post install. You won’t want to run it during the post install because XAPI isn’t up and running at that point which the hotfixes require. You’ll want to install a script into /etc/firstboot.d with a starting number higher than all the other processes that run during firstboot. Once the initial firstboot has run which sets up XenServer and all of it’s storage repositories, you can then kick off the xs_patcher.sh script which will install all of the needed hotfixes. I usually then have one more call to reboot occur after that.

I’ll try and maintain the script going forward as new hotfixes are released by Citrix. Currently it supports Boston, Sanibel, and Tampa. I’ll probably go back and grab earlier versions as well in the future as I have time.

The Dreaded Flipping of NICs

I recently had a problem with NICs flipping around after removing all traces of MAC address rules from the server. I did this because I wanted the flexibility to be able to swap machines around at any point in time and not have to worry about tracking the MAC addresses on all of the devices. The gear was identical in specifications and after doing some research, I ran across a solution that has worked really well so far. It involves creating udev rules that don’t contain any MAC addresses but that instead check the vendor id and bus location of the device. By knowing these items, you can guarantee you’ll always have the correct ethernet device assigned to the correct physical network and you can make the rules a lot more generic in nature. As an example, first you’ll want to identify the devices (example is from an HP ProLiant DL385):

1
2
3
4
lspci | grep -i eth
04:00.0 Ethernet controller: Broadcom Corporation NetXtreme II BCM5708 Gigabit Ethernet (rev 12)
42:00.0 Ethernet controller: Broadcom Corporation
NetXtreme II BCM5708 Gigabit Ethernet (rev 12)

We’ll take the first line for this example and break it down. The first group of numbers is the bus number (04), device number (00), and function
number (0). From here we should be able to generate our udev rules file. Create /etc/udev/rules.d/70-persistent-net.rules and enter in the following or whatever your setup looks like:

1
2
SUBSYSTEM=="net",ACTION=="add",BUS=="pci",KERNEL=="eth*",ID=="0000:04:00.0",NAME="eth0"
SUBSYSTEM=="net",ACTION=="add",BUS=="pci",KERNEL=="eth*",ID=="0000:42:00.0",NAME="eth1"

Once that’s in place, you should be able to reboot and not have to worry about the NICs flipping around. If you’re curious, you can also view more device information by looking at /sys:

1
ls -la /sys/bus/pci/devices/0000:04:00.0

I’ve had success with this in Citrix XenServer (dom0 is based on CentOS) and Debian.