diff options
author | Jim Warner <james.warner@comcast.net> | 2016-08-05 00:00:00 -0500 |
---|---|---|
committer | Craig Small <csmall@enc.com.au> | 2016-08-07 21:40:48 +1000 |
commit | e3270d463de7eebd9f5ae20c85495e3cb5b69a9f (patch) | |
tree | f818e1a1d95fe4ec980fb8e29f97fa01b566473b | |
parent | e0515e23e718094d5651966f672aa241f53d9381 (diff) | |
download | procps-ng-e3270d463de7eebd9f5ae20c85495e3cb5b69a9f.tar.gz |
library: provide for validating result type references
During development, we now have a means for validating
that a type referenced in application code matches the
actual type set by the library. The new feature can be
activated through either of the following two methods:
1) ./configure CFLAGS='-DXTRA_PROCPS_DEBUG' (all pgms)
2) an #include <proc/xtra-procps-debug.h> (single pgm)
[ in the future, one could add a formal configure.ac ]
[ provision. but for now a manual approach is safer. ]
Lastly, for any module which provides a sort function,
the handling for both 'noop' & 'extra' enumerators was
made consistent. Now, 'noop' is not sorted and 'extra'
will be sorted as that module's widest supported type.
Signed-off-by: Jim Warner <james.warner@comcast.net>
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | proc/diskstats.c | 126 | ||||
-rw-r--r-- | proc/libprocps.sym | 11 | ||||
-rw-r--r-- | proc/meminfo.c | 252 | ||||
-rw-r--r-- | proc/pids.c | 287 | ||||
-rw-r--r-- | proc/procps.h | 4 | ||||
-rw-r--r-- | proc/slabinfo.c | 141 | ||||
-rw-r--r-- | proc/stat.c | 141 | ||||
-rw-r--r-- | proc/vmstat.c | 544 | ||||
-rw-r--r-- | proc/xtra-procps-debug.h | 194 |
10 files changed, 1121 insertions, 585 deletions
diff --git a/Makefile.am b/Makefile.am index ae072b7..a2cb7ec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -206,7 +206,8 @@ proc_libprocps_la_SOURCES = \ proc/wchan.c \ proc/wchan.h \ proc/uptime.c \ - proc/uptime.h + proc/uptime.h \ + proc/xtra-procps-debug.h proc_libprocps_la_includedir = $(includedir)/proc/ proc_libprocps_la_include_HEADERS = \ @@ -223,7 +224,8 @@ proc_libprocps_la_include_HEADERS = \ proc/uptime.h \ proc/version.h \ proc/vmstat.h \ - proc/wchan.h + proc/wchan.h \ + proc/xtra-procps-debug.h dist_man_MANS += \ proc/openproc.3 \ diff --git a/proc/diskstats.c b/proc/diskstats.c index 07abb60..019b5fd 100644 --- a/proc/diskstats.c +++ b/proc/diskstats.c @@ -206,6 +206,9 @@ typedef void (*SET_t)(struct diskstats_result *, struct dev_node *); typedef int (*QSR_t)(const void *, const void *, void *); #define QS(t) (QSR_t)srtNAME(t) +#define TS(t) STRINGIFY(t) +#define TS_noop "" + /* * Need it be said? * This table must be kept in the exact same order as @@ -213,43 +216,44 @@ typedef int (*QSR_t)(const void *, const void *, void *); static struct { SET_t setsfunc; // the actual result setting routine QSR_t sortfunc; // sort cmp func for a specific type + char *type2str; // the result type as a string value } Item_table[] = { -/* setsfunc sortfunc - ---------------------------------- --------- */ - { RS(noop), QS(ul_int) }, - { RS(extra), QS(noop) }, - - { RS(DISKSTATS_NAME), QS(str) }, - { RS(DISKSTATS_TYPE), QS(s_int) }, - { RS(DISKSTATS_MAJOR), QS(s_int) }, - { RS(DISKSTATS_MINOR), QS(s_int) }, - - { RS(DISKSTATS_READS), QS(ul_int) }, - { RS(DISKSTATS_READS_MERGED), QS(ul_int) }, - { RS(DISKSTATS_READ_SECTORS), QS(ul_int) }, - { RS(DISKSTATS_READ_TIME), QS(ul_int) }, - { RS(DISKSTATS_WRITES), QS(ul_int) }, - { RS(DISKSTATS_WRITES_MERGED), QS(ul_int) }, - { RS(DISKSTATS_WRITE_SECTORS), QS(ul_int) }, - { RS(DISKSTATS_WRITE_TIME), QS(ul_int) }, - { RS(DISKSTATS_IO_TIME), QS(ul_int) }, - { RS(DISKSTATS_IO_WTIME), QS(ul_int) }, - - { RS(DISKSTATS_IO_INPROGRESS), QS(s_int) }, - - { RS(DISKSTATS_DELTA_READS), QS(s_int) }, - { RS(DISKSTATS_DELTA_READS_MERGED), QS(s_int) }, - { RS(DISKSTATS_DELTA_READ_SECTORS), QS(s_int) }, - { RS(DISKSTATS_DELTA_READ_TIME), QS(s_int) }, - { RS(DISKSTATS_DELTA_WRITES), QS(s_int) }, - { RS(DISKSTATS_DELTA_WRITES_MERGED), QS(s_int) }, - { RS(DISKSTATS_DELTA_WRITE_SECTORS), QS(s_int) }, - { RS(DISKSTATS_DELTA_WRITE_TIME), QS(s_int) }, - { RS(DISKSTATS_DELTA_IO_TIME), QS(s_int) }, - { RS(DISKSTATS_DELTA_IO_WTIME), QS(s_int) }, +/* setsfunc sortfunc type2str + ---------------------------------- ----------- ---------- */ + { RS(noop), QS(noop), TS_noop }, + { RS(extra), QS(ul_int), TS_noop }, + + { RS(DISKSTATS_NAME), QS(str), TS(str) }, + { RS(DISKSTATS_TYPE), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_MAJOR), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_MINOR), QS(s_int), TS(s_int) }, + + { RS(DISKSTATS_READS), QS(ul_int), TS(ul_int) }, + { RS(DISKSTATS_READS_MERGED), QS(ul_int), TS(ul_int) }, + { RS(DISKSTATS_READ_SECTORS), QS(ul_int), TS(ul_int) }, + { RS(DISKSTATS_READ_TIME), QS(ul_int), TS(ul_int) }, + { RS(DISKSTATS_WRITES), QS(ul_int), TS(ul_int) }, + { RS(DISKSTATS_WRITES_MERGED), QS(ul_int), TS(ul_int) }, + { RS(DISKSTATS_WRITE_SECTORS), QS(ul_int), TS(ul_int) }, + { RS(DISKSTATS_WRITE_TIME), QS(ul_int), TS(ul_int) }, + { RS(DISKSTATS_IO_TIME), QS(ul_int), TS(ul_int) }, + { RS(DISKSTATS_IO_WTIME), QS(ul_int), TS(ul_int) }, + + { RS(DISKSTATS_IO_INPROGRESS), QS(s_int), TS(s_int) }, + + { RS(DISKSTATS_DELTA_READS), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_DELTA_READS_MERGED), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_DELTA_READ_SECTORS), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_DELTA_READ_TIME), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_DELTA_WRITES), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_DELTA_WRITES_MERGED), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_DELTA_WRITE_SECTORS), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_DELTA_WRITE_TIME), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_DELTA_IO_TIME), QS(s_int), TS(s_int) }, + { RS(DISKSTATS_DELTA_IO_WTIME), QS(s_int), TS(s_int) }, // dummy entry corresponding to DISKSTATS_logical_end ... - { NULL, NULL } + { NULL, NULL, NULL } }; /* please note, @@ -974,3 +978,57 @@ PROCPS_EXPORT struct diskstats_stack **procps_diskstats_sort ( qsort_r(stacks, numstacked, sizeof(void *), (QSR_t)Item_table[p->item].sortfunc, &parms); return stacks; } // end: procps_diskstats_sort + + +// --- special debugging function(s) ------------------------------------------ +/* + * The following isn't part of the normal programming interface. Rather, + * it exists to validate result types referenced in application programs. + * + * It's used only when: + * 1) the 'XTRA_PROCPS_DEBUG' has been defined, or + * 2) the '#include <proc/xtra-procps-debug.h>' used + */ + +PROCPS_EXPORT struct diskstats_result *xtra_diskstats_get ( + struct diskstats_info *info, + const char *name, + enum diskstats_item actual_enum, + const char *typestr, + const char *file, + int lineno) +{ + struct diskstats_result *r = procps_diskstats_get(info, name, actual_enum); + + if (r) { + char *str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); + } + return r; +} // end: xtra_diskstats_get_ + + +PROCPS_EXPORT void xtra_diskstats_val ( + int relative_enum, + const char *typestr, + const struct diskstats_stack *stack, + struct diskstats_info *info, + const char *file, + int lineno) +{ + struct diskstats_result *r; + char *str; + + r = &stack->head[relative_enum]; + if (r->item < 0 || r->item >= DISKSTATS_logical_end) { + fprintf(stderr, "%s line %d: invalid item = %d, relative_enum = %d, type = %s\n" + , file, lineno, r->item, relative_enum, typestr); + return; + } + str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); +} // end: xtra_diskstats_val diff --git a/proc/libprocps.sym b/proc/libprocps.sym index 6707ce3..8853048 100644 --- a/proc/libprocps.sym +++ b/proc/libprocps.sym @@ -52,6 +52,17 @@ global: procps_vmstat_unref; procps_vmstat_get; procps_vmstat_select; + xtra_diskstats_get; + xtra_diskstats_val; + xtra_meminfo_get; + xtra_meminfo_val; + xtra_pids_val; + xtra_slabinfo_get; + xtra_slabinfo_val; + xtra_stat_get; + xtra_stat_val; + xtra_vmstat_get; + xtra_vmstat_val; local: *; }; diff --git a/proc/meminfo.c b/proc/meminfo.c index d0153cd..fd58349 100644 --- a/proc/meminfo.c +++ b/proc/meminfo.c @@ -235,112 +235,117 @@ MEM_set(SWAP_USED, ul_int, derived_swap_used) typedef void (*SET_t)(struct meminfo_result *, struct mem_hist *); #define RS(e) (SET_t)setNAME(e) +#define TS(t) STRINGIFY(t) +#define TS_noop "" + /* * Need it be said? * This table must be kept in the exact same order as * those 'enum meminfo_item' guys ! */ static struct { SET_t setsfunc; // the actual result setting routine + char *type2str; // the result type as a string value } Item_table[] = { -/* setsfunc - -------------------------- */ - { RS(noop) }, - { RS(extra) }, - - { RS(MEM_ACTIVE) }, - { RS(MEM_ACTIVE_ANON) }, - { RS(MEM_ACTIVE_FILE) }, - { RS(MEM_ANON) }, - { RS(MEM_AVAILABLE) }, - { RS(MEM_BOUNCE) }, - { RS(MEM_BUFFERS) }, - { RS(MEM_CACHED) }, - { RS(MEM_COMMIT_LIMIT) }, - { RS(MEM_COMMITTED_AS) }, - { RS(MEM_HARD_CORRUPTED) }, - { RS(MEM_DIRTY) }, - { RS(MEM_FREE) }, - { RS(MEM_HUGE_ANON) }, - { RS(MEM_HUGE_FREE) }, - { RS(MEM_HUGE_RSVD) }, - { RS(MEM_HUGE_SIZE) }, - { RS(MEM_HUGE_SURPLUS) }, - { RS(MEM_HUGE_TOTAL) }, - { RS(MEM_INACTIVE) }, - { RS(MEM_INACTIVE_ANON) }, - { RS(MEM_INACTIVE_FILE) }, - { RS(MEM_KERNEL_STACK) }, - { RS(MEM_LOCKED) }, - { RS(MEM_MAPPED) }, - { RS(MEM_NFS_UNSTABLE) }, - { RS(MEM_PAGE_TABLES) }, - { RS(MEM_SHARED) }, - { RS(MEM_SLAB) }, - { RS(MEM_SLAB_RECLAIM) }, - { RS(MEM_SLAB_UNRECLAIM) }, - { RS(MEM_TOTAL) }, - { RS(MEM_UNEVICTABLE) }, - { RS(MEM_USED) }, - { RS(MEM_VM_ALLOC_CHUNK) }, - { RS(MEM_VM_ALLOC_TOTAL) }, - { RS(MEM_VM_ALLOC_USED) }, - { RS(MEM_WRITEBACK) }, - { RS(MEM_WRITEBACK_TMP) }, - - { RS(DELTA_ACTIVE) }, - { RS(DELTA_ACTIVE_ANON) }, - { RS(DELTA_ACTIVE_FILE) }, - { RS(DELTA_ANON) }, - { RS(DELTA_AVAILABLE) }, - { RS(DELTA_BOUNCE) }, - { RS(DELTA_BUFFERS) }, - { RS(DELTA_CACHED) }, - { RS(DELTA_COMMIT_LIMIT) }, - { RS(DELTA_COMMITTED_AS) }, - { RS(DELTA_HARD_CORRUPTED) }, - { RS(DELTA_DIRTY) }, - { RS(DELTA_FREE) }, - { RS(DELTA_HUGE_ANON) }, - { RS(DELTA_HUGE_FREE) }, - { RS(DELTA_HUGE_RSVD) }, - { RS(DELTA_HUGE_SIZE) }, - { RS(DELTA_HUGE_SURPLUS) }, - { RS(DELTA_HUGE_TOTAL) }, - { RS(DELTA_INACTIVE) }, - { RS(DELTA_INACTIVE_ANON) }, - { RS(DELTA_INACTIVE_FILE) }, - { RS(DELTA_KERNEL_STACK) }, - { RS(DELTA_LOCKED) }, - { RS(DELTA_MAPPED) }, - { RS(DELTA_NFS_UNSTABLE) }, - { RS(DELTA_PAGE_TABLES) }, - { RS(DELTA_SHARED) }, - { RS(DELTA_SLAB) }, - { RS(DELTA_SLAB_RECLAIM) }, - { RS(DELTA_SLAB_UNRECLAIM) }, - { RS(DELTA_TOTAL) }, - { RS(DELTA_UNEVICTABLE) }, - { RS(DELTA_USED) }, - { RS(DELTA_VM_ALLOC_CHUNK) }, - { RS(DELTA_VM_ALLOC_TOTAL) }, - { RS(DELTA_VM_ALLOC_USED) }, - { RS(DELTA_WRITEBACK) }, - { RS(DELTA_WRITEBACK_TMP) }, - - { RS(MEMHI_FREE) }, - { RS(MEMHI_TOTAL) }, - { RS(MEMHI_USED) }, - { RS(MEMLO_FREE) }, - { RS(MEMLO_TOTAL) }, - { RS(MEMLO_USED) }, - - { RS(SWAP_CACHED) }, - { RS(SWAP_FREE) }, - { RS(SWAP_TOTAL) }, - { RS(SWAP_USED) }, +/* setsfunc type2str + ------------------------- ---------- */ + { RS(noop), TS_noop }, + { RS(extra), TS_noop }, + + { RS(MEM_ACTIVE), TS(ul_int) }, + { RS(MEM_ACTIVE_ANON), TS(ul_int) }, + { RS(MEM_ACTIVE_FILE), TS(ul_int) }, + { RS(MEM_ANON), TS(ul_int) }, + { RS(MEM_AVAILABLE), TS(ul_int) }, + { RS(MEM_BOUNCE), TS(ul_int) }, + { RS(MEM_BUFFERS), TS(ul_int) }, + { RS(MEM_CACHED), TS(ul_int) }, + { RS(MEM_COMMIT_LIMIT), TS(ul_int) }, + { RS(MEM_COMMITTED_AS), TS(ul_int) }, + { RS(MEM_HARD_CORRUPTED), TS(ul_int) }, + { RS(MEM_DIRTY), TS(ul_int) }, + { RS(MEM_FREE), TS(ul_int) }, + { RS(MEM_HUGE_ANON), TS(ul_int) }, + { RS(MEM_HUGE_FREE), TS(ul_int) }, + { RS(MEM_HUGE_RSVD), TS(ul_int) }, + { RS(MEM_HUGE_SIZE), TS(ul_int) }, + { RS(MEM_HUGE_SURPLUS), TS(ul_int) }, + { RS(MEM_HUGE_TOTAL), TS(ul_int) }, + { RS(MEM_INACTIVE), TS(ul_int) }, + { RS(MEM_INACTIVE_ANON), TS(ul_int) }, + { RS(MEM_INACTIVE_FILE), TS(ul_int) }, + { RS(MEM_KERNEL_STACK), TS(ul_int) }, + { RS(MEM_LOCKED), TS(ul_int) }, + { RS(MEM_MAPPED), TS(ul_int) }, + { RS(MEM_NFS_UNSTABLE), TS(ul_int) }, + { RS(MEM_PAGE_TABLES), TS(ul_int) }, + { RS(MEM_SHARED), TS(ul_int) }, + { RS(MEM_SLAB), TS(ul_int) }, + { RS(MEM_SLAB_RECLAIM), TS(ul_int) }, + { RS(MEM_SLAB_UNRECLAIM), TS(ul_int) }, + { RS(MEM_TOTAL), TS(ul_int) }, + { RS(MEM_UNEVICTABLE), TS(ul_int) }, + { RS(MEM_USED), TS(ul_int) }, + { RS(MEM_VM_ALLOC_CHUNK), TS(ul_int) }, + { RS(MEM_VM_ALLOC_TOTAL), TS(ul_int) }, + { RS(MEM_VM_ALLOC_USED), TS(ul_int) }, + { RS(MEM_WRITEBACK), TS(ul_int) }, + { RS(MEM_WRITEBACK_TMP), TS(ul_int) }, + + { RS(DELTA_ACTIVE), TS(s_int) }, + { RS(DELTA_ACTIVE_ANON), TS(s_int) }, + { RS(DELTA_ACTIVE_FILE), TS(s_int) }, + { RS(DELTA_ANON), TS(s_int) }, + { RS(DELTA_AVAILABLE), TS(s_int) }, + { RS(DELTA_BOUNCE), TS(s_int) }, + { RS(DELTA_BUFFERS), TS(s_int) }, + { RS(DELTA_CACHED), TS(s_int) }, + { RS(DELTA_COMMIT_LIMIT), TS(s_int) }, + { RS(DELTA_COMMITTED_AS), TS(s_int) }, + { RS(DELTA_HARD_CORRUPTED), TS(s_int) }, + { RS(DELTA_DIRTY), TS(s_int) }, + { RS(DELTA_FREE), TS(s_int) }, + { RS(DELTA_HUGE_ANON), TS(s_int) }, + { RS(DELTA_HUGE_FREE), TS(s_int) }, + { RS(DELTA_HUGE_RSVD), TS(s_int) }, + { RS(DELTA_HUGE_SIZE), TS(s_int) }, + { RS(DELTA_HUGE_SURPLUS), TS(s_int) }, + { RS(DELTA_HUGE_TOTAL), TS(s_int) }, + { RS(DELTA_INACTIVE), TS(s_int) }, + { RS(DELTA_INACTIVE_ANON), TS(s_int) }, + { RS(DELTA_INACTIVE_FILE), TS(s_int) }, + { RS(DELTA_KERNEL_STACK), TS(s_int) }, + { RS(DELTA_LOCKED), TS(s_int) }, + { RS(DELTA_MAPPED), TS(s_int) }, + { RS(DELTA_NFS_UNSTABLE), TS(s_int) }, + { RS(DELTA_PAGE_TABLES), TS(s_int) }, + { RS(DELTA_SHARED), TS(s_int) }, + { RS(DELTA_SLAB), TS(s_int) }, + { RS(DELTA_SLAB_RECLAIM), TS(s_int) }, + { RS(DELTA_SLAB_UNRECLAIM), TS(s_int) }, + { RS(DELTA_TOTAL), TS(s_int) }, + { RS(DELTA_UNEVICTABLE), TS(s_int) }, + { RS(DELTA_USED), TS(s_int) }, + { RS(DELTA_VM_ALLOC_CHUNK), TS(s_int) }, + { RS(DELTA_VM_ALLOC_TOTAL), TS(s_int) }, + { RS(DELTA_VM_ALLOC_USED), TS(s_int) }, + { RS(DELTA_WRITEBACK), TS(s_int) }, + { RS(DELTA_WRITEBACK_TMP), TS(s_int) }, + + { RS(MEMHI_FREE), TS(ul_int) }, + { RS(MEMHI_TOTAL), TS(ul_int) }, + { RS(MEMHI_USED), TS(ul_int) }, + + { RS(MEMLO_FREE), TS(ul_int) }, + { RS(MEMLO_TOTAL), TS(ul_int) }, + { RS(MEMLO_USED), TS(ul_int) }, + + { RS(SWAP_CACHED), TS(ul_int) }, + { RS(SWAP_FREE), TS(ul_int) }, + { RS(SWAP_TOTAL), TS(ul_int) }, + { RS(SWAP_USED), TS(ul_int) }, // dummy entry corresponding to MEMINFO_logical_end ... - { NULL, } + { NULL, NULL } }; /* please note, @@ -846,3 +851,56 @@ PROCPS_EXPORT struct meminfo_stack *procps_meminfo_select ( return info->extents->stacks[0]; } // end: procps_meminfo_select + + +// --- special debugging function(s) ------------------------------------------ +/* + * The following isn't part of the normal programming interface. Rather, + * it exists to validate result types referenced in application programs. + * + * It's used only when: + * 1) the 'XTRA_PROCPS_DEBUG' has been defined, or + * 2) the '#include <proc/xtra-procps-debug.h>' used + */ + +PROCPS_EXPORT struct meminfo_result *xtra_meminfo_get ( + struct meminfo_info *info, + enum meminfo_item actual_enum, + const char *typestr, + const char *file, + int lineno) +{ + struct meminfo_result *r = procps_meminfo_get(info, actual_enum); + + if (r) { + char *str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); + } + return r; +} // end: xtra_meminfo_get_ + + +PROCPS_EXPORT void xtra_meminfo_val ( + int relative_enum, + const char *typestr, + const struct meminfo_stack *stack, + struct meminfo_info *info, + const char *file, + int lineno) +{ + struct meminfo_result *r; + char *str; + + r = &stack->head[relative_enum]; + if (r->item < 0 || r->item >= MEMINFO_logical_end) { + fprintf(stderr, "%s line %d: invalid item = %d, relative_enum = %d, type = %s\n" + , file, lineno, r->item, relative_enum, typestr); + return; + } + str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); +} // end: xtra_meminfo_val diff --git a/proc/pids.c b/proc/pids.c index 9260a8c..f3c3393 100644 --- a/proc/pids.c +++ b/proc/pids.c @@ -369,6 +369,8 @@ typedef int (*QSR_t)(const void *, const void *, void *); #define RS(e) (SET_t)setNAME(e) #define FF(t) (FRE_t)freNAME(t) #define QS(t) (QSR_t)srtNAME(t) +#define TS(t) STRINGIFY(t) +#define TS_noop "" /* * Need it be said? @@ -380,134 +382,135 @@ static struct { FRE_t freefunc; // free function for strings storage QSR_t sortfunc; // sort cmp func for a specific type int needhist; // a result requires history support + char *type2str; // the result type as a string value } Item_table[] = { -/* setsfunc oldflags freefunc sortfunc needhist - --------------------- ---------- --------- ------------- -------- */ - { RS(noop), 0, NULL, QS(noop), 0 }, // user only, never altered - { RS(extra), 0, NULL, QS(ull_int), 0 }, // user only, reset to zero - - { RS(ADDR_END_CODE), f_stat, NULL, QS(ul_int), 0 }, - { RS(ADDR_KSTK_EIP), f_stat, NULL, QS(ul_int), 0 }, - { RS(ADDR_KSTK_ESP), f_stat, NULL, QS(ul_int), 0 }, - { RS(ADDR_START_CODE), f_stat, NULL, QS(ul_int), 0 }, - { RS(ADDR_START_STACK), f_stat, NULL, QS(ul_int), 0 }, - { RS(ALARM), f_stat, NULL, QS(ul_int), 0 }, - { RS(CGNAME), x_cgroup, FF(str), QS(str), 0 }, - { RS(CGROUP), x_cgroup, FF(str), QS(str), 0 }, - { RS(CGROUP_V), v_cgroup, FF(strv), QS(strv), 0 }, - { RS(CMD), f_either, FF(str), QS(str), 0 }, - { RS(CMDLINE), x_cmdline, FF(str), QS(str), 0 }, - { RS(CMDLINE_V), v_arg, FF(strv), QS(strv), 0 }, - { RS(ENVIRON), x_environ, FF(str), QS(str), 0 }, - { RS(ENVIRON_V), v_env, FF(strv), QS(strv), 0 }, - { RS(EXIT_SIGNAL), f_stat, NULL, QS(s_int), 0 }, - { RS(FLAGS), f_stat, NULL, QS(ul_int), 0 }, - { RS(FLT_MAJ), f_stat, NULL, QS(ul_int), 0 }, - { RS(FLT_MAJ_C), f_stat, NULL, QS(ul_int), 0 }, - { RS(FLT_MAJ_DELTA), f_stat, NULL, QS(s_int), +1 }, - { RS(FLT_MIN), f_stat, NULL, QS(ul_int), 0 }, - { RS(FLT_MIN_C), f_stat, NULL, QS(ul_int), 0 }, - { RS(FLT_MIN_DELTA), f_stat, NULL, QS(s_int), +1 }, - { RS(ID_EGID), 0, NULL, QS(u_int), 0 }, // oldflags: free w/ simple_read - { RS(ID_EGROUP), f_grp, NULL, QS(str), 0 }, - { RS(ID_EUID), 0, NULL, QS(u_int), 0 }, // oldflags: free w/ simple_read - { RS(ID_EUSER), f_usr, NULL, QS(str), 0 }, // freefunc NULL w/ cached string - { RS(ID_FGID), f_status, NULL, QS(u_int), 0 }, - { RS(ID_FGROUP), x_ogroup, NULL, QS(str), 0 }, - { RS(ID_FUID), f_status, NULL, QS(u_int), 0 }, - { RS(ID_FUSER), x_ouser, NULL, QS(str), 0 }, // freefunc NULL w/ cached string - { RS(ID_PGRP), f_stat, NULL, QS(s_int), 0 }, - { RS(ID_PID), 0, NULL, QS(s_int), 0 }, // oldflags: free w/ simple_nextpid - { RS(ID_PPID), f_either, NULL, QS(s_int), 0 }, - { RS(ID_RGID), f_status, NULL, QS(u_int), 0 }, - { RS(ID_RGROUP), x_ogroup, NULL, QS(str), 0 }, - { RS(ID_RUID), f_status, NULL, QS(u_int), 0 }, - { RS(ID_RUSER), x_ouser, NULL, QS(str), 0 }, // freefunc NULL w/ cached string - { RS(ID_SESSION), f_stat, NULL, QS(s_int), 0 }, - { RS(ID_SGID), f_status, NULL, QS(u_int), 0 }, - { RS(ID_SGROUP), x_ogroup, NULL, QS(str), 0 }, - { RS(ID_SUID), f_status, NULL, QS(u_int), 0 }, - { RS(ID_SUSER), x_ouser, NULL, QS(str), 0 }, // freefunc NULL w/ cached string - { RS(ID_TGID), 0, NULL, QS(s_int), 0 }, // oldflags: free w/ simple_nextpid - { RS(ID_TPGID), f_stat, NULL, QS(s_int), 0 }, - { RS(LXCNAME), f_lxc, NULL, QS(str), 0 }, // freefunc NULL w/ cached string - { RS(MEM_CODE), f_statm, NULL, QS(ul_int), 0 }, - { RS(MEM_CODE_PGS), f_statm, NULL, QS(ul_int), 0 }, - { RS(MEM_DATA), f_statm, NULL, QS(ul_int), 0 }, - { RS(MEM_DATA_PGS), f_statm, NULL, QS(ul_int), 0 }, - { RS(MEM_DT_PGS), f_statm, NULL, QS(ul_int), 0 }, // ( always 0 w/ since 2.6 ) - { RS(MEM_LRS_PGS), f_statm, NULL, QS(ul_int), 0 }, - { RS(MEM_RES), f_statm, NULL, QS(ul_int), 0 }, - { RS(MEM_RES_PGS), f_statm, NULL, QS(ul_int), 0 }, - { RS(MEM_SHR), f_statm, NULL, QS(ul_int), 0 }, - { RS(MEM_SHR_PGS), f_statm, NULL, QS(ul_int), 0 }, - { RS(MEM_VIRT), f_statm, NULL, QS(ul_int), 0 }, - { RS(MEM_VIRT_PGS), f_statm, NULL, QS(ul_int), 0 }, - { RS(NICE), f_stat, NULL, QS(s_int), 0 }, - { RS(NLWP), f_either, NULL, QS(s_int), 0 }, - { RS(NS_IPC), f_ns, NULL, QS(ul_int), 0 }, - { RS(NS_MNT), f_ns, NULL, QS(ul_int), 0 }, - { RS(NS_NET), f_ns, NULL, QS(ul_int), 0 }, - { RS(NS_PID), f_ns, NULL, QS(ul_int), 0 }, - { RS(NS_USER), f_ns, NULL, QS(ul_int), 0 }, - { RS(NS_UTS), f_ns, NULL, QS(ul_int), 0 }, - { RS(OOM_ADJ), f_oom, NULL, QS(s_int), 0 }, - { RS(OOM_SCORE), f_oom, NULL, QS(s_int), 0 }, - { RS(PRIORITY), f_stat, NULL, QS(s_int), 0 }, - { RS(PROCESSOR), f_stat, NULL, QS(u_int), 0 }, - { RS(RSS), f_stat, NULL, QS(ul_int), 0 }, - { RS(RSS_RLIM), f_stat, NULL, QS(ul_int), 0 }, - { RS(RTPRIO), f_stat, NULL, QS(s_int), 0 }, - { RS(SCHED_CLASS), f_stat, NULL, QS(s_int), 0 }, - { RS(SD_MACH), f_systemd, FF(str), QS(str), 0 }, - { RS(SD_OUID), f_systemd, FF(str), QS(str), 0 }, - { RS(SD_SEAT), f_systemd, FF(str), QS(str), 0 }, - { RS(SD_SESS), f_systemd, FF(str), QS(str), 0 }, - { RS(SD_SLICE), f_systemd, FF(str), QS(str), 0 }, - { RS(SD_UNIT), f_systemd, FF(str), QS(str), 0 }, - { RS(SD_UUNIT), f_systemd, FF(str), QS(str), 0 }, - { RS(SIGBLOCKED), f_status, FF(str), QS(str), 0 }, - { RS(SIGCATCH), f_status, FF(str), QS(str), 0 }, - { RS(SIGIGNORE), f_status, FF(str), QS(str), 0 }, - { RS(SIGNALS), f_status, FF(str), QS(str), 0 }, - { RS(SIGPENDING), f_status, FF(str), QS(str), 0 }, - { RS(STATE), f_either, NULL, QS(s_ch), 0 }, - { RS(SUPGIDS), f_status, FF(str), QS(str), 0 }, - { RS(SUPGROUPS), x_supgrp, FF(str), QS(str), 0 }, - { RS(TICS_ALL), f_stat, NULL, QS(ull_int), 0 }, - { RS(TICS_ALL_C), f_stat, NULL, QS(ull_int), 0 }, - { RS(TICS_ALL_DELTA), f_stat, NULL, QS(s_int), +1 }, - { RS(TICS_BLKIO), f_stat, NULL, QS(ull_int), 0 }, - { RS(TICS_GUEST), f_stat, NULL, QS(ull_int), 0 }, - { RS(TICS_GUEST_C), f_stat, NULL, QS(ull_int), 0 }, - { RS(TICS_SYSTEM), f_stat, NULL, QS(ull_int), 0 }, - { RS(TICS_SYSTEM_C), f_stat, NULL, QS(ull_int), 0 }, - { RS(TICS_USER), f_stat, NULL, QS(ull_int), 0 }, - { RS(TICS_USER_C), f_stat, NULL, QS(ull_int), 0 }, - { RS(TIME_ALL), f_stat, NULL, QS(ull_int), 0 }, - { RS(TIME_ELAPSED), f_stat, NULL, QS(ull_int), 0 }, - { RS(TIME_START), f_stat, NULL, QS(ull_int), 0 }, - { RS(TTY), f_stat, NULL, QS(s_int), 0 }, - { RS(TTY_NAME), f_stat, FF(str), QS(strvers), 0 }, - { RS(TTY_NUMBER), f_stat, FF(str), QS(strvers), 0 }, - { RS(VM_DATA), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_EXE), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_LIB), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_RSS), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_RSS_ANON), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_RSS_FILE), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_RSS_LOCKED), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_RSS_SHARED), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_SIZE), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_STACK), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_SWAP), f_status, NULL, QS(ul_int), 0 }, - { RS(VM_USED), f_status, NULL, QS(ul_int), 0 }, - { RS(VSIZE_PGS), f_stat, NULL, QS(ul_int), 0 }, - { RS(WCHAN_ADDR), 0, NULL, QS(ul_int), 0 }, // oldflags: was f_stat, but linux obsoleted - { RS(WCHAN_NAME), 0, FF(str), QS(str), 0 }, // oldflags: tid already free +/* setsfunc oldflags freefunc sortfunc needhist type2str + --------------------- ---------- --------- ------------- -------- ----------- */ + { RS(noop), 0, NULL, QS(noop), 0, TS_noop }, // user only, never altered + { RS(extra), 0, NULL, QS(ull_int), 0, TS_noop }, // user only, reset to zero + + { RS(ADDR_END_CODE), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(ADDR_KSTK_EIP), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(ADDR_KSTK_ESP), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(ADDR_START_CODE), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(ADDR_START_STACK), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(ALARM), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(CGNAME), x_cgroup, FF(str), QS(str), 0, TS(str) }, + { RS(CGROUP), x_cgroup, FF(str), QS(str), 0, TS(str) }, + { RS(CGROUP_V), v_cgroup, FF(strv), QS(strv), 0, TS(strv) }, + { RS(CMD), f_either, FF(str), QS(str), 0, TS(str) }, + { RS(CMDLINE), x_cmdline, FF(str), QS(str), 0, TS(str) }, + { RS(CMDLINE_V), v_arg, FF(strv), QS(strv), 0, TS(strv) }, + { RS(ENVIRON), x_environ, FF(str), QS(str), 0, TS(str) }, + { RS(ENVIRON_V), v_env, FF(strv), QS(strv), 0, TS(strv) }, + { RS(EXIT_SIGNAL), f_stat, NULL, QS(s_int), 0, TS(s_int) }, + { RS(FLAGS), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(FLT_MAJ), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(FLT_MAJ_C), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(FLT_MAJ_DELTA), f_stat, NULL, QS(s_int), +1, TS(s_int) }, + { RS(FLT_MIN), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(FLT_MIN_C), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(FLT_MIN_DELTA), f_stat, NULL, QS(s_int), +1, TS(s_int) }, + { RS(ID_EGID), 0, NULL, QS(u_int), 0, TS(u_int) }, // oldflags: free w/ simple_read + { RS(ID_EGROUP), f_grp, NULL, QS(str), 0, TS(str) }, + { RS(ID_EUID), 0, NULL, QS(u_int), 0, TS(u_int) }, // oldflags: free w/ simple_read + { RS(ID_EUSER), f_usr, NULL, QS(str), 0, TS(str) }, // freefunc NULL w/ cached string + { RS(ID_FGID), f_status, NULL, QS(u_int), 0, TS(u_int) }, + { RS(ID_FGROUP), x_ogroup, NULL, QS(str), 0, TS(str) }, + { RS(ID_FUID), f_status, NULL, QS(u_int), 0, TS(u_int) }, + { RS(ID_FUSER), x_ouser, NULL, QS(str), 0, TS(str) }, // freefunc NULL w/ cached string + { RS(ID_PGRP), f_stat, NULL, QS(s_int), 0, TS(s_int) }, + { RS(ID_PID), 0, NULL, QS(s_int), 0, TS(s_int) }, // oldflags: free w/ simple_nextpid + { RS(ID_PPID), f_either, NULL, QS(s_int), 0, TS(s_int) }, + { RS(ID_RGID), f_status, NULL, QS(u_int), 0, TS(u_int) }, + { RS(ID_RGROUP), x_ogroup, NULL, QS(str), 0, TS(str) }, + { RS(ID_RUID), f_status, NULL, QS(u_int), 0, TS(u_int) }, + { RS(ID_RUSER), x_ouser, NULL, QS(str), 0, TS(str) }, // freefunc NULL w/ cached string + { RS(ID_SESSION), f_stat, NULL, QS(s_int), 0, TS(s_int) }, + { RS(ID_SGID), f_status, NULL, QS(u_int), 0, TS(u_int) }, + { RS(ID_SGROUP), x_ogroup, NULL, QS(str), 0, TS(str) }, + { RS(ID_SUID), f_status, NULL, QS(u_int), 0, TS(u_int) }, + { RS(ID_SUSER), x_ouser, NULL, QS(str), 0, TS(str) }, // freefunc NULL w/ cached string + { RS(ID_TGID), 0, NULL, QS(s_int), 0, TS(s_int) }, // oldflags: free w/ simple_nextpid + { RS(ID_TPGID), f_stat, NULL, QS(s_int), 0, TS(s_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) }, + { RS(MEM_DATA), f_statm, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(MEM_DATA_PGS), f_statm, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(MEM_DT_PGS), f_statm, NULL, QS(ul_int), 0, TS(ul_int) }, // ( always 0 w/ since 2.6 ) + { RS(MEM_LRS_PGS), f_statm, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(MEM_RES), f_statm, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(MEM_RES_PGS), f_statm, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(MEM_SHR), f_statm, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(MEM_SHR_PGS), f_statm, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(MEM_VIRT), f_statm, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(MEM_VIRT_PGS), f_statm, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(NICE), f_stat, NULL, QS(s_int), 0, TS(s_int) }, + { RS(NLWP), f_either, NULL, QS(s_int), 0, TS(s_int) }, + { RS(NS_IPC), f_ns, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(NS_MNT), f_ns, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(NS_NET), f_ns, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(NS_PID), f_ns, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(NS_USER), f_ns, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(NS_UTS), f_ns, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(OOM_ADJ), f_oom, NULL, QS(s_int), 0, TS(s_int) }, + { RS(OOM_SCORE), f_oom, NULL, QS(s_int), 0, TS(s_int) }, + { RS(PRIORITY), f_stat, NULL, QS(s_int), 0, TS(s_int) }, + { RS(PROCESSOR), f_stat, NULL, QS(u_int), 0, TS(u_int) }, + { RS(RSS), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(RSS_RLIM), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(RTPRIO), f_stat, NULL, QS(s_int), 0, TS(s_int) }, + { RS(SCHED_CLASS), f_stat, NULL, QS(s_int), 0, TS(s_int) }, + { RS(SD_MACH), f_systemd, FF(str), QS(str), 0, TS(str) }, + { RS(SD_OUID), f_systemd, FF(str), QS(str), 0, TS(str) }, + { RS(SD_SEAT), f_systemd, FF(str), QS(str), 0, TS(str) }, + { RS(SD_SESS), f_systemd, FF(str), QS(str), 0, TS(str) }, + { RS(SD_SLICE), f_systemd, FF(str), QS(str), 0, TS(str) }, + { RS(SD_UNIT), f_systemd, FF(str), QS(str), 0, TS(str) }, + { RS(SD_UUNIT), f_systemd, FF(str), QS(str), 0, TS(str) }, + { RS(SIGBLOCKED), f_status, FF(str), QS(str), 0, TS(str) }, + { RS(SIGCATCH), f_status, FF(str), QS(str), 0, TS(str) }, + { RS(SIGIGNORE), f_status, FF(str), QS(str), 0, TS(str) }, + { RS(SIGNALS), f_status, FF(str), QS(str), 0, TS(str) }, + { RS(SIGPENDING), f_status, FF(str), QS(str), 0, TS(str) }, + { RS(STATE), f_either, NULL, QS(s_ch), 0, TS(s_ch) }, + { RS(SUPGIDS), f_status, FF(str), QS(str), 0, TS(str) }, + { RS(SUPGROUPS), x_supgrp, FF(str), QS(str), 0, TS(str) }, + { RS(TICS_ALL), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TICS_ALL_C), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TICS_ALL_DELTA), f_stat, NULL, QS(s_int), +1, TS(s_int) }, + { RS(TICS_BLKIO), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TICS_GUEST), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TICS_GUEST_C), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TICS_SYSTEM), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TICS_SYSTEM_C), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TICS_USER), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TICS_USER_C), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TIME_ALL), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TIME_ELAPSED), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TIME_START), f_stat, NULL, QS(ull_int), 0, TS(ull_int) }, + { RS(TTY), f_stat, NULL, QS(s_int), 0, TS(s_int) }, + { RS(TTY_NAME), f_stat, FF(str), QS(strvers), 0, TS(str) }, + { RS(TTY_NUMBER), f_stat, FF(str), QS(strvers), 0, TS(str) }, + { RS(VM_DATA), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_EXE), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_LIB), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_RSS), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_RSS_ANON), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_RSS_FILE), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_RSS_LOCKED), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_RSS_SHARED), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_SIZE), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_STACK), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_SWAP), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VM_USED), f_status, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(VSIZE_PGS), f_stat, NULL, QS(ul_int), 0, TS(ul_int) }, + { RS(WCHAN_ADDR), 0, NULL, QS(ul_int), 0, TS(ul_int) }, // oldflags: was f_stat, but linux obsoleted + { RS(WCHAN_NAME), 0, FF(str), QS(str), 0, TS(str) }, // oldflags: tid already free // dummy entry corresponding to PIDS_logical_end ... - { NULL, 0, NULL, NULL, 0 } + { NULL, 0, NULL, NULL, 0, NULL } }; /* please note, @@ -1488,3 +1491,37 @@ PROCPS_EXPORT struct pids_stack **procps_pids_sort ( qsort_r(stacks, numstacked, sizeof(void *), (QSR_t)Item_table[p->item].sortfunc, &parms); return stacks; } // end: procps_pids_sort + + +// --- special debugging function(s) ------------------------------------------ +/* + * The following isn't part of the normal programming interface. Rather, + * it exists to validate result types referenced in application programs. + * + * It's used only when: + * 1) the 'XTRA_PROCPS_DEBUG' has been defined, or + * 2) the '#include <proc/xtra-procps-debug.h>' used + */ + +PROCPS_EXPORT void xtra_pids_val ( + int relative_enum, + const char *typestr, + const struct pids_stack *stack, + struct pids_info *info, + const char *file, + int lineno) +{ + struct pids_result *r; + char *str; + + r = &stack->head[relative_enum]; + if (r->item < 0 || r->item >= PIDS_logical_end) { + fprintf(stderr, "%s line %d: invalid item = %d, relative_enum = %d, type = %s\n" + , file, lineno, r->item, relative_enum, typestr); + return; + } + str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); +} // end: xtra_pids_val diff --git a/proc/procps.h b/proc/procps.h index 53033e9..0b8da28 100644 --- a/proc/procps.h +++ b/proc/procps.h @@ -34,4 +34,8 @@ #define ESC_STRETCH 1 // since we mangle to '?' this is 1 (would be 4 for octal escapes) int escape_str(char *__restrict dst, const char *__restrict src, int bufsize, int *maxcells); +#ifdef XTRA_PROCPS_DEBUG +#include <proc/xtra-procps-debug.h> +#endif + #endif diff --git a/proc/slabinfo.c b/proc/slabinfo.c index b603ac1..985b507 100644 --- a/proc/slabinfo.c +++ b/proc/slabinfo.c @@ -241,6 +241,9 @@ typedef void (*SET_t)(struct slabinfo_result *, struct slabs_hist *, struct slab typedef int (*QSR_t)(const void *, const void *, void *); #define QS(t) (QSR_t)srtNAME(t) +#define TS(t) STRINGIFY(t) +#define TS_noop "" + /* * Need it be said? * This table must be kept in the exact same order as @@ -248,51 +251,52 @@ typedef int (*QSR_t)(const void *, const void *, void *); static struct { SET_t setsfunc; // the actual result setting routine QSR_t sortfunc; // sort cmp func for a specific type + char *type2str; // the result type as a string value } Item_table[] = { -/* setsfunc sortfunc - --------------------------- --------- */ - { RS(noop), QS(ul_int) }, - { RS(extra), QS(noop) }, - - { RS(SLABS_OBJS), QS(noop) }, - { RS(SLABS_AOBJS), QS(noop) }, - { RS(SLABS_PAGES), QS(noop) }, - { RS(SLABS_SLABS), QS(noop) }, - { RS(SLABS_ASLABS), QS(noop) }, - { RS(SLABS_CACHES), QS(noop) }, - { RS(SLABS_ACACHES), QS(noop) }, - { RS(SLABS_SIZE_AVG), QS(noop) }, - { RS(SLABS_SIZE_MIN), QS(noop) }, - { RS(SLABS_SIZE_MAX), QS(noop) }, - { RS(SLABS_SIZE_ACTIVE), QS(noop) }, - { RS(SLABS_SIZE_TOTAL), QS(noop) }, - - { RS(SLABS_DELTA_OBJS), QS(noop) }, - { RS(SLABS_DELTA_AOBJS), QS(noop) }, - { RS(SLABS_DELTA_PAGES), QS(noop) }, - { RS(SLABS_DELTA_SLABS), QS(noop) }, - { RS(SLABS_DELTA_ASLABS), QS(noop) }, - { RS(SLABS_DELTA_CACHES), QS(noop) }, - { RS(SLABS_DELTA_ACACHES), QS(noop) }, - { RS(SLABS_DELTA_SIZE_AVG), QS(noop) }, - { RS(SLABS_DELTA_SIZE_MIN), QS(noop) }, - { RS(SLABS_DELTA_SIZE_MAX), QS(noop) }, - { RS(SLABS_DELTA_SIZE_ACTIVE), QS(noop) }, - { RS(SLABS_DELTA_SIZE_TOTAL), QS(noop) }, - - { RS(SLABNODE_NAME), QS(str) }, - { RS(SLABNODE_OBJS), QS(u_int) }, - { RS(SLABNODE_AOBJS), QS(u_int) }, - { RS(SLABNODE_OBJ_SIZE), QS(u_int) }, - { RS(SLABNODE_OBJS_PER_SLAB), QS(u_int) }, - { RS(SLABNODE_PAGES_PER_SLAB), QS(u_int) }, - { RS(SLABNODE_SLABS), QS(u_int) }, - { RS(SLABNODE_ASLABS), QS(u_int) }, - { RS(SLABNODE_USE), QS(u_int) }, - { RS(SLABNODE_SIZE), QS(ul_int) }, +/* setsfunc sortfunc type2str + ---------------------------- ----------- ---------- */ + { RS(noop), QS(noop), TS_noop }, + { RS(extra), QS(ul_int), TS_noop }, + + { RS(SLABS_OBJS), QS(noop), TS(u_int) }, + { RS(SLABS_AOBJS), QS(noop), TS(u_int) }, + { RS(SLABS_PAGES), QS(noop), TS(u_int) }, + { RS(SLABS_SLABS), QS(noop), TS(u_int) }, + { RS(SLABS_ASLABS), QS(noop), TS(u_int) }, + { RS(SLABS_CACHES), QS(noop), TS(u_int) }, + { RS(SLABS_ACACHES), QS(noop), TS(u_int) }, + { RS(SLABS_SIZE_AVG), QS(noop), TS(u_int) }, + { RS(SLABS_SIZE_MIN), QS(noop), TS(u_int) }, + { RS(SLABS_SIZE_MAX), QS(noop), TS(u_int) }, + { RS(SLABS_SIZE_ACTIVE), QS(noop), TS(ul_int) }, + { RS(SLABS_SIZE_TOTAL), QS(noop), TS(ul_int) }, + + { RS(SLABS_DELTA_OBJS), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_AOBJS), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_PAGES), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_SLABS), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_ASLABS), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_CACHES), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_ACACHES), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_SIZE_AVG), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_SIZE_MIN), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_SIZE_MAX), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_SIZE_ACTIVE), QS(noop), TS(s_int) }, + { RS(SLABS_DELTA_SIZE_TOTAL), QS(noop), TS(s_int) }, + + { RS(SLABNODE_NAME), QS(str), TS(str) }, + { RS(SLABNODE_OBJS), QS(u_int), TS(u_int) }, + { RS(SLABNODE_AOBJS), QS(u_int), TS(u_int) }, + { RS(SLABNODE_OBJ_SIZE), QS(u_int), TS(u_int) }, + { RS(SLABNODE_OBJS_PER_SLAB), QS(u_int), TS(u_int) }, + { RS(SLABNODE_PAGES_PER_SLAB), QS(u_int), TS(u_int) }, + { RS(SLABNODE_SLABS), QS(u_int), TS(u_int) }, + { RS(SLABNODE_ASLABS), QS(u_int), TS(u_int) }, + { RS(SLABNODE_USE), QS(u_int), TS(u_int) }, + { RS(SLABNODE_SIZE), QS(ul_int), TS(ul_int) }, // dummy entry corresponding to SLABINFO_logical_end ... - { NULL, NULL } + { NULL, NULL, NULL } }; /* please note, @@ -1004,3 +1008,56 @@ PROCPS_EXPORT struct slabinfo_stack **procps_slabinfo_sort ( qsort_r(stacks, numstacked, sizeof(void *), (QSR_t)Item_table[p->item].sortfunc, &parms); return stacks; } // end: procps_slabinfo_sort + + +// --- special debugging function(s) ------------------------------------------ +/* + * The following isn't part of the normal programming interface. Rather, + * it exists to validate result types referenced in application programs. + * + * It's used only when: + * 1) the 'XTRA_PROCPS_DEBUG' has been defined, or + * 2) the '#include <proc/xtra-procps-debug.h>' used + */ + +PROCPS_EXPORT struct slabinfo_result *xtra_slabinfo_get ( + struct slabinfo_info *info, + enum slabinfo_item actual_enum, + const char *typestr, + const char *file, + int lineno) +{ + struct slabinfo_result *r = procps_slabinfo_get(info, actual_enum); + + if (r) { + char *str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); + } + return r; +} // end: xtra_slabinfo_get_ + + +PROCPS_EXPORT void xtra_slabinfo_val ( + int relative_enum, + const char *typestr, + const struct slabinfo_stack *stack, + struct slabinfo_info *info, + const char *file, + int lineno) +{ + struct slabinfo_result *r; + char *str; + + r = &stack->head[relative_enum]; + if (r->item < 0 || r->item >= SLABINFO_logical_end) { + fprintf(stderr, "%s line %d: invalid item = %d, relative_enum = %d, type = %s\n" + , file, lineno, r->item, relative_enum, typestr); + return; + } + str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); +} // end: xtra_slabinfo_val diff --git a/proc/stat.c b/proc/stat.c index 653e22f..003c1e5 100644 --- a/proc/stat.c +++ b/proc/stat.c @@ -255,6 +255,9 @@ typedef void (*SET_t)(struct stat_result *, struct hist_sys *, struct hist_tic * typedef int (*QSR_t)(const void *, const void *, void *); #define QS(t) (QSR_t)srtNAME(t) +#define TS(t) STRINGIFY(t) +#define TS_noop "" + /* * Need it be said? * This table must be kept in the exact same order as @@ -262,51 +265,52 @@ typedef int (*QSR_t)(const void *, const void *, void *); static struct { SET_t setsfunc; // the actual result setting routine QSR_t sortfunc; // sort cmp func for a specific type + char *type2str; // the result type as a string value } Item_table[] = { -/* setsfunc sortfunc - -------------------------- --------- */ - { RS(noop), QS(ul_int) }, - { RS(extra), QS(noop) }, - - { RS(TIC_ID), QS(s_int) }, - { RS(TIC_NUMA_NODE), QS(s_int) }, - { RS(TIC_USER), QS(ull_int) }, - { RS(TIC_NICE), QS(ull_int) }, - { RS(TIC_SYSTEM), QS(ull_int) }, - { RS(TIC_IDLE), QS(ull_int) }, - { RS(TIC_IOWAIT), QS(ull_int) }, - { RS(TIC_IRQ), QS(ull_int) }, - { RS(TIC_SOFTIRQ), QS(ull_int) }, - { RS(TIC_STOLEN), QS(ull_int) }, - { RS(TIC_GUEST), QS(ull_int) }, - { RS(TIC_GUEST_NICE), QS(ull_int) }, - - { RS(TIC_DELTA_USER), QS(sl_int) }, - { RS(TIC_DELTA_NICE), QS(sl_int) }, - { RS(TIC_DELTA_SYSTEM), QS(sl_int) }, - { RS(TIC_DELTA_IDLE), QS(sl_int) }, - { RS(TIC_DELTA_IOWAIT), QS(sl_int) }, - { RS(TIC_DELTA_IRQ), QS(sl_int) }, - { RS(TIC_DELTA_SOFTIRQ), QS(sl_int) }, - { RS(TIC_DELTA_STOLEN), QS(sl_int) }, - { RS(TIC_DELTA_GUEST), QS(sl_int) }, - { RS(TIC_DELTA_GUEST_NICE), QS(sl_int) }, - - { RS(SYS_CTX_SWITCHES), QS(ul_int) }, - { RS(SYS_INTERRUPTS), QS(ul_int) }, - { RS(SYS_PROC_BLOCKED), QS(ul_int) }, - { RS(SYS_PROC_CREATED), QS(ul_int) }, - { RS(SYS_PROC_RUNNING), QS(ul_int) }, - { RS(SYS_TIME_OF_BOOT), QS(ul_int) }, - - { RS(SYS_DELTA_CTX_SWITCHES), QS(s_int) }, - { RS(SYS_DELTA_INTERRUPTS), QS(s_int) }, - { RS(SYS_DELTA_PROC_BLOCKED), QS(s_int) }, - { RS(SYS_DELTA_PROC_CREATED), QS(s_int) }, - { RS(SYS_DELTA_PROC_RUNNING), QS(s_int) }, +/* setsfunc sortfunc type2str + --------------------------- ------------ ----------- */ + { RS(noop), QS(noop), TS_noop }, + { RS(extra), QS(ull_int), TS_noop }, + + { RS(TIC_ID), QS(s_int), TS(s_int) }, + { RS(TIC_NUMA_NODE), QS(s_int), TS(s_int) }, + { RS(TIC_USER), QS(ull_int), TS(ull_int) }, + { RS(TIC_NICE), QS(ull_int), TS(ull_int) }, + { RS(TIC_SYSTEM), QS(ull_int), TS(ull_int) }, + { RS(TIC_IDLE), QS(ull_int), TS(ull_int) }, + { RS(TIC_IOWAIT), QS(ull_int), TS(ull_int) }, + { RS(TIC_IRQ), QS(ull_int), TS(ull_int) }, + { RS(TIC_SOFTIRQ), QS(ull_int), TS(ull_int) }, + { RS(TIC_STOLEN), QS(ull_int), TS(ull_int) }, + { RS(TIC_GUEST), QS(ull_int), TS(ull_int) }, + { RS(TIC_GUEST_NICE), QS(ull_int), TS(ull_int) }, + + { RS(TIC_DELTA_USER), QS(sl_int), TS(sl_int) }, + { RS(TIC_DELTA_NICE), QS(sl_int), TS(sl_int) }, + { RS(TIC_DELTA_SYSTEM), QS(sl_int), TS(sl_int) }, + { RS(TIC_DELTA_IDLE), QS(sl_int), TS(sl_int) }, + { RS(TIC_DELTA_IOWAIT), QS(sl_int), TS(sl_int) }, + { RS(TIC_DELTA_IRQ), QS(sl_int), TS(sl_int) }, + { RS(TIC_DELTA_SOFTIRQ), QS(sl_int), TS(sl_int) }, + { RS(TIC_DELTA_STOLEN), QS(sl_int), TS(sl_int) }, + { RS(TIC_DELTA_GUEST), QS(sl_int), TS(sl_int) }, + { RS(TIC_DELTA_GUEST_NICE), QS(sl_int), TS(sl_int) }, + + { RS(SYS_CTX_SWITCHES), QS(ul_int), TS(ul_int) }, + { RS(SYS_INTERRUPTS), QS(ul_int), TS(ul_int) }, + { RS(SYS_PROC_BLOCKED), QS(ul_int), TS(ul_int) }, + { RS(SYS_PROC_CREATED), QS(ul_int), TS(ul_int) }, + { RS(SYS_PROC_RUNNING), QS(ul_int), TS(ul_int) }, + { RS(SYS_TIME_OF_BOOT), QS(ul_int), TS(ul_int) }, + + { RS(SYS_DELTA_CTX_SWITCHES), QS(s_int), TS(s_int) }, + { RS(SYS_DELTA_INTERRUPTS), QS(s_int), TS(s_int) }, + { RS(SYS_DELTA_PROC_BLOCKED), QS(s_int), TS(s_int) }, + { RS(SYS_DELTA_PROC_CREATED), QS(s_int), TS(s_int) }, + { RS(SYS_DELTA_PROC_RUNNING), QS(s_int), TS(s_int) }, // dummy entry corresponding to STAT_logical_end ... - { NULL, NULL } + { NULL, NULL, NULL } }; /* please note, @@ -1122,3 +1126,56 @@ PROCPS_EXPORT struct stat_stack **procps_stat_sort ( qsort_r(stacks, numstacked, sizeof(void *), (QSR_t)Item_table[p->item].sortfunc, &parms); return stacks; } // end: procps_stat_sort + + +// --- special debugging function(s) ------------------------------------------ +/* + * The following isn't part of the normal programming interface. Rather, + * it exists to validate result types referenced in application programs. + * + * It's used only when: + * 1) the 'XTRA_PROCPS_DEBUG' has been defined, or + * 2) the '#include <proc/xtra-procps-debug.h>' used + */ + +PROCPS_EXPORT struct stat_result *xtra_stat_get ( + struct stat_info *info, + enum stat_item actual_enum, + const char *typestr, + const char *file, + int lineno) +{ + struct stat_result *r = procps_stat_get(info, actual_enum); + + if (r) { + char *str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); + } + return r; +} // end: xtra_stat_get_ + + +PROCPS_EXPORT void xtra_stat_val ( + int relative_enum, + const char *typestr, + const struct stat_stack *stack, + struct stat_info *info, + const char *file, + int lineno) +{ + struct stat_result *r; + char *str; + + r = &stack->head[relative_enum]; + if (r->item < 0 || r->item >= STAT_logical_end) { + fprintf(stderr, "%s line %d: invalid item = %d, relative_enum = %d, type = %s\n" + , file, lineno, r->item, relative_enum, typestr); + return; + } + str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); +} // end: xtra_stat_val diff --git a/proc/vmstat.c b/proc/vmstat.c index 612894d..3b21bdd 100644 --- a/proc/vmstat.c +++ b/proc/vmstat.c @@ -25,6 +25,7 @@ #include <errno.h> #include <fcntl.h> #include <search.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> @@ -454,258 +455,262 @@ HST_set(DELTA_ZONE_RECLAIM_FAILED, zone_reclaim_failed) typedef void (*SET_t)(struct vmstat_result *, struct vmstat_hist *); #define RS(e) (SET_t)setNAME(e) +#define TS(t) STRINGIFY(t) +#define TS_noop "" + /* * Need it be said? * This table must be kept in the exact same order as * those 'enum vmstat_item' guys ! */ static struct { SET_t setsfunc; // the actual result setting routine + char *type2str; // the result type as a string value } Item_table[] = { -/* setsfunc - --------------------------------------- */ - { RS(noop) }, - { RS(extra) }, - - { RS(ALLOCSTALL) }, - { RS(BALLOON_DEFLATE) }, - { RS(BALLOON_INFLATE) }, - { RS(BALLOON_MIGRATE) }, - { RS(COMPACT_FAIL) }, - { RS(COMPACT_FREE_SCANNED) }, - { RS(COMPACT_ISOLATED) }, - { RS(COMPACT_MIGRATE_SCANNED) }, - { RS(COMPACT_STALL) }, - { RS(COMPACT_SUCCESS) }, - { RS(DROP_PAGECACHE) }, - { RS(DROP_SLAB) }, - { RS(HTLB_BUDDY_ALLOC_FAIL) }, - { RS(HTLB_BUDDY_ALLOC_SUCCESS) }, - { RS(KSWAPD_HIGH_WMARK_HIT_QUICKLY) }, - { RS(KSWAPD_INODESTEAL) }, - { RS(KSWAPD_LOW_WMARK_HIT_QUICKLY) }, - { RS(NR_ACTIVE_ANON) }, - { RS(NR_ACTIVE_FILE) }, - { RS(NR_ALLOC_BATCH) }, - { RS(NR_ANON_PAGES) }, - { RS(NR_ANON_TRANSPARENT_HUGEPAGES) }, - { RS(NR_BOUNCE) }, - { RS(NR_DIRTIED) }, - { RS(NR_DIRTY) }, - { RS(NR_DIRTY_BACKGROUND_THRESHOLD) }, - { RS(NR_DIRTY_THRESHOLD) }, - { RS(NR_FILE_PAGES) }, - { RS(NR_FREE_CMA) }, - { RS(NR_FREE_PAGES) }, - { RS(NR_INACTIVE_ANON) }, - { RS(NR_INACTIVE_FILE) }, - { RS(NR_ISOLATED_ANON) }, - { RS(NR_ISOLATED_FILE) }, - { RS(NR_KERNEL_STACK) }, - { RS(NR_MAPPED) }, - { RS(NR_MLOCK) }, - { RS(NR_PAGES_SCANNED) }, - { RS(NR_PAGE_TABLE_PAGES) }, - { RS(NR_SHMEM) }, - { RS(NR_SLAB_RECLAIMABLE) }, - { RS(NR_SLAB_UNRECLAIMABLE) }, - { RS(NR_UNEVICTABLE) }, - { RS(NR_UNSTABLE) }, - { RS(NR_VMSCAN_IMMEDIATE_RECLAIM) }, - { RS(NR_VMSCAN_WRITE) }, - { RS(NR_WRITEBACK) }, - { RS(NR_WRITEBACK_TEMP) }, - { RS(NR_WRITTEN) }, - { RS(NUMA_FOREIGN) }, - { RS(NUMA_HINT_FAULTS) }, - { RS(NUMA_HINT_FAULTS_LOCAL) }, - { RS(NUMA_HIT) }, - { RS(NUMA_HUGE_PTE_UPDATES) }, - { RS(NUMA_INTERLEAVE) }, - { RS(NUMA_LOCAL) }, - { RS(NUMA_MISS) }, - { RS(NUMA_OTHER) }, - { RS(NUMA_PAGES_MIGRATED) }, - { RS(NUMA_PTE_UPDATES) }, - { RS(PAGEOUTRUN) }, - { RS(PGACTIVATE) }, - { RS(PGALLOC_DMA) }, - { RS(PGALLOC_DMA32) }, - { RS(PGALLOC_MOVABLE) }, - { RS(PGALLOC_NORMAL) }, - { RS(PGDEACTIVATE) }, - { RS(PGFAULT) }, - { RS(PGFREE) }, - { RS(PGINODESTEAL) }, - { RS(PGMAJFAULT) }, - { RS(PGMIGRATE_FAIL) }, - { RS(PGMIGRATE_SUCCESS) }, - { RS(PGPGIN) }, - { RS(PGPGOUT) }, - { RS(PGREFILL_DMA) }, - { RS(PGREFILL_DMA32) }, - { RS(PGREFILL_MOVABLE) }, - { RS(PGREFILL_NORMAL) }, - { RS(PGROTATED) }, - { RS(PGSCAN_DIRECT_DMA) }, - { RS(PGSCAN_DIRECT_DMA32) }, - { RS(PGSCAN_DIRECT_MOVABLE) }, - { RS(PGSCAN_DIRECT_NORMAL) }, - { RS(PGSCAN_DIRECT_THROTTLE) }, - { RS(PGSCAN_KSWAPD_DMA) }, - { RS(PGSCAN_KSWAPD_DMA32) }, - { RS(PGSCAN_KSWAPD_MOVEABLE) }, - { RS(PGSCAN_KSWAPD_NORMAL) }, - { RS(PGSTEAL_DIRECT_DMA) }, - { RS(PGSTEAL_DIRECT_DMA32) }, - { RS(PGSTEAL_DIRECT_MOVABLE) }, - { RS(PGSTEAL_DIRECT_NORMAL) }, - { RS(PGSTEAL_KSWAPD_DMA) }, - { RS(PGSTEAL_KSWAPD_DMA32) }, - { RS(PGSTEAL_KSWAPD_MOVABLE) }, - { RS(PGSTEAL_KSWAPD_NORMAL) }, - { RS(PSWPIN) }, - { RS(PSWPOUT) }, - { RS(SLABS_SCANNED) }, - { RS(THP_COLLAPSE_ALLOC) }, - { RS(THP_COLLAPSE_ALLOC_FAILED) }, - { RS(THP_FAULT_ALLOC) }, - { RS(THP_FAULT_FALLBACK) }, - { RS(THP_SPLIT) }, - { RS(THP_ZERO_PAGE_ALLOC) }, - { RS(THP_ZERO_PAGE_ALLOC_FAILED) }, - { RS(UNEVICTABLE_PGS_CLEARED) }, - { RS(UNEVICTABLE_PGS_CULLED) }, - { RS(UNEVICTABLE_PGS_MLOCKED) }, - { RS(UNEVICTABLE_PGS_MUNLOCKED) }, - { RS(UNEVICTABLE_PGS_RESCUED) }, - { RS(UNEVICTABLE_PGS_SCANNED) }, - { RS(UNEVICTABLE_PGS_STRANDED) }, - { RS(WORKINGSET_ACTIVATE) }, - { RS(WORKINGSET_NODERECLAIM) }, - { RS(WORKINGSET_REFAULT) }, - { RS(ZONE_RECLAIM_FAILED) }, - - { RS(DELTA_ALLOCSTALL) }, - { RS(DELTA_BALLOON_DEFLATE) }, - { RS(DELTA_BALLOON_INFLATE) }, - { RS(DELTA_BALLOON_MIGRATE) }, - { RS(DELTA_COMPACT_FAIL) }, - { RS(DELTA_COMPACT_FREE_SCANNED) }, - { RS(DELTA_COMPACT_ISOLATED) }, - { RS(DELTA_COMPACT_MIGRATE_SCANNED) }, - { RS(DELTA_COMPACT_STALL) }, - { RS(DELTA_COMPACT_SUCCESS) }, - { RS(DELTA_DROP_PAGECACHE) }, - { RS(DELTA_DROP_SLAB) }, - { RS(DELTA_HTLB_BUDDY_ALLOC_FAIL) }, - { RS(DELTA_HTLB_BUDDY_ALLOC_SUCCESS) }, - { RS(DELTA_KSWAPD_HIGH_WMARK_HIT_QUICKLY) }, - { RS(DELTA_KSWAPD_INODESTEAL) }, - { RS(DELTA_KSWAPD_LOW_WMARK_HIT_QUICKLY) }, - { RS(DELTA_NR_ACTIVE_ANON) }, - { RS(DELTA_NR_ACTIVE_FILE) }, - { RS(DELTA_NR_ALLOC_BATCH) }, - { RS(DELTA_NR_ANON_PAGES) }, - { RS(DELTA_NR_ANON_TRANSPARENT_HUGEPAGES) }, - { RS(DELTA_NR_BOUNCE) }, - { RS(DELTA_NR_DIRTIED) }, - { RS(DELTA_NR_DIRTY) }, - { RS(DELTA_NR_DIRTY_BACKGROUND_THRESHOLD) }, - { RS(DELTA_NR_DIRTY_THRESHOLD) }, - { RS(DELTA_NR_FILE_PAGES) }, - { RS(DELTA_NR_FREE_CMA) }, - { RS(DELTA_NR_FREE_PAGES) }, - { RS(DELTA_NR_INACTIVE_ANON) }, - { RS(DELTA_NR_INACTIVE_FILE) }, - { RS(DELTA_NR_ISOLATED_ANON) }, - { RS(DELTA_NR_ISOLATED_FILE) }, - { RS(DELTA_NR_KERNEL_STACK) }, - { RS(DELTA_NR_MAPPED) }, - { RS(DELTA_NR_MLOCK) }, - { RS(DELTA_NR_PAGES_SCANNED) }, - { RS(DELTA_NR_PAGE_TABLE_PAGES) }, - { RS(DELTA_NR_SHMEM) }, - { RS(DELTA_NR_SLAB_RECLAIMABLE) }, - { RS(DELTA_NR_SLAB_UNRECLAIMABLE) }, - { RS(DELTA_NR_UNEVICTABLE) }, - { RS(DELTA_NR_UNSTABLE) }, - { RS(DELTA_NR_VMSCAN_IMMEDIATE_RECLAIM) }, - { RS(DELTA_NR_VMSCAN_WRITE) }, - { RS(DELTA_NR_WRITEBACK) }, - { RS(DELTA_NR_WRITEBACK_TEMP) }, - { RS(DELTA_NR_WRITTEN) }, - { RS(DELTA_NUMA_FOREIGN) }, - { RS(DELTA_NUMA_HINT_FAULTS) }, - { RS(DELTA_NUMA_HINT_FAULTS_LOCAL) }, - { RS(DELTA_NUMA_HIT) }, - { RS(DELTA_NUMA_HUGE_PTE_UPDATES) }, - { RS(DELTA_NUMA_INTERLEAVE) }, - { RS(DELTA_NUMA_LOCAL) }, - { RS(DELTA_NUMA_MISS) }, - { RS(DELTA_NUMA_OTHER) }, - { RS(DELTA_NUMA_PAGES_MIGRATED) }, - { RS(DELTA_NUMA_PTE_UPDATES) }, - { RS(DELTA_PAGEOUTRUN) }, - { RS(DELTA_PGACTIVATE) }, - { RS(DELTA_PGALLOC_DMA) }, - { RS(DELTA_PGALLOC_DMA32) }, - { RS(DELTA_PGALLOC_MOVABLE) }, - { RS(DELTA_PGALLOC_NORMAL) }, - { RS(DELTA_PGDEACTIVATE) }, - { RS(DELTA_PGFAULT) }, - { RS(DELTA_PGFREE) }, - { RS(DELTA_PGINODESTEAL) }, - { RS(DELTA_PGMAJFAULT) }, - { RS(DELTA_PGMIGRATE_FAIL) }, - { RS(DELTA_PGMIGRATE_SUCCESS) }, - { RS(DELTA_PGPGIN) }, - { RS(DELTA_PGPGOUT) }, - { RS(DELTA_PGREFILL_DMA) }, - { RS(DELTA_PGREFILL_DMA32) }, - { RS(DELTA_PGREFILL_MOVABLE) }, - { RS(DELTA_PGREFILL_NORMAL) }, - { RS(DELTA_PGROTATED) }, - { RS(DELTA_PGSCAN_DIRECT_DMA) }, - { RS(DELTA_PGSCAN_DIRECT_DMA32) }, - { RS(DELTA_PGSCAN_DIRECT_MOVABLE) }, - { RS(DELTA_PGSCAN_DIRECT_NORMAL) }, - { RS(DELTA_PGSCAN_DIRECT_THROTTLE) }, - { RS(DELTA_PGSCAN_KSWAPD_DMA) }, - { RS(DELTA_PGSCAN_KSWAPD_DMA32) }, - { RS(DELTA_PGSCAN_KSWAPD_MOVEABLE) }, - { RS(DELTA_PGSCAN_KSWAPD_NORMAL) }, - { RS(DELTA_PGSTEAL_DIRECT_DMA) }, - { RS(DELTA_PGSTEAL_DIRECT_DMA32) }, - { RS(DELTA_PGSTEAL_DIRECT_MOVABLE) }, - { RS(DELTA_PGSTEAL_DIRECT_NORMAL) }, - { RS(DELTA_PGSTEAL_KSWAPD_DMA) }, - { RS(DELTA_PGSTEAL_KSWAPD_DMA32) }, - { RS(DELTA_PGSTEAL_KSWAPD_MOVABLE) }, - { RS(DELTA_PGSTEAL_KSWAPD_NORMAL) }, - { RS(DELTA_PSWPIN) }, - { RS(DELTA_PSWPOUT) }, - { RS(DELTA_SLABS_SCANNED) }, - { RS(DELTA_THP_COLLAPSE_ALLOC) }, - { RS(DELTA_THP_COLLAPSE_ALLOC_FAILED) }, - { RS(DELTA_THP_FAULT_ALLOC) }, - { RS(DELTA_THP_FAULT_FALLBACK) }, - { RS(DELTA_THP_SPLIT) }, - { RS(DELTA_THP_ZERO_PAGE_ALLOC) }, - { RS(DELTA_THP_ZERO_PAGE_ALLOC_FAILED) }, - { RS(DELTA_UNEVICTABLE_PGS_CLEARED) }, - { RS(DELTA_UNEVICTABLE_PGS_CULLED) }, - { RS(DELTA_UNEVICTABLE_PGS_MLOCKED) }, - { RS(DELTA_UNEVICTABLE_PGS_MUNLOCKED) }, - { RS(DELTA_UNEVICTABLE_PGS_RESCUED) }, - { RS(DELTA_UNEVICTABLE_PGS_SCANNED) }, - { RS(DELTA_UNEVICTABLE_PGS_STRANDED) }, - { RS(DELTA_WORKINGSET_ACTIVATE) }, - { RS(DELTA_WORKINGSET_NODERECLAIM) }, - { RS(DELTA_WORKINGSET_REFAULT) }, - { RS(DELTA_ZONE_RECLAIM_FAILED) }, +/* setsfunc type2str + ---------------------------------------- ---------- */ + { RS(noop), TS_noop }, + { RS(extra), TS_noop }, + + { RS(ALLOCSTALL), TS(ul_int) }, + { RS(BALLOON_DEFLATE), TS(ul_int) }, + { RS(BALLOON_INFLATE), TS(ul_int) }, + { RS(BALLOON_MIGRATE), TS(ul_int) }, + { RS(COMPACT_FAIL), TS(ul_int) }, + { RS(COMPACT_FREE_SCANNED), TS(ul_int) }, + { RS(COMPACT_ISOLATED), TS(ul_int) }, + { RS(COMPACT_MIGRATE_SCANNED), TS(ul_int) }, + { RS(COMPACT_STALL), TS(ul_int) }, + { RS(COMPACT_SUCCESS), TS(ul_int) }, + { RS(DROP_PAGECACHE), TS(ul_int) }, + { RS(DROP_SLAB), TS(ul_int) }, + { RS(HTLB_BUDDY_ALLOC_FAIL), TS(ul_int) }, + { RS(HTLB_BUDDY_ALLOC_SUCCESS), TS(ul_int) }, + { RS(KSWAPD_HIGH_WMARK_HIT_QUICKLY), TS(ul_int) }, + { RS(KSWAPD_INODESTEAL), TS(ul_int) }, + { RS(KSWAPD_LOW_WMARK_HIT_QUICKLY), TS(ul_int) }, + { RS(NR_ACTIVE_ANON), TS(ul_int) }, + { RS(NR_ACTIVE_FILE), TS(ul_int) }, + { RS(NR_ALLOC_BATCH), TS(ul_int) }, + { RS(NR_ANON_PAGES), TS(ul_int) }, + { RS(NR_ANON_TRANSPARENT_HUGEPAGES), TS(ul_int) }, + { RS(NR_BOUNCE), TS(ul_int) }, + { RS(NR_DIRTIED), TS(ul_int) }, + { RS(NR_DIRTY), TS(ul_int) }, + { RS(NR_DIRTY_BACKGROUND_THRESHOLD), TS(ul_int) }, + { RS(NR_DIRTY_THRESHOLD), TS(ul_int) }, + { RS(NR_FILE_PAGES), TS(ul_int) }, + { RS(NR_FREE_CMA), TS(ul_int) }, + { RS(NR_FREE_PAGES), TS(ul_int) }, + { RS(NR_INACTIVE_ANON), TS(ul_int) }, + { RS(NR_INACTIVE_FILE), TS(ul_int) }, + { RS(NR_ISOLATED_ANON), TS(ul_int) }, + { RS(NR_ISOLATED_FILE), TS(ul_int) }, + { RS(NR_KERNEL_STACK), TS(ul_int) }, + { RS(NR_MAPPED), TS(ul_int) }, + { RS(NR_MLOCK), TS(ul_int) }, + { RS(NR_PAGES_SCANNED), TS(ul_int) }, + { RS(NR_PAGE_TABLE_PAGES), TS(ul_int) }, + { RS(NR_SHMEM), TS(ul_int) }, + { RS(NR_SLAB_RECLAIMABLE), TS(ul_int) }, + { RS(NR_SLAB_UNRECLAIMABLE), TS(ul_int) }, + { RS(NR_UNEVICTABLE), TS(ul_int) }, + { RS(NR_UNSTABLE), TS(ul_int) }, + { RS(NR_VMSCAN_IMMEDIATE_RECLAIM), TS(ul_int) }, + { RS(NR_VMSCAN_WRITE), TS(ul_int) }, + { RS(NR_WRITEBACK), TS(ul_int) }, + { RS(NR_WRITEBACK_TEMP), TS(ul_int) }, + { RS(NR_WRITTEN), TS(ul_int) }, + { RS(NUMA_FOREIGN), TS(ul_int) }, + { RS(NUMA_HINT_FAULTS), TS(ul_int) }, + { RS(NUMA_HINT_FAULTS_LOCAL), TS(ul_int) }, + { RS(NUMA_HIT), TS(ul_int) }, + { RS(NUMA_HUGE_PTE_UPDATES), TS(ul_int) }, + { RS(NUMA_INTERLEAVE), TS(ul_int) }, + { RS(NUMA_LOCAL), TS(ul_int) }, + { RS(NUMA_MISS), TS(ul_int) }, + { RS(NUMA_OTHER), TS(ul_int) }, + { RS(NUMA_PAGES_MIGRATED), TS(ul_int) }, + { RS(NUMA_PTE_UPDATES), TS(ul_int) }, + { RS(PAGEOUTRUN), TS(ul_int) }, + { RS(PGACTIVATE), TS(ul_int) }, + { RS(PGALLOC_DMA), TS(ul_int) }, + { RS(PGALLOC_DMA32), TS(ul_int) }, + { RS(PGALLOC_MOVABLE), TS(ul_int) }, + { RS(PGALLOC_NORMAL), TS(ul_int) }, + { RS(PGDEACTIVATE), TS(ul_int) }, + { RS(PGFAULT), TS(ul_int) }, + { RS(PGFREE), TS(ul_int) }, + { RS(PGINODESTEAL), TS(ul_int) }, + { RS(PGMAJFAULT), TS(ul_int) }, + { RS(PGMIGRATE_FAIL), TS(ul_int) }, + { RS(PGMIGRATE_SUCCESS), TS(ul_int) }, + { RS(PGPGIN), TS(ul_int) }, + { RS(PGPGOUT), TS(ul_int) }, + { RS(PGREFILL_DMA), TS(ul_int) }, + { RS(PGREFILL_DMA32), TS(ul_int) }, + { RS(PGREFILL_MOVABLE), TS(ul_int) }, + { RS(PGREFILL_NORMAL), TS(ul_int) }, + { RS(PGROTATED), TS(ul_int) }, + { RS(PGSCAN_DIRECT_DMA), TS(ul_int) }, + { RS(PGSCAN_DIRECT_DMA32), TS(ul_int) }, + { RS(PGSCAN_DIRECT_MOVABLE), TS(ul_int) }, + { RS(PGSCAN_DIRECT_NORMAL), TS(ul_int) }, + { RS(PGSCAN_DIRECT_THROTTLE), TS(ul_int) }, + { RS(PGSCAN_KSWAPD_DMA), TS(ul_int) }, + { RS(PGSCAN_KSWAPD_DMA32), TS(ul_int) }, + { RS(PGSCAN_KSWAPD_MOVEABLE), TS(ul_int) }, + { RS(PGSCAN_KSWAPD_NORMAL), TS(ul_int) }, + { RS(PGSTEAL_DIRECT_DMA), TS(ul_int) }, + { RS(PGSTEAL_DIRECT_DMA32), TS(ul_int) }, + { RS(PGSTEAL_DIRECT_MOVABLE), TS(ul_int) }, + { RS(PGSTEAL_DIRECT_NORMAL), TS(ul_int) }, + { RS(PGSTEAL_KSWAPD_DMA), TS(ul_int) }, + { RS(PGSTEAL_KSWAPD_DMA32), TS(ul_int) }, + { RS(PGSTEAL_KSWAPD_MOVABLE), TS(ul_int) }, + { RS(PGSTEAL_KSWAPD_NORMAL), TS(ul_int) }, + { RS(PSWPIN), TS(ul_int) }, + { RS(PSWPOUT), TS(ul_int) }, + { RS(SLABS_SCANNED), TS(ul_int) }, + { RS(THP_COLLAPSE_ALLOC), TS(ul_int) }, + { RS(THP_COLLAPSE_ALLOC_FAILED), TS(ul_int) }, + { RS(THP_FAULT_ALLOC), TS(ul_int) }, + { RS(THP_FAULT_FALLBACK), TS(ul_int) }, + { RS(THP_SPLIT), TS(ul_int) }, + { RS(THP_ZERO_PAGE_ALLOC), TS(ul_int) }, + { RS(THP_ZERO_PAGE_ALLOC_FAILED), TS(ul_int) }, + { RS(UNEVICTABLE_PGS_CLEARED), TS(ul_int) }, + { RS(UNEVICTABLE_PGS_CULLED), TS(ul_int) }, + { RS(UNEVICTABLE_PGS_MLOCKED), TS(ul_int) }, + { RS(UNEVICTABLE_PGS_MUNLOCKED), TS(ul_int) }, + { RS(UNEVICTABLE_PGS_RESCUED), TS(ul_int) }, + { RS(UNEVICTABLE_PGS_SCANNED), TS(ul_int) }, + { RS(UNEVICTABLE_PGS_STRANDED), TS(ul_int) }, + { RS(WORKINGSET_ACTIVATE), TS(ul_int) }, + { RS(WORKINGSET_NODERECLAIM), TS(ul_int) }, + { RS(WORKINGSET_REFAULT), TS(ul_int) }, + { RS(ZONE_RECLAIM_FAILED), TS(ul_int) }, + + { RS(DELTA_ALLOCSTALL), TS(sl_int) }, + { RS(DELTA_BALLOON_DEFLATE), TS(sl_int) }, + { RS(DELTA_BALLOON_INFLATE), TS(sl_int) }, + { RS(DELTA_BALLOON_MIGRATE), TS(sl_int) }, + { RS(DELTA_COMPACT_FAIL), TS(sl_int) }, + { RS(DELTA_COMPACT_FREE_SCANNED), TS(sl_int) }, + { RS(DELTA_COMPACT_ISOLATED), TS(sl_int) }, + { RS(DELTA_COMPACT_MIGRATE_SCANNED), TS(sl_int) }, + { RS(DELTA_COMPACT_STALL), TS(sl_int) }, + { RS(DELTA_COMPACT_SUCCESS), TS(sl_int) }, + { RS(DELTA_DROP_PAGECACHE), TS(sl_int) }, + { RS(DELTA_DROP_SLAB), TS(sl_int) }, + { RS(DELTA_HTLB_BUDDY_ALLOC_FAIL), TS(sl_int) }, + { RS(DELTA_HTLB_BUDDY_ALLOC_SUCCESS), TS(sl_int) }, + { RS(DELTA_KSWAPD_HIGH_WMARK_HIT_QUICKLY), TS(sl_int) }, + { RS(DELTA_KSWAPD_INODESTEAL), TS(sl_int) }, + { RS(DELTA_KSWAPD_LOW_WMARK_HIT_QUICKLY), TS(sl_int) }, + { RS(DELTA_NR_ACTIVE_ANON), TS(sl_int) }, + { RS(DELTA_NR_ACTIVE_FILE), TS(sl_int) }, + { RS(DELTA_NR_ALLOC_BATCH), TS(sl_int) }, + { RS(DELTA_NR_ANON_PAGES), TS(sl_int) }, + { RS(DELTA_NR_ANON_TRANSPARENT_HUGEPAGES), TS(sl_int) }, + { RS(DELTA_NR_BOUNCE), TS(sl_int) }, + { RS(DELTA_NR_DIRTIED), TS(sl_int) }, + { RS(DELTA_NR_DIRTY), TS(sl_int) }, + { RS(DELTA_NR_DIRTY_BACKGROUND_THRESHOLD), TS(sl_int) }, + { RS(DELTA_NR_DIRTY_THRESHOLD), TS(sl_int) }, + { RS(DELTA_NR_FILE_PAGES), TS(sl_int) }, + { RS(DELTA_NR_FREE_CMA), TS(sl_int) }, + { RS(DELTA_NR_FREE_PAGES), TS(sl_int) }, + { RS(DELTA_NR_INACTIVE_ANON), TS(sl_int) }, + { RS(DELTA_NR_INACTIVE_FILE), TS(sl_int) }, + { RS(DELTA_NR_ISOLATED_ANON), TS(sl_int) }, + { RS(DELTA_NR_ISOLATED_FILE), TS(sl_int) }, + { RS(DELTA_NR_KERNEL_STACK), TS(sl_int) }, + { RS(DELTA_NR_MAPPED), TS(sl_int) }, + { RS(DELTA_NR_MLOCK), TS(sl_int) }, + { RS(DELTA_NR_PAGES_SCANNED), TS(sl_int) }, + { RS(DELTA_NR_PAGE_TABLE_PAGES), TS(sl_int) }, + { RS(DELTA_NR_SHMEM), TS(sl_int) }, + { RS(DELTA_NR_SLAB_RECLAIMABLE), TS(sl_int) }, + { RS(DELTA_NR_SLAB_UNRECLAIMABLE), TS(sl_int) }, + { RS(DELTA_NR_UNEVICTABLE), TS(sl_int) }, + { RS(DELTA_NR_UNSTABLE), TS(sl_int) }, + { RS(DELTA_NR_VMSCAN_IMMEDIATE_RECLAIM), TS(sl_int) }, + { RS(DELTA_NR_VMSCAN_WRITE), TS(sl_int) }, + { RS(DELTA_NR_WRITEBACK), TS(sl_int) }, + { RS(DELTA_NR_WRITEBACK_TEMP), TS(sl_int) }, + { RS(DELTA_NR_WRITTEN), TS(sl_int) }, + { RS(DELTA_NUMA_FOREIGN), TS(sl_int) }, + { RS(DELTA_NUMA_HINT_FAULTS), TS(sl_int) }, + { RS(DELTA_NUMA_HINT_FAULTS_LOCAL), TS(sl_int) }, + { RS(DELTA_NUMA_HIT), TS(sl_int) }, + { RS(DELTA_NUMA_HUGE_PTE_UPDATES), TS(sl_int) }, + { RS(DELTA_NUMA_INTERLEAVE), TS(sl_int) }, + { RS(DELTA_NUMA_LOCAL), TS(sl_int) }, + { RS(DELTA_NUMA_MISS), TS(sl_int) }, + { RS(DELTA_NUMA_OTHER), TS(sl_int) }, + { RS(DELTA_NUMA_PAGES_MIGRATED), TS(sl_int) }, + { RS(DELTA_NUMA_PTE_UPDATES), TS(sl_int) }, + { RS(DELTA_PAGEOUTRUN), TS(sl_int) }, + { RS(DELTA_PGACTIVATE), TS(sl_int) }, + { RS(DELTA_PGALLOC_DMA), TS(sl_int) }, + { RS(DELTA_PGALLOC_DMA32), TS(sl_int) }, + { RS(DELTA_PGALLOC_MOVABLE), TS(sl_int) }, + { RS(DELTA_PGALLOC_NORMAL), TS(sl_int) }, + { RS(DELTA_PGDEACTIVATE), TS(sl_int) }, + { RS(DELTA_PGFAULT), TS(sl_int) }, + { RS(DELTA_PGFREE), TS(sl_int) }, + { RS(DELTA_PGINODESTEAL), TS(sl_int) }, + { RS(DELTA_PGMAJFAULT), TS(sl_int) }, + { RS(DELTA_PGMIGRATE_FAIL), TS(sl_int) }, + { RS(DELTA_PGMIGRATE_SUCCESS), TS(sl_int) }, + { RS(DELTA_PGPGIN), TS(sl_int) }, + { RS(DELTA_PGPGOUT), TS(sl_int) }, + { RS(DELTA_PGREFILL_DMA), TS(sl_int) }, + { RS(DELTA_PGREFILL_DMA32), TS(sl_int) }, + { RS(DELTA_PGREFILL_MOVABLE), TS(sl_int) }, + { RS(DELTA_PGREFILL_NORMAL), TS(sl_int) }, + { RS(DELTA_PGROTATED), TS(sl_int) }, + { RS(DELTA_PGSCAN_DIRECT_DMA), TS(sl_int) }, + { RS(DELTA_PGSCAN_DIRECT_DMA32), TS(sl_int) }, + { RS(DELTA_PGSCAN_DIRECT_MOVABLE), TS(sl_int) }, + { RS(DELTA_PGSCAN_DIRECT_NORMAL), TS(sl_int) }, + { RS(DELTA_PGSCAN_DIRECT_THROTTLE), TS(sl_int) }, + { RS(DELTA_PGSCAN_KSWAPD_DMA), TS(sl_int) }, + { RS(DELTA_PGSCAN_KSWAPD_DMA32), TS(sl_int) }, + { RS(DELTA_PGSCAN_KSWAPD_MOVEABLE), TS(sl_int) }, + { RS(DELTA_PGSCAN_KSWAPD_NORMAL), TS(sl_int) }, + { RS(DELTA_PGSTEAL_DIRECT_DMA), TS(sl_int) }, + { RS(DELTA_PGSTEAL_DIRECT_DMA32), TS(sl_int) }, + { RS(DELTA_PGSTEAL_DIRECT_MOVABLE), TS(sl_int) }, + { RS(DELTA_PGSTEAL_DIRECT_NORMAL), TS(sl_int) }, + { RS(DELTA_PGSTEAL_KSWAPD_DMA), TS(sl_int) }, + { RS(DELTA_PGSTEAL_KSWAPD_DMA32), TS(sl_int) }, + { RS(DELTA_PGSTEAL_KSWAPD_MOVABLE), TS(sl_int) }, + { RS(DELTA_PGSTEAL_KSWAPD_NORMAL), TS(sl_int) }, + { RS(DELTA_PSWPIN), TS(sl_int) }, + { RS(DELTA_PSWPOUT), TS(sl_int) }, + { RS(DELTA_SLABS_SCANNED), TS(sl_int) }, + { RS(DELTA_THP_COLLAPSE_ALLOC), TS(sl_int) }, + { RS(DELTA_THP_COLLAPSE_ALLOC_FAILED), TS(sl_int) }, + { RS(DELTA_THP_FAULT_ALLOC), TS(sl_int) }, + { RS(DELTA_THP_FAULT_FALLBACK), TS(sl_int) }, + { RS(DELTA_THP_SPLIT), TS(sl_int) }, + { RS(DELTA_THP_ZERO_PAGE_ALLOC), TS(sl_int) }, + { RS(DELTA_THP_ZERO_PAGE_ALLOC_FAILED), TS(sl_int) }, + { RS(DELTA_UNEVICTABLE_PGS_CLEARED), TS(sl_int) }, + { RS(DELTA_UNEVICTABLE_PGS_CULLED), TS(sl_int) }, + { RS(DELTA_UNEVICTABLE_PGS_MLOCKED), TS(sl_int) }, + { RS(DELTA_UNEVICTABLE_PGS_MUNLOCKED), TS(sl_int) }, + { RS(DELTA_UNEVICTABLE_PGS_RESCUED), TS(sl_int) }, + { RS(DELTA_UNEVICTABLE_PGS_SCANNED), TS(sl_int) }, + { RS(DELTA_UNEVICTABLE_PGS_STRANDED), TS(sl_int) }, + { RS(DELTA_WORKINGSET_ACTIVATE), TS(sl_int) }, + { RS(DELTA_WORKINGSET_NODERECLAIM), TS(sl_int) }, + { RS(DELTA_WORKINGSET_REFAULT), TS(sl_int) }, + { RS(DELTA_ZONE_RECLAIM_FAILED), TS(sl_int) }, // dummy entry corresponding to VMSTAT_logical_end ... - { NULL, } + { NULL, NULL } }; /* please note, @@ -1242,3 +1247,56 @@ PROCPS_EXPORT struct vmstat_stack *procps_vmstat_select ( return info->extents->stacks[0]; } // end: procps_vmstat_select + + +// --- special debugging function(s) ------------------------------------------ +/* + * The following isn't part of the normal programming interface. Rather, + * it exists to validate result types referenced in application programs. + * + * It's used only when: + * 1) the 'XTRA_PROCPS_DEBUG' has been defined, or + * 2) the '#include <proc/xtra-procps-debug.h>' used + */ + +PROCPS_EXPORT struct vmstat_result *xtra_vmstat_get ( + struct vmstat_info *info, + enum vmstat_item actual_enum, + const char *typestr, + const char *file, + int lineno) +{ + struct vmstat_result *r = procps_vmstat_get(info, actual_enum); + + if (r) { + char *str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); + } + return r; +} // end: xtra_vmstat_get_ + + +PROCPS_EXPORT void xtra_vmstat_val ( + int relative_enum, + const char *typestr, + const struct vmstat_stack *stack, + struct vmstat_info *info, + const char *file, + int lineno) +{ + struct vmstat_result *r; + char *str; + + r = &stack->head[relative_enum]; + if (r->item < 0 || r->item >= VMSTAT_logical_end) { + fprintf(stderr, "%s line %d: invalid item = %d, relative_enum = %d, type = %s\n" + , file, lineno, r->item, relative_enum, typestr); + return; + } + str = Item_table[r->item].type2str; + if (str[0] + && (strcmp(typestr, str))) + fprintf(stderr, "%s line %d: was %s, expected %s\n", file, lineno, typestr, str); +} // end: xtra_vmstat_val diff --git a/proc/xtra-procps-debug.h b/proc/xtra-procps-debug.h new file mode 100644 index 0000000..7a8eb4a --- /dev/null +++ b/proc/xtra-procps-debug.h @@ -0,0 +1,194 @@ +/* + * libprocps - Library to read proc filesystem + * + * Copyright (C) 2016 Jim Warner <james.warner@comcast.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef XTRA_PROCPS_DEBUG_H +#define XTRA_PROCPS_DEBUG_H + +#include <proc/procps-private.h> + + +// --- DISKSTATS ------------------------------------------ +#ifdef DISKSTATS_GET +#undef DISKSTATS_GET +struct diskstats_result *xtra_diskstats_get ( + struct diskstats_info *info, + const char *name, + enum diskstats_item actual_enum, + const char *typestr, + const char *file, + int lineno); + +#define DISKSTATS_GET( info, name, actual_enum, type ) \ + xtra_diskstats_get(info, name, actual_enum , STRINGIFY(type), __FILE__, __LINE__) -> result . type; } ) +#endif // . . . . . . . . . . + +#ifdef DISKSTATS_VAL +#undef DISKSTATS_VAL +void xtra_diskstats_val ( + int relative_enum, + const char *typestr, + const struct diskstats_stack *stack, + struct diskstats_info *info, + const char *file, + int lineno); + +#define DISKSTATS_VAL( relative_enum, type, stack, info ) ( { \ + xtra_diskstats_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \ + stack -> head [ relative_enum ] . result . type; } ) +#endif // . . . . . . . . . . + + +// --- MEMINFO -------------------------------------------- +#ifdef MEMINFO_GET +#undef MEMINFO_GET +struct meminfo_result *xtra_meminfo_get ( + struct meminfo_info *info, + enum meminfo_item actual_enum, + const char *typestr, + const char *file, + int lineno); + +#define MEMINFO_GET( info, actual_enum, type ) ( { \ + xtra_meminfo_get(info, actual_enum , STRINGIFY(type), __FILE__, __LINE__) -> result . type; } ) +#endif // . . . . . . . . . . + +#ifdef MEMINFO_VAL +#undef MEMINFO_VAL +void xtra_meminfo_val ( + int relative_enum, + const char *typestr, + const struct meminfo_stack *stack, + struct meminfo_info *info, + const char *file, + int lineno); + +#define MEMINFO_VAL( relative_enum, type, stack, info ) ( { \ + xtra_meminfo_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \ + stack -> head [ relative_enum ] . result . type; } ) +#endif // . . . . . . . . . . + + +// --- PIDS ----------------------------------------------- +#ifdef PIDS_VAL +#undef PIDS_VAL +void xtra_pids_val ( + int relative_enum, + const char *typestr, + const struct pids_stack *stack, + struct pids_info *info, + const char *file, + int lineno); + +#define PIDS_VAL( relative_enum, type, stack, info ) ( { \ + xtra_pids_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \ + stack -> head [ relative_enum ] . result . type; } ) +#endif // . . . . . . . . . . + + +// --- SLABINFO ------------------------------------------- +#ifdef SLABINFO_GET +#undef SLABINFO_GET +struct slabinfo_result *xtra_slabinfo_get ( + struct slabinfo_info *info, + enum slabinfo_item actual_enum, + const char *typestr, + const char *file, + int lineno); + +#define SLABINFO_GET( info, actual_enum, type ) \ + xtra_slabinfo_get(info, actual_enum , STRINGIFY(type), __FILE__, __LINE__) -> result . type; } ) +#endif // . . . . . . . . . . + +#ifdef SLABINFO_VAL +#undef SLABINFO_VAL +void xtra_slabinfo_val ( + int relative_enum, + const char *typestr, + const struct slabinfo_stack *stack, + struct slabinfo_info *info, + const char *file, + int lineno); + +#define SLABINFO_VAL( relative_enum, type, stack, info ) ( { \ + xtra_slabinfo_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \ + stack -> head [ relative_enum ] . result . type; } ) +#endif // . . . . . . . . . . + + +// --- STAT ----------------------------------------------- +#ifdef STAT_GET +#undef STAT_GET +struct stat_result *xtra_stat_get ( + struct stat_info *info, + enum stat_item actual_enum, + const char *typestr, + const char *file, + int lineno); + +#define STAT_GET( info, actual_enum, type ) ( { \ + xtra_stat_get(info, actual_enum , STRINGIFY(type), __FILE__, __LINE__) -> result . type; } ) +#endif // . . . . . . . . . . + +#ifdef STAT_VAL +#undef STAT_VAL +void xtra_stat_val ( + int relative_enum, + const char *typestr, + const struct stat_stack *stack, + struct stat_info *info, + const char *file, + int lineno); + +#define STAT_VAL( relative_enum, type, stack, info ) ( { \ + xtra_stat_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \ + stack -> head [ relative_enum ] . result . type; } ) +#endif // . . . . . . . . . . + + +// --- VMSTAT --------------------------------------------- +#ifdef VMSTAT_GET +#undef VMSTAT_GET +struct vmstat_result *xtra_vmstat_get ( + struct vmstat_info *info, + enum vmstat_item actual_enum, + const char *typestr, + const char *file, + int lineno); + +#define VMSTAT_GET( info, actual_enum, type ) ( { \ + xtra_vmstat_get(info, actual_enum , STRINGIFY(type), __FILE__, __LINE__) -> result . type; } ) +#endif // . . . . . . . . . . + +#ifdef VMSTAT_VAL +#undef VMSTAT_VAL +void xtra_vmstat_val ( + int relative_enum, + const char *typestr, + const struct vmstat_stack *stack, + struct vmstat_info *info, + const char *file, + int lineno); + +#define VMSTAT_VAL( relative_enum, type, stack, info ) ( { \ + xtra_vmstat_val(relative_enum, STRINGIFY(type), stack, info, __FILE__, __LINE__); \ + stack -> head [ relative_enum ] . result . type; } ) +#endif // . . . . . . . . . . + +#endif // end: XTRA_PROCPS_DEBUG_H |