From: ebiederm@xmission.com (Eric W. Biederman)
To: Stephen Hemminger <shemminger@vyatta.com>
Cc: <netdev@vger.kernel.org>, "Serge E. Hallyn" <serge@hallyn.com>
Subject: [PATCH for 3.8] iproute2: Add "ip netns pids" and "ip netns identify"
Date: Mon, 26 Nov 2012 17:16:06 -0600 [thread overview]
Message-ID: <87a9u4q7k9.fsf@xmission.com> (raw)
Add command that go between network namespace names and process
identifiers. The code builds and runs agains older kernels but
only works on Linux 3.8+ kernels where I have fixed stat to work
properly.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
I don't know if this is too soon to send this patch to iproute as the
kernel code that fixes stat is currently sitting in my for-next branch
of:
git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git
and has not hit Linus's tree yet. Still the code runs and is harmless
on older kernels so it should be harmless whatever happens with it.
ip/ipnetns.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++
man/man8/ip-netns.8 | 5 ++-
2 files changed, 145 insertions(+), 1 deletions(-)
diff --git a/ip/ipnetns.c b/ip/ipnetns.c
index e41a598..c55fe3a 100644
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -13,6 +13,7 @@
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
+#include <ctype.h>
#include "utils.h"
#include "ip_common.h"
@@ -48,6 +49,8 @@ static void usage(void)
fprintf(stderr, "Usage: ip netns list\n");
fprintf(stderr, " ip netns add NAME\n");
fprintf(stderr, " ip netns delete NAME\n");
+ fprintf(stderr, " ip netns identify PID\n");
+ fprintf(stderr, " ip netns pids NAME\n");
fprintf(stderr, " ip netns exec NAME cmd ...\n");
fprintf(stderr, " ip netns monitor\n");
exit(-1);
@@ -171,6 +174,138 @@ static int netns_exec(int argc, char **argv)
exit(-1);
}
+static int is_pid(const char *str)
+{
+ int ch;
+ for (; (ch = *str); str++) {
+ if (!isdigit(ch))
+ return 0;
+ }
+ return 1;
+}
+
+static int netns_pids(int argc, char **argv)
+{
+ const char *name;
+ char net_path[MAXPATHLEN];
+ int netns;
+ struct stat netst;
+ DIR *dir;
+ struct dirent *entry;
+
+ if (argc < 1) {
+ fprintf(stderr, "No netns name specified\n");
+ return -1;
+ }
+ if (argc > 1) {
+ fprintf(stderr, "extra arguments specified\n");
+ return -1;
+ }
+
+ name = argv[0];
+ snprintf(net_path, sizeof(net_path), "%s/%s", NETNS_RUN_DIR, name);
+ netns = open(net_path, O_RDONLY);
+ if (netns < 0) {
+ fprintf(stderr, "Cannot open network namespace: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ if (fstat(netns, &netst) < 0) {
+ fprintf(stderr, "Stat of netns failed: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ dir = opendir("/proc/");
+ if (!dir) {
+ fprintf(stderr, "Open of /proc failed: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ while((entry = readdir(dir))) {
+ char pid_net_path[MAXPATHLEN];
+ struct stat st;
+ if (!is_pid(entry->d_name))
+ continue;
+ snprintf(pid_net_path, sizeof(pid_net_path), "/proc/%s/ns/net",
+ entry->d_name);
+ if (stat(pid_net_path, &st) != 0)
+ continue;
+ if ((st.st_dev == netst.st_dev) &&
+ (st.st_ino == netst.st_ino)) {
+ printf("%s\n", entry->d_name);
+ }
+ }
+ closedir(dir);
+ return 0;
+
+}
+
+static int netns_identify(int argc, char **argv)
+{
+ const char *pidstr;
+ char net_path[MAXPATHLEN];
+ int netns;
+ struct stat netst;
+ DIR *dir;
+ struct dirent *entry;
+
+ if (argc < 1) {
+ fprintf(stderr, "No pid specified\n");
+ return -1;
+ }
+ if (argc > 1) {
+ fprintf(stderr, "extra arguments specified\n");
+ return -1;
+ }
+ pidstr = argv[0];
+
+ if (!is_pid(pidstr)) {
+ fprintf(stderr, "Specified string '%s' is not a pid\n",
+ pidstr);
+ return -1;
+ }
+
+ snprintf(net_path, sizeof(net_path), "/proc/%s/ns/net", pidstr);
+ netns = open(net_path, O_RDONLY);
+ if (netns < 0) {
+ fprintf(stderr, "Cannot open network namespace: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ if (fstat(netns, &netst) < 0) {
+ fprintf(stderr, "Stat of netns failed: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ dir = opendir(NETNS_RUN_DIR);
+ if (!dir)
+ return 0;
+
+ while((entry = readdir(dir))) {
+ char name_path[MAXPATHLEN];
+ struct stat st;
+
+ if (strcmp(entry->d_name, ".") == 0)
+ continue;
+ if (strcmp(entry->d_name, "..") == 0)
+ continue;
+
+ snprintf(name_path, sizeof(name_path), "%s/%s", NETNS_RUN_DIR,
+ entry->d_name);
+
+ if (stat(name_path, &st) != 0)
+ continue;
+
+ if ((st.st_dev == netst.st_dev) &&
+ (st.st_ino == netst.st_ino)) {
+ printf("%s\n", entry->d_name);
+ }
+ }
+ closedir(dir);
+ return 0;
+
+}
+
static int netns_delete(int argc, char **argv)
{
const char *name;
@@ -298,6 +433,12 @@ int do_netns(int argc, char **argv)
if (matches(*argv, "delete") == 0)
return netns_delete(argc-1, argv+1);
+ if (matches(*argv, "identify") == 0)
+ return netns_identify(argc-1, argv+1);
+
+ if (matches(*argv, "pids") == 0)
+ return netns_pids(argc-1, argv+1);
+
if (matches(*argv, "exec") == 0)
return netns_exec(argc-1, argv+1);
diff --git a/man/man8/ip-netns.8 b/man/man8/ip-netns.8
index 349ee7e..e639836 100644
--- a/man/man8/ip-netns.8
+++ b/man/man8/ip-netns.8
@@ -1,4 +1,4 @@
-.TH IP\-NETNS 8 "20 Dec 2011" "iproute2" "Linux"
+.TH IP\-NETNS 8 "26 Dec 2012" "iproute2" "Linux"
.SH NAME
ip-netns \- process network namespace management
.SH SYNOPSIS
@@ -58,6 +58,9 @@ their traditional location in /etc.
.SS ip netns delete NAME - delete the name of a network namespace
.SS ip netns exec NAME cmd ... - Run cmd in the named network namespace
+.SS ip netns pids NAME - Report processes in the named network namespace
+.SS ip netns identify PID - Report network namespaces names for process
+
.SH EXAMPLES
.SH SEE ALSO
--
1.7.5.4
next reply other threads:[~2012-11-26 23:16 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-26 23:16 Eric W. Biederman [this message]
2012-11-27 18:00 ` [PATCH for 3.8] iproute2: Add "ip netns pids" and "ip netns identify" Ben Hutchings
2013-01-18 0:23 ` Eric W. Biederman
2013-01-18 1:00 ` Ben Hutchings
2013-01-18 1:27 ` Eric W. Biederman
2013-01-18 9:41 ` David Laight
2013-01-18 13:53 ` Ben Hutchings
2013-01-18 18:49 ` Eric W. Biederman
2013-01-21 9:52 ` David Laight
2013-01-18 0:44 ` [PATCH iproute-3.8 0/6] ip netns bug fixes and enhancements Eric W. Biederman
2013-01-18 0:45 ` [PATCH iproute2-3.8 1/6] iproute2: Don't propogate mounts out of ip Eric W. Biederman
2013-01-18 0:46 ` [PATCH iproute2-3.8 2/6] iproute2: Normalize return codes in "ip netns" Eric W. Biederman
2013-01-18 0:46 ` [PATCH iproute2-3.8 3/6] iproute2: Improve "ip netns add" failure error message Eric W. Biederman
2013-01-18 0:47 ` [PATCH iproute2-3.8 4/6] iproute2: Make "ip netns delete" more likely to succeed Eric W. Biederman
2013-01-18 0:47 ` [PATCH iproute2-3.8 5/6] iproute2: Fill in the ip-netns.8 manpage Eric W. Biederman
2013-01-18 0:48 ` [PATCH iproute2-3.8 6/6] iproute2: Add "ip netns pids" and "ip netns identify" Eric W. Biederman
2013-02-07 0:56 ` [PATCH iproute-3.8 0/6] ip netns bug fixes and enhancements Vijay Subramanian
2013-02-07 8:57 ` Eric W. Biederman
2013-02-07 18:17 ` Vijay Subramanian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87a9u4q7k9.fsf@xmission.com \
--to=ebiederm@xmission.com \
--cc=netdev@vger.kernel.org \
--cc=serge@hallyn.com \
--cc=shemminger@vyatta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.