diff options
author | Christian Göttsche <cgzones@googlemail.com> | 2021-01-27 15:11:48 +0100 |
---|---|---|
committer | BenBE <BenBE@geshi.org> | 2021-01-30 14:21:26 +0100 |
commit | fdaa15bd8d6df7dd4721ed70a913865b343a80c7 (patch) | |
tree | 2015c85afa9a2167e1c92a151dea924e05c72570 /linux | |
parent | fee744abd2d7c1a3a9b8fa4ece7ddfc872078850 (diff) |
Linux: overhaul io process fields
- avoid UBSAN conversions
- print N/A on no data (i.e. as unprivileged user)
- fix rate calculation to show bytes (instead of a thousandth)
- print bytes as human number (i.e. 8MB) instead of 8388608
- stabilize sorting by adjusting NAN values to very tiny negative number
Diffstat (limited to 'linux')
-rw-r--r-- | linux/LinuxProcess.c | 39 | ||||
-rw-r--r-- | linux/LinuxProcess.h | 20 | ||||
-rw-r--r-- | linux/LinuxProcessList.c | 37 |
3 files changed, 58 insertions, 38 deletions
diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c index 79e73e84..df9958d8 100644 --- a/linux/LinuxProcess.c +++ b/linux/LinuxProcess.c @@ -74,14 +74,14 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { #ifdef HAVE_VSERVER [VXID] = { .name = "VXID", .title = " VXID ", .description = "VServer process ID", .flags = PROCESS_FLAG_LINUX_VSERVER, }, #endif - [RCHAR] = { .name = "RCHAR", .title = " RD_CHAR ", .description = "Number of bytes the process has read", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, - [WCHAR] = { .name = "WCHAR", .title = " WR_CHAR ", .description = "Number of bytes the process has written", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, - [SYSCR] = { .name = "SYSCR", .title = " RD_SYSC ", .description = "Number of read(2) syscalls for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, - [SYSCW] = { .name = "SYSCW", .title = " WR_SYSC ", .description = "Number of write(2) syscalls for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, - [RBYTES] = { .name = "RBYTES", .title = " IO_RBYTES ", .description = "Bytes of read(2) I/O for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, - [WBYTES] = { .name = "WBYTES", .title = " IO_WBYTES ", .description = "Bytes of write(2) I/O for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, - [CNCLWB] = { .name = "CNCLWB", .title = " IO_CANCEL ", .description = "Bytes of cancelled write(2) I/O", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, - [IO_READ_RATE] = { .name = "IO_READ_RATE", .title = " DISK READ ", .description = "The I/O rate of read(2) in bytes per second for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, + [RCHAR] = { .name = "RCHAR", .title = "RCHAR ", .description = "Number of bytes the process has read", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, + [WCHAR] = { .name = "WCHAR", .title = "WCHAR ", .description = "Number of bytes the process has written", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, + [SYSCR] = { .name = "SYSCR", .title = " READ_SYSC ", .description = "Number of read(2) syscalls for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, + [SYSCW] = { .name = "SYSCW", .title = " WRITE_SYSC ", .description = "Number of write(2) syscalls for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, + [RBYTES] = { .name = "RBYTES", .title = " IO_R ", .description = "Bytes of read(2) I/O for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, + [WBYTES] = { .name = "WBYTES", .title = " IO_W ", .description = "Bytes of write(2) I/O for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, + [CNCLWB] = { .name = "CNCLWB", .title = " IO_C ", .description = "Bytes of cancelled write(2) I/O", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, + [IO_READ_RATE] = { .name = "IO_READ_RATE", .title = " DISK READ ", .description = "The I/O rate of read(2) in bytes per second for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, [IO_WRITE_RATE] = { .name = "IO_WRITE_RATE", .title = " DISK WRITE ", .description = "The I/O rate of write(2) in bytes per second for the process", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, [IO_RATE] = { .name = "IO_RATE", .title = " DISK R/W ", .description = "Total I/O rate in bytes per second", .flags = PROCESS_FLAG_IO, .defaultSortDesc = true, }, [CGROUP] = { .name = "CGROUP", .title = " CGROUP ", .description = "Which cgroup the process is in", .flags = PROCESS_FLAG_LINUX_CGROUP, }, @@ -637,13 +637,13 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces case STIME: Process_printTime(str, lp->stime); return; case CUTIME: Process_printTime(str, lp->cutime); return; case CSTIME: Process_printTime(str, lp->cstime); return; - case RCHAR: Process_colorNumber(str, lp->io_rchar, coloring); return; - case WCHAR: Process_colorNumber(str, lp->io_wchar, coloring); return; + case RCHAR: Process_humanNumber(str, lp->io_rchar, coloring); return; + case WCHAR: Process_humanNumber(str, lp->io_wchar, coloring); return; case SYSCR: Process_colorNumber(str, lp->io_syscr, coloring); return; case SYSCW: Process_colorNumber(str, lp->io_syscw, coloring); return; - case RBYTES: Process_colorNumber(str, lp->io_read_bytes, coloring); return; - case WBYTES: Process_colorNumber(str, lp->io_write_bytes, coloring); return; - case CNCLWB: Process_colorNumber(str, lp->io_cancelled_write_bytes, coloring); return; + case RBYTES: Process_humanNumber(str, lp->io_read_bytes, coloring); return; + case WBYTES: Process_humanNumber(str, lp->io_write_bytes, coloring); return; + case CNCLWB: Process_humanNumber(str, lp->io_cancelled_write_bytes, coloring); return; case IO_READ_RATE: Process_outputRate(str, buffer, n, lp->io_rate_read_bps, coloring); return; case IO_WRITE_RATE: Process_outputRate(str, buffer, n, lp->io_rate_write_bps, coloring); return; case IO_RATE: { @@ -753,6 +753,13 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces RichString_appendWide(str, attr, buffer); } +static double adjustNaN(double num) { + if (isnan(num)) + return -0.0005; + + return num; +} + static int LinuxProcess_compareByKey(const Process* v1, const Process* v2, ProcessField key) { const LinuxProcess* p1 = (const LinuxProcess*)v1; const LinuxProcess* p2 = (const LinuxProcess*)v2; @@ -797,11 +804,11 @@ static int LinuxProcess_compareByKey(const Process* v1, const Process* v2, Proce case CNCLWB: return SPACESHIP_NUMBER(p1->io_cancelled_write_bytes, p2->io_cancelled_write_bytes); case IO_READ_RATE: - return SPACESHIP_NUMBER(p1->io_rate_read_bps, p2->io_rate_read_bps); + return SPACESHIP_NUMBER(adjustNaN(p1->io_rate_read_bps), adjustNaN(p2->io_rate_read_bps)); case IO_WRITE_RATE: - return SPACESHIP_NUMBER(p1->io_rate_write_bps, p2->io_rate_write_bps); + return SPACESHIP_NUMBER(adjustNaN(p1->io_rate_write_bps), adjustNaN(p2->io_rate_write_bps)); case IO_RATE: - return SPACESHIP_NUMBER(p1->io_rate_read_bps + p1->io_rate_write_bps, p2->io_rate_read_bps + p2->io_rate_write_bps); + return SPACESHIP_NUMBER(adjustNaN(p1->io_rate_read_bps) + adjustNaN(p1->io_rate_write_bps), adjustNaN(p2->io_rate_read_bps) + adjustNaN(p2->io_rate_write_bps)); #ifdef HAVE_OPENVZ case CTID: return SPACESHIP_NULLSTR(p1->ctid, p2->ctid); diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h index 2e9a9d13..03103c36 100644 --- a/linux/LinuxProcess.h +++ b/linux/LinuxProcess.h @@ -81,15 +81,31 @@ typedef struct LinuxProcess_ { long m_drs; long m_lrs; long m_dt; + + /* Data read (in kilobytes) */ unsigned long long io_rchar; + + /* Data written (in kilobytes) */ unsigned long long io_wchar; + + /* Number of read(2) syscalls */ unsigned long long io_syscr; + + /* Number of write(2) syscalls */ unsigned long long io_syscw; + + /* Storage data read (in kilobytes) */ unsigned long long io_read_bytes; + + /* Storage data written (in kilobytes) */ unsigned long long io_write_bytes; + + /* Storgae data cancelled (in kilobytes) */ unsigned long long io_cancelled_write_bytes; - unsigned long long io_rate_read_time; - unsigned long long io_rate_write_time; + + /* Point in time of last io scan (in seconds elapsed since the Epoch) */ + unsigned long long io_last_scan_time; + double io_rate_read_bps; double io_rate_write_bps; #ifdef HAVE_OPENVZ diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index ed512df8..2e751b8a 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -385,15 +385,14 @@ static void LinuxProcessList_readIoFile(LinuxProcess* process, openat_arg_t proc if (r < 0) { process->io_rate_read_bps = NAN; process->io_rate_write_bps = NAN; - process->io_rchar = -1LL; - process->io_wchar = -1LL; - process->io_syscr = -1LL; - process->io_syscw = -1LL; - process->io_read_bytes = -1LL; - process->io_write_bytes = -1LL; - process->io_cancelled_write_bytes = -1LL; - process->io_rate_read_time = -1LL; - process->io_rate_write_time = -1LL; + process->io_rchar = ULLONG_MAX; + process->io_wchar = ULLONG_MAX; + process->io_syscr = ULLONG_MAX; + process->io_syscw = ULLONG_MAX; + process->io_read_bytes = ULLONG_MAX; + process->io_write_bytes = ULLONG_MAX; + process->io_cancelled_write_bytes = ULLONG_MAX; + process->io_last_scan_time = now; return; } @@ -405,22 +404,18 @@ static void LinuxProcessList_readIoFile(LinuxProcess* process, openat_arg_t proc switch (line[0]) { case 'r': if (line[1] == 'c' && String_startsWith(line + 2, "har: ")) { - process->io_rchar = strtoull(line + 7, NULL, 10); + process->io_rchar = strtoull(line + 7, NULL, 10) / ONE_K; } else if (String_startsWith(line + 1, "ead_bytes: ")) { - process->io_read_bytes = strtoull(line + 12, NULL, 10); - process->io_rate_read_bps = - ((double)(process->io_read_bytes - last_read)) / (((double)(now - process->io_rate_read_time)) / 1000); - process->io_rate_read_time = now; + process->io_read_bytes = strtoull(line + 12, NULL, 10) / ONE_K; + process->io_rate_read_bps = ONE_K * (process->io_read_bytes - last_read) / (now - process->io_last_scan_time); } break; case 'w': if (line[1] == 'c' && String_startsWith(line + 2, "har: ")) { - process->io_wchar = strtoull(line + 7, NULL, 10); + process->io_wchar = strtoull(line + 7, NULL, 10) / ONE_K; } else if (String_startsWith(line + 1, "rite_bytes: ")) { - process->io_write_bytes = strtoull(line + 13, NULL, 10); - process->io_rate_write_bps = - ((double)(process->io_write_bytes - last_write)) / (((double)(now - process->io_rate_write_time)) / 1000); - process->io_rate_write_time = now; + process->io_write_bytes = strtoull(line + 13, NULL, 10) / ONE_K; + process->io_rate_write_bps = ONE_K * (process->io_write_bytes - last_write) / (now - process->io_last_scan_time); } break; case 's': @@ -432,10 +427,12 @@ static void LinuxProcessList_readIoFile(LinuxProcess* process, openat_arg_t proc break; case 'c': if (String_startsWith(line + 1, "ancelled_write_bytes: ")) { - process->io_cancelled_write_bytes = strtoull(line + 23, NULL, 10); + process->io_cancelled_write_bytes = strtoull(line + 23, NULL, 10) / ONE_K; } } } + + process->io_last_scan_time = now; } typedef struct LibraryData_ { |