]> granicus.if.org Git - procps-ng/commitdiff
top: added provision for autogroup nice (AGNI) changes
authorJim Warner <james.warner@comcast.net>
Sun, 24 Apr 2022 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@dropbear.xyz>
Tue, 26 Apr 2022 10:18:15 +0000 (20:18 +1000)
When autogroups are active programs such as renice and
nice are basically useless because the nice value will
only affect the target task priority relative to other
processes in the same autogroup. So to accomplish what
we thought of as renice, /proc/<pid>/autogroup must be
changed. Altering a single member in an autogroup will
also affect every other member of that same autogroup.

Since top's renice provision ('r') suffers constraints
like those of the stand alone nice/renice programs, we
will now provide a means to manipulate that nice value
found within some process' /proc/<pid>/autogroup file.

[ to alter this file for other user's tasks requires ]
[ root privileges, as does setting a negative value. ]

[ however, unlike that 'r' command, this new command ]
[ allows raising *and* lowering all positive values. ]

Reference(s):
. Aug 2021, autogroups added to librady
commit 631e5d91f3c34374a095b8351235627545617de7
. Aug 2021, autogroups added to top
commit b789b46f84da590a39afd8d74c76c2f5e5436d40

Signed-off-by: Jim Warner <james.warner@comcast.net>
top/top.c
top/top.h
top/top_nls.c
top/top_nls.h

index b63c15580984aeb932ad0997b88273cce8441a66..e321bc598e742dc7aff2d2fa6539ebf9ea3c9a82 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -5223,6 +5223,32 @@ static void keys_global (int ch) {
             Rc.tics_scaled = 0;
 #endif
          break;
+      case kbd_CtrlR:
+         if (Secure_mode)
+            show_msg(N_txt(NOT_onsecure_txt));
+         else {
+            int def = PID_VAL(EU_PID, s_int, w->ppt[w->begtask]),
+                pid = get_int(fmtmk(N_fmt(GET_pid2nice_fmt), def));
+            if (pid > GET_NUM_ESC) {
+               int val, fd;
+               if (pid == GET_NUM_NOT) pid = def;
+               val = get_int(fmtmk(N_fmt(AGNI_valueof_fmt), pid));
+               if (val > GET_NUM_NOT) {
+                  if (val < -20 || val > +19)
+                     show_msg(N_txt(AGNI_invalid_txt));
+                  else if (0 > (fd = open(fmtmk("/proc/%d/autogroup", pid), O_WRONLY)))
+                     show_msg(fmtmk(N_fmt(AGNI_notopen_fmt), strerror(errno)));
+                  else {
+                     char buf[TNYBUFSIZ];
+                     snprintf(buf, sizeof(buf), "%d", val);
+                     if (0 >= write(fd, buf, strlen(buf)))
+                        show_msg(fmtmk(N_fmt(AGNI_nowrite_fmt), strerror(errno)));
+                     close(fd);
+                  }
+               }
+            }
+         }
+         break;
       case kbd_ENTER:             // these two have the effect of waking us
       case kbd_SPACE:             // from 'pselect', refreshing the display
          break;                   // and updating any hot-plugged resources
@@ -6063,7 +6089,7 @@ static void do_key (int ch) {
       { keys_global,
          { '?', 'B', 'd', 'E', 'e', 'f', 'g', 'H', 'h'
          , 'I', 'k', 'r', 's', 'X', 'Y', 'Z', '0'
-         , kbd_CtrlE, kbd_ENTER, kbd_SPACE, '\0' } },
+         , kbd_CtrlE, kbd_CtrlR, kbd_ENTER, kbd_SPACE, '\0' } },
       { keys_summary,
          { '!', '1', '2', '3', '4', 'C', 'l', 'm', 't', '\0' } },
       { keys_task,
index 5b9436f42a60b7d4b10810490fc794d45fa7e9a1..0627170073629a7c9101e6140331066e0474e59a 100644 (file)
--- a/top/top.h
+++ b/top/top.h
@@ -130,6 +130,7 @@ char *strcasestr(const char *haystack, const char *needle);
    /* the above might seem pretty stingy, until you consider that with every
       field displayed the column header would be approximately 250 bytes
       -- so SCREENMAX provides for all fields plus a 250+ byte command line */
+#define TNYBUFSIZ    16
 #define CAPBUFSIZ    32
 #define CLRBUFSIZ    64
 #define PFLAGSSIZ   128
@@ -169,8 +170,9 @@ char *strcasestr(const char *haystack, const char *needle);
 #define kbd_BKSP   137
 #define kbd_INS    138
 #define kbd_DEL    139
-#define kbd_CtrlO  '\017'
 #define kbd_CtrlE  '\005'
+#define kbd_CtrlO  '\017'
+#define kbd_CtrlR  '\022'
 
         /* Special value in Pseudo_row to force an additional procs refresh
            -- used at startup and for task/thread mode transitions */
index bdf8ad1fa1d2181b3e4fbdc508713a13e294a5d4..23a83851ea7a05fd2c4e2c6426debe39b81f2bd6 100644 (file)
@@ -584,6 +584,10 @@ static void build_norm_nlstab (void) {
    Norm_nlstab[X_SEMAPHORES_fmt] = _("failed sem_init() at %d: %s");
    Norm_nlstab[X_THREADINGS_fmt] = _("failed pthread_create() at %d: %s");
    Norm_nlstab[X_RESTRICTED_txt] = _("sorry, restricted namespace with reduced functionality");
+   Norm_nlstab[AGNI_valueof_fmt] = _("set pid %d AGNI value to");
+   Norm_nlstab[AGNI_invalid_txt] = _("valid AGNI range is -20 to +19");
+   Norm_nlstab[AGNI_notopen_fmt] = _("autogroup open failed, %s");
+   Norm_nlstab[AGNI_nowrite_fmt] = _("autogroup write failed, %s");
 }
 
 
@@ -718,7 +722,7 @@ static void build_uniq_nlstab (void) {
    .                 also imbedded in the translatable text (along with escape seqs)
    .                 should never themselves be translated. */
    Uniq_nlstab[KEYS_helpext_fmt] = _(""
-      "  k,r       Manipulate tasks: '~1k~2' kill; '~1r~2' renice\n"
+      "  k,r,^R,   Tasks: '~1k~2' kill; '~1r~2' renice; ~1Ctrl~2+'~1R~2' renice autogroup\n"
       "  d or s    Set update interval\n");
 
 /* Translation Hint:
index a9c1453360619e458a3184acd01b3a1cb6570610..8ae505f1b5480c95a3a7b827bd84c10f41412baf 100644 (file)
@@ -60,6 +60,7 @@ extern const char *Uniq_nlstab[];
          * from any text also containiing c-format specifiers.
          */
 enum norm_nls {
+   AGNI_invalid_txt, AGNI_notopen_fmt, AGNI_nowrite_fmt, AGNI_valueof_fmt,
    AMT_exxabyte_txt, AMT_gigabyte_txt, AMT_kilobyte_txt, AMT_megabyte_txt,
    AMT_petabyte_txt, AMT_terabyte_txt, BAD_delayint_fmt, BAD_integers_txt,
    BAD_max_task_txt, BAD_memscale_fmt, BAD_mon_pids_fmt, BAD_niterate_fmt,