summaryrefslogtreecommitdiffstats
path: root/linux/LinuxProcessList.c
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2022-10-29 19:20:54 +0200
committerBenBE <BenBE@geshi.org>2023-02-05 00:24:13 +0100
commit8ea144df7494bad0c46d3bf4f16c9a6556c500d2 (patch)
tree1dd657c8af4e69a9bde3ecc208a97cb35c602469 /linux/LinuxProcessList.c
parent436279a01c8e49265c504eb4e6bc5b97fe8290d8 (diff)
Linux: Refactor /proc/<pid>/status parsing
Merge parsing /proc/<pid>/status for context switches, vserver ID and container detection into one function. (OpenVZ still does a separate cycle but is left as an exercise for someone actually using it.)
Diffstat (limited to 'linux/LinuxProcessList.c')
-rw-r--r--linux/LinuxProcessList.c216
1 files changed, 92 insertions, 124 deletions
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index 27792bf8..0576dd67 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -534,6 +534,80 @@ static bool LinuxProcessList_readStatFile(Process* process, openat_arg_t procFd,
return true;
}
+static bool LinuxProcessList_readStatusFile(Process* process, openat_arg_t procFd) {
+ LinuxProcess* lp = (LinuxProcess*) process;
+
+ unsigned long ctxt = 0;
+#ifdef HAVE_VSERVER
+ lp->vxid = 0;
+#endif
+
+ FILE* statusfile = fopenat(procFd, "status", "r");
+ if (!statusfile)
+ return false;
+
+ char buffer[PROC_LINE_LENGTH + 1];
+
+ while (fgets(buffer, sizeof(buffer), statusfile)) {
+
+ if (String_startsWith(buffer, "NSpid:")) {
+ const char* ptr = buffer;
+ int pid_ns_count = 0;
+ while (*ptr && *ptr != '\n' && !isdigit((unsigned char)*ptr))
+ ++ptr;
+
+ while (*ptr && *ptr != '\n') {
+ if (isdigit(*ptr))
+ pid_ns_count++;
+ while (isdigit((unsigned char)*ptr))
+ ++ptr;
+ while (*ptr && *ptr != '\n' && !isdigit((unsigned char)*ptr))
+ ++ptr;
+ }
+
+ if (pid_ns_count > 1)
+ process->isRunningInContainer = true;
+
+ } else if (String_startsWith(buffer, "voluntary_ctxt_switches:")) {
+ unsigned long vctxt;
+ int ok = sscanf(buffer, "voluntary_ctxt_switches:\t%lu", &vctxt);
+ if (ok >= 1) {
+ ctxt += vctxt;
+ }
+
+ } else if (String_startsWith(buffer, "nonvoluntary_ctxt_switches:")) {
+ unsigned long nvctxt;
+ int ok = sscanf(buffer, "nonvoluntary_ctxt_switches:\t%lu", &nvctxt);
+ if (ok >= 1) {
+ ctxt += nvctxt;
+ }
+
+#ifdef HAVE_VSERVER
+ } else if (String_startsWith(buffer, "VxID:")) {
+ int vxid;
+ int ok = sscanf(buffer, "VxID:\t%32d", &vxid);
+ if (ok >= 1) {
+ lp->vxid = vxid;
+ }
+#ifdef HAVE_ANCIENT_VSERVER
+ } else if (String_startsWith(buffer, "s_context:")) {
+ int vxid;
+ int ok = sscanf(buffer, "s_context:\t%32d", &vxid);
+ if (ok >= 1) {
+ lp->vxid = vxid;
+ }
+#endif /* HAVE_ANCIENT_VSERVER */
+#endif /* HAVE_VSERVER */
+ }
+ }
+
+ fclose(statusfile);
+
+ lp->ctxt_diff = (ctxt > lp->ctxt_total) ? (ctxt - lp->ctxt_total) : 0;
+ lp->ctxt_total = ctxt;
+
+ return true;
+}
static bool LinuxProcessList_updateUser(ProcessList* processList, Process* process, openat_arg_t procFd) {
struct stat sstat;
@@ -765,43 +839,6 @@ 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 && *ptr != '\n' && !isdigit(*ptr))
- ++ptr;
-
- while (*ptr && *ptr != '\n') {
- if (isdigit(*ptr))
- pid_ns_count++;
- while (isdigit(*ptr))
- ++ptr;
- while (*ptr && *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.
@@ -930,13 +967,6 @@ 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) {
@@ -1009,38 +1039,6 @@ static void LinuxProcessList_readCGroupFile(LinuxProcess* process, openat_arg_t
}
}
-#ifdef HAVE_VSERVER
-
-static void LinuxProcessList_readVServerData(LinuxProcess* process, openat_arg_t procFd) {
- FILE* file = fopenat(procFd, "status", "r");
- if (!file)
- return;
-
- char buffer[PROC_LINE_LENGTH + 1];
- process->vxid = 0;
- while (fgets(buffer, PROC_LINE_LENGTH, file)) {
- if (String_startsWith(buffer, "VxID:")) {
- int vxid;
- int ok = sscanf(buffer, "VxID:\t%32d", &vxid);
- if (ok >= 1) {
- process->vxid = vxid;
- }
- }
- #if defined HAVE_ANCIENT_VSERVER
- else if (String_startsWith(buffer, "s_context:")) {
- int vxid;
- int ok = sscanf(buffer, "s_context:\t%32d", &vxid);
- if (ok >= 1) {
- process->vxid = vxid;
- }
- }
- #endif
- }
- fclose(file);
-}
-
-#endif
-
static void LinuxProcessList_readOomData(LinuxProcess* process, openat_arg_t procFd) {
FILE* file = fopenat(procFd, "oom_score", "r");
if (!file)
@@ -1074,33 +1072,6 @@ static void LinuxProcessList_readAutogroup(LinuxProcess* process, openat_arg_t p
}
}
-static void LinuxProcessList_readCtxtData(LinuxProcess* process, openat_arg_t procFd) {
- FILE* file = fopenat(procFd, "status", "r");
- if (!file)
- return;
-
- char buffer[PROC_LINE_LENGTH + 1];
- unsigned long ctxt = 0;
- while (fgets(buffer, PROC_LINE_LENGTH, file)) {
- if (String_startsWith(buffer, "voluntary_ctxt_switches:")) {
- unsigned long vctxt;
- int ok = sscanf(buffer, "voluntary_ctxt_switches:\t%lu", &vctxt);
- if (ok >= 1) {
- ctxt += vctxt;
- }
- } else if (String_startsWith(buffer, "nonvoluntary_ctxt_switches:")) {
- unsigned long nvctxt;
- int ok = sscanf(buffer, "nonvoluntary_ctxt_switches:\t%lu", &nvctxt);
- if (ok >= 1) {
- ctxt += nvctxt;
- }
- }
- }
- fclose(file);
- process->ctxt_diff = (ctxt > process->ctxt_total) ? (ctxt - process->ctxt_total) : 0;
- process->ctxt_total = ctxt;
-}
-
static void LinuxProcessList_readSecattrData(LinuxProcess* process, openat_arg_t procFd) {
FILE* file = fopenat(procFd, "attr/current", "r");
if (!file) {
@@ -1551,15 +1522,6 @@ 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
@@ -1663,6 +1625,9 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
if (! LinuxProcessList_updateUser(pl, proc, procFd))
goto errorReadingProcess;
+ if (!LinuxProcessList_readStatusFile(proc, procFd))
+ goto errorReadingProcess;
+
if (!preExisting) {
#ifdef HAVE_OPENVZ
@@ -1671,12 +1636,6 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
}
#endif
- #ifdef HAVE_VSERVER
- if (ss->flags & PROCESS_FLAG_LINUX_VSERVER) {
- LinuxProcessList_readVServerData(lp, procFd);
- }
- #endif
-
if (proc->isKernelThread) {
Process_updateCmdline(proc, NULL, 0, 0);
} else if (!LinuxProcessList_readCmdlineFile(proc, procFd)) {
@@ -1696,6 +1655,9 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
}
}
+ if (ss->flags & PROCESS_FLAG_LINUX_CGROUP)
+ LinuxProcessList_readCGroupFile(lp, procFd);
+
#ifdef HAVE_DELAYACCT
if (ss->flags & PROCESS_FLAG_LINUX_DELAYACCT) {
LinuxProcessList_readDelayAcctData(this, lp);
@@ -1706,10 +1668,6 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
LinuxProcessList_readOomData(lp, procFd);
}
- if (ss->flags & PROCESS_FLAG_LINUX_CTXT) {
- LinuxProcessList_readCtxtData(lp, procFd);
- }
-
if (ss->flags & PROCESS_FLAG_LINUX_SECATTR) {
LinuxProcessList_readSecattrData(lp, procFd);
}
@@ -1733,6 +1691,18 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
Process_updateCmdline(proc, statCommand, 0, strlen(statCommand));
}
+ /*
+ * Final section after all data has been gathered
+ */
+
+ proc->updated = true;
+ Compat_openatArgClose(procFd);
+
+ if (hideRunningInContainer && proc->isRunningInContainer) {
+ proc->show = false;
+ continue;
+ }
+
if (Process_isKernelThread(proc)) {
pl->kernelThreads++;
} else if (Process_isUserlandThread(proc)) {
@@ -1744,8 +1714,6 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
pl->totalTasks++;
/* runningTasks is set in LinuxProcessList_scanCPUTime() from /proc/stat */
- proc->updated = true;
- Compat_openatArgClose(procFd);
continue;
// Exception handler.

© 2014-2024 Faster IT GmbH | imprint | privacy policy