Implements support for arbitrary Performance Co-Pilot
metrics with per-process instance domains to form new
htop columns. The column-to-metric mappings are setup
using configuration files which will be documented via
man pages as part of a follow-up commit.
We provide an initial set of column configurations so
as to provide new capabilities to pcp-htop: including
configs for containers, open fd counts, scheduler run
queue time, tcp/udp bytes/calls sent/recv, delay acct,
virtual machine guests, detailed virtual memory, swap.
Note there is a change to the configuration file path
resolution algorithm introduced for 'dynamic meters'.
First, look in any custom PCP_HTOP_DIR location. Then
iterate, in priority order, users home directory, then
local sysadmins files in /etc/pcp/htop, then readonly
configuration files below /usr/share/pcp/htop. This
final location becomes the preferred place for our own
shipped meter and column files.
The Settings file (htoprc) writing code is updated to
not using the numeric identifier for dynamic columns.
The same strategy used for dynamic meters is used here
where we write Dynamic(name) so the name can be setup
once more at start. Regular (static) columns writing
to htoprc - i.e. numerically indexed - is unchanged.
Currently htop does not support offline CPUs and hot-swapping, e.g. via
echo 0 > /sys/devices/system/cpu/cpu2/online
Split the current single cpuCount variable into activeCPUs and
existingCPUs.
Supersedes: #650
Related: #580
Before this change, the systemd meter was broken on distros like NixOS,
which have systemctl in PATH, but not at /bin/systemctl. After the
change, it works on all my NixOS machines.
This commit is based on exploratory work by Sohaib Mohamed.
The end goal is two-fold - to support addition of Meters we
build via configuration files for both the PCP platform and
for scripts ( https://github.com/htop-dev/htop/issues/526 )
Here, we focus on generic code and the PCP support. A new
class DynamicMeter is introduced - it uses the special case
'param' field handling that previously was used only by the
CPUMeter, such that every runtime-configured Meter is given
a unique identifier. Unlike with the CPUMeter this is used
internally only. When reading/writing to htoprc instead of
CPU(N) - where N is an integer param (CPU number) - we use
the string name for each meter. For example, if we have a
configuration for a DynamicMeter for some Redis metrics, we
might read and write "Dynamic(redis)". This identifier is
subsequently matched (back) up to the configuration file so
we're able to re-create arbitrary user configurations.
The PCP platform configuration file format is fairly simple.
We expand configs from several directories, including the
users homedir alongside htoprc (below htop/meters/) and also
/etc/pcp/htop/meters. The format will be described via a
new pcp-htop(5) man page, but its basically ini-style and
each Meter has one or more metric expressions associated, as
well as specifications for labels, color and so on via a dot
separated notation for individual metrics within the Meter.
A few initial sample configuration files are provided below
./pcp/meters that give the general idea. The PCP "derived"
metric specification - see pmRegisterDerived(3) - is used
as the syntax for specifying metrics in PCP DynamicMeters.
Reading and parsing /proc/<pid>/maps is quite expensive.
Do not check for deleted libraries if the main binary has been deleted;
in this case the deleted binary takes precedence.
Do not check in threads. The check is void for kernel threads and user-
land threads can just inherit the state from the main process structure.
O_PATH is available since Linux 2.6.39, but we are using fstat(2) on the
returned file descriptor in LinuxProcessList_statProcessDir(), which
is only supported since Linux 3.6.
Fixes#534
Shared libraries can be replaced by an upgrade, highlight processes
using deleted shared libraries.
Link with highlightDeletedExe setting, enabled by default.
Currently only checked on Linux.
Add process columns showing the elapsed time since the process was
started.
Similar to STARTTIME, but shows the time passed since the process start
instead of the fixed start time of the process.
Closes https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=782636
The following assert failure might happen on short running threads with
an empty comm value in /proc/${pid}/stat:
htop: Process.c:1159: void Process_updateCmdline(Process *, const char *, int, int): Assertion `(cmdline && basenameStart < (int)strlen(cmdline)) || (!cmdline && basenameStart == 0)' failed.
The specific task is:
comm=''
exe='(null)'
cmdline='/usr/bin/ruby /usr/bin/how-can-i-help --apt'
So basenameStart is 0, while strlen(cmdline) is also 0.
- fix header width of IO_READ_RATE
- save data in bytes (not kilobytes) to better compute rate
- fix rate data: multiply with 1000 to compensate time difference in
milliseconds
- rename unit less variable now into realtimeMs
- use Process_printBytes(..., data * pageSize, ...) instead of
Process_printKBytes(..., data * pageSizeKB, ...) to avoid wrapper
Make functions formatting data for a process field column less error
prone, unify interfaces and improve some internals.
* Process_printBytes
- rename from Process_humanNumber
- take number in bytes, not kilobytes
- handle petabytes
- increase buffer to avoid crashes when the passed value is
~ ULLONG_MAX
* Process_printKBytes
- add wrapper for Process_printBytes taking kilobytes keeping -1 as
special value
* Process_printCount
- rename from Process_colorNumber
* Process_printTime
- add coloring parameter as other print functions
- improve coloring and formatting for larger times
* Process_printRate
- rename from Process_outputRate
- use local buffer instead of passed one; this function prints to the
RichString after all
`RichString_appendWide()` is more expensive than
`RichString_appendAscii()` due to the calls to `mbstowcs(3)` and
`iswprint(3)`.
Use the latter to print the process field buffer by default.
For the following fields this theoretically can corrupt the output:
- SECATTR
- CGROUP
- CTID
`RichString_appendnAscii()` avoids a `strlen(3)` call over
` RichString_appendAscii()`.
Use the former where the length is available from a previous checked
`snprintf(3)` call.
Keep `RichString_appendAscii()` when passing a string literal and
rely on compilers to optimize the `strlen(3)` call away.
* Rename internal identifier from TTY_NR to just TTY
* Unify column header on platforms
* Use devname(3) on BSD derivate to show the actual terminal,
simplifies current FreeBSD implementation.
* Use 'unsigned long int' as id type, to fit dev_t on Linux.
Only on Solaris the terminal path is not yet resolved.