Statistics User Cache Information

Purpose

A performance statistics operation that returns user cache information.

Format

Start of change
syscall_parmlist
   opcode               int              242    STATOP_USER_CACHE
   parm[0]              int              Offset to STAT_API
   parm[1]              int              Offset of output following STAT_API   
   parm[2]              int              Offset to system name (optional)
   parm[3]              int              0
   parm[4]              int              0
   parm[5]              int              0
   parm[6]              int              0
STAT_API                                
   sa_eye               char[4]          "STAP"
   sa_len               int              Length of buffer that follows STAT_API
   sa_ver               int              1 or 2
   sa_flags             char[1]          0x80 for reset; 0x00 otherwise
   sa_fill              char[3]          Reserved
   sa_supported_ver     int              Version of data returned when sa_ver
                                         is 2
   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
   pad1                 int              Reserved

STAT_USER_CACHE[2]
   VM_STATS[2]
       vm_schedules          unsigned int      Number of I/O requests
       vm_setattrs           unsigned int      Number of setattr requests
       vm_fsyncs             unsigned int      Number of fsync operations
       vm_unmaps             unsigned int      Number of file deletions
       vm_reads              unsigned int      Number of read operations
       vm_readasyncs         unsigned int      Number of readaheads
       vm_writes             unsigned int      Number of write operations
       vm_getattrs           unsigned int      Number of getattr requests
       vm_flushes            unsigned int      Number of cache flushes
       vm_scheduled_deletes  unsigned int      Number of times an I/O is
                                               canceled because the file was
                                               deleted
       vm_reads_faulted      unsigned int      Number of times I/O needed to
                                               satisfy read operation
                                               (data was not in cache)
       vm_writes_faulted     unsigned int      Number of times I/O needed to
                                               read data before data can be
                                               written to cache
       vm_read_ios           unsigned int      Total number of file system
                                               reads for any reason
       vm_scheduled_writes   unsigned int      Number of data write I/Os issued
       vm_error_writes       unsigned int      Number of data writes done when
                                               flushing a file from the cache
                                               after an I/O error or canceled
                                               user
  
End of change Start of change
       vm_reclaim_writes     unsigned int      Number of data writes during
                                               space reclaim
       vm_read_waits         unsigned int      Number of times a read had to
                                               wait for pending I/O
       vm_write_waits        unsigned int      Number of waits for pending I/O
                                               so that new data could be
                                               written to the file
       vm_fsync_waits        unsigned int      Number of waits for pending I/O
                                               fsync operations did
       vm_error_waits        unsigned int      Number of waits when flushing a
                                               file from the cache after an I/O
                                               error or canceled user
       vm_reclaim_waits      unsigned int      Number of waits done during
                                               reclaim processing for I/O
       vm_reclaim_steal      unsigned int      Number of pages stolen during
                                               space reclaim processing
       vm_waits_for_reclaim  unsigned int      Number of waits for reclaim
                                               processing to complete
       vm_reserved           int[10]           Reserved
    suc dataspaces           int               Number of dataspaces in user
                                               data cache
    suc pages_per_dataspace  int               Number of pages per dataspace
    suc seg_size_local       int               Local segment size (in K)
    suc seg_size_remote      int               Remote segment size (in K)
    suc page_size            int               Page size (in K)
    suc cache_pages          int               Number of pages in user cache
    suc total_free           int               Number of free pages
    suc segment_cachesize    int               Number of segments
    stuc_reserved            int[5]            Reserved
    DS_ENTRY[32]
       ds_name               char[9]           Dataspace name
       pad1                  char[3]           Reserved
       ds_alloc_segs         int               Number of used (allocated)
                                               segments in the dataspace
       ds_free_pages         int               Number of free dataspace pages
       ds_reserved           int[5]            Reserved
