diff options
author | Daniel Lange <DLange@git.local> | 2022-06-03 08:55:20 +0200 |
---|---|---|
committer | Daniel Lange <DLange@git.local> | 2022-06-03 08:55:20 +0200 |
commit | 937052b231259a47d881d539ad5748245ef55b99 (patch) | |
tree | 41071229fa007d8cf6902bb9253d2acd8cc66979 /linux/LinuxProcessList.c | |
parent | 1b805a31720727008b32b1129a167758519fd4db (diff) | |
download | debian_htop-937052b231259a47d881d539ad5748245ef55b99.tar.gz debian_htop-937052b231259a47d881d539ad5748245ef55b99.tar.bz2 debian_htop-937052b231259a47d881d539ad5748245ef55b99.zip |
New upstream version 3.2.1upstream/3.2.1
Diffstat (limited to 'linux/LinuxProcessList.c')
-rw-r--r-- | linux/LinuxProcessList.c | 87 |
1 files changed, 67 insertions, 20 deletions
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 5e18f6d..45b045c 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -166,6 +166,28 @@ static void LinuxProcessList_initNetlinkSocket(LinuxProcessList* this) { #endif +static unsigned int scanAvailableCPUsFromCPUinfo(LinuxProcessList* this) { + FILE* file = fopen(PROCCPUINFOFILE, "r"); + if (file == NULL) + return this->super.existingCPUs; + + unsigned int availableCPUs = 0; + + while (!feof(file)) { + char buffer[PROC_LINE_LENGTH]; + + if (fgets(buffer, PROC_LINE_LENGTH, file) == NULL) + break; + + if (String_startsWith(buffer, "processor")) + availableCPUs++; + } + + fclose(file); + + return availableCPUs ? availableCPUs : 1; +} + static void LinuxProcessList_updateCPUcount(ProcessList* super) { /* Similar to get_nprocs_conf(3) / _SC_NPROCESSORS_CONF * https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/getsysstats.c;hb=HEAD @@ -240,6 +262,12 @@ static void LinuxProcessList_updateCPUcount(ProcessList* super) { if (existing < 1) return; + if (Running_containerized) { + /* LXC munges /proc/cpuinfo but not the /sys/devices/system/cpu/ files, + * so limit the visible CPUs to what the guest has been configured to see: */ + currExisting = active = scanAvailableCPUsFromCPUinfo(this); + } + #ifdef HAVE_SENSORS_SENSORS_H /* When started with offline CPUs, libsensors does not monitor those, * even when they become online. */ @@ -248,7 +276,7 @@ static void LinuxProcessList_updateCPUcount(ProcessList* super) { #endif super->activeCPUs = active; - assert(existing == currExisting); + assert(Running_containerized || (existing == currExisting)); super->existingCPUs = currExisting; } @@ -1323,7 +1351,8 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t proc if (process->procExeDeleted) filename[filenameLen - markerLen] = '\0'; - process->mergedCommand.exeChanged |= oldExeDeleted ^ process->procExeDeleted; + if (oldExeDeleted != process->procExeDeleted) + process->mergedCommand.lastUpdate = 0; } Process_updateExe(process, filename); @@ -1389,6 +1418,21 @@ static char* LinuxProcessList_updateTtyDevice(TtyDriver* ttyDrivers, unsigned lo return out; } +static bool isOlderThan(const ProcessList* pl, const Process* proc, unsigned int seconds) { + assert(pl->realtimeMs > 0); + + /* Starttime might not yet be parsed */ + if (proc->starttime_ctime <= 0) + return false; + + uint64_t realtime = pl->realtimeMs / 1000; + + if (realtime < (uint64_t)proc->starttime_ctime) + return false; + + return realtime - proc->starttime_ctime > seconds; +} + static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_t parentFd, const char* dirname, const Process* parent, double period) { ProcessList* pl = (ProcessList*) this; const struct dirent* entry; @@ -1446,22 +1490,22 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ if (parent && pid == parent->pid) continue; - bool preExisting; - Process* proc = ProcessList_getProcess(pl, pid, &preExisting, LinuxProcess_new); - LinuxProcess* lp = (LinuxProcess*) proc; - - proc->tgid = parent ? parent->pid : pid; - proc->isUserlandThread = proc->pid != proc->tgid; - #ifdef HAVE_OPENAT int procFd = openat(dirFd, entry->d_name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW); if (procFd < 0) - goto errorReadingProcess; + continue; #else char procFd[4096]; xSnprintf(procFd, sizeof(procFd), "%s/%s", dirFd, entry->d_name); #endif + bool preExisting; + Process* proc = ProcessList_getProcess(pl, pid, &preExisting, LinuxProcess_new); + LinuxProcess* lp = (LinuxProcess*) proc; + + proc->tgid = parent ? parent->pid : pid; + proc->isUserlandThread = proc->pid != proc->tgid; + LinuxProcessList_recurseProcTree(this, procFd, "task", proc, period); /* @@ -1497,7 +1541,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ bool prev = proc->usesDeletedLib; if (!proc->isKernelThread && !proc->isUserlandThread && - ((ss->flags & PROCESS_FLAG_LINUX_LRS_FIX) || (settings->highlightDeletedExe && !proc->procExeDeleted))) { + ((ss->flags & PROCESS_FLAG_LINUX_LRS_FIX) || (settings->highlightDeletedExe && !proc->procExeDeleted && isOlderThan(pl, proc, 10)))) { // Check if we really should recalculate the M_LRS value for this process uint64_t passedTimeInMs = pl->realtimeMs - lp->last_mlrs_calctime; @@ -1514,7 +1558,8 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ lp->m_lrs = (proc->isUserlandThread && parent) ? ((const LinuxProcess*)parent)->m_lrs : 0; } - proc->mergedCommand.exeChanged |= prev ^ proc->usesDeletedLib; + if (prev != proc->usesDeletedLib) + proc->mergedCommand.lastUpdate = 0; } if ((ss->flags & PROCESS_FLAG_LINUX_SMAPS) && !Process_isKernelThread(proc)) { @@ -1653,8 +1698,13 @@ errorReadingProcess: #endif if (preExisting) { - ProcessList_remove(pl, proc); + /* + * The only real reason for coming here (apart from Linux violating the /proc API) + * would be the process going away with its /proc files disappearing (!HAVE_OPENAT). + * However, we want to keep in the process list for now for the "highlight dying" mode. + */ } else { + /* A really short-lived process that we don't have full info about */ Process_delete((Object*)proc); } } @@ -1874,6 +1924,7 @@ static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) { switch (buffer[0]) { case 'c': + tryRead("c_min", &lpl->zfs.min); tryRead("c_max", &lpl->zfs.max); tryReadFlag("compressed_size", &lpl->zfs.compressed, lpl->zfs.isCompressed); break; @@ -1908,6 +1959,7 @@ static inline void LinuxProcessList_scanZfsArcstats(LinuxProcessList* lpl) { lpl->zfs.enabled = (lpl->zfs.size > 0 ? 1 : 0); lpl->zfs.size /= 1024; + lpl->zfs.min /= 1024; lpl->zfs.max /= 1024; lpl->zfs.MFU /= 1024; lpl->zfs.MRU /= 1024; @@ -2101,16 +2153,11 @@ static void scanCPUFrequencyFromCPUinfo(LinuxProcessList* this) { if (fgets(buffer, PROC_LINE_LENGTH, file) == NULL) break; - if ( - (sscanf(buffer, "processor : %d", &cpuid) == 1) || - (sscanf(buffer, "processor: %d", &cpuid) == 1) - ) { + if (sscanf(buffer, "processor : %d", &cpuid) == 1) { continue; } else if ( (sscanf(buffer, "cpu MHz : %lf", &frequency) == 1) || - (sscanf(buffer, "cpu MHz: %lf", &frequency) == 1) || - (sscanf(buffer, "clock : %lfMHz", &frequency) == 1) || - (sscanf(buffer, "clock: %lfMHz", &frequency) == 1) + (sscanf(buffer, "clock : %lfMHz", &frequency) == 1) ) { if (cpuid < 0 || (unsigned int)cpuid > (existingCPUs - 1)) { continue; |