Navigation Bar

Large FDRinstant Advert

A Sample program to generate FDRinstant Statements

This SAS program generates FDRinstant statements to invoke flashcopy on IBM's ESS DASD. It should easy to adapt it to other kinds of disks. It assumes that the ESS box has been configured in a standard way, see the ESS TIPS pages for tips on how to configure a shark.
The outline process is

  • Get a list of all online disks from a DCOLLECT
  • Assign a dummy storage pool to non-sms volumes.
  • Delete all storage pools which do not need backup
  • Determine the flashcopy target UCB
  • create JCL

The SAS code

This code is supplied on an as-is basis, as a suggested way of doing things. It will need some tailoring for your site, and must be thoroughly tested before it goes anywhere near production. If you have a better way, or better code, I'm always willing to learn.

 OPTIONS NODATE NONUMBER REUSE=YES WORKTERM MISSING=' ';              
                                                                     
  /* GET LIST OF ALL ONLINE VOLUMES, THEN SPLIT INTO SMS & non-SMS    */       
                                                                     
 DATA VOLA_LST;        /*  ALL ONLINE VOLUMES  */
  SET SASDB.DCOLVOLS (KEEP=                                           
         DCVSGTCL     /*  STORAGE GROUP        */                    
         DCVDVNUM     /*  UCB                  */                    
         DCVVOLSR);   /*  VOLSER               */                    
                                                                     
    /* GET RID OF VOLUMES WHICH NEVER NEED BACKUP  */                
                                                                     
    IF DCVVOLSR =: 'SP' THEN DELETE;   /* SPARE VOLUMES  */          
                                                           
      RENAME  DCVSGTCL=STORGRP;                            
      RENAME  DCVVOLSR=VOLSER;                             
      RENAME  DCVDVNUM=UNIT;                               
                  
 PROC SORT;
  BY DCVVOLSR;                                                      
                                                           
 DATA VOLN_LST;          /* ALL NON_SMS VOLUMES */          
  SET VOLA_LST;                                             
                                                           
  IF STORGRP ¬= '' THEN DELETE;                             
                                                           
 DATA VOLS_LST;          /* ALL SMS VOLUMES   */            
  SET VOLA_LST;                                             
                                                         
  IF STORGRP = '' THEN DELETE;                              





 /* ALLOCATE DUMMY STORAGE GROUPS to non-SMS disks                 
    DSKPARMS is a pds member which contains lists of non-sms disks                 
    and a dumptype, used to group the disks into dummy pools, for example
 *   pool    volume 
     CA     CAT001
     SP     SYSRS1    */ 

 DATA DSKPARMS;                                                          
  INFILE DSKPARMS;                                                       
  INPUT COMMENT  £ 1 @;                                                  
  IF COMMENT = '*' THEN DO;                                              
        DELETE;                                                         
        DROP COMMENT;                                                   
                      END;                                              
                 ELSE DO;                                               
  INPUT DUMPTYPE £  5-6                                                  
        VOLSER   £ 12-17;                                                
                       END;                                              
   IF VOLSER = '      ' THEN DELETE;   /* BLANK LINES  */                
                                                                        
 PROC SORT;                                                              
  BY VOLSER;                                                             
                                                                        
 DATA NON_SMS;                                                          
  MERGE DSKPARMS (IN=F1) VOLN_LST (IN=F2);                              
   BY VOLSER;                                                           
                                 
STORGRP = "NONSMS" || DUMPTYPE;                                        
                                                                       
IF F1=1 AND F2=0 THEN DO;                                              
 PUT '********************************************************';       
 PUT '*                                                      *';       
 PUT '*     NON-FATAL ERROR IN SAS MODULE                    *';       
 PUT '*                                                      *';       
 PUT '*     VOLSER ' VOLSER ' SPECIFIED IN  FILE               *';     
 PUT '*           DMGT.PROD.CONTROL(ABRNSMSP)                *';       
 PUT '*           BUT IT DOES NOT EXIST ONLINE.              *';       
 PUT '*                                                      *';       
 PUT '********************************************************';       
 DELETE;                                                               
                      END;                                             
                                                                       
