diff options
author | valdaarhun <icegambit91@gmail.com> | 2022-08-07 00:07:02 +0530 |
---|---|---|
committer | cgzones <cgzones@googlemail.com> | 2022-08-29 19:19:35 +0200 |
commit | a52f6d43542e66b0426e02b6af3589185c29335b (patch) | |
tree | 1f6b3b3166b2e0947beb9ad5739be0c26c67aa9d | |
parent | d078ba15a234228898f1683a2c22eb90ba446a4d (diff) |
Implement LinuxProcessList_checkPidNamespace
Add actionToggle and fix LinuxProcessList_checkPidNamespace
Read cgroup file irrespective of flags
Improve logic to check if running in container
Add isContainerOrVMSlice()
Also change "(Process *)lp" to "proc"
Remove check for root slice
Remove Process_isRunningInContainer
Co-authored-by: BenBE <BenBE@geshi.org>
-rw-r--r-- | Action.c | 6 | ||||
-rw-r--r-- | Process.h | 3 | ||||
-rw-r--r-- | linux/LinuxProcessList.c | 64 |
3 files changed, 69 insertions, 4 deletions
@@ -221,6 +221,11 @@ static Htop_Reaction actionToggleUserlandThreads(State* st) { return HTOP_RECALCULATE | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING; } +static Htop_Reaction actionToggleRunningInContainer(State* st){ + st->settings->hideRunningInContainer = !st->settings->hideRunningInContainer; + return HTOP_RECALCULATE | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING; +} + static Htop_Reaction actionToggleProgramPath(State* st) { st->settings->showProgramPath = !st->settings->showProgramPath; return HTOP_REFRESH | HTOP_SAVE_SETTINGS; @@ -752,6 +757,7 @@ void Action_setBindings(Htop_Action* keys) { keys['K'] = actionToggleKernelThreads; keys['M'] = actionSortByMemory; keys['N'] = actionSortByPID; + keys['O'] = actionToggleRunningInContainer; keys['P'] = actionSortByCPU; keys['S'] = actionSetup; keys['T'] = actionSortByTime; @@ -134,6 +134,9 @@ typedef struct Process_ { /* This is a userland thread / LWP */ bool isUserlandThread; + /* This process is running inside a container */ + bool isRunningInContainer; + /* Controlling terminal identifier of the process */ unsigned long int tty_nr; diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index a28d5148..ac115f24 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -10,6 +10,7 @@ in the source distribution for its full text. #include "linux/LinuxProcessList.h" #include <assert.h> +#include <ctype.h> #include <dirent.h> #include <errno.h> #include <fcntl.h> @@ -763,6 +764,43 @@ static bool LinuxProcessList_readStatmFile(LinuxProcess* process, openat_arg_t p return r == 7; } +static bool LinuxProcessList_checkPidNamespace(Process *process, openat_arg_t procFd) { + FILE *statusfile = fopenat(procFd, "status", "r"); + if (!statusfile) + return false; + + while (true) { + char buffer[PROC_LINE_LENGTH + 1]; + if (fgets(buffer, sizeof(buffer), statusfile) == NULL) + break; + + if (!String_startsWith(buffer, "NSpid:")) + continue; + + char *ptr = buffer; + int pid_ns_count = 0; + while(*ptr != '\0' && *ptr != '\n' && !isdigit(*ptr)) + ++ptr; + + while(*ptr != '\0' && *ptr != '\n') { + if (isdigit(*ptr)) + pid_ns_count++; + while(isdigit(*ptr)) + ++ptr; + while(*ptr != '\0' && *ptr != '\n' && !isdigit(*ptr)) + ++ptr; + } + + if (pid_ns_count > 1) + process->isRunningInContainer = true; + + break; + } + + fclose(statusfile); + return true; +} + static bool LinuxProcessList_readSmapsFile(LinuxProcess* process, openat_arg_t procFd, bool haveSmapsRollup) { //http://elixir.free-electrons.com/linux/v4.10/source/fs/proc/task_mmu.c#L719 //kernel will return data in chunks of size PAGE_SIZE or less. @@ -891,6 +929,13 @@ static void LinuxProcessList_readOpenVZData(LinuxProcess* process, openat_arg_t #endif +static bool isContainerOrVMSlice(char *cgroup) { + if (String_startsWith(cgroup, "/user") || String_startsWith(cgroup, "/system")) + return false; + + return true; +} + static void LinuxProcessList_readCGroupFile(LinuxProcess* process, openat_arg_t procFd) { FILE* file = fopenat(procFd, "cgroup", "r"); if (!file) { @@ -1453,6 +1498,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ const unsigned int activeCPUs = pl->activeCPUs; const bool hideKernelThreads = settings->hideKernelThreads; const bool hideUserlandThreads = settings->hideUserlandThreads; + const bool hideRunningInContainer = settings->hideRunningInContainer; while ((entry = readdir(dir)) != NULL) { const char* name = entry->d_name; @@ -1504,6 +1550,14 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ LinuxProcessList_recurseProcTree(this, procFd, "task", proc, period); + if ((ss->flags & PROCESS_FLAG_LINUX_CGROUP) || hideRunningInContainer) { + LinuxProcessList_readCGroupFile(lp, procFd); + if (hideRunningInContainer && lp->cgroup && isContainerOrVMSlice(lp -> cgroup)) { + if (!LinuxProcessList_checkPidNamespace(proc, procFd)) + goto errorReadingProcess; + } + } + /* * These conditions will not trigger on first occurrence, cause we need to * add the process to the ProcessList and do all one time scans @@ -1526,6 +1580,12 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ Compat_openatArgClose(procFd); continue; } + if (preExisting && hideRunningInContainer && proc->isRunningInContainer) { + proc->updated = true; + proc->show = false; + Compat_openatArgClose(procFd); + continue; + } if (ss->flags & PROCESS_FLAG_IO) LinuxProcessList_readIoFile(lp, procFd, pl->realtimeMs); @@ -1640,10 +1700,6 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ } #endif - if (ss->flags & PROCESS_FLAG_LINUX_CGROUP) { - LinuxProcessList_readCGroupFile(lp, procFd); - } - if (ss->flags & PROCESS_FLAG_LINUX_OOM) { LinuxProcessList_readOomData(lp, procFd); } |