I use libvirt and kvm to run two virtual machines (a linux and a windows guest) on a debian host. Both guests run without a <graphics/> section in their config because I use ssh and rdp to admin these systems.

Last night I broke the network for the windows guest while upgrading the host from lenny to squeeze so I wanted to temporarily enable <graphics type='vnc'/> for troubleshooting. I virsh edit the windows domain and added the following line to the <devices/> section in its config:

<graphics type='vnc' listen='0.0.0.0:0'/>

However, saving the config always resulted in the following error message:

virsh # edit windows
error: internal error unable to reserve PCI address 0:0:2

I tried to run kvm directly by passing a -vnc :0 switch instead of -nographic but that didn’t work either:

TUNGETIFF ioctl() failed: Bad file descriptor

Turns out I had run into a bug (“qemu: Always reserves slot 0x02 for primary VGA. (Osier Yang)”) that always took pci slot 0x02 for vga. Since my guest already had its network interface configured to that slot, things did not work out.

The fix was to move around the pci slot assignments in the config and allow <graphics/> to use 0x02 (irrelevant sections omitted):

<devices>
    <!-- emulator, disk, etc. omitted -->
    <controller type='ide' index='0'>
        <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <interface type='bridge'>
        <!-- mac, source, target, model, etc. omitted -->
        <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </interface>
    <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0:0'/>
    <video>
        <model type='cirrus' vram='9216' heads='1'/>
        <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
        <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </memballoon>
</devices>

That allowed me to boot the guest and connect to it on display :0 via vnc.

The bug was fixed in libvirt 0.9.2-1.el6 but since the host is on squeeze, it is using libvirt 0.8.3-5.