]> granicus.if.org Git - procps-ng/commitdiff
First cut at subset=pid proc mount handling
authorCraig Small <csmall@dropbear.xyz>
Thu, 16 Dec 2021 09:36:00 +0000 (20:36 +1100)
committerCraig Small <csmall@dropbear.xyz>
Thu, 16 Dec 2021 09:36:00 +0000 (20:36 +1100)
The procfs mount option subset=pid only shows the processes, not things
such as /proc/stat etc.

For certain programs, this should mean they still work, but have reduced
functionality. This is the first cut at some of them.

pgrep - Removed always loading uptime which we never used anyway. The
program now works fine unless we use --older. Add note in man page
stating it will silently fail.

ps - Load boot time and memory total only when required instead of
always. Changed the error messages to something the user actually
cares about "can't get system boot time" vs "create a structure".
Works for most fields except starts and percent memory.

uptime - Give more useful error messages if uptime not available.

vmstat - move header generation after testing for required proc
files, makes the default output more consistent with the rest
of the options.

References:
 procps-ng/procps#227
 https://www.kernel.org/doc/html/latest/filesystems/proc.html#chapter-4-configuring-procfs
 https://github.com/torvalds/linux/commit/6814ef2d992af09451bbeda4770daa204461329e

Signed-off-by: Craig Small <csmall@dropbear.xyz>
pgrep.1
pgrep.c
ps/output.c
uptime.c
vmstat.c

diff --git a/pgrep.1 b/pgrep.1
index 0d836844f2e285fa81786eaee62e63577838b645..e29e6e1a741ca373d398e2589692b52109d11f6d 100644 (file)
--- a/pgrep.1
+++ b/pgrep.1
@@ -7,7 +7,7 @@
 .\" the Free Software Foundation; either version 2 of the License, or
 .\" (at your option) any later version.
 .\"
-.TH PGREP "1" "2021-10-26" "procps-ng" "User Commands"
+.TH PGREP "1" "2021-12-25" "procps-ng" "User Commands"
 .SH NAME
 pgrep, pkill, pidwait \- look up, signal, or wait for processes based on name and other attributes
 .SH SYNOPSIS
@@ -266,6 +266,10 @@ or
 .B pidwait
 process will never report itself as a
 match.
+.PP
+The
+.B \-O \-\-older
+option will silently fail if /proc is mounted with the \fIsubset=pid\fR option.
 .SH BUGS
 The options
 .B \-n
diff --git a/pgrep.c b/pgrep.c
index cbcb4cb151acf3acbac8531ec3383e01b7e90b51..1a0041c7f0fe021e2a8761b4c174d40c4662c336 100644 (file)
--- a/pgrep.c
+++ b/pgrep.c
@@ -585,13 +585,9 @@ static struct el * select_procs (int *num)
     char *cmdoutput = xmalloc(cmdlen);
     char *task_cmdline;
     enum pids_fetch_type which;
-    double uptime_secs;
 
     preg = do_regcomp();
 
-    if (procps_uptime(&uptime_secs, NULL) < 0)
-        xerrx(EXIT_FAILURE, "uptime");
-
     if (opt_newest) saved_start_time =  0ULL;
     else saved_start_time = ~0ULL;
 
index 9157b16abab670618f91ddcf6cddc46465f7423d..bd79d9b0a34545aa9be39c6174878a59a0bb7cb2 100644 (file)
@@ -86,29 +86,36 @@ static int wide_signals;  /* true if we have room */
 
 static time_t seconds_since_1970;
 
-static unsigned int boot_time;
-static unsigned long memory_total;
 
 extern long Hertz;
 
 
-static void get_boot_time(void)
+static unsigned int boot_time(void)
 {
+    static unsigned int boot_time = 0;
     struct stat_info *stat_info = NULL;
-    if (procps_stat_new(&stat_info) < 0)
-        xerrx(EXIT_FAILURE, _("Unable to create NEW ystem stat structure"));
-    boot_time = STAT_GET(stat_info, STAT_SYS_TIME_OF_BOOT, ul_int);
-    procps_stat_unref(&stat_info);
+    if (boot_time == 0) {
+        if (procps_stat_new(&stat_info) < 0)
+             xerrx(EXIT_FAILURE, _("Unable to get system boot time"));
+        boot_time = STAT_GET(stat_info, STAT_SYS_TIME_OF_BOOT, ul_int);
+        procps_stat_unref(&stat_info);
+    }
+    return boot_time;
 }
 
-static void get_memory_total()
+static unsigned long memory_total()
 {
+    static unsigned long memory_total = 0;
     struct meminfo_info *mem_info = NULL;
-    if (procps_meminfo_new(&mem_info) < 0)
-       xerrx(EXIT_FAILURE,
-               _("Unable to create meminfo structure"));
-    memory_total = MEMINFO_GET(mem_info, MEMINFO_MEM_TOTAL, ul_int);
-    procps_meminfo_unref(&mem_info);
+
+    if (memory_total == 0) {
+        if (procps_meminfo_new(&mem_info) < 0)
+               xerrx(EXIT_FAILURE,
+                  _("Unable to get total memory"));
+       memory_total = MEMINFO_GET(mem_info, MEMINFO_MEM_TOTAL, ul_int);
+       procps_meminfo_unref(&mem_info);
+    }
+    return memory_total;
 }
 
 #define SECURE_ESCAPE_ARGS(dst, bytes, cells) do { \
