Of course you heard of qemu. Its a hypervisor used by UNetLab and GNS3 to integrate virtual routers like Alcatel-Lucent’s 7750 SR, Junipers vMX and Cisco’s XRv. And it is well-known that those virtual routers come in the form of qemu disk images with an odd qcow2 extension. But how can we alter those disc images if we need, for example, preconfigure and distribute an image with some interfaces configured, or got system name changed or even upload a license file?
I invite you to acquire this useful knowledge under the cut section.
ADD: I wrote another post on how to do this stuff automatically with
When you run your virtual appliance in some lab environment (doesn’t matter if it is Unetlab, GNS3 or some other tool) those applications asks qemu binary to run *.qcow2 image with specific parameters. See what unetlab does when I run an Alcatel-Lucent router:
/opt/qemu/bin/qemu-system-i386 -d 0 -- -device e1000,netdev=net0,mac=50:01:00:02:00:00 -netdev tap,id=net0,ifname=vunl1_2_0,script=no -device e1000,netdev=net1,mac=50:01:00:02:00:01 -netdev tap,id=net1,ifname=vunl1_2_1,script=no -device e1000,netdev=net2,mac=50:01:00:02:00:02 -netdev tap,id=net2,ifname=vunl1_2_2,script=no -device e1000,netdev=net3,mac=50:01:00:02:00:03 -netdev tap,id=net3,ifname=vunl1_2_3,script=no -device e1000,netdev=net4,mac=50:01:00:02:00:04 -netdev tap,id=net4,ifname=vunl1_2_4,script=no -device e1000,netdev=net5,mac=50:01:00:02:00:05 -netdev tap,id=net5,ifname=vunl1_2_5,script=no -smp 4 -m 2048 -name 7750SR2 -uuid 8ec99ad5-dd27-419b-a9b8-8c37feda0496 -hda hda.qcow2 -machine type=pc-1.0,accel=kvm -enable-kvm -serial mon:stdio -nographic -nodefconfig -nodefaults -rtc base=utc -no-shutdown -boot order=c
A sh*tload of parameters fed to qemu. See, at the end we passed along our original image -hda hda.qcow2 , and what happens next? Well, we enjoy our running virtual router, we can configure it the way we love, save configuration and load the router later with the latest saved changes in effect.
Stop here for a moment and give it a thought, how does a virtual router boot up with the latest saved changes? Where do these changes located? Is it a text file with a configuration like we used to have in the days of dynamips and cisco routers? Or maybe by hitting save in CLI we altered the original hda.qcow2 image?
The answer is no, these changes did not save into some cfg file, and we didn’t spoiled original qcow2 image. Qemu saved these changes into additional (or delta) hda.qcow2 image which keeps all the changes we made. This delta image stored in /opt/unetlab/tmp/ for Unetlab and in /root/GNS3/projects/ for GNS3. And these additional images are tiny in terms of size.
So, if all the deltas are kept in a separate disk image how can we change the original hda.qcow2 image to write the changes we want permanently? I will try to add license file to Alcatel image and grab you along with me, lets see where will this journey get us…
Running qcow2 image in a manual mode
We need to manually start qemu image of a desired virtual appliance, and to do so we need:
- locate our qemu binary package
- run qemu with predefined telnet port and qcow2 image
First step is easy, I already mentioned in the listing above that Unetlab stores qemu binary here: /opt/qemu/bin/qemu-system-i386 . If we were using GNS3 then we could make use of which command to get the path to qemu binary:
root@ubuntu-14:~# which qemu-system-i386
Once we know where qemu and our qcow2 image are stored, we could think of what additional parameters we should provide to run our virtual appliance in a manual mode. Though I will save you from that boring stuff, here is a working command line for an Alcatel-Lucent virtual router:
root@ubuntu-14:~# /opt/qemu/bin/qemu-system-i386 -m 2048 -hda /opt/unetlab/addons/qemu/timos12-12.0.R12/hda.qcow2 -serial telnet:0.0.0.0:44444,server,nowait -monitor tcp:127.0.0.1:42379,server,nowait -nographic -enable-kvm
- /opt/qemu/bin/qemu-system-i386 – qemu binary itself
- -m 2048 – amount of memory we grant to the virtual router (2GB)
- -hda /opt/unetlab/addons/qemu/timos12-12.0.R12/hda.qcow2 – path to the qcow2 image
- -serial telnet:0.0.0.0:44444,server,nowait – telnet server configuration. we will connect to this specific port 44444 and unetlab ip address
- -monitor tcp:127.0.0.1:42379,server,nowait – I leave it to you to tell me in comments what this is.
- -nographic – we tell qemu that this image has no graphic output
- -enable-kvm – enable kvm acceleration.
We issue that command and get our router accessible in a minute via telnet <unetlab_ip>:44444 . Voila. From this moment every change you save in that telnet session will be written to the original image (in my example – -hda /opt/unetlab/addons/qemu/timos12-12.0.R12/hda.qcow2).
Stop the qemu process by hitting Ctrl+z and run the same image now from Unetlab/GNS – you should see the changes you made right from the start. Now think of the possibilities this method opens to you:
- provide the license file to the image so you dont need to copy/paste it every time you boot your appliance
- preconfigure an image with a hostname, interfaces and so on
- and I believe you can find some other benefits =)
Images with VNC access
With images that have only vnc access you can use this command:
/opt/qemu/bin/qemu-system-x86_64 -smp 4 -m 4096 -name Spirent -vnc :10 \
-device virtio-net-pci,netdev=net0,mac=50:01:00:04:00:00 -netdev tap,id=net0,ifname=vunl1_4_0,script=no \
-hda /opt/unetlab/addons/qemu/svtc-4.54/hda.qcow2 -machine type=pc-1.0,accel=kvm \
-vga std -usbdevice tablet -boot order=c
The key factor here is -vnc :10 which allows you to point your vnc viewer to a host_address and port number calculated as 5900+<number_from_-vnc_key> . In the abovementioned example vnc viewer will connect to the port 5900+10=5910 .
It is not necessary to add network devices if you dont need them.
Another way to achieve the same effect
Always good to have a Plan B. If you are shy of a CLI and rather GUI fellow, then you can try this method.
- find where unetlab stores delta image of a desired appliance. You can do this by issuing
tail /opt/unetlab/data/Logs/unl_wrapper.txt | grep CWD right after the node started. This will give you the list of last directories used by unetlab
1234root@ubuntu-14:/# tail /opt/unetlab/data/Logs/unl_wrapper.txt | grep CWDINFO: CWD is /opt/unetlab/tmp/1/d3089865-5918-4773-b9b3-ec356919b645/4INFO: CWD is /opt/unetlab/tmp/1/17c5a8bb-8513-451a-84f9-662fa385c0b8/1INFO: CWD is /opt/unetlab/tmp/1/17c5a8bb-8513-451a-84f9-662fa385c0b8/1
- Stop the running node and go to the last directory. You will find there qcow2 delta image.
- Replace this delta image with an original hda.qcow2 image from /opt/unetlab/addons/qemu/
- Start the node once again
- Make any changes to this node from a CLI or VNC
- Stop the node
- Now grab the qcow2 image (it should now be not delta, but the full image size) from the same directory /opt/unetlab/tmp/ and copy to /opt/unetlab/addons/qemu/ back again.
- Now you will have preconfigured image in your /opt/unetlab/addons/qemu/ used for any new project.