Statistics Sysplex Owner Operations Information
Purpose
Returns information about the number of calls processed on the local system as a result of a message sent from another system. Vnode operation statistics are returned for each client system that accessed a file system owned on the local server.
Format
syscall_parmlist
opcode int 253 STATOP_SVI
parms[0] int offset to STAT_API
parms[1] int Offset of output following STAT_API
parms[2] int 0
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] 0x00
SA_RESET 0x80 Reset statistics
sa_fill char[3] 0
sa_supported_ver int version of data returned or reserved
sa_reserve int[3] 0
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
pad1 int
CT_HEADER
ct_eye char[4] "CTHD"
ct_length short Length of the structure
ct_version short Structure version
number_of_ct_sys unsigned int Number of CT_SYS_STATS structures
number_of_ct_call unsigned int Number of CT_CALL_STATS structures
CT_SYS_STATS[number_of_ct_sys]
cs_eye char[4] "CTSY"
cs_length short Length of the structure
cs_version short Structure version
cs_sysname char[9] Name of system. A value of 0
means there is no information in
this record and any subsequent
record (end of list)
reserved char[7]
CT_CALL_STATS[number_of_ct_call]
cc_eye char[4] "CTCL"
cc_length short Length of structure
cc_version short Structure version
cc_count unsigned long long Number of calls of that type
since last statistics reset.
cc_xcfreq unsigned long long Indicates if an XCF request
was required to process the call.
Number of XCF requests that were
required to make callbacks to one
or more clients to process
the requests.
cc_qwait unsigned long long Number of times a request had
to wait in queue before being
dispatched to a processing
task at the owner, valid only
for SVI report
cc_avg_wait_whole int Average time for system to
process call in milliseconds.
This will be average time for the
owner to process the call for SVI
reports. This is the part
before the decimal point.
cc_avg_wait_decimal int The part after the decimal
point for avg. waits time.
This is microseconds.
cc_name char[25]
reserved char[7]
CT_CALL_STATS
cc_eye char[4] "CTCL"
cc_length short Length of structure
cc_version short Structure version
cc_count unsigned long long Number of calls of that type
since last statistics reset.
cc_xcfreq unsigned long long Indicates if an XCF request
was required to process the call.
Number of XCF requests that were
required to make callbacks to one
or more clients to process
the requests.
cc_qwait unsigned long long Number of times a request had
to wait in queue before being
dispatched to a processing
task at the owner, valid only
for SVI report
cc_avg_wait_whole int Average time for system to
process call in milliseconds.
This will be average time for the
owner to process the call for SVI
reports. This is the part
before the decimal point.
cc_avg_wait_decimal int The part after the decimal
point for avg. waits time.
This is microseconds.
cc_name char[25]
reserved char[7]
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 using an osi service
Reason_code
0xEFnnxxxx See z/OS Distributed File Service Messages and Codes
Usage notes
- Users of the API supply as input a buffer that contains a syscall_parmlist followed by a STAT_API structure, followed by an output buffer.
- Output consists of a CT_HEADER followed by an array of CT_SYS_STATS structures and an array of CT_CALL_STATS structures. The number of elements in each array is returned in number_of_ct_sys and number_of_ct_call respectively.
- If the output buffer is not large enough to contain all of the output, E2BIG is returned and the required size is placed in sa_len. The caller can then try the request again with a larger buffer.
- A CT_SYS_STATS structure is returned only for client systems that sent the local server system messages since the last statistics reset.
Privilege required
None.
Related services
- Statistics Server Token Management Information
- Statistics Sysplex Client Operations Information
Restrictions
None.
Examples
#pragma linkage(BPX1PCT, OS)
#pragma LANGLVL(EXTENDED)
extern void BPX1PCT(char *, int, int, char *, int *, int *, int *);
#include <stdio.h>
#define ZFSCALL_STATS 0x40000007
#define STATOP_SVI 254 /* inbound calls from remote clients */
#define E2BIG 145
typedef struct syscall_parmlist_t {
int opcode; /* Operation code to perform */
int parms[7]; /* Specific to type of operation, */
} syscall_parmlist;
typedef struct reset_time {
unsigned int posix_time_high;
unsigned int posix_time_low;
unsigned int posix_usecs;
int pad1;
} RESET_TIME;
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_INIT 0x01
char sa_flags; /* command 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 CT_CALL_STATS_t {
char cc_eye[4];
#define CC_EYE "CTCL"
short cc_length;
short cc_version;
#define CC_VER_INITIAL 1
unsigned long long cc_count;
unsigned long long cc_xcfreq;
unsigned long long cc_qwait; /* number of waits */
int cc_avg_wait_whole; /* average wait time for */
/* calls of this type */
int cc_avg_wait_decimal;
char cc_name[25];
char reserved[7];
} CT_CALL_STATS;
typedef struct CT_SYS_STATS_t {
char cs_eye[4];
#define CS_EYE "CTSY"
short cs_length;
short cs_version;
#define CS_VER_INITIAL 1
char cs_sysname[9];
char reserved[7];
} CT_SYS_STATS;
typedef struct CT_HEADER_t {
char ct_eye[4];
#define CT_EYE "CTHD"
short ct_length;
short ct_version;
#define CT_VER_INITIAL 1
unsigned int number_of_ct_sys;
unsigned int number_of_ct_call;
} CT_HEADER;
int main(int argc, char** argv)
{
int buff_fill_len = 0;
int bpxrv, bpxrc, bpxrs;
char sysname[9];
int num_systems;
int num_calls;
int entry_size;
int mypsize;
int buflen;
int i,j,t;
int buffer_success = 0;
STAT_API local_req;
STAT_API* st_req = NULL;
syscall_parmlist* parmp = NULL;
CT_HEADER* ct_p = NULL;
CT_SYS_STATS* ct_sysp = NULL;
CT_CALL_STATS* ct_callp = NULL;
char* p = NULL;
char* buffp = NULL;
/* Initialize the local_req to 0s */
st_req = &local_req;
memset( st_req, 0x00, sizeof(STAT_API) );
strcpy( local_req.sa_eye, SA_EYE, sizeof(local_req.sa_eye) );
local_req.sa_len = 0;
local_req.sa_ver = SA_VER_INIT;
/* Allocate Buffer */
buffp = (char*) malloc(sizeof(syscall_parmlist) + sizeof(STAT_API));
if( buffp == NULL )
{
printf("Malloc Error\n");
return 0;
}
memset( buffp, 0x00, sizeof(syscall_parmlist) + sizeof(STAT_API));
/* Set the run parms */
parmp = (syscall_parmlist*) &buffp[0];
parmp->opcode = STATOP_SVI;
parmp->parms[0] = buff_fill_len = sizeof(syscall_parmlist);
parmp->parms[1] = buff_fill_len + sizeof(STAT_API);
parmp->parms[2] = 0;
parmp->parms[3] = 0;
parmp->parms[4] = 0;
parmp->parms[5] = 0;
parmp->parms[6] = 0;
st_req = (STAT_API*) &buffp[buff_fill_len];
memcpy( st_req, &local_req, sizeof(STAT_API) );
buff_fill_len += sizeof(STAT_API);
BPX1PCT("ZFS ",
ZFSCALL_STATS, /* Aggregate operation */
buff_fill_len, /* Length of Argument */
(char*) buffp, /* Pointer to Argument */
&bpxrv, /* Pointer to Return_value */
&bpxrc, /* Pointer to Return_code */
&bpxrs); /* Pointer to Reason_code */
printf("bpxrv %d\n", bpxrv);
for(t = 0; t < 1000 && buffer_success == 0; t++)
{
if( bpxrv < 0 )
{
/* Look for E2BIG to get required file size back in the st_req */
if( bpxrc == E2BIG )
{
buflen = st_req->sa_len;
mypsize = sizeof(syscall_parmlist) +
sizeof(STAT_API) + buflen;
free(buffp);
buffp = (char*) malloc(mypsize);
if( buffp == NULL )
{
printf("Malloc Error\n");
return 0;
}
memset( buffp, 0x00, mypsize );
printf("Need buffer size of %d, for a total of %d\n",
buflen, mypsize);
/* Set the run parms */
parmp = (syscall_parmlist*) &buffp[0];
parmp->opcode = STATOP_SVI;
parmp->parms[0] = buff_fill_len = sizeof(syscall_parmlist);
parmp->parms[1] = buff_fill_len + sizeof(STAT_API);
parmp->parms[2] = 0;
parmp->parms[3] = 0;
parmp->parms[4] = 0;
parmp->parms[5] = 0;
parmp->parms[6] = 0;
st_req = (STAT_API*) &buffp[buff_fill_len];
memcpy( st_req->sa_eye, SA_EYE, 4 );
buff_fill_len += sizeof(STAT_API);
st_req->sa_ver = SA_VER_INIT;
st_req->sa_len = buflen;
BPX1PCT("ZFS ",
ZFSCALL_STATS, /* Aggregate operation */
mypsize, /* Length of Argument */
(char*) buffp, /* 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;
ct_p = (CT_HEADER*) &buffp[buff_fill_len];
buff_fill_len += ct_p->ct_length;
ct_sysp = (CT_SYS_STATS*) &buffp[buff_fill_len];
buff_fill_len += ct_sysp->cs_length;
ct_callp = (CT_CALL_STATS*) &buffp[buff_fill_len];
/* Make sure there are systems */
num_systems = ct_p->number_of_ct_sys;
if( num_systems == 0 )
{
printf("Svi stats completed successfully. "
"There is no information to display\n");
free(buffp);
return 0;
}
num_calls = ct_p->number_of_ct_call;
entry_size = ct_sysp->cs_length +
(ct_callp->cc_length * num_calls);
for (j = 0; j < num_systems; j++)
{
printf("SV");
printf("%30cSVI Calls from System %s\n", ' ',
ct_sysp->cs_sysname);
printf(" ");
printf("%30c------------------------------\n", ' ');
printf("SVI Call "
"Count "
"Qwait "
"XCF Req. "
"Avg. Time\n");
printf("-------------------- "
"-------------------- "
"---------------- ---------------- "
"----------\n");
for (i = 0; i < num_calls-1; i++)
{
printf("%-25s%20llu %16llu %16llu%8u.%3.3u\n",
ct_callp[i].cc_name,
ct_callp[i].cc_count,
ct_callp[i].cc_qwait,
ct_callp[i].cc_xcfreq,
ct_callp[i].cc_avg_wait_whole,
ct_callp[i].cc_avg_wait_decimal);
}
/* Put out the Totals entry */
printf("-------------------- "
"-------------------- "
"---------------- ---------------- "
"----------\n");
printf("%-25s%20llu %16llu %16llu%8u.%3.3u\n",
ct_callp[i].cc_name,
ct_callp[i].cc_count,
ct_callp[i].cc_qwait,
ct_callp[i].cc_xcfreq,
ct_callp[i].cc_avg_wait_whole,
ct_callp[i].cc_avg_wait_decimal);
printf("\n");
/* Get the pointers to the next system entry */
p = (char*) ct_sysp;
p += entry_size;
ct_sysp = (CT_SYS_STATS*) p;
p += ct_sysp->cs_length;
ct_callp = (CT_CALL_STATS*) p;
}
}
else
{
/* Second API call failed */
printf("Error on next request for svi stats\n");
printf("Return Value: %d "
"Return Code: %d "
"Reason Code: %x\n",
bpxrv, bpxrc, bpxrs);
buffer_success = -1;
}
}
else
{
/* Expecting E2BIG and it was a different error */
printf("Error on storage stats trying to get required size\n");
printf("BPXRV = %d BPXRC = %d BPXRS = %x\n",
bpxrv, bpxrc, bpxrs);
buffer_success = -1;
}
}
else
{
/* If rv is 0, most likely there was no data to get */
if (st_req->sa_len == 0)
{
printf("No data\n");
printf("BPXRV = %d BPXRC = %d BPXRS = %x\n",
bpxrv, bpxrc, bpxrs);
}
else
{ /* There was some other problem with getting required size */
printf("Error getting size required\n");
printf("BPXRV = %d BPXRC = %d BPXRS = %x\n",
bpxrv, bpxrc, bpxrs);
}
buffer_success = -1;
}
}
if( t == 1000 )
printf("Number of failed buffer resizes exceeded.\n");
free(buffp);
return 0;
}