]> granicus.if.org Git - procps-ng/commitdiff
library: add provision for displaying autogroup values
authorJim Warner <james.warner@comcast.net>
Thu, 5 Aug 2021 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@dropbear.xyz>
Mon, 9 Aug 2021 12:00:23 +0000 (22:00 +1000)
In the link referenced below there's an explanation of
the linux autogroup feature which has been around ever
since linux-2.6.38. With that explanation there's also
surprising (maybe shocking) revelations about the nice
and renice commands if CONFIG_SCHED_AUTOGROUP was set.

When autogroups are active, such programs are rendered
mostly useless because the nice value will only affect
scheduling priority relative to other processes in the
same autogroup. In order to accomplish what we thought
of as renice, that nice value in /proc/<pid>/autogroup
must be changed. Altering any single member of a group
will also affect every other member of that autogroup.

So, this commit will set the stage for users of newlib
to display autogroup identifiers plus their associated
nice values (now that their importance is understood).

Reference(s):
https://github.com/nlburgin/reallynice

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

index 54fd3a37113eb557479186afb4ce6530a985dc00..fae340e028651de1958dfc2fa292cc7a7ffd5542 100644 (file)
@@ -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 ||||||||||||||||||||||||||||||||||||||
index 529da137ae8287cd91fc07666ef8ee5997fddee6..a14a28d4bd9ded625ebfca91a62f91b7249ef087 100644 (file)
@@ -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[]
index 840800366fbd90e824d73784c7583a6e34699a1d..03971c2f153b89acdf8034942ee1c70fbdafa714 100644 (file)
@@ -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:
index 2a8b1c0b2e41a53315248ae703f4add2051d2538..77db696735f50f05a61ee6b58f640e18ed9fbdba 100644 (file)
@@ -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