VSE Tools & Techniques Making Dynamic Disk and Tape Assignments By Mark Hanna NaSPA member Mark Hanna, Hanna & Associates Inc. of Edmond, Okla., specializes in VSE installation, support and education. He has been working with and installing DOS and VSE since 1969. This monthly column is for sharing practical advice and techniques that can be used by any VSE shop. Calls and letters from readers with tips or methods to share are encouraged. Contributors and anyone suggesting a column will be given credit for techniques or ideas used. Mark may be reached at P.O. Box 3325 Edmond, OK, 73083-3325, (405) 340-1457 or fax (405) 340-2053. His NaSCOM ID is Hannmarc. He can also be reached in care of NaSPA. This month's column will feature a method of making a dynamic assignment for tape and disk. It will present a subroutine that is called to perform the assignment, and two test driver programs to call and test the subroutine. These programs were originally written to acquaint me with the macros examined in this month's column. They were first made available sometime around DOS/VSE/AF 1.2. I removed the hard-coded macros and DSECTS, replacing them with the IBM macros. I also made changes to run under VSE/ESA 1.3. All testing was done on VSE/ESA 1.3. The functions provided in the subroutine are: 1. accessing a label in the label area; 2. from the label information retrieved, obtain the characteristics and VOLID of the tape or disk for the assign function; and 3. issue an ASSIGN of the identified device. Description of Macros To carry out a dynamic disk assign function, the following sequence of macros is required: 1. LABEL Macro: You must provide the DLBL statement filename (GETLBL function) as input and you will receive as output the VOLID of the volume containing this file. The LABEL macro is documented in the VSE IPL and JCL Diagnosis Reference. The LPL and LPLDCT macros are used to define and address the label area buffer. 2. GETVCE Macro: Having received the VOLID information of the disk file in question, this may now be used as input to the GETVCE macro to receive as output the address (X`cuu') of the volume in question. This macro is documented in the VSE Diagnosis Reference: Supervisor. The AVRLIST macro is used to define the GETVCE work area. 3. ASSIGN Macro: Having now received the device address, this may be used as input to the assign macro to receive as output an appropriate programmer logical unit that will be dynamically assigned to this device. The ASSIGN macro parameters are documented in the VSE Systems Macro Reference, although they are also documented in the expansion of the ASSIGN macro. The ASPL macro is used to define the assign macro work area. DYNASSGN - Dynamic Assign Subroutine The DYNASSGN program (Figure 1) is a sample subroutine developed to provide a generalized `dynamic assign' routine for both disk and tape assignments. Note that all macros required for the dynamic disk assign subroutine are documented in IBM manuals: The VSE System Macro Reference manual (SC33-6516) for the ASSIGN macro, the VSE Diagnosis Reference: Supervisor (LY33-9150) for the GETVCE Macro and for the LABEL macro the IPL and JCL manual (LY33-9160). The dynamic assign subroutine for tape or disk, shown in Figure 2, consists of the aforementioned three macros. Any user program may call this subroutine to carry out a dynamic assignment, as long as the required assign parameter list is passed to it. Additionally, the calling program will also receive VOLID information returned by the subroutine. DYNATAPE - Dynamic Tape Assignment The sample program in Figure 3 is a routine that tests the use of the previously described DYNASSGN subprogram to carry out a dynamic tape assign. The program may be executed in both a normal batch partition or VSE/ICCF interactive partition. Two key points must be noted with regard to coding programs that execute dynamic tape assign operations: 1. In the case where such a program as this abends (when executing in an interactive partition), the EOJ routines of VSE will not be invoked to release any temporary assignments. As a result, it can be seen in this program that an `STXIT AB' routine has been included within the program to ensure that any tape assignment issued by this program will be released in the event of a program abend. You should include an STXIT routine when execution of a dynamic tape assign is to take place in an interactive partition. In the case of execution of such a program in a batch partition, the VSE EOJ routines will normally do this. 2. An operator will not automatically be told on which unit a tape reel should be mounted. When the dynamic assign has been carried out by the user program, it may not be obvious which tape drive has been selected. Consequently, when the user program issues an open operation for a particular tape file, a `tape unit not ready' message (4n86d) will be issued. This message, however, displays only file name and programmer logical unit information without providing unit address information. As a result, the operator will not know on which unit to mount the tape. The suggestion, then, is to incorporate in user code a warning message which will be displayed on the system console, advising the operator that a prompt is forthcoming, requesting a tape mount of the particular tape on a particular unit. The subprogram sample DYNASSGN, described in Figure 3, includes code for warning the operator about which unit has been selected. DYNATEST - Dynamic Tape and Disk Assignment Test The program in Figure 4 tests the use of the DYNASSGN subprogram to carry out a dynamic tape and disk assign. It is set up as a link-and-go execution. No further comments are required here, as this program is just an extension of the previously described program DYNATAPE, again utilizing the DYNASSGN subprogram. If you would like to share your experiences with any of the aforementioned programs, please contact me. Was this column of value to you? If so, please let us know by circling Reader Response Card No. . Figure 1: DYNASSGN General Calling Sequence LA RF,MYSAVE MVI PARMFUNC,ASG... ASGDPT FOR DISK ASSIGN ASGTPT FOR TAPE ASSIGN ASGUAP FOR UNASSIGN LA R1,DTFNAME STCM R1,15,PARMDTF CALL DYNASS,(PARMLIST) LTR RF,RF BNZ NOGOOD * * PARMLIST DS 0CL11 PARMFUNC DC XL1'00' ASSIGN FUNCTION CODE PARMDTF DC XL4'00' DTFNAME IN CALLING PROGR PARMVOL DC CL6' ' VOLID WILL BE RETURNED PARMERR DC CL3' ' FUNCTION THAT CAUSED ERROR PARMRET DC XL1'00' ERROR CODE * * MYSAVE DC 18F'0' ASSIGN SEQUENCE * CALL DYNASSGN,(PARMLIST) GENERAL CALLING SEQ OPEN DTFNAME UNASSIGN SEQUENCE * CLOSE DTFNAME CALL DYNASSGN,(PARMLIST) GENERAL CALLING SEQ Figure 2: DYNASSGN - Dynamic Assign Subroutine * $$ JOB JNM=DYNASSGN,CLASS=A * $$ LST DISP=L,CLASS=Q * $$ PUN DISP=I,CLASS=A,PUN=SYSPCH * JOB SUBMITTED BY USER = MARK TERMINAL = A001 * MEM = DYNASSGN DATE = 940707 TIME = 170018 // JOB DYNASSGN SUBROUTINE FOR DYNAMIC DISK AND TAPE ASSIGNMENTS // OPTION DECK,NOSYM // EXEC ASSEMBLY,SIZE=100K PRINT GEN PUNCH '// JOB CATALR DYNASSGN SUBROUTINE HANNA ' PUNCH '// EXEC LIBR ' PUNCH ' ACCESS S=HCLIBS.UTIL ' PUNCH ' CATALOG DYNASSGN.OBJ R=YES ' TITLE 'DYNASSGN ASSIGN ROUTINE ' DYNASSGN START 0 STM RE,RC,8(RD) SAVE REGISTERS 14 TO 12 BALR R2,0 ESTABLISH ADDRESSABILITY USING *,R2 ST RD,SAVERD SAVE REGISTER 13 L R3,0(R1) LOAD ADDRESS OF PARAMETER USING PARMLIST,R3 GET ADDRESSIBILITY TO PARMS XC PARMERR,PARMERR CLEAR ERROR CODE LA RD,REGSAVE POINT R13 TO OWN SAVEREA CLI PARMFUNC,ASGDPT IS IT DISK ASSIGN BNE ASGENT NO-GO TO ASSIGN GENERAL ENTRY ICM RA,15,PARMDTF YES-GET DTF ADDRESS LA R4,LPLBUF LPL BUFFER AREA USING LPLDCT,R4 GET ADDRESSIBILITY MVC LPLNAM(7),22(RA) LOAD FILE NAME INTO LPL LABMAC LABEL LPLADDR=LPLBUF,FUNCT=GETLBL CLM RF,1,RETCOD8 RETURN CODE OK BE GETLBLOK YES LTR RF,RF RETURN CODE OK BE GETLBLOK YES STCM RF,01,PARMRET SAVE ERROR CODE IN REG 15 MVC PARMERR,CONLBL SET ERROR TYPE B RETABN GO TO ABNORMAL EXIT GETLBLOK EQU * MVC PARMVOL,LABFSER STORE VOLID INTO PARAMETER LIST GETVCE 1 VOLID=LABFSER, POINT TO VOL SER ID 2 AREA=AVRADR, USE AVRLIST AREA 3 LENGTH=AVRLEN AVRLIST LENGTH L RA,AVRPUB LOAD DISK PUB ADDR LTR RF,RF TEST RETURN CODE BZ ASGENT GETVCE OK - GO TO ASSIGN STCM RF,01,PARMRET SAVE ERROR CODE IN REG 15 MVC PARMERR,CONVCE SET ERROR TYPE B RETABN GO TO ADNORMAL EXIT * * GENERAL ENTRY FOR ASSIGN FUNCTION * ASGENT EQU * MVC ASGFUNCT,PARMFUNC SET FUNCTION IN ASPL ICM RC,15,PARMDTF LOAD DTF ADDR INTO REG 12 CLI PARMFUNC,ASGDPT IS IT DISK ASSIGN BE ASSIGN YES - GET PHYSICAL UNIT CLI PARMFUNC,ASGTPT IS IT TAPE ASSIGN BE ASGEXEC YES - EXECUTE ASSIGN FUNCTION CLI PARMFUNC,ASGUAP IS IT UNASSIGN BE UNASSIGN YES-EXECUTE UNASSIGN FUNCTION STCM RF,01,PARMRET SAVE ERROR CODE IN REG 15 MVC PARMERR,CONINV SET ERROR TYPE B RETABN GO TO ABNORMAL EXIT * * UNASSIGN FUNCTION * UNASSIGN EQU * UNASSIGN A DEVICE MVC ASGLUNO,6(RC) LOAD LUB FROM DTF TABLE B ASGEXEC EXECUTE FUNCTION * * ASSIGN FUNCTION FOR DISK * ASSIGN EQU * GET PHYSICAL UNIT OF DISK MVC ASGCUU,0(RA) STORE DISK ADDR IN PARAMETER LIST ASGEXEC ASSIGN 1 ASPL=ASPLAREA, 2 SAVE=REGSAVE LTR RF,RF TEST RETURN CODE BZ DTFUPD OK-UPDATE DTF FOR ASSIGN FUNCTION STCM RF,01,PARMRET SAVE ERROR CODE IN REG 15 MVC PARMERR,CONASG SET ERROR TYPE B RETABN GO TO ABNORMAL EXIT DTFUPD EQU * CLI PARMFUNC,ASGUAP IS IT UNASSIGN BE RETNORM YES-RETURN MVC 6(2,RC),ASGLUNO STORE LUB INTO DTF CLI PARMFUNC,ASGTPT IS IT TAPE ASSIGN BNE RETNORM NO-RETURN NORMAL * * GIVE OPERATOR A WARNING MESSAGE FOR TAPE ASSIGN * SR RA,RA CLEAR REGISTER 10 IC RA,ASGCUU+1 INSERT LOGICAL UNIT INTO R10 CVD RA,CVDF CONVERT TO DECIMAL UNPK CVDF+1(3),CVDF+6(2) OI CVDF+3,X'F0' MVC MSGLU,CVDF+1 STORE LOGICAL UNIT INTO MESSAGE UNPK CVDF+3(5),ASGCUU(3) STORE PHYSICAL UNIT INTO MESSAGE MVC MSGPU,CVDF+4 TR MSGPU,TRTAB-240 TRANSLATE TO EBCDIC LA R1,MSGCCB LOAD CCB FOR WRITING MESSAGE EXCP (1) WRITE MESSAGE WAIT (1) B RETNORM RETURN TO CALLER RETABN EQU * ABNORMAL RETURN PDUMP DUMPSTRT,DUMPEND RETNORM EQU * NORMAL RETURN L RD,SAVERD RESTORE REG 13 OF CALLER L RE,8(RD) RESTORE CALLER'S REGISTER 14 LM R0,RC,16(RD) RESTORE CALLER'S REGISTER 0 TO 12 BR RE RETURN TO CALLER LTORG TITLE 'DYASSGN CONSTANTS, WORK AREAS ' DUMPSTRT EQU * DC C'DYNASSGN AREA PDUMP' DS 0D SAVERD DC F'0' SAVAREA FOR CALLER REGISTER 13 REGSAVE DC 18F'0' SAVEAREA * WORK AREA FOR GETVCE MACRO AVRLIST AVRLIST DSECT=NO,DEVICE=YES * WORK AREA FOR ASSIGN MACRO ASPLAREA ASPL DSECT=NO * WORK AREAS FOR LABEL MACRO. LPLBUF LPL AREA=LABREC, ADDR OF LPL BUFFER 1 AREALEN=84, LENGTH OF LPL BUFFER 2 FILENAM=DTFNAME DS 0F ALIGN TO WORD BOUNDARY LABREC DS 0CL84 LABEL AREA LAYOUT LABEXN DS CL1 NUMBER OF EXTENTS LABFNAME DS CL7 FILE NAME LABDAISS DS CL1 DA/IS INDICATORS LABDSN DS CL44 DATA SET NAME LABFID DS CL1 FORMAT ID LABFSER DS CL6 VOLID OF FIRST EXTENT LABVSEQ DS CL2 VOLUME SEQUENCE NUMBER LABCRDTE DS CL3 CREATION DATE LABEXDTE DS CL3 EXPIRATION DATE LABRETPD DS CL2 RETENTION PERIOD LABOPCOD DS CL1 DLBL TYPE LABSYSCD DS CL13 SYSTEM CODE LABEXT EQU * BEGIN LABEL EXTENTS * DUMPEND EQU * CONLBL DC CL3'LBL' ERROR INICATOR FOR LABEL ROUTINE CONVCE DC CL3'VCE' ERROR INICATOR FOR GETVCE ROUTINE CONASG DC CL3'ASG' ERROR INDICATOR FOR ASSIGN ROUTINE CONINV DC CL3'INV' ERROR INDICATOR FOR INVALID FUNCTION * MSG DS 0CL54 MESSAGE TO OPERATOR MSGID DC CL8'DYNASG' ERROR MESSAGE ID MSGT1 DC CL21'MOUNT REQUEST FOR SYS' MSGLU DC CL3'00' LOGICAL UNIT DC CL1' ' MSGT2 DC CL8'ON UNIT' MSGPU DC XL3'00' PHYSICAL UNIT DC CL1' ' MSGT3 DC CL9'COMING UP' * RETCOD8 DC XL1'08' RETURN CODE 8 FOR GETLBL MACRO * DS 0D BUMP TO DOUBLEWORD BNDY CVDF DC D'0' USED FOR CONVERT TO DECIMAL * MSGCCB CCB SYSLOG,MSGCCW MESSAGE CCB MSGCCW CCW 9,MSG,0,54 MESSAGE CCW * TRTAB DC CL16'0123456789ABCDEF' LTORG * REGISTER EQUATES R0 EQU 0 R1 EQU 1 R2 EQU 2 R3 EQU 3 R4 EQU 4 R5 EQU 5 R6 EQU 6 R7 EQU 7 R8 EQU 8 R9 EQU 9 RA EQU 10 RB EQU 11 RC EQU 12 RD EQU 13 RE EQU 14 RF EQU 15 * * EQUATES FOR GETLBL ERROR CONIDTIONS * LBLRETOO EQU 0 SUCCESSFUL REQUEST LBLRET04 EQU 4 SPECIFIED LABEL DOES NOT EXIST LBLRET08 EQU 8 BUFFER LENGTH TO SMALL ACCEPTED LCLRET20 EQU 20 CONTENTS OF LPL ARE INVALID LBLRET28 EQU 28 NO GETVIS STORAGE AVAILABLE * * EQUATES FOR GETVCE ERROR CONDITIONS * VCERET00 EQU 0 ALL DATA RETURNED VCERET04 EQU 4 SUCCESSFUL EXCEPT SOME DATA NOT VALID VCERET08 EQU 8 GIVEN VOLUME NOT MOUNTED * GIVEN LOGICAL UNIT NOT ASSIGNED * GIVEN DIVICE NOT IN SYSTEM VCERET12 EQU 12 GIVEN LOGICAL UNIT IS ASSIGNED IGNORE VCERET16 EQU 16 DEVICE IS NOT OPERATIONAL VCERET20 EQU 20 BAD INPUT PARAMETER LIST VCERET24 EQU 24 GIVEN LOGICAL UNIT OR DEVICE NOT DASD VCERET28 EQU 28 DEVICE IS NOT READY * * EQUATES FOR DISK ASSIGN ERROR CONDITIONS * ASGRET00 EQU 0 SUCCESSFUL REQUEST * * * PARMLIST DSECT ELEVEN BYTES PARMFUNC DS XL1 ASSIGN FUNCTION CODE PARMDTF DS XL4 DTFNAME IN CALLING PROGR PARMVOL DS CL6 VOLID WILL BE RETURNED HERE PARMERR DS CL3 FUNCTION THAT CAUSED ERROR PARMRET DS XL1 ERROR RETURN CODE * LPLDCT , END /* // EXEC ASSEMBLY PUNCH '/*' PUNCH '/&&' END /* /& * $$ EOJ Figure 3: DYNATAPE - Dynamic Tape Assignment * $$ JOB JNM=DYNATAPE,CLASS=0,DISP=D * $$ LST CLASS=Q,DISP=L * JOB SUBMITTED BY USER = MARK TERMINAL = A001 * MEM = DYNATAPE DATE = 940707 TIME = 172652 // JOB DYNATAPE HANNA TEST DYNAMIC DEVICE ASSIGN SUBROUTINE // LIBDEF OBJ,SEARCH=HCLIBS.UTIL // OPTION LINK,PARTDUMP PHASE DYNATAPE,* // EXEC ASSEMBLY PRINT GEN DYNATEST START 0 BALR R2,0 USING *,R2 STXIT AB,ABEX,ABSAVE,OPTION=NODUMP LA RD,REGSAV LA R1,TAPE STCM R1,15,TAPEASGN+1 MVI DUMPID,C'1' IDENTIFY THE PDUMP PDUMP DUMPSTRT,DUMPEND CALL DYNASSGN,(TAPEASGN) LTR RF,RF BNZ ALFINE OPEN TAPE CLOSE TAPE MVI TAPEASGN,X'28' MVI DUMPID,C'2' PDUMP DUMPSTRT,DUMPEND CALL DYNASSGN,(TAPEASGN) LTR RF,RF BNZ ALFINE EOF EQU * ALFINE EOJ RC=(15) ABEX EQU * LM R0,RF,8(R1) RELOAD REGS MVI DUMPID,C'3' PDUMP DUMPSTRT,DUMPEND MVI TAPEASGN,X'28' CALL DYNASSGN,(TAPEASGN) B ALFINE LTORG EJECT DUMPSTRT EQU * DUMPID DC C' ' TAPE DTFMT BLKSIZE=80,EOFADDR=EOF,IOAREA1=AREA,IOREG=(9), X DEVADDR=SYS005,FILABL=NO AREA DS CL80 DS 0D REGSAV DC 18F'00' ABSAVE DC 18F'00' TAPEASGN DS 0CL15 DC XL1'40' DC XL4'00' TAPEVOL DC CL6' ' TAPEERR DC CL3' ' FUNCTION THAT CAUSED ERROR TAPERET DC XL1'00' ERROR CODE DUMPEND EQU * * * REGISTER EQUATES R0 EQU 0 R1 EQU 1 R2 EQU 2 R3 EQU 3 R4 EQU 4 R5 EQU 5 R6 EQU 6 R7 EQU 7 R8 EQU 8 R9 EQU 9 RA EQU 10 RB EQU 11 RC EQU 12 RD EQU 3 RE EQU 14 RF EQU 15 END DYNATEST /* // EXEC LNKEDT // EXEC // EXEC LISTLOG /& * $$ EOJ Figure 4: DYNATEST - Dynamic Tape and Disk Assignment Test * $$ JOB JNM=DYNATEST,CLASS=0,DISP=D * $$ LST CLASS=Q,DISP=L * JOB SUBMITTED BY USER = MARK TERMINAL = A001 * MEM = DYNATEST DATE = 940707 TIME = 170543 // JOB DYNATEST TEST DYNAMIC DEVICE ASSIGN SUBROUTINE // LIBDEF OBJ,SEARCH=HCLIBS.UTIL // OPTION LINK,NOSYM PHASE DYNATEST,* // EXEC ASSEMBLY PRINT GEN DYNATEST START 0 BALR R2,0 USING *,R2 LA RD,REGSAV LA R1,TAPE STCM R1,15,TAPEASGN+1 LA R1,DISK STCM R1,15,DISKASGN+1 CALL DYNASSGN,(TAPEASGN) MVI DUMPID,C'1' PDUMP DUMPSTRT,DUMPEND LTR RF,RF BNZ ALFINE OPEN TAPE CLOSE TAPE MVI TAPEASGN,X'28' CALL DYNASSGN,(TAPEASGN) MVI DUMPID,C'2' PDUMP DUMPSTRT,DUMPEND LTR RF,RF BNZ ALFINE DISKTEST CALL DYNASSGN,(DISKASGN) MVI DUMPID,C'3' PDUMP DUMPSTRT,DUMPEND LTR RF,RF BNZ ALFINE OPEN DISK CLOSE DISK MVI DISKASGN,X'28' CALL DYNASSGN,(DISKASGN) MVI DUMPID,C'4' PDUMP DUMPSTRT,DUMPEND LTR RF,RF BNZ ALFINE EOF EQU * ALFINE STC RF,RETURNCD EOJ RC=(15) LTORG EJECT DUMPSTRT EQU * DUMPID DC C' ' RETURNCD DC X'00' TAPE DTFMT BLKSIZE=80,EOFADDR=EOF,IOAREA1=AREA,IOREG=(9), X DEVADDR=SYS005,FILABL=NO DISK DTFSD BLKSIZE=80,IOAREA1=AREA,TYPEFLE=OUTPUT AREA DS CL80 DS 0D REGSAV DC 18F'00' TAPEASGN DS 0CL15 DC XL1'40' DC XL4'00' A(TAPE) TAPEVOL DC CL6' ' TAPEERR DC CL3' ' FUNCTION THAT CAUSED ERROR TAPERET DC XL1'00' ERROR CODE * DISKASGN DS 0CL15 DC XL1'80' DC XL4'00' A(DISK) DISKVOL DC CL6' ' DISKERR DC CL3' ' FUNCTION THAT CAUSED ERROR DISKRET DC XL1'00' ERROR CODE DUMPEND EQU * * * REGISTER EQUATES R0 EQU 0 R1 EQU 1 R2 EQU 2 R3 EQU 3 R4 EQU 4 R5 EQU 5 R6 EQU 6 R7 EQU 7 R8 EQU 8 R9 EQU 9 RA EQU 10 RB EQU 11 RC EQU 12 RD EQU 13 RE EQU 14 RF EQU 15 END DYNATEST /* // EXEC LNKEDT // DLBL DISK,'DYNA.TEST.FILE',0,SD // EXTENT ,SYSWK1,1,0,2002,128 // EXEC /* // EXEC LISTLOG /& * $$ EOJ