ip vrf: Add command name next to pid

'ip vrf pids' is used to list processes bound to a vrf, but it only
shows the pid leaving a lot of work for the user. Add the command
name to the output. With this patch you get the more user friendly:

    $ ip vrf pids mgmt
     1121  ntpd
     1418  gdm-session-wor
     1488  gnome-session
     1491  dbus-launch
     1492  dbus-daemon
     1565  sshd
     ...

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
This commit is contained in:
David Ahern 2017-04-14 16:09:56 -07:00 committed by Stephen Hemminger
parent c6858ef431
commit 0da8250be8
3 changed files with 57 additions and 10 deletions

View File

@ -260,5 +260,6 @@ int get_real_family(int rtm_type, int rtm_family);
int cmd_exec(const char *cmd, char **argv, bool do_fork);
int make_path(const char *path, mode_t mode);
char *find_cgroup2_mount(void);
int get_command_name(const char *pid, char *comm, size_t len);
#endif /* __UTILS_H__ */

View File

@ -111,27 +111,31 @@ static void read_cgroup_pids(const char *base_path, char *name)
{
char path[PATH_MAX];
char buf[4096];
ssize_t n;
int fd;
FILE *fp;
if (snprintf(path, sizeof(path), "%s/vrf/%s%s",
base_path, name, CGRP_PROC_FILE) >= sizeof(path))
return;
fd = open(path, O_RDONLY);
if (fd < 0)
fp = fopen(path, "r");
if (!fp)
return; /* no cgroup file, nothing to show */
/* dump contents (pids) of cgroup.procs */
while (1) {
n = read(fd, buf, sizeof(buf) - 1);
if (n <= 0)
break;
while (fgets(buf, sizeof(buf), fp)) {
char *nl, comm[32];
printf("%s", buf);
nl = strchr(buf, '\n');
if (nl)
*nl = '\0';
if (get_command_name(buf, comm, sizeof(comm)))
strcpy(comm, "<terminated?>");
printf("%5s %s\n", buf, comm);
}
close(fd);
fclose(fp);
}
/* recurse path looking for PATH[/NETNS]/vrf/NAME */

View File

@ -14,6 +14,7 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/mount.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@ -149,3 +150,44 @@ out:
return rc;
}
int get_command_name(const char *pid, char *comm, size_t len)
{
char path[PATH_MAX];
char line[128];
FILE *fp;
if (snprintf(path, sizeof(path),
"/proc/%s/status", pid) >= sizeof(path)) {
return -1;
}
fp = fopen(path, "r");
if (!fp)
return -1;
comm[0] = '\0';
while (fgets(line, sizeof(line), fp)) {
char *nl, *name;
name = strstr(line, "Name:");
if (!name)
continue;
name += 5;
while (isspace(*name))
name++;
nl = strchr(name, '\n');
if (nl)
*nl = '\0';
strncpy(comm, name, len - 1);
comm[len - 1] = '\0';
break;
}
fclose(fp);
return 0;
}