From T2B Wiki
Jump to navigation Jump to search


New hypervisors come with iPXE installed instead of gPXE. This is not a problem in itself since iPXE brings a lot of new interesting features compared to gPXE. But the virtio iPXE ROM that's provided by default doesn't behave as it should with VMs that have several NICs : it only tries to boot from the first found NIC and then it stops if the boot failed, instead of trying the other NICs. For us, it's a big problem since many VMs have two NICs : the first one is the public, and the second one is the private, and that's the one that will be used to pxe-boot.


Instead of downgrading to gPXE (the past pathetic workaround), there's a better way that consists in customizing the rom by embedding an iPXE script in it. The generic method to embed scripts is described here, and iPXE scripting is explained here. We needed a script that tries all the NICs, and we have found this cool iPXE menu on GitHubGist (it does a bit more than just trying all the NICs in turn, its default behaviour...).

Here is the detailed recipe of the solution that we applied on our hypervisors :

1. Git clone the iPXE code :

git clone git://

2. Get into the ipxe git dir and download the script in it :

cd ipxe
wget ...

3. Build iPXE :

cd src && make EMBED=../nic-menu.ipxe && cd ..

Note : During our first attempt, we've got an error saying that lzma.h was missing. It was fixed by installing the package xz-devel.

4. Replace the old rom by the new one :

4.1 The new virtio rom with the embedded script is ipxe/src/bin/1af41000.rom

4.2 Copy this file to the hypervisor :

scp ipxe/src/bin/1af41000.rom hypervisor:/usr/share/qemu-kvm/1af41000_new.rom

4.3 Change a symlink so that the new rom is used (on the hypervisor) :

cd /usr/share/qemu-kvm
rm pxe-virtio.rom
ln -s 1af41000_new.rom pxe-virtio.rom

If you want the details of what the new rom will do, here is the code of the embedded script :


set timeout 1000

menu Network boot options for ${uuid}
item --key a default Try to boot (a)ll network adapters in turn
item --gap -- --- Detected network adapters ---
set i:int8 0
ifopen net${i} && item --key ${i} net${i} net(${i}): ${netX/mac} - ${netX/bustype} ${netX/busloc:busdevfn} ${pci/${netX/busloc}.0.2}:${pci/${netX/busloc}.2.2} ${netX/chip} ; ifclose
inc i
iseq ${i} 10 || goto loop
item --gap -- --- Alternatives ---
item --key c config Open (c)onfiguration
item --key r reboot (R)eboot computer
item --key s shell Drop to iPXE (s)hell
item --key x exit  E(x)it and continue BIOS boot order
choose --timeout ${timeout} selected && goto select || goto default
goto menu

isset ${${selected}/mac} && goto nic || goto label

autoboot ${selected} && goto exit ||
echo Booting '${selected}' failed, exiting iPXE...
goto exit

goto ${selected} || 
echo The label '${selected}' could not be found, returning to menu...
sleep 2
goto restart

autoboot && goto exit ||
echo Booting failed, exiting iPXE...
goto exit

goto restart

goto restart

set timeout 0
goto menu


echo Continuing BIOS boot order...
sleep 1