]> granicus.if.org Git - procps-ng/commitdiff
library: normalize recently added namespaces interface
authorJim Warner <james.warner@comcast.net>
Sun, 10 Nov 2013 06:00:00 +0000 (00:00 -0600)
committerCraig Small <csmall@enc.com.au>
Mon, 25 Nov 2013 09:57:32 +0000 (20:57 +1100)
While 'invisible' thread subdirectories are accessible
under /proc/ with stat/opendir calls, they have always
been treated as non-existent, as is true with readdir.

This patch trades the /proc/#/ns access convention for
the more proper /proc/#/task/#/ns approach when thread
access is desired. In addition some namespace code has
been simplified and made slightly more efficient given
the calloc nature of proc_t acquisition and its reuse.

Reference(s):
commit a01ee3c0b32d4c39aa83066ed61103343469527e

Signed-off-by: Jim Warner <james.warner@comcast.net>
proc/readproc.c
proc/readproc.h

index 05d0189a087f35e0f51ab496806ed9720fe0e034..286e17364598023d54fa5650f5bf7219854173fc 100644 (file)
@@ -457,19 +457,6 @@ static void oomadj2proc(const char* S, proc_t *restrict P)
 #endif
 ///////////////////////////////////////////////////////////////////////
 
-static ino_t _ns2proc(unsigned pid, const char *ns)
-{
-    struct stat s;
-    char filename[40];
-
-    snprintf(filename, sizeof(filename), "/proc/%i/ns/%s", pid, ns);
-
-    if (stat(filename, &s) == -1)
-        return 0;
-
-    return s.st_ino;
-}
-
 static const char *ns_names[] = {
     [IPCNS] = "ipc",
     [MNTNS] = "mnt",
@@ -494,11 +481,20 @@ int get_ns_id(const char *name) {
     return -1;
 }
 
-static void ns2proc(proc_t *restrict P) {
+static void ns2proc(const char *directory, proc_t *restrict p) {
+    char path[PROCPATHLEN];
+    struct stat sb;
     int i;
 
-    for (i = 0; i < NUM_NS; i++)
-        P->ns[i] = _ns2proc(P->tgid, ns_names[i]);
+    for (i = 0; i < NUM_NS; i++) {
+        snprintf(path, sizeof(path), "%s/ns/%s", directory, ns_names[i]);
+        if (0 == stat(path, &sb))
+            p->ns[i] = (long)sb.st_ino;
+#if 0
+        else                           // this allows a caller to distinguish
+            p->ns[i] = -errno;         // between the ENOENT or EACCES errors
+#endif
+    }
 }
 ///////////////////////////////////////////////////////////////////////
 
@@ -802,7 +798,6 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons
     static struct stat sb;     // stat() buffer
     char *restrict const path = PT->path;
     unsigned flags = PT->flags;
-    int i;
 
     if (unlikely(stat(path, &sb) == -1))        /* no such dirent (anymore) */
         goto next_proc;
@@ -890,11 +885,8 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons
     }
 #endif
 
-    if (unlikely(flags & PROC_FILLNS))         // read /proc/#/ns/*
-        ns2proc(p);
-    else
-        for (i = 0; i < NUM_NS; i++)
-             p->ns[i] = 0;
+    if (unlikely(flags & PROC_FILLNS))          // read /proc/#/ns/*
+        ns2proc(path, p);
 
     return p;
 next_proc:
@@ -914,7 +906,6 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric
     static struct utlbuf_s ub = { NULL, 0 };    // buf for stat,statm,status
     static struct stat sb;     // stat() buffer
     unsigned flags = PT->flags;
-    int i;
 
     if (unlikely(stat(path, &sb) == -1))        /* no such dirent (anymore) */
         goto next_task;
@@ -1027,11 +1018,9 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric
             oomadj2proc(ub.buf, t);
     }
 #endif
-    if (unlikely(flags & PROC_FILLNS))
-        ns2proc(t);
-    else
-        for (i = 0; i < NUM_NS; i++)
-            t->ns[i] = 0;
+
+    if (unlikely(flags & PROC_FILLNS))                  // read /proc/#/task/#/ns/*
+        ns2proc(path, t);
 
     return t;
 next_task:
index 643fb2693068855f80fef2e086dadd5f5bde0bfc..817277ac9653087d113ce2f500f093224fd6846a 100644 (file)
@@ -31,14 +31,14 @@ EXTERN_C_BEGIN
 // neither tgid nor tid seemed correct. (in other words, FIXME)
 #define XXXID tid
 
-#define NUM_NS 6
 enum ns_type {
     IPCNS = 0,
     MNTNS,
     NETNS,
     PIDNS,
     USERNS,
-    UTSNS
+    UTSNS,
+    NUM_NS         // total namespaces (fencepost)
 };
 extern const char *get_ns_name(int id);
 extern int get_ns_id(const char *name);
@@ -169,8 +169,8 @@ typedef struct proc_t {
         oom_score,      // oom_score       (badness for OOM killer)
         oom_adj;        // oom_adj         (adjustment to OOM score)
 #endif
-    ino_t
-        ns[NUM_NS];     // ns/*            inode number of /proc/<pid>/ns/*
+    long
+        ns[NUM_NS];     // (ns subdir)     inode number of namespaces
 } proc_t;
 
 // PROCTAB: data structure holding the persistent information readproc needs