diff options
author | Jim Warner <james.warner@comcast.net> | 2013-11-10 00:00:00 -0600 |
---|---|---|
committer | Craig Small <csmall@enc.com.au> | 2013-11-25 20:57:32 +1100 |
commit | 583cdaca1a52420be3533fddc0fd8dab53876850 (patch) | |
tree | 34792070f24f4d40952a54678089a3ea0f4fdcc0 | |
parent | 89c2f28e393830d899e3e91b60c830a6f07d38d5 (diff) | |
download | procps-ng-583cdaca1a52420be3533fddc0fd8dab53876850.tar.gz |
library: normalize recently added namespaces interface
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>
-rw-r--r-- | proc/readproc.c | 45 | ||||
-rw-r--r-- | proc/readproc.h | 8 |
2 files changed, 21 insertions, 32 deletions
diff --git a/proc/readproc.c b/proc/readproc.c index 05d0189..286e173 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -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: diff --git a/proc/readproc.h b/proc/readproc.h index 643fb26..817277a 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -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 |