STAT_USER_CACHE2
   VM_STATS2
      vm_schedules           unsigned long long int  Number of I/O requests
      vm_setattrs            unsigned long long int  Number of setattrs
      vm_fsyncs              unsigned long long int  Number of fysnc operations
      vm_unmaps              unsigned long long int  Number of file deletions
      vm_reads               unsigned long long int  Number of read operations
      vm_readasyncs          unsigned long long int  Number of readaheads
      vm_writes              unsigned long long int  Number of write operations
      vm_getattrs            unsigned long long int  Number of getattrs
      vm_flushes             unsigned long long int  Number of times the
                                                     user cache was flushed

      vm_scheduled_deletes   unsigned long long int  Number of times an I/O
                                                     is canceled because the
                                                     file was deleted
End of change Start of change
      vm_reads_faulted       unsigned long long int  Number of times I/O needed
                                                     to satisfy read operation
                                                     (data was not in cache)
      vm_writes_faulted      unsigned long long int  Number of times I/O needed
                                                     to read data before data
                                                     can be written to cache
      vm_read_ios            unsigned long long int  Total number of file
                                                     system reads for any
                                                     reason
      vm_scheduled_writes    unsigned long long int  Number of data write
                                                     I/Os issued
      vm_error_writes        unsigned long long int  Number of data writes
                                                     when flushing a file
                                                     from the cache after
                                                     an I/O error or a
                                                     canceled user
      vm_reclaim_writes      unsigned long long int  Number of data writes
                                                     during space reclaim
      vm_read_waits          unsigned long long int  Number of times a read had
                                                     to wait for pending I/O
      vm_write_waits         unsigned long long int  Number of waits for a
                                                     pending I/O so that new
                                                     data could be written to
                                                     the file
      vm_fsync_waits         unsigned long long int  Number of waits for
                                                     pending I/O fsync
                                                     operations did
      vm_error_waits         unsigned long long int  Number of waits in
                                                     user cache error
                                                     processing      
      vm_reclaim_waits       unsigned long long int  Number of waits done
                                                     during the reclaim
                                                     processing for I/O
      vm_reclaim_steal       unsigned long long int  Number of user cache
                                                     pages stolen during
                                                     reclaim processing
      vm_waits_for_reclaim   unsigned long long int  Number of waits for
                                                     space reclaim process
                                                     to complete
      vm_reserved            unsigned long long int[10]  Reserved
    suc dataspaces           int                     Number of dataspaces in
                                                     user data cache
    suc pages_per_dataspace  int                     Number of pages per
                                                     dataspace
    suc seg_size_local       int                     Local segment size (in K)
    suc seg_size_remote      int                     Remote segment size (in K)
    suc page_size            int                     Page size (in K)
    suc cache_pages          int                     Number of pages in cache
    suc total_free           int                     Number of free pages
    suc segment_cachesize    int                     Number of segments
    stuc_reserved            int[5]                  Reserved
    DS_ENTRY[32]
      ds_name                char[9]                 Dataspace name
      pad1                   char[3]                 Reserved
      ds_alloc_segs          int                     Number of used segments in
                                                     dataspace
      ds_free_pages          int                     Number of free pages in
                                                     dataspace
      ds_reserved             int[5]                 Reserved
   reserved                  char[4]                 Reserved
systemname                   char[9]                 Name of system to get
                                                     statistics from
End of change Start of change
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

Reason code
  0xEFxxnnnn     See z/OS Distributed File Service Messages and Codes
End of change

Usage notes

  • Reserved fields and undefined flags must be set to binary zeros.
  • Start of changeWhen sa_supported_ver is 0 or 1, the output consists of STAT_USER_CACHE[2] and DS_ENTRY.End of change
  • Start of changeWhen sa_supported_ver is 2 the output consists of STAT_USER_CACHE2 and DS_ENTRY.End of change

Privilege required

None.

Related services

  • Statistics Locking Information
  • Statistics Storage 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_USER_CACHE 242 /* Performance API queries */
