将 IVSHMEM 与 libvirt virt-manager 结合使用
Using IVSHMEM with libvirt virt-manager
在 qemu 中使用 ivshmem 需要以下步骤。
- 在主机
./ivshmem_server
中启动 ivshmem 服务器,这将创建一个 unix 域套接字 /tmp/ivshmem_socket
- 使用以下命令行选项启动 qemu-
-chardev socket,path=/tmp/ivshmem_socket,id=ivshmem_socket -device ivshmem,chardev=ivshmem_socket,size=1m
现在如果我们在来宾中执行 lspci
,ivshmem pci 设备就会显示在其中。
我如何在 virt-manager 中做同样的事情?
具体来说,我想做两件事。
- 在 virt-manager 启动时将上述命令行选项传递给 qemu
- libvirt virt-manager 使用 apparmor 来隔离虚拟机,如何确保对
/tmp/ivshmem_socket
的访问不会被 VM 拒绝?
传递命令行选项
从 virt-manager 向 qemu 传递命令行选项需要以下步骤。
virsh edit <name of vm>
,或者直接使用 vim /etc/libvirt/qemu/<name of virtual machine>.xml
修改文件
- 将
<domain type='kvm'>
更改为<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
- 为命令行参数添加标签
<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>
执行此操作后,qemu 将尝试访问 /tmp/ivshmem_socket
,并且由于 apparmor(我的情况下 libvirt 使用的是 apparmor,它也可能使用 SeLinux),访问将被拒绝,并出现错误将显示类似于以下内容。
error starting domain: internal error: process exited while connecting to monitor:
...
virt-manager Failed to connect socket: Permission denied
AppArmor
要修复此错误,需要执行以下两个步骤。
1. Make qemu 运行 as root(这一步是optional
,你可能不需要,继续第二步)
- vim
/etc/libvirt/qemu.conf
- 将行
user =
和 group =
更改为以下内容
user = "root"
group = "root"
重启 PC 或 libvirt 守护进程。
2。 AppArmor
- 从 guest 的 xml 配置文件中找到 guest 的 uuid(使用 virsh 编辑并查找标签)
- cd
/etc/apparmor.d/libvirt
- 检查
libvirt-<uuid>
文件是否存在,用 vm 的 uuid 替换 <uuid>
将 AppArmor 模式更改为抱怨,而不是强制执行,这将允许 VM 的所有操作,并记录那些应该被阻止的操作。
sudo aa-complain libvirt-<uuid> //replace <uuid> with uuid of vm
在 qemu 中使用 ivshmem 需要以下步骤。
- 在主机
./ivshmem_server
中启动 ivshmem 服务器,这将创建一个 unix 域套接字/tmp/ivshmem_socket
- 使用以下命令行选项启动 qemu-
-chardev socket,path=/tmp/ivshmem_socket,id=ivshmem_socket -device ivshmem,chardev=ivshmem_socket,size=1m
现在如果我们在来宾中执行 lspci
,ivshmem pci 设备就会显示在其中。
我如何在 virt-manager 中做同样的事情? 具体来说,我想做两件事。
- 在 virt-manager 启动时将上述命令行选项传递给 qemu
- libvirt virt-manager 使用 apparmor 来隔离虚拟机,如何确保对
/tmp/ivshmem_socket
的访问不会被 VM 拒绝?
传递命令行选项
从 virt-manager 向 qemu 传递命令行选项需要以下步骤。
virsh edit <name of vm>
,或者直接使用vim /etc/libvirt/qemu/<name of virtual machine>.xml
修改文件
- 将
<domain type='kvm'>
更改为<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
- 为命令行参数添加标签
<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>
执行此操作后,qemu 将尝试访问 /tmp/ivshmem_socket
,并且由于 apparmor(我的情况下 libvirt 使用的是 apparmor,它也可能使用 SeLinux),访问将被拒绝,并出现错误将显示类似于以下内容。
error starting domain: internal error: process exited while connecting to monitor:
...
virt-manager Failed to connect socket: Permission denied
AppArmor
要修复此错误,需要执行以下两个步骤。
1. Make qemu 运行 as root(这一步是optional
,你可能不需要,继续第二步)
- vim
/etc/libvirt/qemu.conf
- 将行
user =
和group =
更改为以下内容
user = "root"
group = "root"
重启 PC 或 libvirt 守护进程。
2。 AppArmor
- 从 guest 的 xml 配置文件中找到 guest 的 uuid(使用 virsh 编辑并查找标签)
- cd
/etc/apparmor.d/libvirt
- 检查
libvirt-<uuid>
文件是否存在,用 vm 的 uuid 替换 将 AppArmor 模式更改为抱怨,而不是强制执行,这将允许 VM 的所有操作,并记录那些应该被阻止的操作。
sudo aa-complain libvirt-<uuid> //replace <uuid> with uuid of vm
<uuid>