List Detailed File System Information
Purpose
Returns detailed information for one or more file systems. It offers the ability to get information for file systems that have common names, common attributes, or that have encountered similar unexpected conditions.
IBM recommends that you use the List Detailed File System Information API instead of List Aggregate Status, List File System Status, List File System Names (Version 1) or List File System Names (Version 2).
Format
syscall_parmlist
opcode int 153 AGOP_FSINFO_PARMDATA
154 AGOP_FSINFO_RESET_PARMDATA
parms[0] int offset to FSINFO_REQUEST
parms[1] int 0
parms[2] int 0
parms[3] int 0
parms[4] int 0
parms[5] int 0
parms[6] int 0
FSINFO_REQUEST
fr_eye char[4] "FIRQ"
fr_length short Length of Structure
fr_sversion char Structure Version, must be 1
fr_reqtype char SingleQuery=0, NameCursor=1
fr_version char Version of input/output
buffer, must be 1
fr_output char Type of output/function selected, one of:
0 - Local statistics only, use only local
cache. Only allowed with
fr_nameSelection=2.
1 - Full sysplex-wide statistics
(including owner statistics).
2 - Reset statistics.
fr_nameSelection char Selection of aggregates desired, one of:
0 - When SingleQuery selected.
Options for fr_reqtype=1 (NameCursor):
1 - All aggregates. fr_output can be
1 (full) or 2 (reset).
2 - Aggregates known on the local system.
This is only allowed with fr_output
0 (local statistics).
3 - All aggregates matching a specific
pattern provided in fr_patternName.
fr_output can be 1 (full) or
2 (reset).
fr_eol char Indicates if a multi-aggregate read has
completed. 1 if yes, 0 if no.
fr_selection int Selection mask for aggregates meeting
certain state criteria. More than one bit
can be set. Note zFS will use an OR-ing
of the criteria so that aggregates that
meet one or more criteria are returned.
0 - all aggregates desired.
x1 - Show aggregates that have sysplex
thrashing objects.
x2 - Show aggregates that contain v5
directories with overflow pages.
x4 - Show aggregates mounted R/W.
x8 - Show aggregates mounted R/O.
x10 - Show aggregates that are disabled.
x20 - Show aggregates that are growing.
x40 - Show aggregates that are quiesced.
x80 - Show aggregates that had grow
failures.
x100 - Show aggregates that are low on
space, as defined by the zFS
bitmap manager.
x200 - Show aggregates that are damaged.
x400 - Show aggregates that are mounted
RWSHARE.
x800 - Show aggregates that are mounted
NORWSHARE.
x1000 - Show aggregates that had requests
x2000 - Show aggregates that had write
requests.
x4000 - Show aggregates where applications
saw ENOSPC errors.
x8000 - Show aggregates that had disk I/O
errors.
x10000 - Show aggregates that had XCF
timeouts between client systems
and owning systems (for RWSHARE
aggregates).
x20000 - Show aggregates that are version
1.4 aggregates.
x40000 - Show aggregates that are version
1.5 aggregates.
x80000 - Show aggregates that are
disabled for dynamic grow.
x100000 - Show aggregates that are
disabled for conversion to
version 1.5.
x80000000 - Tells zFS to use an AND-ing
method of examining criteria.
Hence only aggregates meeting
all criteria will be returned.
x801FFFFF - Represents all valid bits.
fr_entries unsigned int Number of aggregatess returned in output.
fr_nonFatalRc int Non-fatal error code.
fr_nonFatalRsn int Reason code if fr_nonFatalRc is non-zero.
fr_resumeName char[45] Dataset name to resume with for NameCursor
or the name of a single-aggregate query.
fr_patternName char[45] The aggregate name to be used. This can
contain wildcards.
fr_future2 char[2] For future use (reserved).
FSINFO_NAME
fn_eye char[4] "FINA"
fn_slength short Structure length.
fn_sversion short Structure version, must be 1.
fn_name char[44] Aggregate name.
fn_connected unsigned int Number of connected systems if owner
output is requested; 0 otherwise.
fn_owner char[8] System name of the owner.
fn_length unsigned int Total length of all information for this
aggregate.
fn_future char[4] For future use (reserved).
fn_sysnames char[8] Names of connected systems (32 at most).
FSINFO_OWNER
fo_eye char[4] "FIOW"
fo_length short Length of structure
fo_sversion short Structure version, must be 1.
fo_size unsigned int Number of 8K blocks in the aggregate.
fo_free unsigned int Number of unused 8K blocks in the
aggregate.
fo_frags unsigned long long int Number of free 1K fragments
available in the aggregate.
fo_logsize unsigned int Number of 8K blocks allocated to the log
file for transaction logging, including
indirect blocks.
fo_bitmapsize unsigned int Number of 8K blocks allocated to the
bitmap file, including indirect blocks.
fo_anodesize unsigned int Number of 8K blocks allocated to the
anode table.
fo_objects unsigned int Number of objects in the file system.
fo_version char Aggregate version number.
fo_threshold char Space monitoring threshold.
fo_increment char Space monitoring increment.
reserved1 char Reserved
fo_flags int Flag bits:
x01 - Mounted in R/W mode.
x02 - Disabled for access.
x04 - Grow failure occurred since
last reset.
x08 - Aggregate is low on space
(zfs definition).
x10 - Aggregate considered damaged by
salvage verification and not
repaired yet.
x20 - Aggregage using zFS sysplex sharing
(RWSHARE).
x40 - Dynamic grow set at mount time.
x80 - Aggregate is in the process of
growing at time of query.
x100 - converttov5 is set.
x200 - Aggregate is not mounted.
x400 - Aggregate is unowned.
x800 - Dynamic grow allowed, no grow
failures or since a grow failure
an admin grow was done.
x1000 - The quiesce is done for chgowner.
x2000 - converttov5 disabled.
x4000 - Aggregate version 1.4.
x8000 - Aggregate version 1.5.
fo_overflow unsigned int Number of overflow pages used in v5
directories.
fo_overflowhiwater unsigned int Hi-water mark of fo_overflow for life of
the file system.
fo_thrashing unsigned int Current number of objects using the
thrash-resolution protocol.
reserved2 char[4] Reserved.
fo_thrash_resolution unsigned long long int Number of thrash resolutions
performed since last statistics
reset.
fo_revocations unsigned long long int Number of token revocations
performed since last statistics
reset.
fo_revwait unsigned long long int Average revocation wait time in
microseconds.
fo_qsysname char[8] Name of system requesting quiesce, if the
aggregate is quiesced, 0 otherwise.
fo_jobname char[8] Name of job requesting the quiesce, if the
aggregate is quiesced, 0 otherwise.
fo_createtime unsigned long long int Creation time in seconds since
last epoch.
fo_ownership unsigned long long int Owership time in seconds since
last epoch.
fo_reset unsigned long long int Time statistic counters reset
in seconds since last epoch.
fo_quiesce unsigned long long int Quiesce time in seconds since
epoch, 0 if not quiesced.
fo_devno unsigned int z/OS UNIX device number.
fo_auditfid char[10] Audit fid for file system.
fo_qasid unsigned short ASID which issued the quiesce.
fo_growcount unsigned int Number of grows since mount.
reserved3 char[4] Reserved.
fo_growtime unsigned long long int Time of the last grow as known
by the owner.
FSINFO_LOCAL
fl_eye char[4] "FILO"
fl_length short Structure Length.
fl_sversion short Structure version.
fl_vnodes unsigned long long int Number of vnodes cached in
memory on the local system.
fl_ussheld unsigned long long int Number of vnodes held by USS.
fl_sysname char[8] System name stats are for.
fl_open unsigned long long int Number of open objects in the
file system.
fl_tokens unsigned long long int Number of tokens held from the
token manager.
fl_usercache unsigned int Number of 4K pages held in the
user cache for the file system.
fl_metacache unsigned int Number of 8K pages held in the
metadata cache.
fl_appreads unsigned long long int Number of application reads
done since last reset.
fl_appreadresp unsigned long long int Average read response time,
in microseconds.
fl_appwrites unsigned long long int Number of application writes
done since last reset.
fl_appwriteresp unsigned long long int Average write response time,
in microseconds.
fl_xcfreads unsigned long long int Number of XCF read calls made
to the owner since last reset.
fl_xcfreadresp unsigned long long int Average XCF read call response
time, in microseconds.
fl_xcfwrites unsigned long long int Number of XCF write calls made
to the server since last reset.
fl_xcfwriteresp unsigned long long int Average XCF write call response
time, in microseconds.
fl_enospc unsigned long long int Number of ENOSPC errors
returned to applications
since last reset.
fl_ioerrs unsigned long long int Number of disk I/O errors
since last reset.
fl_commerrs unsigned long long int Number of XCF communication
timeouts or failures since last
reset.
fl_cancels unsigned long long int Number of cancelled operations
since last reset by asynchronus
abends, cancels, or forces.
fl_ddname char[8] DDNAME during allocation of
aggregagte dataset.
fl_mounttime struct timeval64 Mount time in seconds since
the last epoch.
fl_numdasd unsigned int Number of DASD volumes listed
for aggregate in FSINFO_DASD
array.
fl_flags unsigned int 1 indicates this system has tasks
waiting on a quiesced FS.
FSINFO_DASD
fd_eye char[4] "FIDA"
fd_length short Structure Length.
fd_sversion short Structure version, must be 1.
fd_volser char[6] Volume serial.
fd_pavios short Number of I/Os zFS will issue
at one time for non-critical
I/Os.
fd_reads unsigned long long int Number of reads to this volume.
fd_readbytes unsigned long long int Number of kilobytes read.
fd_writes unsigned long long int Number of writes to this volume
fd_writebytes unsigned long long int Number of kilobytes written.
fd_waits unsigned long long int Number of times a zFS task had
to wait for an I/O to this
volume.
fd_waitTime unsigned long long int (includes all time, queue wait,
DASD response time etc.)
since last reset.
fd_resptime unsigned long long int Avg. wait time in microseconds.
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
ENOENT Specified data set is not found
EPERM Permission denied to perform request
Reason_code
0xEFnnxxxx See z/OS Distributed File Service Messages and Codes
Usage notes
- Users of the API supply an input buffer that contains a syscall_parmlist followed by an FSINFO_REQUEST structure. Output will be placed in this buffer after the FSINFO_REQUEST.
- A minimum length output buffer for a single-aggregate query is 10 K, and a minimum length output buffer for a multi-aggregate query is 64 K.
- A single specific aggregate can be queried by putting its name in fr_resumeName. The name must be null-terminated. Also specify fr_reqtype 0 (SingleQuery). This aggregate does not need to be attached. fr_selection and fr_nameSelection must also be 0.
- Multiple aggregate names can be specified by entering a string in fr_patternName that can contain a wildcard character ('*'). A wildcard can be specified at the beginning, at the end, or both at the beginning and the end of the string. The string must be null-terminated. The input string is converted to uppercase before it is processed. Use a fr_nameSelection value of 3 when specifying a wildcard, and a fr_reqtype of NameCursor (1).
- All attached aggregates can be specified by using fr_nameSelection value of 1 and a fr_reqtype value of NameCursor (1).
- If the output buffer cannot hold all of the returned information, fr_eol will be 0 and fr_resumeName will contain a value to be returned to zFS on the next query. Keep querying zFS until fr_eol is 1 to indicate that all information has been returned.
- Use fr_selection to return only aggregates that match the specified criteria in a multiple aggregate query. The options are defined in the Format section.
- fr_output determines the output of the request. Options are defined in the Format section.
- There is no file system information returned when a reset is requested (fr_output=2). A reset can only be requested when the opcode is 154 (AGOP_FSINFO_RESET_PARMDATA) and fr_selection is 0.
- Reserved fields and undefined flags must be set to binary zeros.
- Any names returned that are less than the full length of the field are null terminated. If the length of the name is equal to the length of the field that contains it, then it is not null terminated.
- Output consists of various structures following the FSINFO_REQUEST area in the buffer. For each aggregate that has information returned, first will be an FSINFO_NAME structure. This contains the name of an aggregate and the systems that are connected to it. Then, if present, will be the FSINFO_OWNER structure. This contains aggregate statistics and attributes as known by the owner. There can be no FSINFO_OWNER in some cases when the aggregate is unowned (fn_owner is *UNOWNED). This is followed by FSINFO_LOCAL structures. There are fn_connected FSINFO_LOCAL structures (if it is unowned), otherwise there are fn_connected+1 FSINFO_LOCAL structures. Each FSINFO_LOCAL structure is followed by fl_numdasd FSINFO_DASD structures to describe the DASD volumes that contain the zFS aggregate data set.
Privilege required
If a reset of the statistics values is requested and the fr_output field of the FSINFO_REQUEST structure contains the value 2, the issuer must be UID 0 or have READ authority to the SUPERUSER.FILESYS.PFSCTL resource in the z/OS UNIXPRIV class. Otherwise, no privilege is required.
Related services
- List Aggregate Status (Version 1)
- List Aggregate Status (Version 2)
- List Attached Aggregate Names (Version 1)
- List Attached Aggregate Names (Version 2)
- List File System Names (Version 1)
- List File System Names (Version 2)
- List File System Status
Restrictions
None.
Examples
#pragma linkage(BPX1PCT, OS)
#pragma LANGLVL(EXTENDED)
extern void BPX1PCT(char *, int, int, char *, int *, int *, int *);
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <time.h>
#define ZFSCALL_FSINFO 0x40000013
#define ZFS_MAX_AGGRNAME 44
#define AGOP_FSINFO_PARMDATA 153 /* Get status on aggr & fs */
#define BUFFER_SIZE 1024 * 64
#define FSINFO_XCF_ERR 0x1
#define FSINFO_IO_ERR 0x2
#define FSINFO_SPC_ERR 0x4
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[1]-parms[6] are currently unused*/
} syscall_parmlist;
struct timeval64 {
uint64_t tv_sec;
int32_t tv_usec_pad;
uint32_t tv_usec;
};
typedef struct FSINFO_REQUEST_t {
char fr_eye[4];
#define FR_EYE "FIRQ"
short fr_length;
char fr_sversion; /* Structure version. must be 1 */
char fr_reqtype; /*request type. BulkList=0, OffsetCursor=1*/
#define FR_REQTYPE_SINGLEQUERY 0
#define FR_REQTYPE_NAMECURSOR 1
char fr_version; /* Version of input/output buffer; must be 1*/
char fr_output; /* Type of output */
#define FR_OUT_LOCAL_STAT 0 /* Local stats from local system */
#define FR_OUT_FULL_STAT 1 /* Full stats from all systems*/
#define FR_OUT_RESET 2 /* reset statistics */
char fr_nameSelection; /* Selection of aggregates desired, one of: */
#define FR_NM_ALLAGGR 1 /* All aggregates */
#define FR_NM_LOCAL 2 /* Local aggregates */
#define FR_NM_PATTERN 3 /* All aggregates matching pattern */
char fr_eol; /* Indicates if a multi-aggregate
read has completed */
int fr_selection; /* Selection criteria of aggregates desired */
unsigned int fr_entries; /* Number of entries returned
by zFS (for OffsetCusor) */
int fr_nonFatalRc; /* Non-fatal error code */
int fr_nonFatalRsn; /* Reason code if fr_nonFatalRc is non-0 */
char fr_resumeName[45]; /* Dataset name to resume with for NameCursor or */
/* the name for the single-aggregate query.*/
char fr_patternName[45]; /* The pattern name to be used. */
char fr_future2[2];
} FSINFO_REQUEST;
typedef struct FSINFO_NAME_t
{
char fn_eye[4];
#define FN_EYE "FINA"
short fn_slength; /* Structure length */
short fn_sversion;
char fn_name[44]; /* aggregate name */
unsigned int fn_connected; /* number of conneceted systems if owner
output is included; 0 otherwise*/
char fn_owner[8]; /* system name of the owner */
unsigned int fn_length; /* Total length of all information for this
aggregate, so programs can quickly find the
beginning of the next record
in the output buffer. */
char fn_future[4];
char fn_sysnames[8]; /* Names of connected systems (32 at most).Actual
number is defined fn_connected.*/
} FSINFO_NAME;
typedef struct FSINFO_OWNER_t {
char fo_eye[4];
#define FSO_EYE "FIOW"
short fo_length;
short fo_sversion;
unsigned int fo_size; /* Num of 8K blocks in the aggregate */
unsigned int fo_free; /* Number of unused 8K blocks
in the aggregate.*/
unsigned long long int fo_frags; /* Num of free 1K fragments
available in the aggregate.*/
unsigned int fo_logsize; /* Num of 8K blocks allocated
to the log file for
transaction logging,
including indirect blocks.*/
unsigned int fo_bitmapsize; /* Number of 8K blocks allocated to the
bitmap file including indirect blocks.*/
unsigned int fo_anodesize; /* Number of 8K blocks allocated
to the anode table.*/
unsigned int fo_objects; /* Number of objects in the file system. */
char fo_version; /* Aggregate version number */
char fo_threshold; /* Space monitoring threshold */
char fo_increment; /* Space monitoring increment*/
char reserved1;
int fo_flags;
#define FO_OWNER_MNTRW 0x1 /* Mounted in RW mode */
#define FO_OWNER_DISABLED 0x2 /* Disabled for access */
#define FO_OWNER_GROWFAIL 0x4 /* Grow failure since last reset */
#define FO_OWNER_LOW_ONSPC 0x8 /* Low on space (zfs definition)*/
#define FO_OWNER_DAMAGED 0x10 /* Aggregate is damaged by salvage
verification & not repaired yet */
#define FO_OWNER_RWSHARE 0x20 /* Aggregate using zFS sysplex
sharing (RWSHARE) */
#define FO_OWNER_GROWSET 0x40 /* Dynamic grow set at mount time */
#define FO_OWNER_GROWING 0x80 /* Aggregate is in the process
of growing at the time of query */
#define FO_CONVERTOV5 0x100 /* CONVERTTOV5 parm is set on mount. */
#define FO_NOTMOUNT 0x200 /* Aggregate is not mounted */
#define FO_NO_OWNER 0x400 /* Aggregate is un-owned */
#define FO_OWNER_ALLOWGROW 0x800 /* Dynamic grow allowed , no
grow failures or since a grow
failure an admin grow was done. */
#define FO_OWNER_CHGOWNER 0x1000 /* The quiesce is done for a
chgowner instead of a backup */
#define FO_CONVERTTOV5_DISABLED 0x2000 /* CONVERTTOV5 is disabled
due to quiesce or failed convert */
#define FO_V4 0x4000 /* Aggregate with version 1.4 */
#define FO_V5 0x8000 /* Aggregate with version 1.5 */
unsigned int fo_overflow; /* Num of overflow pages used for v5 directories */
unsigned int fo_overflowhiwater; /* Hiwater mark of fo_overflow
for life of file system.*/
unsigned int fo_thrashing; /* Current number of objects using
the thrash-resolution protocol*/
char reserved2[4];
unsigned long long int fo_thrash_resolution; /* Number of thrash resolutions
performed since last
statistics reset.*/
unsigned long long int fo_revocations; /* Number of token revocations
performed since last
statistics reset*/
unsigned long long int fo_revwait; /* Average revocation wait time
in microseconds.*/
char fo_qsysname[8]; /* Name of system requesting quiesce,
if the aggregate is quiesced,
0 otherwise.*/
char fo_jobname[8]; /* Name of job requesting quiesce,
if the aggregate is quiesced,
0 otherwise.*/
unsigned long long int fo_createtime; /* Creation time in
seconds since epoch*/
unsigned long long int fo_ownership; /* Owership time in
seconds since epoch*/
unsigned long long int fo_reset; /* Time statistic counters reset in
seconds since last epoch*/
unsigned long long int fo_quiesce; /* Quiesce time in seconds since
epoch, 0 if file system
not quiesced.*/
unsigned int fo_devno; /* Devno for the mount*/
char fo_auditfid[10]; /* Audit fid for file system*/
unsigned short fo_qasid; /* ASID which issued the quiesce */
unsigned int fo_growcount; /* Number of grows since mount. */
char reserved3[4];
unsigned long long int fo_growtime; /* Time of the last grow
as known by owner */
} FSINFO_OWNER;
typedef struct FSINFO_LOCAL_t {
char fl_eye[4];
#define FL_EYE "FILO"
short fl_length;
short fl_sversion; /* Structure version */
unsigned long long int fl_vnodes; /* Number of vnodes cached in memory
on the local system */
unsigned long long int fl_ussheld; /* Number of USS held vnodes*/
char fl_sysname[8]; /* System name these stats are for */
unsigned long long int fl_open; /* Number of open objects in
the file system */
unsigned long long int fl_tokens; /* Number of tokens held from
the token manager */
unsigned int fl_usercache; /* Number of 4K pages held in the
user cache for the file system */
unsigned int fl_metacache; /* Number of 8k pages held in
the metadata cache */
unsigned long long int fl_appreads; /* Number of application reads made
since last reset */
unsigned long long int fl_appreadresp; /* Average read response
time in microseconds*/
unsigned long long int fl_appwrites; /* Number of application writes
made since last reset */
unsigned long long int fl_appwriteresp; /* Average write response
time in microseconds*/
unsigned long long int fl_xcfreads; /* Number of xcf read calls made
to the owner since last reset */
unsigned long long int fl_xcfreadresp; /* Average xcf read call response
time in microseconds*/
unsigned long long int fl_xcfwrites; /* Number of xcf write calls made to
the server since last reset */
unsigned long long int fl_xcfwriteresp; /* Average xcf write call response
time in microseconds*/
unsigned long long int fl_enospc; /* Number of ENOSPC errors returned
to apps since last reset */
unsigned long long int fl_ioerrs; /* Number of disk IO errors
since last reset*/
unsigned long long int fl_commerrs; /* Number of XCF communication timeouts
or failures since last reset*/
unsigned long long int fl_cancels; /* Number of cancelled operations
since last reset by asynchronus
abends, cancel, forces and EOMs */
char fl_ddname[8]; /* DDNAME of allocation of dataset */
struct timeval64 fl_mounttime; /* Mount time, seconds since epoch */
unsigned int fl_numdasd; /* Number of DASD volumes listed for
aggregate in FSINFO_DASD array */
unsigned int fl_flags; /* 1 indicates if this system has
tasks waiting on a quiesced FS.*/
} FSINFO_LOCAL;
typedef struct FSINFO_DASD_t
{
char fd_eye[4];
#define FSD_EYE "FIDA"
short fd_length;
short fd_sversion;
#define FSD_VER_INITIAL 1
char fd_volser[6];
short fd_pavios;
unsigned long long int fd_reads;
unsigned long long int fd_readbytes;
unsigned long long int fd_writes;
unsigned long long int fd_writebytes;
unsigned long long int fd_waits;
unsigned long long int fd_waitTime;
unsigned long long int fd_resptime;
} FSINFO_DASD;
void check_local_error(char *buffp, FSINFO_REQUEST *fs_req, int *lerr_stat);
int main(int argc, char **argv)
{
char* buffp = NULL;
syscall_parmlist* parmp = NULL;
FSINFO_REQUEST* fs_req = NULL;
char owner_sys[9];
int buff_fill_len = 0;
int fs_ownerlen = 0;
int fs_locallen = 0;
int unowned = 0;
int fr_nonFatalRc = 0;
int fr_nonFatalRsn = 0;
int sperr = 0;
int ioerr = 0;
int xcferr = 0;
int lerr_stat = 0;
int bpxrv, bpxrc, bpxrs;
int i, j, k;
unsigned long long int most_writes = 0;
char busiest_volume[7];
int locals = 0;
/* aggrname for fsinfo */
char aggrname[ZFS_MAX_AGGRNAME+1] = "PLEX.DCEIMGQY.FS";
/* Output structure pointers */
FSINFO_NAME* fs_namep = NULL;
FSINFO_OWNER* fs_ownerp = NULL;
FSINFO_LOCAL* fs_localp = NULL;
FSINFO_DASD * fs_dasdp = NULL;
char* outputp = NULL;
/* Allocate buffer */
buffp = (char*) malloc(BUFFER_SIZE);
if( buffp == NULL )
{
printf("Malloc Error\n");
return 0;
}
/* Set the parmdata */
parmp = (syscall_parmlist*) &buffp[0];
parmp->opcode = AGOP_FSINFO_PARMDATA;
parmp->parms[0] = buff_fill_len = sizeof(syscall_parmlist);
parmp->parms[1] = 0;
parmp->parms[2] = 0;
parmp->parms[3] = 0;
parmp->parms[4] = 0;
parmp->parms[5] = 0;
parmp->parms[6] = 0;
fs_req = (FSINFO_REQUEST*) &buffp[buff_fill_len];
memset( fs_req, 0x00, sizeof(FSINFO_REQUEST) );
/* First obtain the statistics for all file systems. We will look */
/* through them to find the DASD volume with the most write operations. */
memcpy( fs_req->fr_eye, FR_EYE, sizeof(fs_req->fr_eye) );
fs_req->fr_length = sizeof(FSINFO_REQUEST);
fs_req->fr_sversion = 1;
fs_req->fr_version = 1;
fs_req->fr_reqtype = FR_REQTYPE_NAMECURSOR;
fs_req->fr_output = FR_OUT_FULL_STAT;
fs_req->fr_nameSelection = FR_NM_ALLAGGR;
buff_fill_len += sizeof(FSINFO_REQUEST);
/* Loop getting file system information from zFS until we have it all. */
do
{
/* Call zFS. */
printf("call zfs\n");
BPX1PCT("ZFS ",
ZFSCALL_FSINFO, /* Aggregate operation */
BUFFER_SIZE, /* 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 )
{
printf("Error getting fsinfo for aggregate %s\n", aggrname);
printf("Return Value: %d Return Code: %d Reason Code: %x\n",
bpxrv, bpxrc, bpxrs);
goto done;
}
if( fs_req->fr_nonFatalRc )
{
fr_nonFatalRc = fs_req->fr_nonFatalRc;
fr_nonFatalRsn = fs_req->fr_nonFatalRsn;
goto print_non_fatals;
}
/* The first structure pointed by output buffer is FSINFO_NAME.*/
fs_namep = (FSINFO_NAME *) &buffp[buff_fill_len];
for (i=0; i<fs_req->fr_entries; i++)
{
fs_ownerp = (FSINFO_OWNER *)((char *)fs_namep+fs_namep->fn_slength);
locals = fs_namep->fn_connected;
/* If file system has an owner, there will be one more */
/* FSINFO_LOCAL structure returned than this count. */
if (memcmp(fs_namep->fn_owner, "*UNOWNED") != 0)
locals++;
/* Determine if there is an FSINFO_OWNER or not. */
/* If not, then the structure should be an FSINFO_LOCAL. */
if (memcmp(fs_ownerp->fo_eye, FSO_EYE, 4) == 0)
{ /* FSINFO_OWNER returned */
fs_localp = (FSINFO_LOCAL *)((char *)fs_ownerp+fs_ownerp->fo_length);
}
else if (memcmp(fs_ownerp->fo_eye, FL_EYE, 4) == 0)
{
/* No FSINFO_OWNER returned. It's FSINFO_LOCAL */
fs_localp = (FSINFO_LOCAL *)fs_ownerp;
fs_ownerp = NULL;
}
else
{
/* Should not get here!! */
printf("Error exit: Incorrect structure sequence!!\n");
goto done;
}
/* Loop through each FSINFO_LOCAL structure returned. */
for (j=0; j<locals; j++)
{
fs_dasdp = (FSINFO_DASD *)((char *)fs_localp + fs_localp->fl_length);
for (k=0; k<fs_localp->fl_numdasd; k++)
{
/* Determine if this DASD volume has more writes than the */
/* previously higher one. Yes, remember DASD volume name. */
if (fs_dasdp->fd_writes > most_writes)
{
strncpy(busiest_volume, fs_dasdp->fd_volser, 6);
busiest_volume[6] = 0;
most_writes = fs_dasdp->fd_writes;
}
/* Set up for next iteration. */
fs_dasdp = (FSINFO_DASD *)((char *)fs_dasdp + fs_dasdp->fd_length);
}
/* After looping through all FSINFO_DASD structures, fs_dasdp */
/* should be pointing at the next FSINFO_LOCAL structure. */
fs_localp = (FSINFO_LOCAL *)fs_dasdp;
}
/* Get ready for next loop iteration. */
fs_namep = (FSINFO_NAME *)((char *)fs_namep+fs_namep->fn_length);
}
}
while (!fs_req->fr_eol);
printf("DASD volume %s has the most writes (%llu)\n",
busiest_volume, most_writes);
/* Now do a single aggregate query for a specific file system. */
memset( fs_req, 0x00, sizeof(FSINFO_REQUEST));
memcpy( fs_req->fr_eye, FR_EYE, sizeof(fs_req->fr_eye) );
fs_req->fr_length = sizeof(FSINFO_REQUEST);
fs_req->fr_sversion = 1;
fs_req->fr_version = 1;
fs_req->fr_output = FR_OUT_FULL_STAT;
fs_req->fr_reqtype = FR_REQTYPE_SINGLEQUERY;
memcpy( fs_req->fr_resumeName, aggrname, ZFS_MAX_AGGRNAME+1 );
BPX1PCT("ZFS ",
ZFSCALL_FSINFO, /* Aggregate operation */
BUFFER_SIZE, /* 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 )
{
printf("Error getting fsinfo for aggregate %s\n", aggrname);
printf("Return Value: %d Return Code: %d Reason Code: %x\n",
bpxrv, bpxrc, bpxrs);
goto done;
}
if( fs_req->fr_nonFatalRc )
{
fr_nonFatalRc = fs_req->fr_nonFatalRc;
fr_nonFatalRsn = fs_req->fr_nonFatalRsn;
goto print_non_fatals;
}
buff_fill_len = sizeof(syscall_parmlist) + sizeof(FSINFO_REQUEST);
outputp = buffp + buff_fill_len;
check_local_error(outputp, fs_req, &lerr_stat);
/* The first structure pointed by output buffer would be FSINFO_NAME. */
fs_namep = (FSINFO_NAME *) &buffp[buff_fill_len];
fs_ownerp = (FSINFO_OWNER *) ((char*) fs_namep + fs_namep->fn_slength);
memcpy(owner_sys, fs_namep->fn_owner, 8);
owner_sys[8] = '\0';
if (memcmp(&owner_sys[0], "*UNOWNED", 8) == 0)
{
unowned = 1;
if (memcmp(fs_ownerp->fo_eye, FSO_EYE, 4) == 0)
{ /* FSINFO_OWNER returned */
fs_localp = (FSINFO_LOCAL *)((char *)fs_ownerp + fs_ownerp->fo_length);
}
else if (memcmp(fs_ownerp->fo_eye, FL_EYE, 4) == 0)
{
/* No FSINFO_OWNER returned. It's FSINFO_LOCAL */
fs_localp = (FSINFO_LOCAL *)fs_ownerp;
fs_ownerp = NULL;
}
}
else if (fs_ownerp->fo_flags & FO_NO_OWNER)
{
unowned = 1;
fs_localp = (FSINFO_LOCAL *)((char *)fs_ownerp + fs_ownerp->fo_length);
}
else
fs_localp = (FSINFO_LOCAL *)((char *)fs_ownerp + fs_ownerp->fo_length);
if ((lerr_stat & FSINFO_SPC_ERR) == FSINFO_SPC_ERR)
{
fs_localp->fl_enospc = 1;
sperr = 1;
}
if ((lerr_stat & FSINFO_IO_ERR) == FSINFO_IO_ERR)
{
fs_localp->fl_ioerrs = 1;
ioerr = 1;
}
if ((lerr_stat & FSINFO_XCF_ERR) == FSINFO_XCF_ERR)
{
fs_localp->fl_commerrs = 1;
xcferr = 1;
}
if( unowned && !fs_ownerp )
{
if (!xcferr && !ioerr && !sperr)
printf("%-44.44s %-8.8s n/a \n\n",
aggrname, "*UNOWNED");
else
{
printf("%-44.44s %-8.8s %s%s%s \n\n",
aggrname, "*UNOWNED",
(sperr)? "SE" :"",
(ioerr)?((sperr)?",IE":"IE"):"",
(xcferr)?((sperr || ioerr)?",CE":"CE"):"");
/* Define the flags in a legend */
printf("Legend: %s%s%s\n\n",
(sperr)? "SE = Space errors reported":"",
(ioerr)?
((sperr)? ",IE = IO errors reported":
"IE = IO errors reported") : "",
(xcferr)?
((sperr || ioerr)?
",CE = Communication errors reported":
"CE = Communication errors reported") : "");
}
}
else
{
/* Print the aggregate info with flags */
printf("%-44.44s %-8.8s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s \n\n",
aggrname, fs_namep->fn_owner,
(fs_ownerp->fo_flags & FO_NOTMOUNT) ? "NM" : "",
/* Multiple Conditions */
(!(fs_ownerp->fo_flags & FO_NOTMOUNT) &&
(fs_ownerp->fo_flags & FO_OWNER_MNTRW)) ? "RW" :
((fs_ownerp->fo_flags & FO_NOTMOUNT) ? "" : "RO"),
/* Multiple Conditions */
(!(fs_ownerp->fo_flags & FO_NOTMOUNT) &&
(fs_ownerp->fo_flags & FO_OWNER_RWSHARE)) ? ",RS" :
((fs_ownerp->fo_flags & FO_NOTMOUNT) ? "" : ",NS"),
(fs_ownerp->fo_thrashing) ? ",TH" : "",
(fs_ownerp->fo_qsysname[0] != '\0') ? ",Q" : "",
(fs_ownerp->fo_flags & FO_OWNER_DISABLED) ? ",DI" : "",
(fs_ownerp->fo_flags & FO_OWNER_GROWING) ? ",GR" : "",
(fs_ownerp->fo_flags & FO_OWNER_GROWFAIL) ? ",GF" : "",
/* Multiple Conditions */
(!(fs_ownerp->fo_flags & FO_NOTMOUNT) &&
!(fs_ownerp->fo_flags & FO_OWNER_ALLOWGROW)) ? ",GD" : "",
(fs_ownerp->fo_flags & FO_OWNER_DAMAGED) ? ",DA" : "",
(fs_ownerp->fo_flags & FO_OWNER_LOW_ONSPC) ? ",L" : "",
(sperr) ? ",SE" : "",
(fs_ownerp->fo_flags & FO_OWNER_DISABLED) ? ",DI" : "",
(ioerr) ? ",IE" : "",
(xcferr) ? ",CE" : "");
/* Define the flags in a legend */
printf("Legend: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s \n\n",
(fs_ownerp->fo_flags & FO_NOTMOUNT) ? "NM = Not mounted" : "",
/* Multiple Conditions */
(!(fs_ownerp->fo_flags & FO_NOTMOUNT) &&
(fs_ownerp->fo_flags & FO_OWNER_MNTRW)) ? "RW = Read-write" :
((fs_ownerp->fo_flags & FO_NOTMOUNT) ? "" : "RO = Read-only"),
/* Multiple Conditions */
(!(fs_ownerp->fo_flags & FO_NOTMOUNT) &&
(fs_ownerp->fo_flags & FO_OWNER_RWSHARE)) ?
",RS = Mounted RWSHARE" : ((fs_ownerp->fo_flags & FO_NOTMOUNT) ?
"" : ",NS = Mounted NORWSHARE"),
(fs_ownerp->fo_thrashing) ? ",TH = Thrashing" : "",
(fs_ownerp->fo_qsysname[0] != '\0') ? ",Q = Queisced" : "",
(fs_ownerp->fo_flags & FO_OWNER_DISABLED) ?
",DI = Disabled" : "",
(fs_ownerp->fo_flags & FO_OWNER_GROWING) ?
",GR = Growing" : "",
(fs_ownerp->fo_flags & FO_OWNER_GROWFAIL) ?
",GF = Grow Failed": "",
/* Multiple Conditions */
(!(fs_ownerp->fo_flags & FO_NOTMOUNT) &&
!(fs_ownerp->fo_flags & FO_OWNER_ALLOWGROW)) ?
",GD = AGGRGROW disabled" : "",
(fs_ownerp->fo_flags & FO_OWNER_DAMAGED) ?
",DA = Damaged" : "",
(fs_ownerp->fo_flags & FO_OWNER_LOW_ONSPC) ?
",L = Low on space": "",
(sperr) ? ",SE = Space errors reported":"",
(fs_ownerp->fo_flags & FO_OWNER_DISABLED) ?
",DI = Disabled" : "",
(ioerr) ? ",IE = IO errors reported" : "",
(xcferr) ? ",CE = Communication errors reported":"");
}
goto done;
print_non_fatals:
if( fr_nonFatalRc )
{
printf("Non-Fatal errors:\n");
printf("Return Code: %d Reason Code: %x\n\n",
fr_nonFatalRc, fr_nonFatalRsn);
}
done:
free(buffp);
return 0;
}
void check_local_error(char *buffptr, FSINFO_REQUEST *fs_req, int *lerr_stat)
{
FSINFO_NAME * fs_namep;
FSINFO_OWNER * fs_ownerp = NULL;
FSINFO_LOCAL * fs_local;
FSINFO_DASD * dasdp;
int dasd_space;
int i, j;
int total_sys = 0;
int unowned = 0;
if ((*lerr_stat) == (FSINFO_XCF_ERR | FSINFO_IO_ERR | FSINFO_SPC_ERR))
{
printf("FSINFO_CheckLocalErr: all 3 bits are set in *lerr_stat=%X\n",
*lerr_stat);
return ;
}
/* The first structure pointed by output buffer would be FSINFO_NAME. */
fs_namep = (FSINFO_NAME *)((char *)buffptr);
fs_ownerp = (FSINFO_OWNER *)((char *)fs_namep + fs_namep->fn_slength);
/* if UNOWNED, make sure we are processing the right stats. */
if (memcmp(&fs_namep->fn_owner, "*UNOWNED", 8) == 0)
{
unowned = 1;
if (memcmp(fs_ownerp->fo_eye, FSO_EYE, 4) == 0)
{ /* FSINFO_OWNER block */
fs_local = (FSINFO_LOCAL *)((char *)fs_ownerp + fs_ownerp->fo_length);
}
else if (memcmp(fs_ownerp->fo_eye, FL_EYE, 4) == 0)
{ /* FSINFO_LOCAL block */
fs_local = (FSINFO_LOCAL *)((char *)fs_ownerp + fs_ownerp->fo_length);
fs_ownerp = NULL;
}
else
{ /* We should not get here!! */
return;
}
}
else
fs_local = (FSINFO_LOCAL *)((char *)fs_ownerp + fs_ownerp->fo_length);
/* If FSINFO_OWNER is not returned, we have 1 less FSINFO_LOCAL to process */
if (unowned && (fs_ownerp == NULL))
total_sys = fs_namep->fn_connected;
else
total_sys = fs_namep->fn_connected+1;
for (i=0; i < total_sys; i++)
{
if (fs_local->fl_commerrs)
(*lerr_stat) |= FSINFO_XCF_ERR;
if (fs_local->fl_enospc)
(*lerr_stat) |= FSINFO_SPC_ERR;
if (fs_local->fl_ioerrs)
(*lerr_stat) |= FSINFO_IO_ERR;
if ((*lerr_stat) == (FSINFO_XCF_ERR | FSINFO_IO_ERR | FSINFO_SPC_ERR))
return ;
/* Find the next FSINFO_LOCAL structure, which is after any FSINFO_DASD */
/* structures that might be present. */
if (fs_local->fl_numdasd > 0)
{
dasdp = (FSINFO_DASD *)((char *)fs_local + fs_local->fl_length);
dasd_space = fs_local->fl_numdasd * dasdp->fd_length;
}
else
dasd_space = 0;
fs_local = (FSINFO_LOCAL *)((char *)fs_local + fs_local->fl_length +
dasd_space);
}
return;
}