Examples
#pragma linkage(BPX1PCT, OS)
extern void BPX1PCT(char *, int, int, char *, int *, int *, int *);
/* #include <stdlib.h> */
#include <stdio.h>
#define ZFSCALL_STATS 0x40000007
#define STATOP_META_CACHE 248 /* Metadata cache (and back cache) stats */
#define u_long unsigned long
#define CONVERT_RATIO_TO_INTS(RATIO, INTEGER, DECIMAL) \
{ \
INTEGER = (int)RATIO; \
DECIMAL = (int)((RATIO - (double)INTEGER) * (double)1000.0); \
}
typedef struct syscall_parmlist_t
{
int opcode; /* Operation code to perform */
int parms[7]; /* Specific to type of operation, */
/* provides access to the parms */
/* parms[4]-parms[6] are currently unused*/
} syscall_parmlist;
typedef struct hyper {
unsigned long high; /* unsigned long reserved */
unsigned long low;
} hyper;
/*********************************************************************/
/* META cache stats, including backing cache. */
/*********************************************************************/
typedef struct PRIMARY_STATS_t {
hyper buffers; /* Number of buffers in cache */
int buffsize; /* Size of each buffer in K bytes */
int amc_res1; /* Reserved for future use, zero in version 1 */
int requests_reserved; /* Reserved */
int requests; /* Requests to the cache */
int hits_reserved; /* Reserved */
int hits; /* Hits in the cache */
int updates_reserved; /* Reserved */
int updates; /* Updates to buffers in the cache */
int reserved[10]; /* For future use */
} PRIMARY_STATS;
typedef struct BACK_STATS_t {
hyper buffers; /* Number of buffers in cache */
int buffsize; /* Size of each buffer in K bytes */
int amc_res1; /* Reserved for future use, zero in version 1 */
int requests_reserved; /* Reserved */
int requests; /* Requests to the cache */
int hits_reserved; /* Reserved */
int hits; /* Hits in the cache */
int discards_reserved; /* Reserved */
int discards; /* Discards of data from backing cache */
int reserved[10]; /* For future use */
} BACK_STATS;
typedef struct API_META_STATS_t {
char am_eye[4]; /* Eye catcher = AMET */
#define MS_EYE "AMET"
short am_size; /* Size of output structure */
char am_version; /* Version of stats */
#define MS_VER_INITIAL 1 /* First version of log stats */
char am_reserved1; /* Reserved byte, 0 in version 1 */
PRIMARY_STATS am_primary; /* Primary space cache statistics */
BACK_STATS am_back; /* Backing cache statistics */
int am_reserved3[10]; /* Reserved for future use */
} API_META_STATS;
/* reset timestamp */
typedef struct reset_time {
u_long posix_time_high; /* high order 32 bits since epoc */
u_long posix_time_low; /* low order 32 bits since epoch */
u_long posix_usecs; /* microseconds */
int pad1;
} RESET_TIME;
/*********************************************************************/
/* The following structure is the api query control block */
/* It is used for all api query commands */
/*********************************************************************/
typedef struct stat_api_t
{
#define SA_EYE "STAP"
char sa_eye[4]; /* 4 byte identifier must be */
int sa_len; /* length of the buffer to put data into*/
/* this buffer area follows this struct*/
int sa_ver; /* the version number currently always 1*/
#define SA_VER_INITIAL 0x01
char sa_flags; /* flags field must be x00 or x80, x80 means reset statistics*/
#define SA_RESET 0x80
char sa_fill[3]; /* spare bytes */
int sa_reserve[4]; /* Reserved */
struct reset_time reset_time_info;
} STAT_API;
struct parmstruct
{
syscall_parmlist myparms;
STAT_API myapi;
API_META_STATS mystats;
char systemname[9];
} myparmstruct;
int main(int argc, char **argv)
{
int bpxrv;
int bpxrc;
int bpxrs;
int i;
double temp_ratio;
int whole,decimal;
STAT_API *stapptr = &(myparmstruct.myapi);
char buf[33];
myparmstruct.myparms.opcode = STATOP_META_CACHE;
myparmstruct.myparms.parms[0] = sizeof(syscall_parmlist);
myparmstruct.myparms.parms[1] = sizeof(syscall_parmlist) + sizeof(STAT_API);
myparmstruct.myparms.parms[2] = 0;
/* Only specify a non-zero offset for the next field (parms[2]) if */
/* you are running z/OS 1.7 and above, and */
/* you want to query the metadata cache statistics of a different system than this one */
/* myparmstruct.myparms.parms[2] = sizeof(syscall_parmlist) + sizeof(STAT_API) + */
/* sizeof(API_META_STATS); */
myparmstruct.myparms.parms[3] = 0;
myparmstruct.myparms.parms[4] = 0;
myparmstruct.myparms.parms[5] = 0;
myparmstruct.myparms.parms[6] = 0;
memset(stapptr,0,sizeof(STAT_API));
memcpy(stapptr->sa_eye,SA_EYE,4);
stapptr->sa_ver=SA_VER_INITIAL;
stapptr->sa_len=(int) sizeof(API_META_STATS);
/* This next field should only be set if parms[2] is non-zero */
/* strcpy(myparmstruct.systemname,"DCEIMGVQ"); */
BPX1PCT("ZFS ",
ZFSCALL_STATS, /* Perf statistics operation */
sizeof(myparmstruct), /* Length of Argument */
(char *) &myparmstruct, /* Pointer to Argument */
&bpxrv, /* Pointer to Return_value */
&bpxrc, /* Pointer to Return_code */
&bpxrs); /* Pointer to Reason_code */
if( bpxrv < 0 )
{
printf("Error querying meta cache, BPXRV = %d BPXRC = %d BPXRS = %x\n",bpxrv,bpxrc,bpxrs);
return bpxrc;
}
else
{
/* Primary cache */
printf("%52s\n","Metadata Caching Statistics");
printf(" \n");
printf("Buffers (K bytes) Requests Hits Ratio Updates\n");
printf("---------- --------- ---------- ---------- ------ ----------\n");
temp_ratio = (myparmstruct.mystats.am_primary.requests.low == 0) ? 0.0 :
((double)myparmstruct.mystats.am_primary.hits.low)/myparmstruct.mystats.am_primary.requests.low;
temp_ratio *= 100.0;
CONVERT_RATIO_TO_INTS(temp_ratio,whole, decimal);
decimal = decimal / 100; /* Just want tenths */
printf("%10u %9u %10u %10u %3u.%1.1u%% %10u\n",
myparmstruct.mystats.am_primary.buffers.low,
myparmstruct.mystats.am_primary.buffers.low * myparmstruct.mystats.am_primary.buffsize,
myparmstruct.mystats.am_primary.requests.low, myparmstruct.mystats.am_primary.hits.low,
whole, decimal, myparmstruct.mystats.am_primary.updates.low);
printf(" \n");
/* Backing cache */
printf("%56s\n","Metadata Backing Caching Statistics");
printf(" \n");
printf("Buffers (K bytes) Requests Hits Ratio Discards\n");
printf("---------- --------- ---------- ---------- ------ ----------\n");
temp_ratio = (myparmstruct.mystats.am_back.requests.low == 0) ? 0.0 :
((double)myparmstruct.mystats.am_back.hits.low)/myparmstruct.mystats.am_back.requests.low;
temp_ratio *= 100.0;
CONVERT_RATIO_TO_INTS(temp_ratio,whole, decimal);
decimal = decimal / 100; /* Just want tenths */
printf("%10u %9u %10u %10u %3u.%1.1u%% %10u\n",
myparmstruct.mystats.am_back.buffers.low,
myparmstruct.mystats.am_back.buffers.low * myparmstruct.mystats.am_back.buffsize,
myparmstruct.mystats.am_back.requests.low, myparmstruct.mystats.am_back.hits.low,
whole, decimal, myparmstruct.mystats.am_back.discards.low);
printf(" \n");
if (0==ctime_r((time_t *) &stapptr->reset_time_info.posix_time_low, buf))
{
printf("Could not get timestamp.\n");
}
else
{ /* Insert the microseconds into the displayable time value */
strncpy(&(buf[27]),&(buf[20]),6);
sprintf(&(buf[20]),"%06d",stapptr->reset_time_info.posix_usecs);
buf[26]=' ';
buf[19]='.';
printf("Last Reset Time: %s",buf);
}
}
return 0;
}