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>
This commit is contained in:
Jim Warner 2016-08-05 00:00:00 -05:00 committed by Craig Small
parent e0515e23e7
commit e3270d463d
10 changed files with 1103 additions and 567 deletions

View File

@ -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 \

View File

@ -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) },
/* setsfunc sortfunc type2str
---------------------------------- ----------- ---------- */
{ RS(noop), QS(noop), TS_noop },
{ RS(extra), QS(ul_int), TS_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_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) },
{ 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_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) },
{ RS(DISKSTATS_IO_INPROGRESS), QS(s_int), TS(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) },
{ 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

View File

@ -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:
*;
};

View File

@ -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) },
/* setsfunc type2str
------------------------- ---------- */
{ RS(noop), TS_noop },
{ RS(extra), TS_noop },
{ 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(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) },
{ 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(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) },
{ RS(MEMHI_TOTAL) },
{ RS(MEMHI_USED) },
{ RS(MEMLO_FREE) },
{ RS(MEMLO_TOTAL) },
{ RS(MEMLO_USED) },
{ RS(MEMHI_FREE), TS(ul_int) },
{ RS(MEMHI_TOTAL), TS(ul_int) },
{ RS(MEMHI_USED), TS(ul_int) },
{ RS(SWAP_CACHED) },
{ RS(SWAP_FREE) },
{ RS(SWAP_TOTAL) },
{ RS(SWAP_USED) },
{ 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

View File

@ -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
/* 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 },
{ 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
{ 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

View File

@ -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

View File

@ -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) },
/* setsfunc sortfunc type2str
---------------------------- ----------- ---------- */
{ RS(noop), QS(noop), TS_noop },
{ RS(extra), QS(ul_int), TS_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_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) },
{ 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(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) },
{ 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) },
{ 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

View File

@ -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) },
/* setsfunc sortfunc type2str
--------------------------- ------------ ----------- */
{ RS(noop), QS(noop), TS_noop },
{ RS(extra), QS(ull_int), TS_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_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) },
{ 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(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) },
{ 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_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) },
{ 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) },
{ 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

View File

@ -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) },
/* setsfunc type2str
---------------------------------------- ---------- */
{ RS(noop), TS_noop },
{ RS(extra), TS_noop },
{ 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(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) },
{ 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) },
{ 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

194
proc/xtra-procps-debug.h Normal file
View File

@ -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