diff --git a/proc/pids.c b/proc/pids.c index 54fd3a37..fae340e0 100644 --- a/proc/pids.c +++ b/proc/pids.c @@ -152,6 +152,8 @@ REG_set(ADDR_CODE_START, ul_int, start_code) REG_set(ADDR_CURR_EIP, ul_int, kstk_eip) REG_set(ADDR_CURR_ESP, ul_int, kstk_esp) REG_set(ADDR_STACK_START, ul_int, start_stack) +REG_set(AUTOGRP_ID, s_int, autogrp_id) +REG_set(AUTOGRP_NICE, s_int, autogrp_nice) STR_set(CGNAME, cgname) STR_set(CGROUP, cgroup) VEC_set(CGROUP_V, cgroup_v) @@ -390,6 +392,8 @@ srtDECL(noop) { #define x_ogroup PROC_FILL_OGROUPS #define x_ouser PROC_FILL_OUSERS #define x_supgrp PROC_FILL_SUPGRP + // placed here so an 'f' prefix wouldn't make 'em first +#define z_autogrp PROC_FILLAUTOGRP typedef void (*SET_t)(struct pids_info *, struct pids_result *, proc_t *); typedef void (*FRE_t)(struct pids_result *); @@ -431,6 +435,8 @@ static struct { { RS(ADDR_CURR_EIP), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, { RS(ADDR_CURR_ESP), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, { RS(ADDR_STACK_START), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(AUTOGRP_ID), z_autogrp, NULL, QS(s_int), 0, TS(s_int) }, + { RS(AUTOGRP_NICE), z_autogrp, NULL, QS(s_int), 0, TS(s_int) }, { RS(CGNAME), x_cgroup, FF(str), QS(str), 0, TS(str) }, { RS(CGROUP), x_cgroup, FF(str), QS(str), 0, TS(str) }, { RS(CGROUP_V), v_cgroup, FF(strv), QS(strv), 0, TS(strv) }, @@ -609,6 +615,7 @@ enum pids_item PIDS_logical_end = MAXTABLE(Item_table); #undef x_ogroup #undef x_ouser #undef x_supgrp +#undef z_autogrp // ___ History Support Private Functions |||||||||||||||||||||||||||||||||||||| diff --git a/proc/pids.h b/proc/pids.h index 529da137..a14a28d4 100644 --- a/proc/pids.h +++ b/proc/pids.h @@ -37,6 +37,8 @@ enum pids_item { PIDS_ADDR_CURR_EIP, // ul_int stat: eip PIDS_ADDR_CURR_ESP, // ul_int stat: esp PIDS_ADDR_STACK_START, // ul_int stat: start_stack + PIDS_AUTOGRP_ID, // s_int autogroup + PIDS_AUTOGRP_NICE, // s_int autogroup PIDS_CGNAME, // str derived from CGROUP ':name=' PIDS_CGROUP, // str cgroup PIDS_CGROUP_V, // strv cgroup, as *str[] diff --git a/proc/readproc.c b/proc/readproc.c index 84080036..03971c2f 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -1066,6 +1066,28 @@ static char *readlink_exe (const char *path){ } + // Provide the autogroup fields (or -1 if not available) +static void autogroup_fill (const char *path, proc_t *p) { + char buf[PROCPATHLEN], *str; + int fd, in; + + p->autogrp_id = -1; + snprintf(buf, sizeof(buf), "%s/autogroup", path); + if ((fd = open(buf, O_RDONLY, 0)) != -1) { + in = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (in > 0) { + buf[in] = '\0'; + if ((str = strstr(buf, "-"))) + p->autogrp_id = atoi(++str); + if ((str = strstr(buf, "nice"))) + p->autogrp_nice = atoi(str + sizeof("nice")); + // above sizeof includes null, skips space ahead of # + } + } +} + + /////////////////////////////////////////////////////////////////////// /* These are some nice GNU C expression subscope "inline" functions. @@ -1203,6 +1225,9 @@ static proc_t *simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons rc += 1; } + if (flags & PROC_FILLAUTOGRP) // value the 2 autogroup fields + autogroup_fill(path, p); + if (rc == 0) return p; errno = ENOMEM; next_proc: @@ -1322,6 +1347,9 @@ static proc_t *simple_readtask(PROCTAB *restrict const PT, proc_t *restrict cons if (flags & PROC_FILL_LUID) t->luid = login_uid(path); + if (flags & PROC_FILLAUTOGRP) // value the 2 autogroup fields + autogroup_fill(path, t); + if (rc == 0) return t; errno = ENOMEM; next_task: diff --git a/proc/readproc.h b/proc/readproc.h index 2a8b1c0b..77db6967 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -177,7 +177,9 @@ typedef struct proc_t { *lxcname, // n/a lxc container name *exe; // exe executable path + name int - luid; // loginuid user id at login + luid, // loginuid user id at login + autogrp_id, // autogroup autogroup number (id) + autogrp_nice; // autogroup autogroup nice value } proc_t; // PROCTAB: data structure holding the persistent information readproc needs @@ -253,6 +255,9 @@ typedef struct PROCTAB { #define PROC_FILL_OGROUPS ( 0x00400000 | PROC_FILLSTATUS ) // obtain other group names #define PROC_FILL_SUPGRP ( 0x00800000 | PROC_FILLSTATUS ) // obtain supplementary group names +// and let's put new flags here ... +#define PROC_FILLAUTOGRP 0x01000000 // fill in proc_t autogroup stuff + // it helps to give app code a few spare bits #define PROC_SPARE_1 0x10000000 #define PROC_SPARE_2 0x20000000