#define NUM_DATASPACES    32
#define REMOTE            1
#define LOCAL             0

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 {
  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 user data cache statistics */
/*********************************************************************/
typedef struct vm_stats_2_t
{
  /**********************************************************************/
  /* First set of counters are for external requests to the VM system.  */
  /**********************************************************************/
  unsigned long long int vm_schedules;
  unsigned long long int vm_setattrs;
  unsigned long long int vm_fsyncs;
  unsigned long long int vm_unmaps;
  unsigned long long int vm_reads;
  unsigned long long int vm_readasyncs;
  unsigned long long int vm_writes;
  unsigned long long int vm_getattrs;
  unsigned long long int vm_flushes;
  unsigned long long int 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).                          */
  /**********************************************************************/
  unsigned long long int vm_reads_faulted;
  unsigned long long int vm_writes_faulted;
  unsigned long long int vm_read_ios;

  /**********************************************************************/
  /* Next counters are write counters.  They measure number of times    */
  /* we scheduled and waited for write I/Os.                            */
  /**********************************************************************/
  unsigned long long int vm_scheduled_writes;
  unsigned long long int vm_error_writes;
  unsigned long long int 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.    */
  /**********************************************************************/
  unsigned long long int vm_read_waits;
  unsigned long long int vm_write_waits;
  unsigned long long int vm_fsync_waits;
  unsigned long long int vm_error_waits;
  unsigned long long int vm_reclaim_waits; /* Waited for pending 
                                              I/O for reclaim */

  /**********************************************************************/
  /* Final set are memory management counters.                          */
  /**********************************************************************/
  unsigned long long int vm_reclaim_steal;       /* Number of times steal from
                                                    others function invoked */
  unsigned long long int vm_waits_for_reclaim;   /* Waits for reclaim thread */
  unsigned long long int vm_reserved[10];        /*reserved for future use*/
} VM_STATS_2;

typedef struct stat_user_cache_2_t
{
   /*Various statistics for both LOCAL and REMOTE systems */
  VM_STATS_2 stuc;                 
  
  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) */ 
  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 for future use*/     
  DS_ENTRY   stuc_ds_entry[NUM_DATASPACES];  /* Array of dataspace entries */
  char       reserved[4];
} STAT_USER_CACHE_2;

/* Version 1 Output Structures */

/*********************************************************************/
/* 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. */
  /**********************************************************************/
  unsigned int            vm_schedules;
  unsigned int            vm_setattrs;
  unsigned int            vm_fsyncs;
  unsigned int            vm_unmaps;
  unsigned int            vm_reads;
  unsigned int            vm_readasyncs;
  unsigned int            vm_writes;
  unsigned int            vm_getattrs;
  unsigned int            vm_flushes;
  unsigned int            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).                           */
  /**********************************************************************/
  unsigned int            vm_reads_faulted;
  unsigned int            vm_writes_faulted;
  unsigned int            vm_read_ios;
  /**********************************************************************/
  /* Next counters are write counters. They measure number of times     */
  /* we scheduled and waited for write I/Os.                            */
  /**********************************************************************/
  unsigned int            vm_scheduled_writes;
  unsigned int            vm_error_writes;
  unsigned int            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.    */
  /**********************************************************************/
  unsigned int            vm_read_waits;
  unsigned int            vm_write_waits;
  unsigned int            vm_fsync_waits;
  unsigned int            vm_error_waits;
  unsigned int            vm_reclaim_waits; /* Waited for pending 
                                               I/O for reclaim */

  /**********************************************************************/
  /* Final set are memory management counters.                          */
  /**********************************************************************/
  unsigned int            vm_reclaim_steal;     /* Number of times steal from 
                                                   others function invoked */
  unsigned int            vm_waits_for_reclaim; /* Waits for reclaim thread */
  unsigned int            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) */
  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;

