top: adapt for running with proc mounted as subset=pid
As the issue cited below illustrates, a pids namespace
with proc mounted as subset=pid denies our library any
access to non-task data. In top's case, the result was
a fatal error message which involved "cpu statistics".
With this patch top will now assume an error involving
global cpu (stat) or memory (meminfo) data means we're
running under a restricted pids namespace. As such, an
attempt will be made to still display task level data.
[ if our assumption is incorrect, it's of no matter. ]
[ instead of a fatal error, we'll still try to offer ]
[ a user some minimally useful bit of functionality. ]
Reference(s):
https://gitlab.com/procps-ng/procps/-/issues/227
https://www.freelists.org/post/procps/three-for-newlib,1
. 1st cut at subset=pid
commit bcb837b8c7
Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
b2c4fcfddb
commit
16145af663
42
top/top.c
42
top/top.c
@ -289,6 +289,10 @@ static sem_t Semaphore_tasks_beg, Semaphore_tasks_end;
|
||||
#if defined THREADED_CPU || defined THREADED_MEM || defined THREADED_TSK
|
||||
static pthread_t Thread_id_main;
|
||||
#endif
|
||||
|
||||
/* Support for a namespace with proc mounted subset=pid,
|
||||
( we'll limit our display to task information only ). */
|
||||
static int Restrict_some = 0;
|
||||
|
||||
/*###### Tiny useful routine(s) ########################################*/
|
||||
|
||||
@ -3368,7 +3372,8 @@ static void before (char *me) {
|
||||
|
||||
// get the total cpus (and, if possible, numa node total)
|
||||
if ((rc = procps_stat_new(&Stat_ctx)))
|
||||
error_exit(fmtmk(N_fmt(LIB_errorcpu_fmt),__LINE__, strerror(-rc)));
|
||||
Restrict_some = Cpu_cnt = 1;
|
||||
else {
|
||||
if (!(Stat_reap = procps_stat_reap(Stat_ctx, which, Stat_items, MAXTBL(Stat_items))))
|
||||
error_exit(fmtmk(N_fmt(LIB_errorcpu_fmt),__LINE__, strerror(errno)));
|
||||
#ifndef PRETEND0NUMA
|
||||
@ -3378,10 +3383,11 @@ static void before (char *me) {
|
||||
#ifdef PRETEND48CPU
|
||||
Cpu_cnt = 48;
|
||||
#endif
|
||||
}
|
||||
|
||||
// prepare for memory stats from new library API ...
|
||||
if ((rc = procps_meminfo_new(&Mem_ctx)))
|
||||
error_exit(fmtmk(N_fmt(LIB_errormem_fmt),__LINE__, strerror(-rc)));
|
||||
Restrict_some = 1;
|
||||
|
||||
// establish max depth for newlib pids stack (# of result structs)
|
||||
Pids_itms = alloc_c(sizeof(enum pids_item) * MAXTBL(Fieldstab));
|
||||
@ -5047,6 +5053,10 @@ static void keys_global (int ch) {
|
||||
static void keys_summary (int ch) {
|
||||
WIN_t *w = Curwin; // avoid gcc bloat with a local copy
|
||||
|
||||
if (Restrict_some && ch != 'C') {
|
||||
show_msg(N_txt(X_RESTRICTED_txt));
|
||||
return;
|
||||
}
|
||||
switch (ch) {
|
||||
case '!':
|
||||
if (CHKw(w, View_CPUSUM) || CHKw(w, View_CPUNOD))
|
||||
@ -5734,6 +5744,22 @@ static void summary_show (void) {
|
||||
char tmp[MEDBUFSIZ];
|
||||
int i;
|
||||
|
||||
if (Restrict_some) {
|
||||
#ifdef THREADED_TSK
|
||||
sem_wait(&Semaphore_tasks_end);
|
||||
#endif
|
||||
// Display Task States only
|
||||
if (isROOM(View_STATES, 1)) {
|
||||
show_special(0, fmtmk(N_unq(STATE_line_1_fmt)
|
||||
, Thread_mode ? N_txt(WORD_threads_txt) : N_txt(WORD_process_txt)
|
||||
, PIDSmaxt, Pids_reap->counts->running
|
||||
, Pids_reap->counts->sleeping + Pids_reap->counts->other
|
||||
, Pids_reap->counts->stopped, Pids_reap->counts->zombied));
|
||||
Msg_row += 1;
|
||||
}
|
||||
goto restrict_end;
|
||||
}
|
||||
|
||||
// Display Uptime and Loadavg
|
||||
if (isROOM(View_LOADAV, 1)) {
|
||||
if (!Rc.mode_altscr)
|
||||
@ -5951,6 +5977,7 @@ numa_oops:
|
||||
#undef memPARM
|
||||
} // end: View_MEMORY
|
||||
|
||||
restrict_end:
|
||||
#undef isROOM
|
||||
#undef anyFLG
|
||||
} // end: summary_show
|
||||
@ -6061,6 +6088,10 @@ static const char *task_show (const WIN_t *q, int idx) {
|
||||
break;
|
||||
/* s_int, scale_pcnt with special handling */
|
||||
case EU_CPU: // PIDS_TICS_ALL_DELTA
|
||||
if (Restrict_some) {
|
||||
cp = justify_pad("?", W, Jn);
|
||||
break;
|
||||
}
|
||||
{ float u = (float)rSv(EU_CPU, u_int);
|
||||
int n = rSv(EU_THD, s_int);
|
||||
#ifndef TREE_VCPUOFF
|
||||
@ -6130,6 +6161,10 @@ static const char *task_show (const WIN_t *q, int idx) {
|
||||
break;
|
||||
/* ul_int, scale_pcnt */
|
||||
case EU_MEM: // derive from PIDS_MEM_RES
|
||||
if (Restrict_some) {
|
||||
cp = justify_pad("?", W, Jn);
|
||||
break;
|
||||
}
|
||||
cp = scale_pcnt((float)rSv(EU_MEM, ul_int) * 100 / MEM_VAL(mem_TOT), W, Jn);
|
||||
break;
|
||||
/* ul_int, make_str with special handling */
|
||||
@ -6399,6 +6434,8 @@ static void frame_make (void) {
|
||||
#else
|
||||
tasks_refresh(NULL);
|
||||
#endif
|
||||
|
||||
if (!Restrict_some) {
|
||||
#ifdef THREADED_CPU
|
||||
sem_post(&Semaphore_cpus_beg);
|
||||
#else
|
||||
@ -6409,6 +6446,7 @@ static void frame_make (void) {
|
||||
#else
|
||||
memory_refresh(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
// whoa either first time or thread/task mode change, (re)prime the pump...
|
||||
if (Pseudo_row == PROC_XTRA) {
|
||||
|
@ -571,6 +571,7 @@ static void build_norm_nlstab (void) {
|
||||
Norm_nlstab[XTRA_warnold_txt] = _("saving prevents older top from reading, save anyway?");
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
|
@ -84,7 +84,7 @@ enum norm_nls {
|
||||
WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt, WRONG_switch_fmt,
|
||||
XTRA_badflds_fmt, XTRA_fixwide_fmt, XTRA_modebad_txt, XTRA_size2up_txt,
|
||||
XTRA_vforest_fmt, XTRA_warncfg_txt, XTRA_warnold_txt, XTRA_winsize_txt,
|
||||
X_SEMAPHORES_fmt, X_THREADINGS_fmt,
|
||||
X_RESTRICTED_txt, X_SEMAPHORES_fmt, X_THREADINGS_fmt,
|
||||
#ifndef INSP_OFFDEMO
|
||||
YINSP_demo01_txt, YINSP_demo02_txt, YINSP_demo03_txt, YINSP_deqfmt_txt,
|
||||
YINSP_deqtyp_txt, YINSP_dstory_txt,
|
||||
|
Loading…
Reference in New Issue
Block a user