如何在 SMB/CIFS 网络共享上使用 QEMU/KVM 虚拟机磁盘映像:权限被拒绝

A_b*_*lop 5 networking kvm ubuntu qemu libvirt

环境

问题

dave我可以直接temp从 shell 或文件应用程序写入/读取。共享所有者设置为,这是属于和uid=dave,gid=dave的用户。使用本地磁盘映像路径运行虚拟机没有问题。在 virt-manager 中,我可以定义为存储池(包含图像的目录)。kvmlibvirt .qcow2/media/nas/temp

但是,一旦我想在 中放置或创建此磁盘映像文件/media/nas/temp,就会触发“权限被拒绝”错误。据我所知,虚拟机qemu:///system被实例化并作为root. 这不应以任何方式影响已配置的网络共享所有者。我尝试sudo su并检查过,我可以以 root 身份写入/media/nas/temp

另一种直接触发错误的方法(从 virt-manager 输出复制)是:

/usr/bin/qemu-img create -f qcow2 -o preallocation=metadata,compat=1.1,lazy_refcounts /media/nas/temp/ubuntu20.04 20971520K
Run Code Online (Sandbox Code Playgroud)

问题

我真的很想了解权限问题以及如何解决它。这里有什么问题?

详细错误信息

尝试创建新的.qcow2磁盘映像会触发:

创建卷时出错:无法创建存储卷'ubuntu20.04':'内部错误:子进程(/usr/bin/qemu-img create -f qcow2 -o preallocation=metadata,compat=1.1,lazy_refcounts /media/nas /temp/ubuntu20.04 20971520K)意外退出状态 1:qemu-img:/media/nas/temp/ubuntu20.04:无法写入 qcow2 标头:权限被拒绝'

回溯(最近一次调用最后一次):文件“/usr/share/virt-manager/virtinst/storage.py”,第 682 行,安装 vol = self.pool.createXML(xml, createflags) 文件“/usr/lib/ python3/dist-packages/libvirt.py",第 3535 行,在 createXML 中,如果 ret 为 None:引发 libvirtError('virStorageVolCreateXML() failed', pool=self) libvirt.libvirtError:内部错误:子进程 (/usr/bin/ qemu-img create -f qcow2 -o preallocation=metadata,compat=1.1,lazy_refcounts /media/nas/temp/ubuntu20.04 20971520K) 意外退出状态 1: qemu-img: /media/nas/temp/ubuntu20.04:无法写入 qcow2 标头:权限被拒绝

在处理上述异常的过程中,又出现了一个异常:

回溯(最近一次调用最后一次):文件“/usr/share/virt-manager/virtManager/asyncjob.py”,第 75 行,在 cb_wrapper 回调(asyncjob,*args,**kwargs)文件“/usr/share/virt”中-manager/virtManager/createvol.py”,第 339 行,在 _async_vol_create vol.install(meter=meter) 文件“/usr/share/virt-manager/virtinst/storage.py”,第 691 行,在安装中 raise RuntimeError("无法创建存储卷“ RuntimeError: 无法创建存储卷 'ubuntu20.04': '内部错误: 子进程 (/usr/bin/qemu-img create -f qcow2 -o preallocation=metadata,compat=1.1, lazy_refcounts /media/nas/temp/ubuntu20.04 20971520K)意外退出状态 1:qemu-img:/media/nas/temp/ubuntu20.04:无法写入 qcow2 标头:权限被拒绝'

更新:我进一步尝试过的

  • 通过搜索其他错误类型journalctl -xf(除了上面的消息之外没有别的)
  • cat /var/log/syslog | grep DENIED | grep libvirt通过(无)搜索被拒绝的操作
  • 通过实验禁用 AppArmor systemctl stop apparmor- 没有效果
  • 在其他本地文件夹中成功创建了图像/var/lib/libvirt/images/

更新 2:使用nobrl挂载选项

如果我使用nobrl挂载选项(感谢 rudib),所有者仍然uid=dave,gid=dave如下:

sudo mount -t cifs -o username=dave,vers=3.11,uid=dave,gid=dave,nobrl //nas/temp /media/nas/temp
Run Code Online (Sandbox Code Playgroud)

,可以成功创建存储卷(virt-manager 向导中的步骤 4/5)。虽然在步骤 5/5 中,我现在收到另一个“权限被拒绝”错误:

无法完成安装:'内部错误:qemu意外关闭了监视器:2020-12-01T06:03:01.710704Z qemu-system-x86_64:-blockdev {“node-name”:“libvirt-2-format”,“read -only":false,"driver":"qcow2","file":"libvirt-2-storage","backing":null}: 无法重新打开文件: 权限被拒绝'

回溯(最近一次调用最后一次):文件“/usr/share/virt-manager/virtManager/asyncjob.py”,第 75 行,在 cb_wrapper 回调(asyncjob,*args,**kwargs)文件“/usr/share/virt”中-manager/virtManager/createvm.py”,第 2089 行,在 _do_async_install guest.installer_instance.start_install(guest,meter=meter) 文件“/usr/share/virt-manager/virtinst/install/installer.py”,第 542 行,在start_install域= self._create_guest(文件“/usr/share/virt-manager/virtinst/install/installer.py”,第491行,在_create_guest域= self.conn.createXML(install_xml或final_xml,0)文件“/ usr/lib/python3/dist-packages/libvirt.py”,第 4034 行,在 createXML 中,如果 ret 为 None:引发 libvirtError('virDomainCreateXML() failed', conn=self) libvirt.libvirtError:内部错误:qemu 意外关闭了监视器:2020-12-01T06:03:01.710704Z qemu-system-x86_64:-blockdev {“节点名称”:“libvirt-2-format”,“只读”:false,“驱动程序”:“qcow2” ,"file":"libvirt-2-storage","backing":null}: 无法重新打开文件: 权限被拒绝

不指定uidgid导致以下权限:

$ ll /media/nas/
drwxr-xr-x 2 root  root     0 Dez  1 07:01 temp/
Run Code Online (Sandbox Code Playgroud)

,错误与之前相同。

rud*_*dib 4

注意:远程安装的活动卷可能会导致一些问题并增加延迟

看来 qemu-img 无法处理字节范围锁,这是cifs. 该标志nobrl应该解决这个问题:

mount -t cifs -o username=dave,vers=3.11,nobrl,uid=libvirt-qemu //nas/temp /media/nas/temp
Run Code Online (Sandbox Code Playgroud)

在图像创建过程中,qemu:///system uid=libvirt-qemu似乎不需要以root 身份virt-manager运行。qemu-img create但是,由于qemu:///system计算机是在 qemu 用户(libvirt-qemu[Ubuntu、Debian] 或qemu[Fedora])下启动的,因此当共享刚刚作为 root 挂载时,您将收到另一个权限被拒绝的错误。

nobrl
Do not send byte range lock requests to the server. This is
necessary for certain applications that break with cifs style
mandatory byte range locks (and most cifs servers do not yet support
requesting advisory byte range locks).
Run Code Online (Sandbox Code Playgroud)

使用时selinux,可能需要设置sebool virt_use_samba

  • 其他人评论道,“libvirtd”以“root”身份运行,但实际上以“libvirt-qemu”用户身份启动虚拟机。对于本地系统,它可以动态更改用户,但对于挂载点,它似乎不起作用,因为这是由“uid”、“gid”确定/固定的。我不确定为什么评论被删除,因为这是非常有用的信息(希望我没有记错)。这至少解释了为什么需要“libvirt-qemu”(不是我创建的自定义用户,而是通过 libvirt 安装创建的)。 (2认同)