使 /dev/net/tun 可用于 qemu?

Nat*_*man 8 qemu tap network-interface

我创建了一个 Tap 设备 ( tap0),我想将其作为 qemu 的网络接口提供。我使用以下命令创建了设备并将其连接到我设置的网桥:

tunctl -t tap0
ifconfig tap0 up
brctl addif virbr0 tap0
Run Code Online (Sandbox Code Playgroud)

然后我运行了这个答案中建议的命令:

chgrp netdev /dev/net/tun
chmod 660 /dev/net/tun
Run Code Online (Sandbox Code Playgroud)

两个命令都成功完成,我确认它们生效了:

nathan@nathan-desktop:~$ stat /dev/net/tun
  File: ‘/dev/net/tun’
  Size: 0           Blocks: 0          IO Block: 4096   character special file
Device: 6h/6d   Inode: 1224        Links: 1     Device type: a,c8
Access: (0660/crw-rw----)  Uid: (    0/    root)   Gid: (  108/  netdev)
Access: 2015-11-16 10:16:35.127338320 -0800
Modify: 2015-11-16 10:16:35.127338320 -0800
Change: 2015-11-16 10:37:18.338948110 -0800
 Birth: -
Run Code Online (Sandbox Code Playgroud)

我也确认我在netdev群里:

nathan@nathan-desktop:~$ groups
[...] netdev [...]
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试使用该界面启动qemu虚拟机时,遇到了以下错误:

nathan@nathan-desktop:~$ qemu-system-arm [...] -net tap,ifname=tap0
qemu-system-arm: -net tap,ifname=tap0: could not configure /dev/net/tun (tap0): Operation not permitted
qemu-system-arm: -net tap,ifname=tap0: Device 'tap' could not be initialized
Run Code Online (Sandbox Code Playgroud)

斯特拉斯

来自的相关输出strace如下所示:

open("/dev/net/tun", O_RDWR)            = 7
ioctl(7, TUNGETFEATURES, 0x7ffcc532ab2c) = 0
ioctl(7, TUNSETVNETHDRSZ, 0x7ffcc532ab28) = -1 EBADFD (File descriptor in bad state)
ioctl(7, TUNSETIFF, 0x7ffcc532ab30)     = -1 EPERM (Operation not permitted)
write(2, "qemu-system-arm:", 16qemu-system-arm:)        = 16
write(2, " -net", 5 -net)                    = 5
write(2, " tap,ifname=tap0", 16 tap,ifname=tap0)        = 16
write(2, ": ", 2: )                       = 2
write(2, "could not configure /dev/net/tun"..., 64could not configure /dev/net/tun (tap0): Operation not permitted) = 64
write(2, "\n", 1
)                       = 1
close(7)                                = 0
write(2, "qemu-system-arm:", 16qemu-system-arm:)        = 16
write(2, " -net", 5 -net)                    = 5
write(2, " tap,ifname=tap0", 16 tap,ifname=tap0)        = 16
write(2, ": ", 2: )                       = 2
write(2, "Device 'tap' could not be initia"..., 37Device 'tap' could not be initialized) = 37
write(2, "\n", 1
)
Run Code Online (Sandbox Code Playgroud)

use*_*445 8

qemu 将尝试运行一些默认脚本,如果您不是 root,这些脚本将失败。当您对相应的 Tap 设备具有适当的访问权限时,这是一个有效的命令行选项:

qemu-system-x86_64 ... \
    -net nic,model=virtio -net tap,ifname=tap0,script=no,downscript=no
Run Code Online (Sandbox Code Playgroud)

script=no,downscript=no避免,失败是很重要的。

您还必须确保您可以访问抽头设备的另一端(不仅仅是控制设备/dev/net/tun)。不确定tunctl,但是对于 iproute2,您必须说ip tuntap add dev tap0 mode tap group netdev(或user等)。


小智 5

您需要在初始 tunctl 调用中指定 netdev 组:

tunctl -t tap0 -g netdev
Run Code Online (Sandbox Code Playgroud)

[我还发现,出于某种原因,我必须在 /dev/net 目录上授予执行权限 (770)。这可能无关。]


小智 5

与您正在工作的用户创建点击界面。

sudo tunctl -p -t tap0 -u <user>
Run Code Online (Sandbox Code Playgroud)

然后尝试运行 Qemu。