summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Warner <james.warner@comcast.net>2013-11-10 00:00:00 -0600
committerCraig Small <csmall@enc.com.au>2013-11-25 20:57:32 +1100
commit583cdaca1a52420be3533fddc0fd8dab53876850 (patch)
tree34792070f24f4d40952a54678089a3ea0f4fdcc0
parent89c2f28e393830d899e3e91b60c830a6f07d38d5 (diff)
downloadprocps-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.c45
-rw-r--r--proc/readproc.h8
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