我有一个qemu
由编排脚本启动的 VM,它创建了临时tap
接口。当我检查进程的命令行参数时qemu-system-x86_64
,我可以看到,该进程tap
使用文件描述符连接到已打开的接口27
:
-netdev tap,fd=27,id=hostnet1,vhost=on,vhostfd=28
照ls -l /proc/<qemu-system-x86_64_PID>/fd/27
它点来/dev/net/tun
。
它是否以某种方式以将tap
接口名称(例如vnet99
)传递给/dev/net/tun
withioctl()
并返回正确的 fd 的方式工作?或者一般来说,如何找出tap
主机中的哪个接口具有文件描述符 27?
可以给出答案的
iff:
条目是在内核 3.14 中添加的 commit ,因此在内核 3.13 或更早版本(例如 Ubuntu 14.04LTS)上不可用。tun: add device name(iff) field to proc fdinfo entry
在这种情况下,虽然不可能要求内核提供信息,但仍然可以通过使用调试器跟踪它来要求实际进程提供此信息。
从 Linux 2.6.27 开始有一个 ioctl 可用于询问有关已配置tuntap 接口的信息:
TUNGETIFF
。它的用途是让继承fd的进程能够查询fd以接收接口的名称和类型(ifr_name
和ifr_flags
)或知道 tuntap 设备尚未配置(EBADFD
)并且应该这样做。因此,虽然可以使用
gdb
,但它有点棘手,因为如果没有可用的开发环境,则必须知道或调整一些所需的参数和值(并且可能在未来或随着架构而改变)。这些信息和调整在这里需要:$malloc
以处理返回的内存地址的正确大小:信用来自 SO的此评论。$malloc(64)
:struct ifreq
在 64 位上似乎是 40 字节,让我们使用 64 来保证安全。0x800454d2
==TUNGETIFF
。ifr_name
在偏移量 0 处。下面是一个 shell 脚本,为每个找到调用的 tuntap fd 做准备
gdb
,以及 gdb 自己的脚本:tungetiff.sh
:tungetiff.gdb
:执行的典型示例(可能只能以 root 身份工作,即使用户 libvirt-qemu 似乎也无法ptrace qemu-system):
在已知文件描述符 27 的
/proc
情况下,您将进入 QEMU 的进程:与该目录处于同一级别的
fd
是另一个目录fdinfo
,其中包含以下详细信息:此文件中的
iff
条目是分接设备。参考