From: Craig Small Date: Thu, 16 Dec 2021 09:36:00 +0000 (+1100) Subject: First cut at subset=pid proc mount handling X-Git-Tag: v4.0.0~82 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bcb837b8c73f23536a2403b61deeb2b7b3c6be20;p=procps-ng First cut at subset=pid proc mount handling 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 --- diff --git a/pgrep.1 b/pgrep.1 index 0d836844..e29e6e1a 100644 --- 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 cbcb4cb1..1a0041c7 100644 --- 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; diff --git a/ps/output.c b/ps/output.c index 9157b16a..bd79d9b0 100644 --- a/ps/output.c +++ b/ps/output.c @@ -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(); } diff --git a/uptime.c b/uptime.c index 8f181046..2702ae77 100644 --- 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; } diff --git a/vmstat.c b/vmstat.c index 3af2b3cc..564edf66 100644 --- 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);