Running QEMU with port redirection through libvirt

This post is more than 12 years old.

Like many developers these days, I use a bunch of different virtual machine images to give me access to multiple development and test environments without having a room full of computers. My VM of choice is QEMU KVM, the kernel-based virtual machine bundled with Fedora. I’ve always used simple shell scripts to start my VMs, which has allowed me great flexibility, but yesterday I set one up using the nice Virtual Machine Manager (VMM) GUI application. And remembered why I wasn’t using it: there’s no way to tell it how to do TCP port redirection! But now, there is a way…

The main reason I want TCP port redirection is so that I can use RDP to access Windows. RDP gives a much faster, smoother GUI experience than the standard VNC connection does, so I’ve set up all of my Windows VMs to use RDP. I remember now that I looked at this a couple of years ago, and there was no way to tell libvirt, the library underneath VMM, that I wanted TCP redirection. Thus, I stuck with my trusty shell scripts.

Looking again today, I was excited to find a post by Stefan Hajnoczi about passing QEMU command line arguments through libvirt. This is just what I need!

So, to the command line! First, take a backup of the configuration file for my VM. On Fedora, the files are in /etc/libvirt/qemu. Next, the message at the top of the file tells you in no uncertain terms to make edits using virsh edit or similar, so:

virsh edit my-vm-name

The first line needs to be changed, so that it uses the XML namespace for the QEMU command line elements:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>

Next, the network type has to be changed. TCP port redirection is a feature of QEMU user-mode networking, and the VMM configures tap networks by default. So, I have to change this line:

<interface type='network'>

to this:

<interface type='user'>

And finally, I need to add my custom command line arguments. I stuck them at the bottom of the file, just before the closing tag for domain:

<qemu:commandline>
   <qemu:arg value='-redir'/>
   <qemu:arg value='tcp:5564::3389'/>
</qemu:commandline>

Job is done; faster, smoother, and remotely.