I run a number of VM’s under KVM. Windows VM’s, RedHat VM’s, SLES and Ubuntu VM’s. Recently, we attempted to provision a VM using LANDesk. We ran into an issue where KVM was not assigning a BIOS serial number. LANDesk uses the BIOS serial number to identify the client to the LANDesk server.
I worked with RedHat on this, and they came back with a simple answer. qemu-kvm has the ability to specify a serial number, but RedHat’s utilities, which are used to do things like… start vm’s, do no thave any method which to call this option. The option is simple:
-smbios type=1,serial=c88f3f87
So the functionality is there, but theres no way to use it, and use the tools which RedHat supplies to interact with VM’s.
So, taking this piece of information, I set out figuring out how to add this command line option to the command line that virsh generates when you start a VM. If you have a look at one of the confiruation files for VM’s, you’ll see that theyre XML, and virsh simply takes these XML attributes and builds a command line. The issue is that virsh does not have any option for the serial. It does however have a UUID, and an attribute which lets you specify what executable to run, to start the vm. I thought maybe the UUID would be a good unique identifier for a VM. So i wrote the following wrapper:
#!/usr/bin/perl
my $qemukvm = "/usr/bin/qemu-kvm";
my $args;
my $serial;
foreach (@ARGV) {
$args .= " $_";
if ($_ =~ m/[\w]{8}(-[\w]{4}){3}-[\w]{12}/) {
my @tmp = split(/-/, $_);
$serial = $tmp[0];
}
}
if ($serial) {
exec ($qemukvm . $args . " -smbios type=1,serial=" . $serial);
} else {
exec ($qemukvm . $args);
}
And then set the "emulator" attribute in the VM’s config file to my wrapper. Then i undefined my vm, and redefined it. After that, I started up my vm, and what do you know, I’ve got a bios serial. W00t!