Ubuntu QEMU KVM libvirt virtio

From richud.com
Jump to navigation Jump to search


These are just some notes form myself rather than a writeup!

Any version

sudo apt-get install qemu-kvm qemu libvirt-bin


Applies to/tested with Ubuntu 15.10

This assumes default libirt/qemu install where virbr0 is created and up with an IP like

#Fixup permissions to helper see http://wiki.qemu.org/Features/HelperNetworking
sudo chmod u+s  /usr/lib/qemu/qemu-bridge-helper

#Create missing bridge.conf!
echo "allow virbr0" | sudo tee /etc/qemu/bridge.conf
sudo chmod 0644 /etc/qemu/bridge.conf

#Run VM - machine config, hdd config, spice config with clipboard (nop security or password), display adapter. net0 is an arbitary name.
/usr/bin/qemu-system-x86_64 -m 4096 -name Windows_7_x64 -cpu host -machine pc-i440fx-utopic,accel=kvm,usb=off \
-drive file=/media/3/VMM/win7.qcow2,if=virtio,format=qcow2,cache=writeback \
-netdev bridge,br=virbr0,id=net0 -device virtio-net-pci,netdev=net0 \
-spice port=5900,addr=,disable-ticketing -device virtio-serial-pci \
-device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 \
-chardev spicevmc,id=spicechannel0,name=vdagent \
-vga qxl

To set a basic password change disable-ticketing to password=youppass

14.04 LTS

...same as above but some paths are different and options too

sudo chmod u+s /usr/lib/qemu/qemu-bridge-helper


sudo chmod u+s /usr/lib/qemu-bridge-helper

Thus need to specify it as in non default location thus;

-netdev bridge, needs to be -netdev bridge,helper=/usr/lib/qemu-bridge-helper

Add yourself to kvm group

sudo usermod -a -G kvm YOUUSERNAMEHERE

Append -enable-kvm

Thus it becomes

/usr/bin/qemu-system-x86_64 -m 4096 -name Windows_7_x64 -cpu host \
-drive file=/VMM/win7.qcow2,if=virtio,format=qcow2,cache=writeback \
-netdev bridge,helper=/usr/lib/qemu-bridge-helper,br=virbr0,id=net0 \
-device virtio-net-pci,netdev=net0 -spice port=5900,addr=,disable-ticketing \
-device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 \
-chardev spicevmc,id=spicechannel0,name=vdagent \
-vga qxl -enable-kvm

Sample virsh config

Save and import like

virsh create Windows_7_x64.xml

<domain type='kvm'>
  <memory unit='KiB'>4194304</memory>
  <currentMemory unit='KiB'>4194304</currentMemory>
    <type arch='x86_64'>hvm</type>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='writeback'/>
      <source file='/VMM/win7.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
    <controller type='virtio-serial' index='0'>
    <interface type='network'>
      <source network='default'/>
      <model type='virtio'/>
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    <graphics type='spice' autoport='yes'/>
      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1'/>
  <seclabel type='dynamic' model='apparmor' relabel='yes'/>

Copying VMM disk image about

  • Make sure target has write access else it only fails after its tried copying whole file

rsync -v -e ssh --progress --preallocate /VMM/centos6.qcow2 user@vmmhost.server.com:/VMM/

Creating a new one from a disk image and existing xml

cd /etc/libvirt/qemu

virsh dumpxml Windows_7_x64 | sudo tee CentOS6_i386.xml >/dev/null

  • Note dumpxml strips things, mostly useful, but also the password from <graphics type='spice' autoport='yes' listen='' passwd='xxxxxxxxxxx'>

sudo nano -w CentOS6_i386.xml

  • remove entire UUID line, change name, change MAC, change qcow2 name/path, fix arch type?

(dont use virsh create CentOS6_i386.xml as will need to define afterwards, to stop error 'error: Requested operation is not valid: cannot set autostart for transient domain')

virsh define CentOS6_i386.xml

virsh autostart CentOS6_i386

virsh start CentOS6_i386

virsh list --all


Some notes

virsh snapshot-create-as --domain CentOS6_i386 --name Snapshot1_Installed

virsh snapshot-list CentOS6_i386

virsh snapshot-info --domain CentOS6_i386 --current

Port Forwarding

1) Semi official way, nasty, some hard coded bits - http://wiki.libvirt.org/page/Networking#Forwarding_Incoming_Connections

2) iptable rules, again hard coded

3) still not great, but best overall,

virsh edit CentOS_i386

a) change <domain type='kvm'>

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

this enables qemu commands to be put in the xml

b) change <interface type='network'> to

<interface type='user'> 

this uses qemu built in network stuff

  • Note if you need to go back at a later time you also need to re-add < source network='default' /> under the <interface> section as it gets scrubbed.

c) prepend closing </domain> tag to

    <qemu:arg value='-redir'/>
    <qemu:arg value='tcp:2222::22'/>

You can then connect to SSH on your VM via host on port 2222

ssh -p 2222 centos@your.vm.host

Securing Spice by SSH'ing

Simplest way IMHO is going over SSH

virsh edit CentOS6_i386

Change the listen= in <graphics to localhost, note the <listen line must match the main one , its some backwards compatible thing

    <graphics type='spice' autoport='yes' listen=''>
      <listen type='address' address=''/>

Now you need to go in via ssh, and crazy shit will occur as you realise it needs about 6 password prompts to work via Spice. (one for each channel) (note it uses an ssh connection and some netcat (nc) voodoo on each channel to glue this together)


1) on your local machine set this in (~/.ssh/config) so it makes a main connection once then does everything multiplexed inside it (presume set host to the vm host, I didn't go wit this in the end)

Host *
        ControlMaster auto
        ControlPath ~/.ssh/master-socket/%r%h:%p
ControlPersist 1

2) Generate your public/private key pair on your machine , assuming you don't already have some, in which case skip to copying them below

ssh-keygen -b 4096
  • <press enter three times, leaving empty answers>

Copy public key to the VM host PC

ssh-copy-id physics@your.vm.host

Then you can just connect without pissing about

virt-viewer -vc qemu+ssh://physics@your.vm.host/system CentOS6_i386

Add macvtap network

At time of writing this except, ubuntu 17.10 used.

This is alternative to using a normal linux bridge , br0

Assuming your ethernet interface to bridge (macvtap onto) is enp6s2, create a temp.xml with below in it.

Dont use mode=vepa as you need a physical switch support.

macvtap-net is just an abitary name.

  <forward mode="bridge">
    <interface dev="enp6s2"/>
virsh net-define temp.xml 

This should create the config file based on the name in the temp.xml


virsh net-list --all
virsh net-autostart macvtap-net
virsh net-start macvtap-net
virsh net-list --all

This is then how the virtual machines xml networking should be, xx is MAC, source network is the name use in original xml.

    <interface type='network'>
      <mac address='xx:xx:xx:xx:xx:xx'/>
      <source network='macvtap-net'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>

Create larger VM from existing one

Assuming you have a 30Gb original and want an 80Gb target.

qemu-img create -f qcow2 win10-NEW.qcow2 80G
sudo virt-resize --resize /dev/sda2=+49G --expand /dev/sda2 win10.qcow2 win10-NEW.qcow2


blog comments powered by Disqus