Statistics iobyaggr Information
Purpose
Displays information about the number of reads and writes (I/Os) and the amount of data in bytes that are transferred for each aggregate.
Format
syscall_parmlist
opcode int 244 STATOP_IOBYAGGR
parms[0] int offset to STAT_API
parms[1] int offset of output following STAT_API
parms[2] int offset to system name (optional)
parms[3] int 0
parms[4] int 0
parms[5] int 0
parms[6] int 0
STAT_API
sa_eye char[4] "STAP"
sa_len int Length of buffer that follows STAT_API
sa_ver int 1
sa_flags char[1] 0x80 - Reset statistics
sa_reserve int[3] Reserved
posix_time_high unsigned int High order 32 bits since epoch
posix_time_low unsigned int Low order 32 bits since epoch
posix_useconds unsigned int Microseconds
IO_REPORT2_2_GRAND_TOTALS
io_count int Count of IO_REPORT2 lines
grand_total_reads unsigned int Total reads
grand_total_writes unsigned int Total writes
grand_total_read_bytes unsigned int Total bytes read (in kilobytes)
grand_total_write_bytes unsigned int Total bytes written (in kilobytes)
grand_total_devices unsigned int Total number of aggregates
total_number_waits_for_io unsigned int Total number of waits for I/O
average_wait_time_for_io_whole unsigned int Average wait time (whole number),
average wait time in milliseconds
average_wait_time_for_io_decimal unsigned int Average wait time (decimal part)
decimal part is in thousanths
3 means .003 and 300 means .3
IO_REPORT2[io_count]
volser char[8] DASD volser where aggregate resides
pavios unsigned int Max number of concurrent I/Os that zFS will issue
read_ind char[4] R/O or R/W (how aggregate is attached)
temp_reads unsigned int Count of reads for this aggregate
temp_read_bytes unsigned int Bytes read for this aggregate (in kilobytes)
temp_writes unsigned int Count of writes for this aggregate
temp_write_bytes unsigned int Bytes written for this aggregate (in kilobytes)
allocation_dsname char[84] Data set name of aggregate
--or--
IO_REPORT2_GRAND_TOTALS2
io_count int Count of IO_REPORT2 lines
grand_total_reads unsigned long long Total reads
grand_total_writes unsigned long long Total writes
grand_total_read_bytes unsigned long long Total bytes read (in kilobytes)
grand_total_write_bytes unsigned long long Total bytes written (in kilobytes)
grand_total_devices unsigned long long Total number of aggregates
total_number_waits_for_io unsigned long long Total number of waits for I/O
average_wait_time_for_io_whole unsigned int Average wait time (whole number),
average wait time in milliseconds
average_wait_time_for_io_decimal unsigned int Average wait time (decimal part)
decimal part is in thousanths
3 means .003 and 300 means .3
IO_REPORT2_2[io_count]
volser char[8] DASD volser where aggregate resides
pavios unsigned int Max number of concurrent I/Os that zFS will issue
read_ind char[4] R/O or R/W (how aggregate is attached)
temp_reads unsigned long long Count of reads for this aggregate
temp_read_bytes unsigned long long Bytes read for this aggregate (in kilobytes)
temp_writes unsigned long long Count of writes for this aggregate
temp_write_bytes unsigned long long Bytes written for this aggregate (in kilobytes)
allocation_dsname char[84] Data set name of aggregate
systemname char[9]
Return_value 0 if request is successful, -1 if it is not successful
Return_code
EINTR zFS is shutting down
EINVAL Invalid parameter list
EMVSERR Internal error occurred
E2BIG Information too big for buffer supplied
Reason_code
0xEFnnxxxx See z/OS Distributed File Service Messages and Codes
Usage notes
Privilege required
None.
Related services
- Statistics iobydasd Information
- Statistics iocounts Information
Restrictions
None.
Examples
#pragma linkage(BPX1PCT, OS)
#pragma LANGLVL(EXTENDED)
extern void BPX1PCT(char *, int, int, char *, int *, int *, int *);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define ZFSCALL_STATS 0x40000007
#define STATOP_IOBYAGGR 244 /* Performance API queries */
#define E2BIG 145
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 {
unsigned int posix_time_high; /* high order 32 bits since epoc */
unsigned int posix_time_low; /* low order 32 bits since epoch */
unsigned 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_2 0x02
#define SA_VER_INIT 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_supported_ver; /* version of data returned */
int sa_reserve[3]; /* Reserved */
struct reset_time reset_time_info;
} STAT_API;
typedef struct io_report2_2_t {
char volser[8];
unsigned int pavios;
char read_ind[4];
unsigned long long int temp_reads;
unsigned long long int temp_read_bytes;
unsigned long long int temp_writes;
unsigned long long int temp_write_bytes;
char allocation_dsname[84];
char reserved[4];
} IO_REPORT2_2;
typedef struct io_report2_grand_totals_2_t {
int io_count; /* number IO_REPORT2 structs in buffer */
int pad;
unsigned long long int grand_total_reads; /* Total # reads */
unsigned long long int grand_total_writes; /* Total # writes */
unsigned long long int grand_total_read_bytes; /* Total bytes read */
unsigned long long int grand_total_write_bytes; /* Total bytes written*/
unsigned long long int grand_total_devices; /* total # aggregates */
unsigned long long int total_number_waits_for_io;
unsigned int average_wait_time_for_io_whole;
unsigned int average_wait_time_for_io_decimal;
} IO_REPORT2_GRAND_TOTALS_2;
/* Version 1 Output structures */
typedef struct io_report2_t {
char volser[8];
unsigned int pavios;
char read_ind[4];
unsigned int temp_reads;
unsigned int temp_read_bytes;
unsigned int temp_writes;
unsigned int temp_write_bytes;
char allocation_dsname[84];
} IO_REPORT2;
typedef struct io_report2_grand_totals_t {
int io_count; /* number IO_REPORT2
structs in buffer */
unsigned int grand_total_reads; /* Total # reads */
unsigned int grand_total_writes; /* Total # writes */
unsigned int grand_total_read_bytes; /* Total bytes read */
unsigned int grand_total_write_bytes; /* Total bytes written*/
unsigned int grand_total_devices; /* total # aggregates */
unsigned int total_number_waits_for_io;
unsigned int average_wait_time_for_io_whole; /* in milliseconds */
unsigned int average_wait_time_for_io_decimal; /* in thousandths */
/* of milliseconds */
/* for example, */
/*3 means .003 and
300 means .3 */
} IO_REPORT2_GRAND_TOTALS;
struct parmstruct {
syscall_parmlist myparms;
STAT_API myapi;
/* output buffer IO_REPORT2_GRAND_TOTALS_2 + multiple IO_REPORT2_2s */
char systemname[9];
} myparmstruct;
int print_iobyaggr_version1(IO_REPORT2_GRAND_TOTALS *stgt,
IO_REPORT2 *str2);
int print_iobyaggr_version2(IO_REPORT2_GRAND_TOTALS_2 *stgt,
IO_REPORT2_2 *str2);
int main(int argc, char **argv)
{
int buffer_success = 0;
int bpxrv;
int bpxrc;
int bpxrs;
int i,t;
IO_REPORT2_GRAND_TOTALS_2 *stgt;
IO_REPORT2_2 *str2;
char *stsy;
char buf[33];
struct parmstruct *myp = &myparmstruct;
int mypsize;
int buflen;
STAT_API *stapptr = &(myparmstruct.myapi);
myparmstruct.myparms.opcode = STATOP_IOBYAGGR;
myparmstruct.myparms.parms[0] = sizeof(syscall_parmlist);
myparmstruct.myparms.parms[1] = sizeof(syscall_parmlist) + sizeof(STAT_API);
/* 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 */
/* iobyaggr statistics of a different system than this one */
/* myparmstruct.myparms.parms[2] = 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_2;
stapptr->sa_len = 0;
/* 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 */
for(t = 0; t < 1000 && buffer_success == 0; t++)
{
if (bpxrv < 0)
{
if (bpxrc == E2BIG)
{
buflen = stapptr->sa_len; /* Get buffer size needed */
mypsize = sizeof(syscall_parmlist) + sizeof(STAT_API) + buflen +
sizeof(myparmstruct.systemname);
free(myp);
myp = (struct parmstruct *)malloc((int)mypsize);
memset(myp, 0, mypsize);
printf("Need buffer size of %d, for a total of %d\n\n\n",
buflen, mypsize);
myp->myparms.opcode = STATOP_IOBYAGGR;
myp->myparms.parms[0] = sizeof(syscall_parmlist);
myp->myparms.parms[1] = sizeof(syscall_parmlist) + sizeof(STAT_API);
myp->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 */
/* iobyaggr statistics of a different system than this one */
/* myp->myparms.parms[2] = sizeof(syscall_parmlist) */
/* + sizeof(STAT_API) + buflen; */
myp->myparms.parms[3] = 0;
myp->myparms.parms[4] = 0;
myp->myparms.parms[5] = 0;
myp->myparms.parms[6] = 0;
stapptr = (STAT_API * )((char *)myp + sizeof(syscall_parmlist));
memcpy(stapptr->sa_eye, SA_EYE, 4);
stapptr->sa_ver = SA_VER_2;
stapptr->sa_len = buflen;
stgt = (IO_REPORT2_GRAND_TOTALS_2 * )((char *)myp +
sizeof(syscall_parmlist) +
sizeof(STAT_API));
str2 = (IO_REPORT2_2*) ((char*) stgt +
sizeof(IO_REPORT2_GRAND_TOTALS_2));
stsy = (char *)((char *)myp +
sizeof(syscall_parmlist) +
sizeof(STAT_API) + buflen);
/* This next field should only be set if parms[2] is non-zero */
/* strcpy(stsy,"DCEIMGVQ"); */
BPX1PCT("ZFS ",
ZFSCALL_STATS, /* Aggregate operation */
mypsize, /* Length of Argument */
(char *)myp, /* Pointer to Argument */
&bpxrv, /* Pointer to Return_value */
&bpxrc, /* Pointer to Return_code */
&bpxrs); /* Pointer to Reason_code */
if( bpxrv != 0 && bpxrc == E2BIG )
printf("E2BIG: %d times total\n", t++);
else if( bpxrv == 0 )
{
buffer_success = 1;
if (stapptr->sa_supported_ver == SA_VER_INIT)
{
IO_REPORT2_GRAND_TOTALS *stgt_v1;
IO_REPORT2 *str2_v1;
stgt_v1 = (IO_REPORT2_GRAND_TOTALS * )((char *)myp +
sizeof(syscall_parmlist) +
sizeof(STAT_API));
str2_v1 = (IO_REPORT2 * ) ((char*) stgt +
sizeof(IO_REPORT2_GRAND_TOTALS));
print_iobyaggr_version1(stgt_v1,str2_v1);
}
else
print_iobyaggr_version2(stgt, str2);
unsigned int ptl = stapptr->reset_time_info.posix_time_low;
if (0 == ctime_r((time_t * ) & ptl, 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);
}
free(myp);
}
else
{ /* iobyaggr failed with large enough buffer */
printf("Error on iobyaggr with large enough buffer\n");
printf("Error querying iobyaggr, BPXRV = %d BPXRC = %d BPXRS = %x\n",
bpxrv, bpxrc, bpxrs);
free(myp);
return bpxrc;
}
}
else
{ /* error was not E2BIG */
printf("Error on iobyaggr trying to get required size\n");
printf("BPXRV = %d BPXRC = %d BPXRS = %x\n", bpxrv, bpxrc, bpxrs);
free(myp);
return bpxrc;
}
}
else
{ /* asking for buffer size gave rv = 0; maybe there is no data */
if (myparmstruct.myapi.sa_len == 0)
{
printf("No data\n");
printf("BPXRV = %d BPXRC = %d BPXRS = %x\n", bpxrv, bpxrc, bpxrs);
}
else
{ /* No, there was some other problem with getting the size needed */
printf("Error getting size required\n");
printf("BPXRV = %d BPXRC = %d BPXRS = %x\n", bpxrv, bpxrc, bpxrs);
}
free(myp);
return bpxrc;
}
}
if( t == 1000 )
printf("Number of failed buffer resizes exceeded.\n");
free(myp);
return 0;
}
int print_iobyaggr_version2(IO_REPORT2_GRAND_TOTALS_2 *stgt,
IO_REPORT2_2 *str2)
{
int i;
printf(" zFS I/O by Currently Attached Aggregate\n");
printf("\n");
printf("DASD PAV\n");
printf("VOLSER IOs Mode Reads K bytes "
"Writes K bytes Dataset Name\n");
printf("------ --- ---- ---------- ---------- "
"---------- ---------- ------------\n");
for (i = 0; i < stgt->io_count; i++, str2++)
{
printf("%6.6s %3u %s %10llu %10llu %10llu %10llu %-44.44s\n",
str2->volser,
str2->pavios,
str2->read_ind,
str2->temp_reads,
str2->temp_read_bytes,
str2->temp_writes,
str2->temp_write_bytes,
str2->allocation_dsname);
}
printf("%6llu %10llu %10llu %10llu %10llu %-44.44s\n",
stgt->grand_total_devices,
stgt->grand_total_reads,
stgt->grand_total_read_bytes,
stgt->grand_total_writes,
stgt->grand_total_write_bytes, "*TOTALS*");
printf("\n");
printf("Total number of waits for I/O: %10u\n",
stgt->total_number_waits_for_io);
printf("Average I/O wait time: %9u.%3.3u (msecs)\n",
stgt->average_wait_time_for_io_whole,
stgt->average_wait_time_for_io_decimal);
printf("\n");
return 1;
}
int print_iobyaggr_version1(IO_REPORT2_GRAND_TOTALS *stgt,
IO_REPORT2 *str2)
{
int i;
printf("Version 1 output is being displayed\n");
printf(" zFS I/O by Currently Attached Aggregate\n");
printf("\n");
printf("DASD PAV\n");
printf("VOLSER IOs Mode Reads K bytes "
"Writes K bytes Dataset Name\n");
printf("------ --- ---- ---------- ---------- "
"---------- ---------- ------------\n");
for (i = 0; i < stgt->io_count; i++, str2++) {
printf("%6.6s %3u %s %10u %10u %10u %10u %-44.44s\n",
str2->volser,
str2->pavios,
str2->read_ind,
str2->temp_reads,
str2->temp_read_bytes,
str2->temp_writes,
str2->temp_write_bytes,
str2->allocation_dsname);
}
printf("%6u %10u %10u %10u %10u %-44.44s\n",
stgt->grand_total_devices,
stgt->grand_total_reads,
stgt->grand_total_read_bytes,
stgt->grand_total_writes,
stgt->grand_total_write_bytes, "*TOTALS*");
printf("\n");
printf("Total number of waits for I/O: %10u\n",
stgt->total_number_waits_for_io);
printf("Average I/O wait time: %9u.%3.3u (msecs)\n",
stgt->average_wait_time_for_io_whole,
stgt->average_wait_time_for_io_decimal);
printf("\n");
}