How to know if a process is attached to a tap interface?
Each file descriptor has a /proc/pid/fdinfo/num entry, like:
# cat /proc/24332/fdinfo/28
pos: 0
flags: 0104002
mnt_id: 18
iff: tap0123acdc-66
So, with the interface name, you can get the pid with:
# egrep -l iff:.*tap0123acdc-66 /proc/*/fdinfo/* 2>/dev/null|cut -d/ -f3
24332
This got me wondering and I had a look at the Linux kernel source (I'm assuming your question is about Linux).
It appears the answer's more difficult than you'd expect. This TUN/TAP API tutorial page offers some insight. Basically, your program allocates a new TUN/TAP device by opening /dev/net/tun
and sending it the TUNSETIFF
ioctl
. If all goes well, an interface is created, the kernel gives you its name and a file descriptor, and that's how you manage it.
There are two catches here:
- The kernel doesn't store the PID of the process that sent the ioctl in
struct tun_struct
(TUN and TAP largely share the same data structures). - A process may mark an interface as persistent, close its file descriptor and thereafter use it as a normal network interface.
In practice, I suspect 2 doesn't happen much. Checking out an openvpn
process with lsof
reveals it's still got its file descriptor to the TAP device open and obviously using it, but since /dev/net/tun
is a sort of multiplexing device like /dev/ptmx
, you can use lsof
to find out what processes are currently using a TUN/TAP device, but you can't know what process is using what device.
There are oblique ways of solving the underlying problem. For OpenVPN, I use a tunnel setup script that names the tunX
/tapX
devices with a more descriptive name that includes the basename of the OpenVPN config file. So, /etc/openvpn/foo.conf
leads to a vpn-foo
device. Then I can correlate the OpenvVPN process with the interface it's using. Haven't had to do this with QEmu/KVM yet, though.