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
6814ef2d99
Signed-off-by: Craig Small <csmall@dropbear.xyz>
This commit is contained in:
parent
dae897b54d
commit
bcb837b8c7
6
pgrep.1
6
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
|
||||
|
4
pgrep.c
4
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;
|
||||
|
||||
|
31
ps/output.c
31
ps/output.c
@ -86,30 +86,37 @@ 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 (boot_time == 0) {
|
||||
if (procps_stat_new(&stat_info) < 0)
|
||||
xerrx(EXIT_FAILURE, _("Unable to create NEW ystem stat structure"));
|
||||
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 (memory_total == 0) {
|
||||
if (procps_meminfo_new(&mem_info) < 0)
|
||||
xerrx(EXIT_FAILURE,
|
||||
_("Unable to create meminfo structure"));
|
||||
_("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 { \
|
||||
if ((bytes) <= 0) return 0; \
|
||||
@ -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();
|
||||
}
|
||||
|
12
uptime.c
12
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;
|
||||
}
|
||||
|
2
vmstat.c
2
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);
|
||||
|
Loading…
Reference in New Issue
Block a user