@@ -901,7 +908,7 @@ static int pr_bsdstart(char *restrict const outbuf, const proc_t *restrict const
   time_t start;
   time_t seconds_ago;
 setREL1(TIME_START)
-  start = boot_time + rSv(TIME_START, ull_int, pp) / Hertz;
+  start = boot_time() + rSv(TIME_START, ull_int, pp) / Hertz;
   seconds_ago = seconds_since_1970 - start;
   if(seconds_ago < 0) seconds_ago=0;
   if(seconds_ago > 3600*24)  snprintf(outbuf, COLWID, "%s", ctime(&start)+4);
@@ -1029,7 +1036,7 @@ static int pr_pmem(char *restrict const outbuf, const proc_t *restrict const pp)
   unsigned long pmem;
 setREL1(VM_RSS)
   pmem = 0;
-  pmem = rSv(VM_RSS, ul_int, pp) * 1000ULL / memory_total;
+  pmem = rSv(VM_RSS, ul_int, pp) * 1000ULL / memory_total();
   if (pmem > 999) pmem = 999;
   return snprintf(outbuf, COLWID, "%2u.%u", (unsigned)(pmem/10), (unsigned)(pmem%10));
 }
@@ -1037,7 +1044,7 @@ setREL1(VM_RSS)
 static int pr_lstart(char *restrict const outbuf, const proc_t *restrict const pp){
   time_t t;
 setREL1(TIME_START)
-  t = boot_time + rSv(TIME_START, ull_int, pp) / Hertz;
+  t = boot_time() + rSv(TIME_START, ull_int, pp) / Hertz;
   return snprintf(outbuf, COLWID, "%24.24s", ctime(&t));
 }
 
@@ -1062,7 +1069,7 @@ setREL1(TIME_START)
   our_time = localtime(&seconds_since_1970);   /* not reentrant */
   tm_year = our_time->tm_year;
   tm_yday = our_time->tm_yday;
-  t = boot_time + rSv(TIME_START, ull_int, pp) / Hertz;
+  t = boot_time() + rSv(TIME_START, ull_int, pp) / Hertz;
   proc_time = localtime(&t); /* not reentrant, this corrupts our_time */
   fmt = "%H:%M";                                   /* 03:02 23:59 */
   if(tm_yday != proc_time->tm_yday) fmt = "%b%d";  /* Jun06 Aug27 */
@@ -1076,7 +1083,7 @@ static int pr_start(char *restrict const outbuf, const proc_t *restrict const pp
   time_t t;
   char *str;
 setREL1(TIME_START)
-  t = boot_time + rSv(TIME_START, ull_int, pp) / Hertz;
+  t = boot_time() + rSv(TIME_START, ull_int, pp) / Hertz;
   str = ctime(&t);
   if(str[8]==' ')  str[8]='0';
   if(str[11]==' ') str[11]='0';
@@ -2292,7 +2299,5 @@ void init_output(void)
     // available space:  page_size*outbuf_pages-SPACE_AMOUNT
     seconds_since_1970 = time(NULL);
 
-    get_boot_time();
-    get_memory_total();
     check_header_width();
 }
index 8f181046d6ee3e515e9b049ca12571621066de73..2702ae7738f5bbbf9731ccbb797e2fb9c4046612 100644 (file)
--- a/uptime.c
+++ b/uptime.c
@@ -44,7 +44,7 @@ static void print_uptime_since()
 
     /* Get the uptime and calculate when that was */
        if (procps_uptime(&uptime_secs, &idle_secs) < 0)
-               xerrx(EXIT_FAILURE, "uptime");
+               xerr(EXIT_FAILURE, _("Cannot get system uptime"));
     up_since_secs = (time_t) ((now - uptime_secs) + 0.5);
 
     /* Show this */
@@ -72,6 +72,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
 int main(int argc, char **argv)
 {
     int c, p = 0;
+    char *uptime_str;
 
     static const struct option longopts[] = {
         {"pretty", no_argument, NULL, 'p'},
@@ -110,8 +111,13 @@ int main(int argc, char **argv)
         usage(stderr);
 
     if (p)
-        printf("%s\n", procps_uptime_sprint_short());
+        uptime_str = procps_uptime_sprint_short();
     else
-        printf("%s\n", procps_uptime_sprint());
+        uptime_str = procps_uptime_sprint();
+
+    if (!uptime_str || uptime_str[0] == '\0')
+       xerr(EXIT_FAILURE, _("Cannot get system uptime"));
+
+    printf("%s\n", uptime_str);
     return EXIT_SUCCESS;
 }
index 3af2b3cca8e866e53cc50d3214e5efab7ba0c3e6..564edf66f9da6543b0ae202d129359ee95ab97cb 100644 (file)
--- a/vmstat.c
+++ b/vmstat.c
@@ -373,7 +373,6 @@ static void new_format(void)
 
     sleep_half = (sleep_time / 2);
     hz = procps_hertz_get();
-    new_header();
 
     if (procps_vmstat_new(&vm_info) < 0)
         xerrx(EXIT_FAILURE, _("Unable to create vmstat structure"));
@@ -381,6 +380,7 @@ static void new_format(void)
         xerrx(EXIT_FAILURE, _("Unable to create system stat structure"));
     if (procps_meminfo_new(&mem_info) < 0)
         xerrx(EXIT_FAILURE, _("Unable to create meminfo structure"));
+    new_header();
 
     pgpgin[tog] = VMSTAT_GET(vm_info, VMSTAT_PGPGIN, ul_int);
     pgpgout[tog] = VMSTAT_GET(vm_info, VMSTAT_PGPGOUT, ul_int);