IF F1=0 AND F2=1 THEN DO;                                              
 PUT '********************************************************';       
 PUT '*                                                      *';       
 PUT '*         FATAL ERROR IN SAS MODULE                    *';       
 PUT '*                                                      *';       
 PUT '*     VOLSER ' VOLSER ' MISSING FROM  FILE               *';     
 PUT '*            DMGT.PROD.CONTROL(ABRNSMSP)               *';       
 PUT '*        SO WE DONT KNOW WHAT TO DO WITH IT            *';         
 PUT '*                                                      *';       
 PUT '********************************************************';       
  ABORT RETURN 16;                                                      
                       END;                                             
                                                                        
 DROP DUMPTYPE;                                                         
                                                                        
 /* GET A LIST OF ALL VOLUMES WITH DATA, NOW ALL WITH STORAGE 
GROUPS,  BY COMBINING SMS & NON-SMS */       
                                                                        
DATA ALL_VOLS;                                                          
 SET NON_SMS VOLS_LST;                                                  
                                                                        
PROC SORT;                                                              
 BY STORGRP;                                                            

 /*  EXTRACT INFO ON WHAT TO DO WITH STORAGE POOLS                   
     THEN DELETE POOLS WHICH DONT NEED BACKUP. Storage pool info
     is held in a PDS member, an example is shown below 
*  dump? pool                          comment
      X   DB2DBPD                      DATABASES imagecopied    
      F   PBVLRG01                     GENERAL LARGE ALLOCATIONS  */
                                                              
DATA STORGRPS;                                                          
 INFILE SGPARMS;                                                        
 INPUT COMMENT  £ 1 @;                                                  
IF COMMENT = '*' THEN DO;                                               
        DELETE;                                                         
        DROP COMMENT;                                                   
END;                                                                    
ELSE DO;                                                                
    INPUT BACKUP    £3                                                  
          STORGRP  £5-12;                                               
IF STORGRP = '        ' THEN DELETE;             /* BLANK LINES */      
                                                                        
END;                                                                    
                                                                        
PROC SORT;                                                              
 BY STORGRP;                                                            
                                                                        
DATA VLSG_LST;             /* MERGE VOLUME & STORAGE GROUP INFO */      
 MERGE STORGRPS (IN=F1) ALL_VOLS (IN=F2);                               
  BY STORGRP;                                                           

                                                               
 IF F1=1 AND F2=0 THEN DO;                                     
   PUT '***********************************************';      
   PUT '*                                             *';      
   PUT '*   NON-FATAL ERROR IN SAS MODULE             *';      
   PUT '*  STORAGE POOL  ' STORGRP '  DEFINED IN      *';      
   PUT '*  DMGT.MASTER,CONTROL(ABRPOOLS) AND IT HAS   *';      
   PUT '*        NO VOLUMES ASSIGNED TO IT            *';      
   PUT '*                                             *';      
   PUT '***********************************************';      
   DELETE;                                                     
                       END;                                    
                                                               
 IF F1=0 AND F2=1 THEN DO;                                     
   PUT '**********************************************';       
   PUT '*                                            *';       
   PUT '*     ERROR IN SAS MODULE                    *';       
   PUT '*                                            *';       
   PUT '* STORAGE POOL  ' STORGRP '  EXISTS, BUT HAS   *';     
   PUT '*  NO ENTRY IN DMGT.PROD.CONTROL(ABRPOOLS) *';       
   PUT '*  PLEASE ADD IT WITH THE CORRECT BACKUP     *';       
   PUT '*          INSTRUCTION                       *';       
   PUT '*  CURRENT VOLUME IS ' VOLSER '                *';     
   PUT '*                                            *';   
  PUT '**********************************************';     
 ABORT RETURN 16;                                           
                      END;                                 
                                                           
 IF BACKUP = 'X' THEN DELETE;                               
                                                               
  /*  WORK OUT THE FLASH COPY ADDRESS FOR EACH DISK       
      The first bit is a bit of a fiddle to cope with hex 
      addresses, Write the hex data out to a file, then 
      read it back in character format. If you know of an 
      easy way to convert hex to char, PLEASE mail me.                 */      
                                                                        
 DATA TEMP;                                                              
  SET VLSG_LST;                                                          
                                                                        
 FILE SAST1 NOPRINT;                                                    
 PUT @2 UNIT @7 VOLSER @16 STORGRP @30 BACKUP;                          
                                                                        
 DATA FDRFLASH;                                                         
                                                                        
 INFILE SAST1;                                                          
   INPUT  @2 UNIT     HEX4.                                             
             BOX      £2                                                
             LCU      £3                                                
             VOLSER   £7-12                                             
             STORGRP  £16-23                                            
             BACKUP   £30;                                              
                                                                        
  ATTRIB UNIT FORMAT=HEX4.;                                             
  ATTRIB FUNIT FORMAT=HEX4.;                                            
                                                                        
                                                                     
  /* ARRAYS ARE EITHER 48 3390-3 DISKS, OR 24 3390-9  */  
                                                                      
