Examples
#pragma linkage(BPX4PCT, OS64_NOSTACK)
extern void BPX4PCT(char *, int, int, char *, int *, int *, int *);
#include <stdio.h>
#include <time.h>
#define ZFSCALL_STATS 0x40000007
#define STATOP_IOCOUNTS 243 /* Performance API queries */
#define TOTAL_TYPES 3
#define TOTAL_CIRC 18
#define u_int unsigned int
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 reset_time {
u_int posix_time_high; /* high order 32 bits since epoc */
u_int posix_time_low; /* low order 32 bits since epoch */
u_int 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;
typedef struct API_IO_BY_TYPE_t
{
unsigned int number_of_lines;
unsigned int count;
unsigned int waits;
unsigned int cancels; /* Successful cancels of IO */
unsigned int merges; /* Successful merges of IO */
char reserved1[6];
char description[51];
char pad1[3];
} API_IO_BY_TYPE;
typedef struct API_IO_BY_CIRC_t
{
unsigned int number_of_lines;
unsigned int count;
unsigned int waits;
unsigned int cancels;
unsigned int merges;
char reserved1[6];
char description[51];
char pad1[3];
} API_IO_BY_CIRC;
/*********************************************************************/
/* The following structures are used to represent cfgop queries */
/* for iocounts */
/*********************************************************************/
struct parmstruct
{
syscall_parmlist myparms;
STAT_API myapi;
API_IO_BY_TYPE mystatsbytype[TOTAL_TYPES];
API_IO_BY_CIRC mystatsbycirc[TOTAL_CIRC];
} myparmstruct;
int main(int argc, char **argv)
{
int bpxrv;
int bpxrc;
int bpxrs;
int i;
STAT_API *stapptr = &(myparmstruct.myapi);
API_IO_BY_TYPE *stiotptr = &(myparmstruct.mystatsbytype[0]);
API_IO_BY_CIRC *stiocptr = &(myparmstruct.mystatsbycirc[0]);
char buf[33];
myparmstruct.myparms.opcode = STATOP_IOCOUNTS;
myparmstruct.myparms.parms[0] = sizeof(syscall_parmlist);
myparmstruct.myparms.parms[1] = sizeof(syscall_parmlist) + sizeof(STAT_API);
myparmstruct.myparms.parms[2] = 0;
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) (TOTAL_TYPES * sizeof(API_IO_BY_TYPE))
+ (TOTAL_CIRC * sizeof(API_IO_BY_CIRC));
BPX4PCT("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 iocounts, BPXRV = %d BPXRC = %d BPXRS = %x\n",bpxrv,bpxrc,bpxrs);
return bpxrc;
}
else
{
if( stiotptr->number_of_lines != TOTAL_TYPES )
{
printf("Unexpected number of IO Types, %d instead of TOTAL_TYPES\n",
stiotptr->number_of_lines);
return 1;
}
if( stiocptr->number_of_lines != TOTAL_CIRC )
{
printf("Unexpected number of IO Circumstances, %d instead of TOTAL_CIRC\n",
stiocptr->number_of_lines);
return 2;
}
printf(" I/O Summary By Type\n");
printf(" -------------------\n");
printf("\n");
printf("Count Waits Cancels Merges Type\n");
printf("---------- ---------- ---------- ---------- ----------\n");
for( i=0; i<TOTAL_TYPES; i++ )
{
printf("%10u %10u %10u %10u %s\n",
stiotptr->count, stiotptr->waits,
stiotptr->cancels, stiotptr->merges,
stiotptr->description);
stiotptr = stiotptr + 1;
}
printf("\n");
printf(" I/O Summary By Circumstance\n");
printf(" ---------------------------\n");
printf("\n");
printf("Count Waits Cancels Merges Circumstance\n");
printf("---------- ---------- ---------- ---------- ------------\n");
for( i=0; i<TOTAL_CIRC; i++ )
{
printf("%10u %10u %10u %10u %s\n",
stiocptr->count, stiocptr->waits,
stiocptr->cancels, stiocptr->merges,
stiocptr->description);
stiocptr = stiocptr +1;
printf("\n");
}
if (0==ctime_r((time_t *) &stapptr->reset_time_info, 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;
}