/*********************************************************************/
/* 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;

struct parmstruct {
  syscall_parmlist  myparms;
  STAT_API          myapi;
  STAT_USER_CACHE_2 mystats;
  char              systemname[9];
} myparmstruct;

int print_user_cache_version1(STAT_USER_CACHE   *stcacheptr);
int print_user_cache_version2(STAT_USER_CACHE_2 *stcacheptr);

int main(int argc, char **argv) 
{
  int      bpxrv;
  int      bpxrc;
  int      bpxrs;
  int      i,j;
  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_2);  */

  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 = (int) sizeof(STAT_USER_CACHE_2);

  /* 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 
  {
    if( stapptr->sa_supported_ver == SA_VER_INIT )
    {
      STAT_USER_CACHE *stcacheptr_v1;
      stcacheptr_v1 = (STAT_USER_CACHE*) &(myparmstruct.mystats);
      print_user_cache_version1(stcacheptr_v1);
    }
    else
    {
      STAT_USER_CACHE_2 *stcacheptr = &(myparmstruct.mystats);
      print_user_cache_version2(stcacheptr);
    }

    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;
}

int print_user_cache_version2(STAT_USER_CACHE_2* stcacheptr)
{
  int i;
  double   ratio1, ratio2, ratio3, ratio4;
  printf("                   User File (VM) Caching System Statistics\n");
  printf("                   ----------------------------------------\n");
  printf("\n");

  printf("                   Direct Statistics\n");
  printf("                   -----------------\n\n");

  printf("External Requests:\n");
  printf("------------------\n");
  printf("%-9s %20llu     %-9s %20llu     %-9s %20llu\n",
         "Reads"    , stcacheptr->stuc.vm_reads,
         "Fsyncs"   , stcacheptr->stuc.vm_fsyncs,
         "Schedules", stcacheptr->stuc.vm_schedules);
  printf("%-9s %20llu     %-9s %20llu     %-9s %20llu\n",
         "Writes"   , stcacheptr->stuc.vm_writes,
         "Setattrs" , stcacheptr->stuc.vm_setattrs,
         "Unmaps"   , stcacheptr->stuc.vm_unmaps);
  printf("%-9s %20llu     %-9s %20llu     %-9s %20llu\n",
         "Asy Reads", stcacheptr->stuc.vm_readasyncs,
         "Getattrs" , stcacheptr->stuc.vm_getattrs,
         "Flushes"  , stcacheptr->stuc.vm_flushes);
  printf("\n");

  printf("File System Reads:\n");
  printf("------------------\n");

  ratio1 = ratio2 = ratio3 = ratio4 = 0.0;

  if (stcacheptr->stuc.vm_reads > 0) 
  {
    ratio1 = 100 * (((double)stcacheptr->stuc.vm_reads_faulted)
                    / ((double)stcacheptr->stuc.vm_reads));
  }
  if (stcacheptr->stuc.vm_writes > 0) 
  {
    ratio2 = 100 * (((double)stcacheptr->stuc.vm_writes_faulted)
                    / ((double)stcacheptr->stuc.vm_writes));
  }
  if (stcacheptr->stuc.vm_reads > 0) 
  {
    ratio3 = 100 * (((double)stcacheptr->stuc.vm_read_waits)
                    / ((double)stcacheptr->stuc.vm_reads));
  }

  printf("%-14s %20llu (%s Ratio %.2f%%)\n",
         "Reads Faulted", stcacheptr->stuc.vm_reads_faulted,
         "Fault", ratio1);

  printf("%-14s %20llu (%s Ratio %.2f%%)\n",
         "Writes Faulted", stcacheptr->stuc.vm_writes_faulted,
         "Fault", ratio2);

  printf("%-14s %20llu (%s Ratio %.2f%%)\n",
         "Read Waits", stcacheptr->stuc.vm_read_ios,
         "Wait", ratio3);

  printf("\n");
  printf("File System Writes:\n");
  printf("-------------------\n");
  printf("%-19s %20llu %-13s %20llu\n",
         "Scheduled Writes"   ,stcacheptr->stuc.vm_scheduled_writes,
         "Sync Waits"         ,stcacheptr->stuc.vm_fsync_waits);

  printf("%-19s %20llu %-13s %20llu\n",
         "Error Writes"       ,stcacheptr->stuc.vm_error_writes,
         "Error Waits"        ,stcacheptr->stuc.vm_error_waits);

  printf("%-19s %20llu %-13s %20llu\n",
         "Page Reclaim Writes", stcacheptr->stuc.vm_reclaim_writes,
         "Reclaim Waits"      , stcacheptr->stuc.vm_reclaim_waits);

  if (stcacheptr->stuc.vm_writes > 0) 
  {
    ratio4 = 100 * (((double)stcacheptr->stuc.vm_write_waits)
                    / ((double)stcacheptr->stuc.vm_writes));
  }
  printf("%-19s %20llu (Wait Ratio %.2f%%)\n",
         "Write Waits", stcacheptr->stuc.vm_write_waits,
         ratio4);

        
  printf("\n");
  printf("Page Management (Segment Size = (%dK Local %dK Remote) ) "
         "(Page Size = %dK)\n",
         stcacheptr->stuc_seg_size_loc,
         stcacheptr->stuc_seg_size_rmt,
         stcacheptr->stuc_page_size);
  printf("----------------------------------------"
         "---------------------------------\n");

  printf("Total Pages       %10u     Free               %10u\n",
         stcacheptr->stuc_cache_pages,
         stcacheptr->stuc_total_free);
  printf("Segments          %10u\n",
         stcacheptr->stuc_vmSegTable_cachesize);
  printf("Steal Invocations %20llu     Waits for Reclaim %21llu\n\n",
         stcacheptr->stuc.vm_reclaim_steal,
         stcacheptr->stuc.vm_waits_for_reclaim);

  printf("Number of dataspaces used: %5d ", 
         stcacheptr->stuc_dataspaces);
  printf("Pages per dataspace: %11d\n",
         stcacheptr->stuc_pages_per_ds);
  printf("\n");
  printf("Dataspace   Allocated     Free\n");
  printf("Name        Segments      Pages\n");
  printf("--------    ----------    ----------\n");

  for (i = 0; i < stcacheptr->stuc_dataspaces; i++)
  {
    printf("%8s    %10u    %10u\n\n",
           stcacheptr->stuc_ds_entry[i].ds_name,
           stcacheptr->stuc_ds_entry[i].ds_alloc_segs,
           stcacheptr->stuc_ds_entry[i].ds_free_pages);
  }
  return 1;
}

int print_user_cache_version1(STAT_USER_CACHE *stcacheptr)
{
  int i;
  double ratio1, ratio2, ratio3, ratio4;
  printf("Version 1 Output is being displayed\n\n");
  
  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\n");
    } 
    else 
    {
      printf("\n                   Client Statistics\n");
      printf("                   -----------------\n\n");
    }

    printf("External Requests:\n");
    printf("------------------\n");
    printf("%-9s %10u     %-9s %10u     %-9s %10u\n",
           "Reads"    , stcacheptr->stuc[i].vm_reads,
           "Fsyncs"   , stcacheptr->stuc[i].vm_fsyncs,
           "Schedules", stcacheptr->stuc[i].vm_schedules);
    printf("%-9s %10u     %-9s %10u     %-9s %10u\n",
           "Writes"   , stcacheptr->stuc[i].vm_writes,
           "Setattrs" , stcacheptr->stuc[i].vm_setattrs,
           "Unmaps"   , stcacheptr->stuc[i].vm_unmaps);
    printf("%-9s %10u     %-9s %10u     %-9s %10u\n",
           "Asy Reads", stcacheptr->stuc[i].vm_readasyncs,
           "Getattrs" , stcacheptr->stuc[i].vm_getattrs,
           "Flushes"  , stcacheptr->stuc[i].vm_flushes);
    printf("\n");

    printf("File System Reads:\n");
    printf("------------------\n");

    ratio1 = ratio2 = ratio3 = ratio4 = 0.0;

    if (stcacheptr->stuc[i].vm_reads > 0) 
    {
      ratio1 = 100 * (((double)stcacheptr->stuc[i].vm_reads_faulted)
                      / ((double)stcacheptr->stuc[i].vm_reads));
    }
    if (stcacheptr->stuc[i].vm_writes > 0) 
    {
      ratio2 = 100 * (((double)stcacheptr->stuc[i].vm_writes_faulted)
                      / ((double)stcacheptr->stuc[i].vm_writes));
    }
    if (stcacheptr->stuc[i].vm_reads > 0) 
    {
      ratio3 = 100 * (((double)stcacheptr->stuc[i].vm_read_waits)
                      / ((double)stcacheptr->stuc[i].vm_reads));
    }

    printf("%-14s %10u (%s Ratio %.2f%%)\n",
           "Reads Faulted", stcacheptr->stuc[i].vm_reads_faulted,
           "Fault", ratio1);

    printf("%-14s %10u (%s Ratio %.2f%%)\n",
           "Writes Faulted", stcacheptr->stuc[i].vm_writes_faulted,
           "Fault", ratio2);

    printf("%-14s %10u (%s Ratio %.2f%%)\n",
           "Read Waits", stcacheptr->stuc[i].vm_read_ios,
           "Wait", ratio3);

    printf("\n");
    printf("File System Writes:\n");
    printf("-------------------\n");
    printf("%-19s %10u %-13s %10u\n",
           "Scheduled Writes"   , stcacheptr->stuc[i].vm_scheduled_writes,
           "Sync Waits"         , stcacheptr->stuc[i].vm_fsync_waits);

    printf("%-19s %10u %-13s %10u\n",
           "Error Writes"       , stcacheptr->stuc[i].vm_error_writes,
           "Error Waits"        , stcacheptr->stuc[i].vm_error_waits);

    printf("%-19s %10u %-13s %10u\n",
           "Page Reclaim Writes", stcacheptr->stuc[i].vm_reclaim_writes,
           "Reclaim Waits"      , stcacheptr->stuc[i].vm_reclaim_waits);

    if (stcacheptr->stuc[i].vm_writes > 0) 
    {
      ratio4 = 100 * (((double)stcacheptr->stuc[i].vm_write_waits)
                      / ((double)stcacheptr->stuc[i].vm_writes));
    }
    printf("%-19s %10u (Wait Ratio %.2f%%)\n",
           "Write Waits", stcacheptr->stuc[i].vm_write_waits,
           ratio4);
  }
        
  printf("\n");
  printf("Page Management (Segment Size = (%dK Local %dK Remote) ) "
         "(Page Size = %dK)\n",
         stcacheptr->stuc_seg_size_loc,
         stcacheptr->stuc_seg_size_rmt,
         stcacheptr->stuc_page_size);
  printf("--------------------------------------"
         "-----------------------------------\n");

  printf("Total Pages       %10u     Free               %10u\n",
         stcacheptr->stuc_cache_pages,stcacheptr->stuc_total_free);
  printf("Segments          %10u\n",
         stcacheptr->stuc_vmSegTable_cachesize);
  printf("Steal Invocations %10u     Waits for Reclaim %11u\n\n",
         stcacheptr->stuc[0].vm_reclaim_steal,
         stcacheptr->stuc[0].vm_waits_for_reclaim);

  printf("Number of dataspaces used: %5d ", stcacheptr->stuc_dataspaces);
  printf("Pages per dataspace: %11d\n", stcacheptr->stuc_pages_per_ds);
  printf("\n");
  printf("Dataspace   Allocated     Free\n");
  printf("Name        Segments      Pages\n");
  printf("--------    ----------    ----------\n");

  for (i = 0; i < stcacheptr->stuc_dataspaces; i++)
  {
    printf("%8s    %10u    %10u\n\n",
           stcacheptr->stuc_ds_entry[i].ds_name,
           stcacheptr->stuc_ds_entry[i].ds_alloc_segs,
           stcacheptr->stuc_ds_entry[i].ds_free_pages);
  }
  
  return 1;
}