library: adding IO accounting
This is a modification of MR !122 by @renit1609 to fit the new library. Problem statement: The procps library has no PROC_FILLIO flag to fetch the proc field "/proc/[pid]/io" data process-wise. IO Accounting is not included as part of procps. Requirement: We have a requirement to fetch process wise IO utilization which can be used for monitoring. When looking through the procps library, I see that IO Accounting (/proc/[pid]/io) is not being included as part of procps. There is no such flag like PROC_FILLIO being included in readproc.h . Solution: While looking at the implementation done for other proc fields, I used the spare bits in app code. I renamed PROC_SPARE_1 as PROC_FILLIO, the spare bit from PROC_SPARE_* and used it for fetching /proc/[pid]/io data as part of the procps library similar to other fields. I moved the PROC_SPARE_* bits each by 1 bit to retain the spare bits. Meanwhile added the IO fields in proc_t structure. References: procps-ng/procps!122 procps-ng/procps#184
This commit is contained in:
parent
fa31656f07
commit
a7afe06e6f
15
proc/pids.c
15
proc/pids.c
@ -193,6 +193,13 @@ REG_set(ID_SUSER, str, suser)
|
||||
REG_set(ID_TGID, s_int, tgid)
|
||||
REG_set(ID_TID, s_int, tid)
|
||||
REG_set(ID_TPGID, s_int, tpgid)
|
||||
REG_set(IO_READ_BYTES, ul_int, read_bytes)
|
||||
REG_set(IO_READ_CHARS, ul_int, rchar)
|
||||
REG_set(IO_READ_OPS, ul_int, syscr)
|
||||
REG_set(IO_WRITE_BYTES, ul_int, write_bytes)
|
||||
REG_set(IO_WRITE_CBYTES, ul_int, cancelled_write_bytes)
|
||||
REG_set(IO_WRITE_CHARS, ul_int, wchar)
|
||||
REG_set(IO_WRITE_OPS, ul_int, syscw)
|
||||
REG_set(LXCNAME, str, lxcname)
|
||||
CVT_set(MEM_CODE, ul_int, trs)
|
||||
REG_set(MEM_CODE_PGS, ul_int, trs)
|
||||
@ -341,6 +348,7 @@ srtDECL(noop) {
|
||||
#define f_grp PROC_FILLGRP
|
||||
#define f_login PROC_FILL_LUID
|
||||
#define f_lxc PROC_FILL_LXC
|
||||
#define f_io PROC_FILLIO
|
||||
#define f_ns PROC_FILLNS
|
||||
#define f_oom PROC_FILLOOM
|
||||
#define f_stat PROC_FILLSTAT
|
||||
@ -442,6 +450,13 @@ static struct {
|
||||
{ RS(ID_TGID), 0, NULL, QS(s_int), 0, TS(s_int) }, // oldflags: free w/ simple_nextpid
|
||||
{ RS(ID_TID), 0, NULL, QS(s_int), 0, TS(s_int) }, // oldflags: free w/ simple_nexttid
|
||||
{ RS(ID_TPGID), f_stat, NULL, QS(s_int), 0, TS(s_int) },
|
||||
{ RS(IO_READ_BYTES), f_io, NULL, QS(ul_int), 0, TS(ul_int) },
|
||||
{ RS(IO_READ_CHARS), f_io, NULL, QS(ul_int), 0, TS(ul_int) },
|
||||
{ RS(IO_READ_OPS), f_io, NULL, QS(ul_int), 0, TS(ul_int) },
|
||||
{ RS(IO_WRITE_BYTES), f_io, NULL, QS(ul_int), 0, TS(ul_int) },
|
||||
{ RS(IO_WRITE_CBYTES), f_io, NULL, QS(ul_int), 0, TS(ul_int) },
|
||||
{ RS(IO_WRITE_CHARS), f_io, NULL, QS(ul_int), 0, TS(ul_int) },
|
||||
{ RS(IO_WRITE_OPS), f_io, NULL, QS(ul_int), 0, TS(ul_int) },
|
||||
{ RS(LXCNAME), f_lxc, NULL, QS(str), 0, TS(str) }, // freefunc NULL w/ cached string
|
||||
{ RS(MEM_CODE), f_statm, NULL, QS(ul_int), 0, TS(ul_int) },
|
||||
{ RS(MEM_CODE_PGS), f_statm, NULL, QS(ul_int), 0, TS(ul_int) },
|
||||
|
@ -78,6 +78,13 @@ enum pids_item {
|
||||
PIDS_ID_TGID, // s_int status: Tgid
|
||||
PIDS_ID_TID, // s_int from /proc/<pid>/task/<tid>
|
||||
PIDS_ID_TPGID, // s_int stat: tty_pgrp
|
||||
PIDS_IO_READ_BYTES, // ul_int io: bytes read
|
||||
PIDS_IO_READ_CHARS, // ul_int io: characters read
|
||||
PIDS_IO_READ_OPS, // ul_int io: read operations
|
||||
PIDS_IO_WRITE_BYTES, // ul_int io: bytes written
|
||||
PIDS_IO_WRITE_CBYTES, // ul_int io: cancelled write bytes
|
||||
PIDS_IO_WRITE_CHARS, // ul_int io: characters written
|
||||
PIDS_IO_WRITE_OPS, // ul_int io: write operations
|
||||
PIDS_LXCNAME, // str derived from CGROUP 'lxc.payload'
|
||||
PIDS_MEM_CODE, // ul_int derived from MEM_CODE_PGS, as KiB
|
||||
PIDS_MEM_CODE_PGS, // ul_int statm: trs
|
||||
|
@ -641,6 +641,12 @@ static void statm2proc(const char* s, proc_t *restrict P) {
|
||||
&P->trs, &P->lrs, &P->drs, &P->dt);
|
||||
}
|
||||
|
||||
static void io2proc(const char* s, proc_t *restrict P) {
|
||||
int num;
|
||||
num = sscanf(s, "rchar: %lu wchar: %lu syscr: %lu syscw: %lu read_bytes: %lu write_bytes: %lu cancelled_write_bytes: %lu",
|
||||
&P->rchar, &P->wchar, &P->syscr,
|
||||
&P->syscw, &P->read_bytes, &P->write_bytes, &P->cancelled_write_bytes);
|
||||
}
|
||||
|
||||
static int file2str(const char *directory, const char *what, struct utlbuf_s *ub) {
|
||||
#define buffGRW 1024
|
||||
@ -1043,6 +1049,11 @@ static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict cons
|
||||
rc += stat2proc(ub.buf, p);
|
||||
}
|
||||
|
||||
if (flags & PROC_FILLIO) { // read /proc/#/io
|
||||
if (file2str(path, "io", &ub) != -1)
|
||||
io2proc(ub.buf, p);
|
||||
}
|
||||
|
||||
if (flags & PROC_FILLMEM) { // read /proc/#/statm
|
||||
if (file2str(path, "statm", &ub) != -1)
|
||||
statm2proc(ub.buf, p);
|
||||
@ -1153,6 +1164,11 @@ static proc_t* simple_readtask(PROCTAB *restrict const PT, proc_t *restrict cons
|
||||
rc += stat2proc(ub.buf, t);
|
||||
}
|
||||
|
||||
if (flags & PROC_FILLIO) { // read /proc/#/io
|
||||
if (file2str(path, "io", &ub) != -1)
|
||||
io2proc(ub.buf, t);
|
||||
}
|
||||
|
||||
if (flags & PROC_FILLMEM) { // read /proc/#/task/#statm
|
||||
if (file2str(path, "statm", &ub) != -1)
|
||||
statm2proc(ub.buf, t);
|
||||
|
@ -97,7 +97,14 @@ typedef struct proc_t {
|
||||
min_flt, // stat number of minor page faults since process start
|
||||
maj_flt, // stat number of major page faults since process start
|
||||
cmin_flt, // stat cumulative min_flt of process and child processes
|
||||
cmaj_flt; // stat cumulative maj_flt of process and child processes
|
||||
cmaj_flt, // stat cumulative maj_flt of process and child processes
|
||||
rchar, // io characters read
|
||||
wchar, // io characters written
|
||||
syscr, // io number of read I/O operations
|
||||
syscw, // io number of write I/O operations
|
||||
read_bytes, // io number of bytes fetched from the storage layer
|
||||
write_bytes, // io number of bytes sent to the storage layer
|
||||
cancelled_write_bytes; // io number of bytes truncating pagecache
|
||||
char
|
||||
*environ, // (special) environment as string (/proc/#/environ)
|
||||
*cmdline, // (special) command line as string (/proc/#/cmdline)
|
||||
@ -209,6 +216,7 @@ typedef struct PROCTAB {
|
||||
#define PROC_FILL_LXC 0x800000 // fill in proc_t lxcname, if possible
|
||||
#define PROC_FILL_LUID 0x400000 // fill in proc_t luid (login user id)
|
||||
#define PROC_FILL_EXE 0x200000 // fill in proc_t exe path + pgm name
|
||||
#define PROC_FILLIO 0x01000000 // fill in proc_t io information
|
||||
|
||||
// consider only processes with one of the passed:
|
||||
#define PROC_PID 0x1000 // process id numbers ( 0 terminated)
|
||||
@ -225,10 +233,10 @@ typedef struct PROCTAB {
|
||||
#define PROC_FILL_SUPGRP ( 0x0400 | PROC_FILLSTATUS ) // obtain supplementary group names
|
||||
|
||||
// it helps to give app code a few spare bits
|
||||
#define PROC_SPARE_1 0x01000000
|
||||
#define PROC_SPARE_2 0x02000000
|
||||
#define PROC_SPARE_3 0x04000000
|
||||
#define PROC_SPARE_4 0x08000000
|
||||
#define PROC_SPARE_1 0x02000000
|
||||
#define PROC_SPARE_2 0x04000000
|
||||
#define PROC_SPARE_3 0x08000000
|
||||
#define PROC_SPARE_4 0x10000000
|
||||
|
||||
// Function definitions
|
||||
// Initialize a PROCTAB structure holding needed call-to-call persistent data
|
||||
|
Loading…
Reference in New Issue
Block a user