diff options
author | Daniel Lange <DLange@git.local> | 2023-02-05 04:25:56 +0100 |
---|---|---|
committer | Daniel Lange <DLange@git.local> | 2023-02-05 04:25:56 +0100 |
commit | f288666edc9180a2e81e6655951878124f321df6 (patch) | |
tree | da70bf44b2423f6f8e9a070c063fed79d190b489 /linux | |
parent | 937052b231259a47d881d539ad5748245ef55b99 (diff) | |
download | debian_htop-f288666edc9180a2e81e6655951878124f321df6.tar.gz debian_htop-f288666edc9180a2e81e6655951878124f321df6.tar.bz2 debian_htop-f288666edc9180a2e81e6655951878124f321df6.zip |
New upstream version 3.2.2upstream/3.2.2
Diffstat (limited to 'linux')
-rw-r--r-- | linux/CGroupUtils.c | 10 | ||||
-rw-r--r-- | linux/CGroupUtils.h | 2 | ||||
-rw-r--r-- | linux/LinuxProcess.c | 4 | ||||
-rw-r--r-- | linux/LinuxProcessList.c | 95 | ||||
-rw-r--r-- | linux/Platform.c | 167 | ||||
-rw-r--r-- | linux/Platform.h | 18 | ||||
-rw-r--r-- | linux/SystemdMeter.c | 6 |
7 files changed, 170 insertions, 132 deletions
diff --git a/linux/CGroupUtils.c b/linux/CGroupUtils.c index 22cce91..c11c460 100644 --- a/linux/CGroupUtils.c +++ b/linux/CGroupUtils.c @@ -11,7 +11,7 @@ in the source distribution for its full text. typedef struct StrBuf_state { - char *buf; + char* buf; size_t size; size_t pos; } StrBuf_state; @@ -60,7 +60,7 @@ static bool Label_checkSuffix(const char* labelStart, size_t labelLen, const cha return labelLen > strlen(expected) && String_startsWith(labelStart + labelLen - strlen(expected), expected); } -static bool CGroup_filterName_internal(const char *cgroup, StrBuf_state* s, StrBuf_putc_t w) { +static bool CGroup_filterName_internal(const char* cgroup, StrBuf_state* s, StrBuf_putc_t w) { const char* str_slice_suffix = ".slice"; const char* str_system_slice = "system.slice"; const char* str_user_slice = "user.slice"; @@ -237,7 +237,7 @@ static bool CGroup_filterName_internal(const char *cgroup, StrBuf_state* s, StrB if (String_startsWith(cgroup, "user@")) { cgroup = nextSlash; - while(*cgroup == '/') + while (*cgroup == '/') cgroup++; continue; @@ -275,7 +275,7 @@ static bool CGroup_filterName_internal(const char *cgroup, StrBuf_state* s, StrB cgroup += strlen(str_nspawn_payload_label); continue; - } else if(Label_checkPrefix(labelStart, scopeNameLen, str_snap_scope_prefix)) { + } else if (Label_checkPrefix(labelStart, scopeNameLen, str_snap_scope_prefix)) { const char* nextDot = strchrnul(labelStart + strlen(str_snap_scope_prefix), '.'); if (!StrBuf_putsz(s, w, "!snap:")) @@ -316,7 +316,7 @@ static bool CGroup_filterName_internal(const char *cgroup, StrBuf_state* s, StrB return true; } -char* CGroup_filterName(const char *cgroup) { +char* CGroup_filterName(const char* cgroup) { StrBuf_state s = { .buf = NULL, .size = 0, diff --git a/linux/CGroupUtils.h b/linux/CGroupUtils.h index db2df7f..ff13437 100644 --- a/linux/CGroupUtils.h +++ b/linux/CGroupUtils.h @@ -11,6 +11,6 @@ in the source distribution for its full text. #include <stddef.h> -char* CGroup_filterName(const char *cgroup); +char* CGroup_filterName(const char* cgroup); #endif /* HEADER_CGroupUtils */ diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c index 92be326..381b7cf 100644 --- a/linux/LinuxProcess.c +++ b/linux/LinuxProcess.c @@ -53,8 +53,8 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [M_VIRT] = { .name = "M_VIRT", .title = " VIRT ", .description = "Total program size in virtual memory", .flags = 0, .defaultSortDesc = true, }, [M_RESIDENT] = { .name = "M_RESIDENT", .title = " RES ", .description = "Resident set size, size of the text and data sections, plus stack usage", .flags = 0, .defaultSortDesc = true, }, [M_SHARE] = { .name = "M_SHARE", .title = " SHR ", .description = "Size of the process's shared pages", .flags = 0, .defaultSortDesc = true, }, - [M_TRS] = { .name = "M_TRS", .title = " CODE ", .description = "Size of the text segment of the process", .flags = 0, .defaultSortDesc = true, }, - [M_DRS] = { .name = "M_DRS", .title = " DATA ", .description = "Size of the data segment plus stack usage of the process", .flags = 0, .defaultSortDesc = true, }, + [M_TRS] = { .name = "M_TRS", .title = " CODE ", .description = "Size of the .text segment of the process (CODE)", .flags = 0, .defaultSortDesc = true, }, + [M_DRS] = { .name = "M_DRS", .title = " DATA ", .description = "Size of the .data segment plus stack usage of the process (DATA)", .flags = 0, .defaultSortDesc = true, }, [M_LRS] = { .name = "M_LRS", .title = " LIB ", .description = "The library size of the process (calculated from memory maps)", .flags = PROCESS_FLAG_LINUX_LRS_FIX, .defaultSortDesc = true, }, [ST_UID] = { .name = "ST_UID", .title = "UID", .description = "User ID of the process owner", .flags = 0, }, [PERCENT_CPU] = { .name = "PERCENT_CPU", .title = " CPU%", .description = "Percentage of the CPU time the process used in the last sampling", .flags = 0, .defaultSortDesc = true, .autoWidth = true, }, diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 45b045c..eca9459 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> @@ -181,7 +182,7 @@ static unsigned int scanAvailableCPUsFromCPUinfo(LinuxProcessList* this) { if (String_startsWith(buffer, "processor")) availableCPUs++; - } + } fclose(file); @@ -219,7 +220,7 @@ static void LinuxProcessList_updateCPUcount(ProcessList* super) { if (!String_startsWith(entry->d_name, "cpu")) continue; - char *endp; + char* endp; unsigned long int id = strtoul(entry->d_name + 3, &endp, 10); if (id == ULONG_MAX || endp == entry->d_name + 3 || *endp != '\0') continue; @@ -263,9 +264,9 @@ static void LinuxProcessList_updateCPUcount(ProcessList* super) { 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); + /* 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 @@ -671,7 +672,7 @@ static void LinuxProcessList_readMaps(LinuxProcess* process, openat_arg_t procFd if (' ' != *readptr++) continue; - while(*readptr > ' ') + while (*readptr > ' ') readptr++; // Skip parsing this hex value if (' ' != *readptr++) continue; @@ -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 && *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. @@ -851,7 +889,7 @@ static void LinuxProcessList_readOpenVZData(LinuxProcess* process, openat_arg_t char* value_end = name_value_sep; - while(*value_end > 32) { + while (*value_end > 32) { value_end++; } @@ -861,7 +899,7 @@ static void LinuxProcessList_readOpenVZData(LinuxProcess* process, openat_arg_t *value_end = '\0'; - switch(field) { + switch (field) { case 1: foundEnvID = true; if (!String_eq(name_value_sep, process->ctid ? process->ctid : "")) @@ -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) { @@ -941,7 +986,7 @@ static void LinuxProcessList_readCGroupFile(LinuxProcess* process, openat_arg_t free_and_xStrdup(&process->cgroup, output); if (!changed) { - if(process->cgroup_short) { + if (process->cgroup_short) { Process_updateFieldWidth(CCGROUP, strlen(process->cgroup_short)); } else { //CCGROUP is alias to normal CGROUP if shortening fails @@ -1090,9 +1135,7 @@ static void LinuxProcessList_readCwd(LinuxProcess* process, openat_arg_t procFd) #if defined(HAVE_READLINKAT) && defined(HAVE_OPENAT) ssize_t r = readlinkat(procFd, "cwd", pathBuffer, sizeof(pathBuffer) - 1); #else - char filename[MAX_NAME + 1]; - xSnprintf(filename, sizeof(filename), "%s/cwd", procFd); - ssize_t r = readlink(filename, pathBuffer, sizeof(pathBuffer) - 1); + ssize_t r = Compat_readlink(procFd, "cwd", pathBuffer, sizeof(pathBuffer) - 1); #endif if (r < 0) { @@ -1329,9 +1372,7 @@ static bool LinuxProcessList_readCmdlineFile(Process* process, openat_arg_t proc #if defined(HAVE_READLINKAT) && defined(HAVE_OPENAT) amtRead = readlinkat(procFd, "exe", filename, sizeof(filename) - 1); #else - char path[4096]; - xSnprintf(path, sizeof(path), "%s/exe", procFd); - amtRead = readlink(path, filename, sizeof(filename) - 1); + amtRead = Compat_readlink(procFd, "exe", filename, sizeof(filename) - 1); #endif if (amtRead > 0) { filename[amtRead] = 0; @@ -1423,7 +1464,7 @@ static bool isOlderThan(const ProcessList* pl, const Process* proc, unsigned int /* Starttime might not yet be parsed */ if (proc->starttime_ctime <= 0) - return false; + return false; uint64_t realtime = pl->realtimeMs / 1000; @@ -1457,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; @@ -1508,6 +1550,15 @@ 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 @@ -1530,6 +1581,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); @@ -1580,7 +1637,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ char statCommand[MAX_NAME + 1]; unsigned long long int lasttimes = (lp->utime + lp->stime); unsigned long int tty_nr = proc->tty_nr; - if (! LinuxProcessList_readStatFile(proc, procFd, statCommand, sizeof(statCommand))) + if (!LinuxProcessList_readStatFile(proc, procFd, statCommand, sizeof(statCommand))) goto errorReadingProcess; if (lp->flags & PF_KTHREAD) { @@ -1644,10 +1701,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); } diff --git a/linux/Platform.c b/linux/Platform.c index 38b66e8..64f25c4 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -12,6 +12,7 @@ in the source distribution for its full text. #include <assert.h> #include <ctype.h> #include <dirent.h> +#include <errno.h> #include <fcntl.h> #include <inttypes.h> #include <math.h> @@ -21,6 +22,7 @@ in the source distribution for its full text. #include <string.h> #include <time.h> #include <unistd.h> +#include <sys/sysmacros.h> #include "BatteryMeter.h" #include "ClockMeter.h" @@ -250,7 +252,7 @@ const MeterClass* const Platform_meterTypes[] = { NULL }; -int Platform_getUptime() { +int Platform_getUptime(void) { double uptime = 0; FILE* fd = fopen(PROCDIR "/uptime", "r"); if (fd) { @@ -285,7 +287,7 @@ err: *fifteen = NAN; } -int Platform_getMaxPid() { +int Platform_getMaxPid(void) { FILE* file = fopen(PROCDIR "/sys/kernel/pid_max", "r"); if (!file) return -1; @@ -351,20 +353,20 @@ void Platform_setMemoryValues(Meter* this) { const LinuxProcessList* lpl = (const LinuxProcessList*) pl; this->total = pl->totalMem; - this->values[0] = pl->usedMem; - this->values[1] = pl->buffersMem; - this->values[2] = pl->sharedMem; - this->values[3] = pl->cachedMem; - this->values[4] = pl->availableMem; + this->values[MEMORY_METER_USED] = pl->usedMem; + this->values[MEMORY_METER_BUFFERS] = pl->buffersMem; + this->values[MEMORY_METER_SHARED] = pl->sharedMem; + this->values[MEMORY_METER_CACHE] = pl->cachedMem; + this->values[MEMORY_METER_AVAILABLE] = pl->availableMem; if (lpl->zfs.enabled != 0 && !Running_containerized) { // ZFS does not shrink below the value of zfs_arc_min. unsigned long long int shrinkableSize = 0; if (lpl->zfs.size > lpl->zfs.min) shrinkableSize = lpl->zfs.size - lpl->zfs.min; - this->values[0] -= shrinkableSize; - this->values[3] += shrinkableSize; - this->values[4] += shrinkableSize; + this->values[MEMORY_METER_USED] -= shrinkableSize; + this->values[MEMORY_METER_CACHE] += shrinkableSize; + this->values[MEMORY_METER_AVAILABLE] += shrinkableSize; } } @@ -430,117 +432,90 @@ char* Platform_getProcessEnv(pid_t pid) { return env; } -/* - * Return the absolute path of a file given its pid&inode number - * - * Based on implementation of lslocks from util-linux: - * https://sources.debian.org/src/util-linux/2.36-3/misc-utils/lslocks.c/#L162 - */ -char* Platform_getInodeFilename(pid_t pid, ino_t inode) { - struct stat sb; - const struct dirent* de; +FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { + FileLocks_ProcessData* pdata = xCalloc(1, sizeof(FileLocks_ProcessData)); DIR* dirp; - ssize_t len; - int fd; + int dfd; char path[PATH_MAX]; - char sym[PATH_MAX]; - char* ret = NULL; - - memset(path, 0, sizeof(path)); - memset(sym, 0, sizeof(sym)); - - xSnprintf(path, sizeof(path), "%s/%d/fd/", PROCDIR, pid); + xSnprintf(path, sizeof(path), PROCDIR "/%d/fdinfo/", pid); if (strlen(path) >= (sizeof(path) - 2)) - return NULL; + goto err; if (!(dirp = opendir(path))) - return NULL; + goto err; - if ((fd = dirfd(dirp)) < 0 ) - goto out; + if ((dfd = dirfd(dirp)) == -1) { + closedir(dirp); + goto err; + } - while ((de = readdir(dirp))) { + FileLocks_LockData** data_ref = &pdata->locks; + for (struct dirent* de; (de = readdir(dirp)); ) { if (String_eq(de->d_name, ".") || String_eq(de->d_name, "..")) continue; - /* care only for numerical descriptors */ - if (!strtoull(de->d_name, (char **) NULL, 10)) + errno = 0; + char *end = de->d_name; + int file = strtoull(de->d_name, &end, 10); + if (errno || *end) continue; - if (!Compat_fstatat(fd, path, de->d_name, &sb, 0) && inode != sb.st_ino) + int fd = openat(dfd, de->d_name, O_RDONLY | O_CLOEXEC); + if(fd == -1) continue; + FILE *f = fdopen(fd, "r"); + if(!f) { + close(fd); + continue; + } - if ((len = Compat_readlinkat(fd, path, de->d_name, sym, sizeof(sym) - 1)) < 1) - goto out; - - sym[len] = '\0'; - - ret = xStrdup(sym); - break; - } - -out: - closedir(dirp); - return ret; -} + for (char buffer[1024]; fgets(buffer, sizeof(buffer), f); ) { + if (!strchr(buffer, '\n')) + continue; -FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) { - FileLocks_ProcessData* pdata = xCalloc(1, sizeof(FileLocks_ProcessData)); + if (strncmp(buffer, "lock:\t", strlen("lock:\t"))) + continue; - FILE* f = fopen(PROCDIR "/locks", "r"); - if (!f) { - pdata->error = true; - return pdata; - } + FileLocks_Data data = {.fd = file}; + int _; + unsigned int maj, min; + char lock_end[25], locktype[32], exclusive[32], readwrite[32]; + if (10 != sscanf(buffer + strlen("lock:\t"), "%d: %31s %31s %31s %d %x:%x:%"PRIu64" %"PRIu64" %24s", + &_, locktype, exclusive, readwrite, &_, + &maj, &min, &data.inode, + &data.start, lock_end)) + continue; - char buffer[1024]; - FileLocks_LockData** data_ref = &pdata->locks; - while(fgets(buffer, sizeof(buffer), f)) { - if (!strchr(buffer, '\n')) - continue; + data.locktype = xStrdup(locktype); + data.exclusive = xStrdup(exclusive); + data.readwrite = xStrdup(readwrite); + data.dev = makedev(maj, min); - int lock_id; - char lock_type[16]; - char lock_excl[16]; - char lock_rw[16]; - pid_t lock_pid; - unsigned int lock_dev[2]; - uint64_t lock_inode; - char lock_start[25]; - char lock_end[25]; - - if (10 != sscanf(buffer, "%d: %15s %15s %15s %d %x:%x:%"PRIu64" %24s %24s", - &lock_id, lock_type, lock_excl, lock_rw, &lock_pid, - &lock_dev[0], &lock_dev[1], &lock_inode, - lock_start, lock_end)) - continue; + if (String_eq(lock_end, "EOF")) + data.end = ULLONG_MAX; + else + data.end = strtoull(lock_end, NULL, 10); - if (pid != lock_pid) - continue; + xSnprintf(path, sizeof(path), PROCDIR "/%d/fd/%s", pid, de->d_name); + char link[PATH_MAX]; + ssize_t link_len; + if (strlen(path) < (sizeof(path) - 2) && (link_len = readlink(path, link, sizeof(link))) != -1) + data.filename = xStrndup(link, link_len); - FileLocks_LockData* ldata = xCalloc(1, sizeof(FileLocks_LockData)); - FileLocks_Data* data = &ldata->data; - data->id = lock_id; - data->locktype = xStrdup(lock_type); - data->exclusive = xStrdup(lock_excl); - data->readwrite = xStrdup(lock_rw); - data->filename = Platform_getInodeFilename(lock_pid, lock_inode); - data->dev[0] = lock_dev[0]; - data->dev[1] = lock_dev[1]; - data->inode = lock_inode; - data->start = strtoull(lock_start, NULL, 10); - if (!String_eq(lock_end, "EOF")) { - data->end = strtoull(lock_end, NULL, 10); - } else { - data->end = ULLONG_MAX; + *data_ref = xCalloc(1, sizeof(FileLocks_LockData)); + (*data_ref)->data = data; + data_ref = &(*data_ref)->next; } - *data_ref = ldata; - data_ref = &ldata->next; + fclose(f); } - fclose(f); + closedir(dirp); + return pdata; + +err: + pdata->error = true; return pdata; } diff --git a/linux/Platform.h b/linux/Platform.h index e6fa161..f6ac188 100644 --- a/linux/Platform.h +++ b/linux/Platform.h @@ -75,8 +75,6 @@ void Platform_setZfsCompressedArcValues(Meter* this); char* Platform_getProcessEnv(pid_t pid); -char* Platform_getInodeFilename(pid_t pid, ino_t inode); - FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid); void Platform_getPressureStall(const char* file, bool some, double* ten, double* sixty, double* threehundred); @@ -114,7 +112,9 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) { Generic_gettime_monotonic(msec); } -static inline Hashtable* Platform_dynamicMeters(void) { return NULL; } +static inline Hashtable* Platform_dynamicMeters(void) { + return NULL; +} static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { } @@ -124,12 +124,18 @@ static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) { static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter, ATTR_UNUSED RichString* out) { } -static inline Hashtable* Platform_dynamicColumns(void) { return NULL; } +static inline Hashtable* Platform_dynamicColumns(void) { + return NULL; +} static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { } -static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; } +static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { + return NULL; +} -static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; } +static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { + return false; +} #endif diff --git a/linux/SystemdMeter.c b/linux/SystemdMeter.c index 53ae2d2..cee3231 100644 --- a/linux/SystemdMeter.c +++ b/linux/SystemdMeter.c @@ -310,8 +310,12 @@ static int valueDigitColor(unsigned int value) { static void SystemdMeter_display(ATTR_UNUSED const Object* cast, RichString* out) { char buffer[16]; int len; + int color = METER_VALUE_ERROR; - int color = (systemState && String_eq(systemState, "running")) ? METER_VALUE_OK : METER_VALUE_ERROR; + if (systemState) { + color = String_eq(systemState, "running") ? METER_VALUE_OK : + String_eq(systemState, "degraded") ? METER_VALUE_ERROR : METER_VALUE_WARN; + } RichString_writeAscii(out, CRT_colors[color], systemState ? systemState : "N/A"); RichString_appendAscii(out, CRT_colors[METER_TEXT], " ("); |