SELECT(BOX);                                                          
                                                                      
 WHEN('8')  DO;        /*  ESS1     */                                
      SELECT (LCU);                                                   
        WHEN('0')  FUNIT = UNIT + 24;      /* 3390-9 ARRAYS  */       
        WHEN('B')  FUNIT = UNIT + 24;                                 
        OTHERWISE  FUNIT = UNIT + 48;      /* 3390-3 ARRAYS  */       
      END;   /* OF SELECT */                                          
            END;                                                      
                                                                      
                                            
                                                                   
    WHEN('6') DO;                  /*  ESS4     */                 
         SELECT (LCU);                                             
            WHEN('A')  FUNIT = UNIT + 48;    /* 3390-3 ARRAYS  */                        
            WHEN('B')  FUNIT = UNIT + 48;                          
            WHEN('C')  FUNIT = UNIT + 48;                          
            WHEN('D')  FUNIT = UNIT + 48;                                                  
            OTHERWISE  FUNIT = UNIT + 24;   /* 3390-9 ARRAYS  */   
          END;                                                     
              END;                                                 
                                                                   
    WHEN(' ') DELETE;                                              
    OTHERWISE DO;                                                  
   PUT '*****************************************';                
   PUT '*                                       *';                
   PUT '*    ERROR IN SAS MODULE                *';                
   PUT '*                                       *';                
   PUT '*  YOU ARE TRYING TO FLASHCOPY ' VOLSER '  *';             
   PUT '*     IN STORAGE POOL   ' STORGRP '       *';              
   PUT '* WITH ADDRESS ' UNIT '                    *';             
   PUT '*                                       *';            
   PUT '*  IF YOU HAVE ADDED A NEW FLASHCOPY    *';            
   PUT '*  CAPABLE SUBSYSTEM, THEN IT MUST BE   *';            
   PUT '* ADDED INTO DMGT.PROD.SAS(ABRBKFLP)  *';            
   PUT '*   YOU WILL ALSO NEED TO GET MORE      *';            
   PUT '*      FLASH COPY JOBS SCHEDULED        *';            
   PUT '*                                       *';            
   PUT '*                                       *';            
   PUT '*****************************************';            
   ABORT RETURN 16;                                            
              END;                                             
   END;     
  
 /*  CREATE FDRFLASH COMMANDS, ONE SET OF EACH DASD LCU     */       
                                                                        
DATA TEMP;                                                              
 SET FDRFLASH;                                                          
  BLCU = BOX || LCU;                                                    
  DROP BOX UNIT STORGRP;                                                
                                                                        
PROC SORT;                                                              
 BY BLCU;                                                               
                                                                        
DATA FLASHOUT;                                                          
 SET TEMP;                                                              
                                                                        
 LENGTH OUTFILE £ 50;                                                   
 ATTRIB N FORMAT=Z2. LENGTH=2;                                          
 RETAIN N 00  OLD_BLCU '  ';                                            
                                                                        
 IF BLCU ¬= OLD_BLCU THEN NEW_JOB='Y';                                  
 OLD_BLCU = BLCU;                                                       
 IF NEW_JOB = 'Y' THEN GOTO HEAD;                                       
                                                                        
BODY:                                                                   

                                                          
 IF N < 10 THEN M='0'|| N;                                
                        ELSE M=N;                         
 OUTFILE='DMGT.PROD.CONTROL(X4FLBC'||M||')';              
 OUTFILE=COMPRESS(OUTFILE);                               
                                                          
