Using IVSHMEM with libvirt virt-manager

2019-07-29 03:47发布

问题:

Using ivshmem in qemu requires the following steps.

  1. Start ivshmem server in host ./ivshmem_server which will create a unix domain socket /tmp/ivshmem_socket
  2. Start qemu with the following command line options- -chardev socket,path=/tmp/ivshmem_socket,id=ivshmem_socket -device ivshmem,chardev=ivshmem_socket,size=1m

Now if we do lspci in guest, the ivshmem pci device is shown in it.

How can I do the same in virt-manager? Specifically, I want to do 2 things.

  • Pass the above command line option to qemu, when virt-manager starts it
  • libvirt virt-manager uses apparmor to isolate guests, how to make sure that access to /tmp/ivshmem_socket is not denied to the VM ?

回答1:

Passing command line options

Passing command line option to qemu from virt-manager requires the following steps.

  • virsh edit <name of vm> , or directly modify the file using vim /etc/libvirt/qemu/<name of virtual machine>.xml
  • change <domain type='kvm'> to <domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  • add tags for command line parameters
<qemu:commandline>
    <qemu:arg value='-chardev'/>
    <qemu:arg value='socket,path=/tmp/ivshmem_socket,id=ivshmem_socket'/>
    <qemu:arg value='-device'/>
    <qemu:arg value='ivshmem,chardev=ivshmem_socket,size=1m'/>
</qemu:commandline>

After doing this, qemu will try to access /tmp/ivshmem_socket, and because of apparmor (libvirt was using apparmor in my case, it may as well use SeLinux), the access will be denied, and an error similar to the following will be shown.

error starting domain: internal error: process exited while connecting to monitor:
  ...
virt-manager Failed to connect socket: Permission denied

AppArmor

To fix this error, the following two steps are required.

1. Make qemu run as root (This step is optional, and may not be required for you, continue to second step)

  • vim /etc/libvirt/qemu.conf
  • change the lines user =, and group = , to the following

user = "root"
group = "root"

Restart PC or libvirt daemon.

2. AppArmor

  • find the uuid of guest from its xml configuration file (use virsh edit and look for tag)
  • cd /etc/apparmor.d/libvirt
  • check if libvirt-<uuid> file is present, replace <uuid> with uuid of vm
  • Change AppArmor mode to complain, instead of enforcing, which will allow all actions of the VM, and log those which should have been blocked.

    sudo aa-complain libvirt-<uuid> //replace <uuid> with uuid of vm