List Attached Aggregate Names (Version 2)

Purpose

The List Attached Aggregate Names (Version 2) subcommand call returns a list of the names of all attached aggregates on a system with the system name.

Format

syscall_parmlist
   opcode           int           140       AGOP_LISTAGGRNAMES2_PARMDATA
   parms[0]         int           buffer length or 0
   parms[1]         int           offset to AGGR_ID2 or 0
   parms[2]         int           offset to size
   parms[3]         int           offset to system name (optional)
   parms[4]         int           0
   parms[5]         int           0
   parms[6]         int           0
AGGR_ID2[n]                       Array of AGGR_ID2s (n can be 0)
   aid_eye          char[4]       "AGID"
   aid_len          char          sizeof(AGGR_ID)
   aid_ver          char          2
   aid_name         char[45]      "OMVS.PRV.AGGR001.LDS0001"
   aid_sysname      char[9]       "DCEIMGVN"
   aid_reserved     char[24]      0
size                int           bytes returned or size needed 
                                  if the return code is E2BIG
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 using an osi service
  ENOENT        Aggregate is not attached
  E2BIG         List is too big for buffer supplied
Reason_code
  0xEFnnxxxx    See z/OS Distributed File Service Messages and Codes

Usage notes

  1. This call returns an array of AGGR_ID2 structures, one for each attached aggregate on the system. Each AGGR_ID2 structure is 84 bytes. You can specify a buffer that you think might hold all of them or you can specify a buffer length and offset to AGGR_ID2 of zero. If you get a return code of E2BIG, the required size for the buffer is contained in the size field.
  2. Reserved fields and undefined flags must be set to binary zeros.

Privilege required

None.

Related services

  • List Aggregate Status
  • List File System Names

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_AGGR 0x40000005
#define AGOP_LISTAGGRNAMES2_PARMDATA 140 /* list attached aggregates */
                                         /* with system name */
#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;

#define ZFS_MAX_AGGRNAME 44
#define SYS_MAX_NAMELEN 8 /* Max. z/OS system name length*/

typedef struct aggr_id2_t {
  char aid_eye[4];                     /* Eye Catcher */
#define  AID_EYE "AGID"
  char aid_len;                        /* Length of this structure */
  char aid_ver;                        /* Version */
#define  AID_VER_2 2                     /* version 2 */
  char aid_name[ZFS_MAX_AGGRNAME+1];   /* aggr name, null terminated */
  char aid_sysname[SYS_MAX_NAMELEN+1]; /* system name, NULL terminated */
  char aid_reserved[24];               /* Reserved for the future */
} AGGR_ID2;

struct parmstruct {
  syscall_parmlist myparms;

  /* Real malloc'd structure will have an array of AGGR_ID2s here */
  int              size;
  char             systemname[9];
};

int main(int argc, char **argv) 
{
  int               buffer_success = 0;
  int               bpxrv;
  int               bpxrc;
  int               bpxrs;
  int               t; 
  struct parmstruct myparmstruct;
  AGGR_ID2          *aggPtr;
  int               aggSize      = sizeof(AGGR_ID2);
  int               buflen       = sizeof(AGGR_ID2);
  struct parmstruct *myp         = &myparmstruct;
  int               mypsize;
  char              *systemp;
  int               count_aggrs;
  int               total_aggrs;

  myparmstruct.myparms.opcode  = AGOP_LISTAGGRNAMES2_PARMDATA;
  myparmstruct.myparms.parms[0] = 0;
  myparmstruct.myparms.parms[1] = 0;
  myparmstruct.myparms.parms[2] = sizeof(syscall_parmlist);
  myparmstruct.myparms.parms[3] = 0;
  myparmstruct.myparms.parms[4] = 0;
  myparmstruct.myparms.parms[5] = 0;
  myparmstruct.myparms.parms[6] = 0;

  BPX1PCT("ZFS     ",
          ZFSCALL_AGGR,               /* Aggregate 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 = myp->size;         /* Get buffer size needed */
        mypsize = buflen + sizeof(syscall_parmlist) + sizeof(int) + 9;

        free(myp);

        myp = (struct parmstruct *)malloc((int)mypsize);
        memset(myp, 0, mypsize);
      
        /* This next field should only be set if parms[3] is non-zero */
        /* systemp = (char *)myp + buflen                             */
        /*           + sizeof(syscall_parmlist) + sizeof(int);        */
        /* strcpy(systemp,"DCEIMGVN");        */ 
        /* set system to get lsaggr info from */
      
        myp->myparms.opcode = AGOP_LISTAGGRNAMES2_PARMDATA;
        myp->myparms.parms[0] = buflen;
        myp->myparms.parms[1] = sizeof(syscall_parmlist);
        myp->myparms.parms[2] = sizeof(syscall_parmlist) + buflen;
        myp->myparms.parms[3] = 0;
      
        /* Only specify a non-zero offset for the next field (parms[3]) if */
        /* you are running z/OS 1.7 and above, and */
        /* you want lsaggr aggregates owned on a single system */
        /* myp->myparms.parms[3] = sizeof(syscall_parmlist)    */
        /*                         + buflen + sizeof(int);     */
      
        myp->myparms.parms[4] = 0;
        myp->myparms.parms[5] = 0;
        myp->myparms.parms[6] = 0;

        BPX1PCT("ZFS     ",
                ZFSCALL_AGGR,       /* 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;
          total_aggrs = buflen / aggSize;
          count_aggrs = 1;
          for (aggPtr = (AGGR_ID2 * ) & (myp->size); 
               count_aggrs <= total_aggrs;
               aggPtr++, count_aggrs++) 
          {
            if (strlen(aggPtr->aid_name) != 0) 
              printf("%-64.64s %-8.8s\n", 
                     aggPtr->aid_name, aggPtr->aid_sysname);
          }
          free(myp);
        } 
        else 
        { /* lsaggr names failed with large enough buffer */
          printf("Error on ls aggr with large enough buffer\n");
          printf("BPXRV = %d BPXRC = %d BPXRS = %x\n", bpxrv, bpxrc, bpxrs);
          free(myp);
          return bpxrc;
        }
      } 
      else 
      { /* error was not E2BIG */
        printf("Error on ls aggr 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 are no aggregates */
      if (myparmstruct.size == 0) 
        printf("No attached aggregates\n");
      else /* No, there was some other problem with getting the size needed */
        printf("Error getting size required\n");
      free(myp);
      return bpxrc;
    }
  }
  
  if( t == 1000 )
    printf("Number of failed buffer resizes exceeded.\n");

  free(myp);
  return 0;
}