qemu 命令行无法看到 /dev/net/tun

qemu 命令行无法看到 /dev/net/tun

我是 qemu 和 libvirt 的新手。我在使用 virsh 和 qemu 时遇到了问题,尤其是在设置 tun 接口时。一旦我运行

qemu-system-x86_64 \
    -nographic -enable-kvm \
    -cpu host -m 2048 \
    -serial mon:stdio \
    -netdev tap,id=et0,ifname=tap0,script=no -device e1000,netdev=et0

它运行正常,并且还在tap0主机上创建了接口。当我尝试使用 libvirt xml 创建虚拟机时,出现了问题:

<domain type="kvm" xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <name>testttt</name>
  <uuid>21ddfabd-1312-45ad-aced-cf7a10257d83</uuid>
  <memory unit="MB">2048</memory>
  <currentMemory unit="MB">2048</currentMemory>
  <vcpu placement="static">1</vcpu>
  <os>
    <type arch="x86_64" machine="pc-i440fx-6.2">hvm</type>
    <boot dev="hd"/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <vmport state="off"/>
  </features>
  <cpu mode="host-passthrough" check="none" migratable="on"/>
  <clock offset="utc">
    <timer name="rtc" tickpolicy="catchup"/>
    <timer name="pit" tickpolicy="delay"/>
    <timer name="hpet" present="no"/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled="no"/>
    <suspend-to-disk enabled="no"/>
  </pm>
  <devices>
    <emulator>/usr/bin/qemu-system-x86_64</emulator>
    <disk type="file" device="disk">
      <driver name="qemu" type="vdi"/>
      <source file="..."/>
      <target dev="hda" bus="ide"/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>
    <controller type="usb" index="0" model="ich9-ehci1">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x04" function="0x7"/>
    </controller>
    <controller type="usb" index="0" model="ich9-uhci1">
      <master startport="0"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x04" function="0x0" multifunction="on"/>
    </controller>
    <controller type="usb" index="0" model="ich9-uhci2">
      <master startport="2"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x04" function="0x1"/>
    </controller>
    <controller type="usb" index="0" model="ich9-uhci3">
      <master startport="4"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x04" function="0x2"/>
    </controller>
    <controller type="pci" index="0" model="pci-root"/>
    <controller type="ide" index="0">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x1"/>
    </controller>
    <controller type="virtio-serial" index="0">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x05" function="0x0"/>
    </controller>
    <serial type="pty">
      <target type="isa-serial" port="0">
        <model name="isa-serial"/>
      </target>
    </serial>
    <console type="pty">
      <target type="serial" port="0"/>
    </console>
    <channel type="spicevmc">
      <target type="virtio" name="com.redhat.spice.0"/>
      <address type="virtio-serial" controller="0" bus="0" port="1"/>
    </channel>
    <input type="mouse" bus="ps2"/>
    <input type="keyboard" bus="ps2"/>
    <graphics type="vnc" port="-1" autoport="yes">
      <listen type="address"/>
    </graphics>
    <video>
      <model type="qxl" ram="65536" vram="65536" vgamem="16384" heads="1" primary="yes"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0"/>
    </video>
    <redirdev bus="usb" type="spicevmc">
      <address type="usb" bus="0" port="2"/>
    </redirdev>
    <redirdev bus="usb" type="spicevmc">
      <address type="usb" bus="0" port="3"/>
    </redirdev>
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x06" function="0x0"/>
    </memballoon>
    <rng model="virtio">
      <backend model="random">/dev/urandom</backend>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0"/>
    </rng>
  </devices>
  <qemu:commandline>
    <qemu:arg value='-serial'/>
    <qemu:arg value='mon:stdio'/>

    <qemu:arg value='-device'/>
    <qemu:arg value='e1000,netdev=et0'/>
    <qemu:arg value='-netdev'/>
    <qemu:arg value='tap,id=et0,script=no,downscript=no,ifname=tap0'/>


  </qemu:commandline>
</domain>

机器已创建,但当我尝试运行它时出现以下错误:

internal error: qemu unexpectedly closed the monitor:
2022-07-13T12:12:59.151035Z qemu-system-x86_64: -netdev tap,id=et0,script=no,downscript=no,ifname=tap0:
could not open /dev/net/tun: No such file or directory

我认为,这样做有些不妥:

  <qemu:commandline>
    <qemu:arg value='-serial'/>
    <qemu:arg value='mon:stdio'/>

    <qemu:arg value='-device'/>
    <qemu:arg value='e1000,netdev=et0'/>
    <qemu:arg value='-netdev'/>
    <qemu:arg value='tap,id=et0,script=no,downscript=no,ifname=tap0'/>


  </qemu:commandline>

我跑了cat /dev/net/tuncat: /dev/net/tun: File descriptor in bad state所以tun应该没问题,而且当我跑步时它也能起作用qemu-system-x86_64

答案1

Libvirt 在 QEMU 周围应用了多层安全保护,以防止它访问主机上未通过客户机 XML 配置明确分配的资源。它只能自动对使用官方支持的 XML 元素配置的功能执行正确的操作。一旦您使用覆盖<qemu:arg>来设置任意 QEMU 功能,您很可能会被安全措施阻止。

在您的情况下没有特别强烈的理由使用该<qemu:arg>语法,因为您所做的事情非常简单。

   <serial type='pty'/>

足以设置一个串行端口,您可以使用“virsh console $GUEST”与其进行交互。

不需要在 stdio 上设置“mon”,因为 libvirt 代表用户与 QEMU 监视器对话。如果存在这样还不够好的极端情况,您可以通过以下方式与 QEMU 监视器对话virsh qemu-monitor-command

对于网络接口,假设你想连接到网桥

  <interface type='bridge'>
      <source bridge='br0'/>
      <model type='e1000'/>
  </interface>

尽管 libvirt 可以通过许多其他方式设置 NIC。

https://libvirt.org/formatdomain.html#network-interfaces

如果你仍然必须使用,<qemu:arg>则需要禁用各种安全功能

https://libvirt.org/kbase/qemu-passthrough-security.html

答案2

我遇到了和你一模一样的问题:用 qemu 运行没问题,但用 libvirt 时出错。我使用qemu:commandline网络接口而不是 libvirt 的原因是 libvirt 将设置 virtio-net-pci 后端默认值而不是 virtio-net-device,但我的客户内核没有 pci 驱动程序。

/dev/net/tun添加设备并cgroup_device_acl重启/etc/libvirt/qemu.conflibvirtd服务即可完美解决问题。

相关内容