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 a01ee3c0b3
Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
89c2f28e39
commit
583cdaca1a
@ -457,19 +457,6 @@ static void oomadj2proc(const char* S, proc_t *restrict P)
|
|||||||
#endif
|
#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[] = {
|
static const char *ns_names[] = {
|
||||||
[IPCNS] = "ipc",
|
[IPCNS] = "ipc",
|
||||||
[MNTNS] = "mnt",
|
[MNTNS] = "mnt",
|
||||||
@ -494,11 +481,20 @@ int get_ns_id(const char *name) {
|
|||||||
return -1;
|
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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NUM_NS; i++)
|
for (i = 0; i < NUM_NS; i++) {
|
||||||
P->ns[i] = _ns2proc(P->tgid, ns_names[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
|
static struct stat sb; // stat() buffer
|
||||||
char *restrict const path = PT->path;
|
char *restrict const path = PT->path;
|
||||||
unsigned flags = PT->flags;
|
unsigned flags = PT->flags;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (unlikely(stat(path, &sb) == -1)) /* no such dirent (anymore) */
|
if (unlikely(stat(path, &sb) == -1)) /* no such dirent (anymore) */
|
||||||
goto next_proc;
|
goto next_proc;
|
||||||
@ -890,11 +885,8 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (unlikely(flags & PROC_FILLNS)) // read /proc/#/ns/*
|
if (unlikely(flags & PROC_FILLNS)) // read /proc/#/ns/*
|
||||||
ns2proc(p);
|
ns2proc(path, p);
|
||||||
else
|
|
||||||
for (i = 0; i < NUM_NS; i++)
|
|
||||||
p->ns[i] = 0;
|
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
next_proc:
|
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 utlbuf_s ub = { NULL, 0 }; // buf for stat,statm,status
|
||||||
static struct stat sb; // stat() buffer
|
static struct stat sb; // stat() buffer
|
||||||
unsigned flags = PT->flags;
|
unsigned flags = PT->flags;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (unlikely(stat(path, &sb) == -1)) /* no such dirent (anymore) */
|
if (unlikely(stat(path, &sb) == -1)) /* no such dirent (anymore) */
|
||||||
goto next_task;
|
goto next_task;
|
||||||
@ -1027,11 +1018,9 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t *restric
|
|||||||
oomadj2proc(ub.buf, t);
|
oomadj2proc(ub.buf, t);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (unlikely(flags & PROC_FILLNS))
|
|
||||||
ns2proc(t);
|
if (unlikely(flags & PROC_FILLNS)) // read /proc/#/task/#/ns/*
|
||||||
else
|
ns2proc(path, t);
|
||||||
for (i = 0; i < NUM_NS; i++)
|
|
||||||
t->ns[i] = 0;
|
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
next_task:
|
next_task:
|
||||||
|
@ -31,14 +31,14 @@ EXTERN_C_BEGIN
|
|||||||
// neither tgid nor tid seemed correct. (in other words, FIXME)
|
// neither tgid nor tid seemed correct. (in other words, FIXME)
|
||||||
#define XXXID tid
|
#define XXXID tid
|
||||||
|
|
||||||
#define NUM_NS 6
|
|
||||||
enum ns_type {
|
enum ns_type {
|
||||||
IPCNS = 0,
|
IPCNS = 0,
|
||||||
MNTNS,
|
MNTNS,
|
||||||
NETNS,
|
NETNS,
|
||||||
PIDNS,
|
PIDNS,
|
||||||
USERNS,
|
USERNS,
|
||||||
UTSNS
|
UTSNS,
|
||||||
|
NUM_NS // total namespaces (fencepost)
|
||||||
};
|
};
|
||||||
extern const char *get_ns_name(int id);
|
extern const char *get_ns_name(int id);
|
||||||
extern int get_ns_id(const char *name);
|
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_score, // oom_score (badness for OOM killer)
|
||||||
oom_adj; // oom_adj (adjustment to OOM score)
|
oom_adj; // oom_adj (adjustment to OOM score)
|
||||||
#endif
|
#endif
|
||||||
ino_t
|
long
|
||||||
ns[NUM_NS]; // ns/* inode number of /proc/<pid>/ns/*
|
ns[NUM_NS]; // (ns subdir) inode number of namespaces
|
||||||
} proc_t;
|
} proc_t;
|
||||||
|
|
||||||
// PROCTAB: data structure holding the persistent information readproc needs
|
// PROCTAB: data structure holding the persistent information readproc needs
|
||||||
|
Loading…
Reference in New Issue
Block a user