FILE FDRFLASH NOPRINT FILEVAR=OUTFILE;                    
                                                          
  PUT @2 'MOUNT'                                          
      @12 'VOL='                                          
      @16 VOLSER                                          
      @22 ',FLASHUNIT='                                   
      @33 FUNIT;                                          
                                                          
 RETURN;                                                  
                                                          
 /* THIS BIT GETS INVOKED WHEN WE START A NEW ARRAY */    
                                                          
 HEAD:                                                    
 N+1;                                                     
                                                          
 /*  IF EXTRA FLASH CAPABLE DASD IS ADDED, CHANGE   */    
 /*     THE COUNTER BELOW, AND THE ERROR MESSAGE    */    
 IF N > 48 THEN DO;                                       
  FILE SASLOG;                                                 
  PUT '*****************************************';             
  PUT '*                                       *';             
  PUT '*    ERROR IN SAS MODULE                *';             
  PUT '*                                       *';             
  PUT '*  YOU HAVE TRIED TO CREATE MORE THAN   *';             
  PUT '*  48 FDRFLASH JOBS, AND ONLY 48 JOBS   *';             
  PUT '*  ARE SCHEDULED. YOU NEED TO SPEAK TO  *';             
  PUT '*       THE  SCHEDULERS QUICKLY         *';             
  PUT '*                                       *';             
  PUT '*****************************************';             
  ABORT RETURN 16;                                             
                 END;                                          
 IF N < 10 THEN M='0'|| N;                                     
                        ELSE M=N;                              
 OUTFILE='DMGT.PROD.CONTROL(X4FLBC'||M||')';                   
 OUTFILE=COMPRESS(OUTFILE);                                    
                                                               
 FILE FDRFLASH NOPRINT FILEVAR=OUTFILE;                        
 PUT @2  'FCOPY TYPE=AUTO,DSNENQ=USE,ENQERR=NO SMSPROT=NONE';  
                                                               
                                                               
                                                               
  /* CREATE REAL PROCLIB MEMBERS FOR USED ARRAYS  */           
                                                                    
                                                                    
  IF N < 10 THEN M='0'|| N;                                         
                         ELSE M=N;                                  
  M=COMPRESS(M);                                                    
  OUTFILE='DMGT.PROD.PROCLIB(X4FLBC'||M||')';                       
  OUTFILE=COMPRESS(OUTFILE);                                        
                                                                    
  FILE PROCLIB  NOPRINT FILEVAR=OUTFILE;                            
  PUT @1  '//STEP1    EXEC PGM=FDRABR';                               
  PUT @1  '//TAPE1    DD DUMMY';                                    
  PUT @1  '//SYSPRINT DD *';                 
  PUT @1  '//SYSPRIN1 DD SYSOUT=*';                                 
  PUT @1  '//SYSUDUMP DD SYSOUT=*';                                 
                                                                    
  GOTO BODY;                                                        
                                                                    
                                                                    
   /* CREATE DUMMY PROCLIB MEMBERS FOR BLANK ARRAYS  */             
   /* 48 jobs are scheduled to run in OPC, but they  */
   /* may not all be used. The JCL in the OPC library */
   /* looks like 

   //X4FLBC01 JOB (Backup),CLASS=4,                             
   //         MSGCLASS=X,MSGLEVEL=(1,1)                          
   //INCLIB  JCLLIB  ORDER=(DMGT.PROD.PROCLIB)                   
   //JCLIN   INCLUDE MEMBER=X4FLBC01                                
        which points it to the user libraries
    */
                                                                          
 DATA _NULL_;                                                           
 SET FLASHOUT (KEEP=N) END=LAST;   /* GET N COUNTER FROM LAST RECORD */ 
                                                                        
 IF LAST ¬= 1 THEN DELETE;                                              
                                                                        
 DO WHILE (N<48);                                                       
   N+1;                                                                 
   LINK NEWJOB;                                                         
 END;                                                                   
                                                                        
NEWJOB:                                                                 
                                                                        
 IF N < 10 THEN M='0'|| N;                                              
                        ELSE M=N;                                       
 OUTFILE='DMGT.PROD.PROCLIB(X4FLBC'||M||')';                            
 OUTFILE=COMPRESS(OUTFILE);                                             
                                                                        
 FILE PROCLIB NOPRINT FILEVAR=OUTFILE;                                  
 PUT @1  '//STEP1    EXEC PGM=IEFBR14';                                 
 PUT @1  '//DD1      DD   DUMMY      ';                                 
                                                                        
 RETURN;                                                                
                                                             
                                                                   

back to previous page

back to top


                           VENDOR SHOWCASE

Copyright © Lascon Storage Ltd. 2000 to present date. By entering and using this site, you accept the conditions and limitations of use