无需猜测即可获取与 macvtap 关联的 /dev/tapX

无需猜测即可获取与 macvtap 关联的 /dev/tapX

下列的设置指南macvtap很棒。
该指南的摘录如下所示:

# ip link add link eth1 name macvtap0 type macvtap
# ip link set macvtap0 address 1a:46:0b:ca:bc:7b up
# ip link show macvtap0

然后该指南继续解释您可以执行以下操作:

#qemu-system-x86_64 -net nic,model=virtio,addr=1a:46:0b:ca:bc:7b -net tap,fd=3 3<>/dev/tap11

如果你的macvtap最终结果是/dev/tap11.
但是你如何检查哪个/dev/tapX接口实际上被分配给了macvtap0上面的接口呢?

我有很多服务随机在我的机器上设置点击设备。我无法猜测我的具体结果是哪一个。

我希望用以下命令启动 qemu 机器:

    -netdev tap,ifname="macvtap0",id=network0,script=no,downscript=no \
    -device i82559b,netdev=network0,mac=${MAC}

可以,macvtap0我刚刚创建的设备在哪里。
然而,这给了我:

qemu-system-x86_64: could not configure /dev/net/tun (macvtap0): Invalid argument

本文概述:如何找到tap接口与其文件描述符之间的联系?- 他们描述了一种通过访问 PID 并检查关联文件描述符来实现此目的的方法,对我来说问题是 qemu 没有设置设备,而我是。并且没有与之关联的 PID。

/dev那么如何获取与新创建的接口关联的文件句柄macvtap

编辑:我已经解决这个问题几天了,但我刚刚意识到我忘记检查/sys/class/net/macvtap0/,并且有一个/tap2设备。显然,我仍然需要遍历所有内容才能找到匹配的名称regex(tap[0-9]+)。这会起作用,但不确定这是最好/正确的方法。

答案1

设备名称是已创建基于接口索引:

snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex);

[...]

      devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor);
      classdev = device_create(&macvtap_class, &dev->dev, devt,
                   dev, tap_name);

如果OP的ip link show macvtap0答案存在,它很可能会以:

11: macvtap0@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 [...]

如果您不想依赖这个似乎没有正式记录的特定属性(单词macvtap整个树中不存在linux/Documentation/),您可以依赖/sys(似乎也没有正式记录的条目)macvtap):

这些信息可在macvtap/*子目录中找到。请注意,这tap11是单个条目的符号链接macvtap/tap11,因为它在哪里不切实际,所以应该忽略它(但不是它指向的目录)。

  • 来自网络接口名称查找设备节点条目名称:

    1. /sys/class/net/macvtap0/macvtap/*有一个条目,tap 设备名称,它是一个目录:

      $ printf '/dev/%s\n' "$(basename /sys/class/net/macvtap0/macvtap/*)"
      /dev/tap11
      

      intf_to_devtap可以使用一个名为的函数:

      intf_to_devtap () {
          [ -e "/sys/class/net/$1/macvtap" ] || return 1
          printf '/dev/%s\n' "$(basename /sys/class/net/$1/macvtap/*)"
      }
      

      对于OP的情况:

      $ intf_to_devtap macvtap0
      /dev/tap11
      
    2. dev条目为主要次要:

      $ cat /sys/class/net/macvtap0/macvtap/*/dev
      242:1
      

      该属性(以及下面的等效属性uevent)是唯一保证唯一的,以防万一macvtap在多个网络命名空间中创建,每个命名空间具有相同的接口索引,从而形成一个设备节点姓名碰撞。碰撞示例(当没有macvtap设备是之前创建的):

      # ip netns add collision1; ip netns add collision2
      # ip -n collision1 link add type dummy; ip -n collision2 link add type dummy
      # ip -n collision1 link add link dummy0 type macvtap
      # ls -l /dev/tap*
      crw-------. 1 root root 242, 1 Apr 19 21:24 /dev/tap3
      # ip -n collision2 link add link dummy0 type macvtap
      # ls -l /dev/tap*
      crw-------. 1 root root 242, 1 Apr 19 21:24 /dev/tap3
      

      没有出现第二个点击条目。这是因为当第二个网络命名空间也创建索引为 3 ( lo=1、dummy0=2、 =3)的接口时发生冲突,并且由于同名文件已存在而未macvtap0创建第二个设备条目。/dev由于ip netns还重新安装/sys以准确处理网络设备,因此可以验证实际上是否存在两个分路设备,即使第二个没有“映射”:

      # ip netns exec collision1 sh -c 'cat /sys/class/net/macvtap0/macvtap/*/dev'
      242:1
      # ip netns exec collision2 sh -c 'cat /sys/class/net/macvtap0/macvtap/*/dev'
      242:2
      

      所以人们仍然可以使用第二个macvtap通过“映射”接口后端,然后使用设备,即使有一半的/sys信息与此不匹配,例如:

      # mknod /dev/tap3b c 242 2
      

      或者使用更详细的名称,例如/dev/tap-VM1-intfA.

    3. uevent条目,给出主要:次要和名称:

      $ cat /sys/class/net/macvtap0/macvtap/*/uevent
      MAJOR=242
      MINOR=1
      DEVNAME=tap11
      
  • 开发者进入接口名称:

    /dev/tap11

    /dev/tap11-> /sys/class/macvtap/tap11-> /sys/devices/virtual/net/macvtap0/macvtap/tap11。请注意,/sys/class/net/macvtap0before 实际上是 的符号链接/sys/devices/virtual/net/macvtap0

    仍然在最后一个目录中,device条目是接口目录的符号链接,所以我们最终有/sys/class/macvtap/tap11/device->/sys/devices/virtual/net/macvtap0

    devtap_to_intf可以使用一个名为的函数:

    devtap_to_intf () {
        [ -c "$1" ] || [ -c "/dev/$1" ] || return 1
        local path="$(readlink -e "/sys/class/macvtap/${1#/dev/}/device")"
        printf '%s\n' "${path#/sys/devices/virtual/net/}"
    }
    

    以OP为例:

    $ devtap_to_intf /dev/tap11
    macvtap0
    

相关内容