Message ID | 1472062105-17995-1-git-send-email-hannes@stressinduktion.org |
---|---|
State | Accepted, archived |
Delegated to: | stephen hemminger |
Headers | show |
On Wed, 24 Aug 2016 20:08:25 +0200 Hannes Frederic Sowa <hannes@stressinduktion.org> wrote: > Show which processes are using which tun/tap devices, e.g.: > > $ ip -d tuntap > tun0: tun > Attached to processes: vpnc(9531) > vnet0: tap vnet_hdr > Attached to processes: qemu-system-x86(10442) > virbr0-nic: tap UNKNOWN_FLAGS:800 > Attached to processes: > > Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> I think reading all of /proc like this will scale really badly on large systems. Why reinvent lsof?
On 25.08.2016 17:44, Stephen Hemminger wrote: > On Wed, 24 Aug 2016 20:08:25 +0200 > Hannes Frederic Sowa <hannes@stressinduktion.org> wrote: > >> Show which processes are using which tun/tap devices, e.g.: >> >> $ ip -d tuntap >> tun0: tun >> Attached to processes: vpnc(9531) >> vnet0: tap vnet_hdr >> Attached to processes: qemu-system-x86(10442) >> virbr0-nic: tap UNKNOWN_FLAGS:800 >> Attached to processes: >> >> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> > > I think reading all of /proc like this will scale really badly on large systems. Yes, it is quite heavy weight but so far I didn't see any major latency on even more busy systems (tens of thousands of fds). Also this code is only entered if details are requested. I don't see a cheaper way to determine those information currently without further patches (which probably all will have the same n:m problem, as fds can be shared between multiple processes). > Why reinvent lsof? lsof currently doesn't provide this information and would also have to brute force in the same way (it scans all fds anyway, thought). In my opinion it is just very helpful on virtualization boxes to quickly identify the vm associated with an interface. I would propose that in case we see people reporting latency issues to speed it up in possibly two ways: a) not glob over the whole pid/fd space, but just take one number at a time, e.g. /proc/1*/fd/*, /proc/2*/fd/* etc. b) or/and we just push everything into an internal hash table so for multiple interfaces we don't need to walk again. I would just try to not add the complexity if it is not necessary. Thoughts? Bye, Hannes
On Wed, 24 Aug 2016 20:08:25 +0200 Hannes Frederic Sowa <hannes@stressinduktion.org> wrote: > Show which processes are using which tun/tap devices, e.g.: > > $ ip -d tuntap > tun0: tun > Attached to processes: vpnc(9531) > vnet0: tap vnet_hdr > Attached to processes: qemu-system-x86(10442) > virbr0-nic: tap UNKNOWN_FLAGS:800 > Attached to processes: > > Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Applied, but needed a followon change to fix some style issues.
On 01.09.2016 18:06, Stephen Hemminger wrote: > On Wed, 24 Aug 2016 20:08:25 +0200 > Hannes Frederic Sowa <hannes@stressinduktion.org> wrote: > >> Show which processes are using which tun/tap devices, e.g.: >> >> $ ip -d tuntap >> tun0: tun >> Attached to processes: vpnc(9531) >> vnet0: tap vnet_hdr >> Attached to processes: qemu-system-x86(10442) >> virbr0-nic: tap UNKNOWN_FLAGS:800 >> Attached to processes: >> >> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> > > Applied, but needed a followon change to fix some style issues. Thanks, the clean up looks good!
diff --git a/ip/iptuntap.c b/ip/iptuntap.c index 43774f96e335ef..b5aa0542c1f8f2 100644 --- a/ip/iptuntap.c +++ b/ip/iptuntap.c @@ -25,6 +25,7 @@ #include <fcntl.h> #include <dirent.h> #include <errno.h> +#include <glob.h> #include "rt_names.h" #include "utils.h" @@ -273,6 +274,109 @@ static void print_flags(long flags) printf(" UNKNOWN_FLAGS:%lx", flags); } +static char *pid_name(pid_t pid) +{ + char *comm; + FILE *f; + int err; + + err = asprintf(&comm, "/proc/%d/comm", pid); + if (err < 0) + return NULL; + + f = fopen(comm, "r"); + free(comm); + if (!f) { + perror("fopen"); + return NULL; + } + + if (fscanf(f, "%ms\n", &comm) != 1) { + perror("fscanf"); + comm = NULL; + } + + + if (fclose(f)) + perror("fclose"); + + return comm; +} + +static void show_processes(const char *name) +{ + glob_t globbuf = { }; + char **fd_path; + int err; + + err = glob("/proc/[0-9]*/fd/[0-9]*", GLOB_NOSORT, + NULL, &globbuf); + if (err) + return; + + fd_path = globbuf.gl_pathv; + while (*fd_path) { + const char *dev_net_tun = "/dev/net/tun"; + const size_t linkbuf_len = strlen(dev_net_tun) + 2; + char linkbuf[linkbuf_len], *fdinfo; + int pid, fd; + FILE *f; + + if (sscanf(*fd_path, "/proc/%d/fd/%d", &pid, &fd) != 2) + goto next; + + if (pid == getpid()) + goto next; + + err = readlink(*fd_path, linkbuf, linkbuf_len - 1); + if (err < 0) { + perror("readlink"); + goto next; + } + linkbuf[err] = '\0'; + if (strcmp(dev_net_tun, linkbuf)) + goto next; + + if (asprintf(&fdinfo, "/proc/%d/fdinfo/%d", pid, fd) < 0) + goto next; + + f = fopen(fdinfo, "r"); + free(fdinfo); + if (!f) { + perror("fopen"); + goto next; + } + + while (!feof(f)) { + char *key = NULL, *value = NULL; + + err = fscanf(f, "%m[^:]: %ms\n", &key, &value); + if (err == EOF) { + if (ferror(f)) + perror("fscanf"); + break; + } else if (err == 2 && + !strcmp("iff", key) && !strcmp(name, value)) { + char *pname = pid_name(pid); + printf(" %s(%d)", pname ? pname : "<NULL>", pid); + free(pname); + } + + free(key); + free(value); + } + if (fclose(f)) + perror("fclose"); + +next: + ++fd_path; + } + + globfree(&globbuf); + return; +} + + static int do_show(int argc, char **argv) { DIR *dir; @@ -302,6 +406,11 @@ static int do_show(int argc, char **argv) if (group != -1) printf(" group %ld", group); printf("\n"); + if (show_details) { + printf("\tAttached to processes:"); + show_processes(d->d_name); + printf("\n"); + } } closedir(dir); return 0;
Show which processes are using which tun/tap devices, e.g.: $ ip -d tuntap tun0: tun Attached to processes: vpnc(9531) vnet0: tap vnet_hdr Attached to processes: qemu-system-x86(10442) virbr0-nic: tap UNKNOWN_FLAGS:800 Attached to processes: Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> --- ip/iptuntap.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+)