Examples
#pragma linkage(BPX1PCT, OS)
extern void BPX1PCT(char *, int, int, char *, int *, int *, int *);
#include <stdio.h>
#define ZFSCALL_STATS 0x40000007
#define STATOP_USER_CACHE 242 /* Performance API queries */
#define LOCAL 0
#define REMOTE 1
#define u_long unsigned long
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 ds_entry
{
char ds_name[9];
char pad1[3];
int ds_alloc_segs;
int ds_free_pages;
int ds_reserved[5]; /*reserved for future use*/
} DS_ENTRY;
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;
/*********************************************************************/
/* The following structure is the user data cache statistics */
/*********************************************************************/
typedef struct vm_stats_t
{
/**********************************************************************/
/* First set of counters are for external requests to the VM system. */
/**********************************************************************/
u_long vm_schedules;
u_long vm_setattrs;
u_long vm_fsyncs;
u_long vm_unmaps;
u_long vm_reads;
u_long vm_readasyncs;
u_long vm_writes;
u_long vm_getattrs;
u_long vm_flushes;
u_long vm_scheduled_deletes;
/**********************************************************************/
/* Next two are fault counters, they measure number of read or write */
/* requests requiring a fault to read in data, this synchronizes */
/* an operation to a DASD read, we want these counters as small as */
/* possible. (These are read I/O counters). */
/**********************************************************************/
u_long vm_reads_faulted;
u_long vm_writes_faulted;
u_long vm_read_ios;
/**********************************************************************/
/* Next counters are write counters. They measure number of times */
/* we scheduled and waited for write I/Os. */
/**********************************************************************/
u_long vm_scheduled_writes;
u_long vm_error_writes;
u_long vm_reclaim_writes; /* Wrote dirty data for reclaim */
/**********************************************************************/
/* Next counters are I/O wait counters. They count the number of */
/* times we had to wait for a write I/O and under what conditions. */
/**********************************************************************/
u_long vm_read_waits;
u_long vm_write_waits;
u_long vm_fsync_waits;
u_long vm_error_waits;
u_long vm_reclaim_waits; /* Waited for pending I/O for reclaim */
/**********************************************************************/
/* Final set are memory management counters. */
/**********************************************************************/
u_long vm_reclaim_steal; /* Number of times steal from others function invoked */
u_long vm_waits_for_reclaim; /* Waits for reclaim thread */
u_long vm_reserved[10]; /*reserved for future use*/
} VM_STATS;
typedef struct stat_user_cache_t
{
VM_STATS stuc[2]; /*Various statistics for both LOCAL and REMOTE systems*/
int stuc_dataspaces; /* Number of dataspaces in user data cache */
int stuc_pages_per_ds; /* Pages per dataspace */
int stuc_seg_size_loc; /* Local Segment Size (in K) */ /*#B@D12838MG*/
int stuc_seg_size_rmt; /* Remote Segment Size (in K) */
int stuc_page_size; /* Page Size (in K) */
int stuc_cache_pages; /* Total number of pages */
int stuc_total_free; /* Total number of free pages */
int stuc_vmSegTable_cachesize; /* Number of segments */
int stuc_reserved[5]; /* reserved */
DS_ENTRY stuc_ds_entry[32]; /* Array of dataspace entries */
} STAT_USER_CACHE;
struct parmstruct
{
syscall_parmlist myparms;
STAT_API myapi;
STAT_USER_CACHE mystats;
char systemname[9];
} myparmstruct;
int main(int argc, char **argv)
{
int bpxrv;
int bpxrc;
int bpxrs;
int i,j;
double ratio1,ratio2,ratio3,ratio4;
char buf[33];
STAT_API *stapptr = &(myparmstruct.myapi);
myparmstruct.myparms.opcode = STATOP_USER_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 user cache statistics of a different system than this one */
/* myparmstruct.myparms.parms[2] = sizeof(syscall_parmlist) + sizeof(STAT_API) + */
/* sizeof(STAT_USER_CACHE); */
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(STAT_USER_CACHE);
/* 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 user cache stats, BPXRV = %d BPXRC = %d BPXRS = %x\n",bpxrv,bpxrc,bpxrs);
return bpxrc;
}
else
{
printf(" User File (VM) Caching System Statistics\n");
printf(" ----------------------------------------\n");
printf("\n");
for( i = 0 ; i <= REMOTE ; i++ )
{
if( i == 0 )
{
printf(" Direct Statistics\n");
printf(" -----------------\n");
printf("\n");
}
else
{
printf(" Client Statistics\n");
printf(" -----------------\n");
printf("\n");
}
printf("External Requests:\n");
printf("------------------\n");
printf("%-9s %10u %-9s %10u %-9s %10u\n",
"Reads",myparmstruct.mystats.stuc[i].vm_reads,
"Fsyncs",myparmstruct.mystats.stuc[i].vm_fsyncs,
"Schedules",myparmstruct.mystats.stuc[i].vm_schedules);
printf("%-9s %10u %-9s %10u %-9s %10u\n",
"Writes",myparmstruct.mystats.stuc[i].vm_writes,
"Setattrs",myparmstruct.mystats.stuc[i].vm_setattrs,
"Unmaps",myparmstruct.mystats.stuc[i].vm_unmaps);
printf("%-9s %10u %-9s %10u %-9s %10u\n",
"Asy Reads",myparmstruct.mystats.stuc[i].vm_readasyncs,
"Getattrs",myparmstruct.mystats.stuc[i].vm_getattrs,
"Flushes",myparmstruct.mystats.stuc[i].vm_flushes);
printf("\n");
printf("File System Reads:\n");
printf("------------------\n");
ratio1 = ratio2 = ratio3 = ratio4 = 0.0;
if( myparmstruct.mystats.stuc[i].vm_reads > 0 )
{
ratio1 = 100 * (((double)myparmstruct.mystats.stuc[i].vm_reads_faulted)
/ ((double)myparmstruct.mystats.stuc[i].vm_reads));
}
if( myparmstruct.mystats.stuc[i].vm_writes > 0 )
{
ratio2 = 100 * (((double)myparmstruct.mystats.stuc[i].vm_writes_faulted)
/ ((double)myparmstruct.mystats.stuc[i].vm_writes));
}
if( myparmstruct.mystats.stuc[i].vm_reads > 0 )
{
ratio3 = 100 * (((double)myparmstruct.mystats.stuc[i].vm_read_waits)
/ ((double)myparmstruct.mystats.stuc[i].vm_reads));
}
printf("%-14s %10u (%s Ratio %.2f%%)\n",
"Reads Faulted",myparmstruct.mystats.stuc[i].vm_reads_faulted,
"Fault",ratio1);
printf("%-14s %10u (%s Ratio %.2f%%)\n",
"Writes Faulted",myparmstruct.mystats.stuc[i].vm_writes_faulted,
"Fault",ratio2);
printf("%-14s %10u (%s Ratio %.2f%%)\n",
"Read Waits",myparmstruct.mystats.stuc[i].vm_read_ios,
"Wait",ratio3);
printf("\n");
printf("File System Writes:\n");
printf("-------------------\n");
printf("%-19s %10u %-13s %10u\n",
"Scheduled Writes", myparmstruct.mystats.stuc[i].vm_scheduled_writes,
"Sync Waits", myparmstruct.mystats.stuc[i].vm_fsync_waits);
printf("%-19s %10u %-13s %10u\n",
"Error Writes", myparmstruct.mystats.stuc[i].vm_error_writes,
"Error Waits", myparmstruct.mystats.stuc[i].vm_error_waits);
printf("%-19s %10u %-13s %10u\n",
"Page Reclaim Writes", myparmstruct.mystats.stuc[i].vm_reclaim_writes,
"Reclaim Waits", myparmstruct.mystats.stuc[i].vm_reclaim_waits);
if( myparmstruct.mystats.stuc[i].vm_writes > 0 )
{
ratio4 = 100 * (((double)myparmstruct.mystats.stuc[i].vm_write_waits)
/ ((double)myparmstruct.mystats.stuc[i].vm_writes));
}
printf("%-19s %10u (Wait Ratio %.2f%%)\n",
"Write Waits", myparmstruct.mystats.stuc[i].vm_write_waits,
ratio4);
}
printf("\n");
printf("Page Management (Segment Size = (%dK Local %dK Remote) ) (Page Size = %dK)\n",
myparmstruct.mystats.stuc_seg_size_loc,
myparmstruct.mystats.stuc_seg_size_rmt,
myparmstruct.mystats.stuc_page_size);
printf("-------------------------------------------------------------------------\n");
printf("Total Pages %10u Free %10u\n",
myparmstruct.mystats.stuc_cache_pages,myparmstruct.mystats.stuc_total_free);
printf("Segments %10u\n",
myparmstruct.mystats.stuc_vmSegTable_cachesize);
printf("Steal Invocations %10u Waits for Reclaim %11u\n",
myparmstruct.mystats.stuc[0].vm_reclaim_steal,
myparmstruct.mystats.stuc[0].vm_waits_for_reclaim);
printf("\n");
printf("Number of dataspaces used: %5d ",myparmstruct.mystats.stuc_dataspaces);
printf("Pages per dataspace: %11d\n",myparmstruct.mystats.stuc_pages_per_ds);
printf("\n");
printf("Dataspace Allocated Free\n");
printf("Name Segments Pages\n");
printf("-------- ---------- ----------\n");
for( i = 0 ; i < myparmstruct.mystats.stuc_dataspaces ; i++ )
{
printf("%8s %10u %10u\n",
myparmstruct.mystats.stuc_ds_entry[i].ds_name,
myparmstruct.mystats.stuc_ds_entry[i].ds_alloc_segs,
myparmstruct.mystats.stuc_ds_entry[i].ds_free_pages);
}
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;
}