Utilities uncovered

Introduction
Just imagine, you have IPLed your brand-new MVT system (or MVS, if and when it becomes available for Hercules). Now you decide to change some parameters in SYS1.PARMLIB. Of course, you want to play it safe, like  Wear a belt  Wear suspenders  Keep your hands in your pockets With other words, before you change a crucial member (let's say LNKLST00) you will want to make a safe copy, or backup, of this member. Very simple, you say: You fire up explorer, click with the mouse, drag the member.... Oooops wrong timeframe, wrong system, restarting..... You enter COPY LNKLST00 LNKLST01 at the MVT master console.... Ooops again, it ain't as simple as that at all What you really do is: You call up a little helper and tell him to do the copying for you. IBM has provided a lot of little helpers in MVT, and they are called UTILITIES. We will discuss a few of the more useful ones here.

General Syntax Guidelines
Utilities (aka utility programs) are invoked using standard JCL. (For a short introduction see the JCL in the N.U.D.E. document). You will neither need a JOBLIB nor a STEPLIB DD statement, as the utilities are in the standard system library. Depending on the utility program you will need certain required DD statements in your JCL SYSPRINT With the SYSPRINT DD statement you tell MVT into which output queue you want the utility to place its messages and report. Usually you would code
//SYSPRINT DD SYSOUT=A

i. Nix. Nothing.aka disk) IEBPTPCH .. you code: //SYSIN DD DUMMY Whenever you code commands for the utility (they are called Utility Control Statements). Inge Ting. if you are not interested in the messages: //SYSPRINT DD DUMMY SYSIN The SYSIN DD statement specifies the dataset that contains the commands you want to give to the utility program. some special rules apply: • • • Commands must go in column 2 or later Anything written in column 1 is considered a label If a command does not fit unto one line.e.: //SYSIN DD * or //SYSIN DD DATA If you do not want to issue any specific commands (but rely on some default action the utility will take). IEBGENER Copies sequential data sets IEBCOPY Copies partitoned data sets IEHDASDR Doing weird things to a DASD (. Does Nothing. Really. place a nonblank characer in column 72 and continue in the next line at exactly column 16 Utility Programs The following utility program will be discussed in this article (eventually) IEFBR14 A Dummy Program. Nada.. In most cases this is an instream data set.or. Ne Riens.

REGION=256K. but the error is in the EXEC statement! Which EXEC statement? Well. UNIT=3330. THAT exec statement.10. but what if the file to be deleted doesn't exist? Your job will fail with .NEW.DSN=NOT.CATLG).ANY.MSGLEVEL=(1.(10.(10.DELETE). it will fail with a JCL error!!! Can you see the error in the JCL statement? It is not really obvious. of course. SPACE=(CYL.10. Why do we need such a thing? Well. SPACE=(CYL.1) EXEC PGM=IEFBR14 DD DISP=(OLD. Unfortunately.REGION=256K.1) PGM=IEFBR14 DISP=(NEW.MSGLEVEL=(1.FILE. The JCL error message is JOB HAS NO STEPS And here is where IEFBR14 comes in: A program that just doesn't do anything .DSN=MY.but keeps the MVT JCL parser happy: //MYJOB JOB //ALLOC EXEC //NEWFILE DD // // // CLASS=A. UNIT=3330.DSN=MY.MSGCLASS=A.DCB=SYS1.MSGLEVEL=(1.NEEDED.REGION=256K.VOL=SER=WORK01.DCB=SYS1. the one that has not been coded.10)).MORE This is nice.PARMLIB From the NEWFILE DD statement it is clearly seen that this job tries to make a new file. Can delete and uncatalog datasets IEFBR14 A program that REALLY does nothing.FILE.Prints (or punches) partitioned or sequential datsets or members of partitioned data sets IEHLIST Prints datasets and VTOC information IEHPROGM Maintains the catalog.10)).1) DISP=(NEW.MSGCLASS=A.VOL=SER=WORK01.PARMLIB IEFBR14 can also be used to get rid of a data set: //MYJOB //DELETE //GETRID JOB CLASS=A. Zilch.MSGCLASS=A.NEW.DELETE. look at the following JCL: //MYJOB JOB //NEWFILE DD // // // CLASS=A.CATLG).

do not try to delete a member of a PDS with IEFBR14 . If DUMMY.REGION=256K.IMPORTNT. the member is gone.DELETE. and if it does not exist.DSN=VERY. Good.MSGCLASS=A.grown men have been known to cry because of this. the default operation is COPY from SYSUT1 to SYSUT2.DONT). Remember.IMPORTNT. What would the following JCL do: //DONTRUN JOB (REALLY.FILE? Hm .DELETE). not to individual members!!! IEBGENER IEBGENER is basically a copy program that copies sequential file to another sequential file. It can also be used to read a sequential file and place parts of it into different members of a partitioned dataset.DELETE).MORE. Not so good. Therefore it might be better to code sometimes: //MYJOB //DELETE //GETRID // JOB CLASS=A.CLASS=Z.JCL ERROR. it will be created at step beginning and deleted at step end By the way. the file is gone.DSN=NOT. Can be DUMMY. DATASET NOT FOUND and none of the subsequent steps will execute.ANY. it will be deleted. no editing . but also.(0)) If the file exists.DELETE.after the job completes. UNIT=SYSDA.MSGCLASS=A //ALLOC EXEC PGM=IEFBR14 //GETRID DD DISP=(OLD.1) EXEC PGM=IEFBR14 DD DISP=(MOD.'RUN THIS!!'.MSGLEVEL=(1. disposition in JCL refers to the whole dataset.SPACE=(TRK.FILE(OBSOLETE) Will it delete the member OBSOLETE which is in file VERY. Required DD statements SYSUT1 Dataset containing the INPUT data for IEBGENER SYSUT2 Dataset containing the OUTPUT data from IEBGENER SYSIN Utility control statements.NEEDED.

making the whole SYS1. This is where our next utility can shine: IEBCOPY IEBCOPY is a utility program used to copy partitioned datasets (aka libraries) Required DD statements SYSUT1 Dataset containing the INPUT data for IEBCOPY SYSUT2 Dataset containing the OUTPUT data from IEBCOPY SYSIN . Also.1) PGM=IEBGENER SYSOUT=A DISP=SHR. do not forget the member name on the SYSUT2 DD statement!!! Can you guess what happens if you do forget? IEBGENER will gladly write the contents of the member LNKLST00 to the beginning of the dataset SYS1. and it will be overwritten.REGION=256K.PARMLIB is located. DISP applies to the whole dataset.MSGLEVEL=(1.PARMLIB(LNKLST01) DUMMY Note. Unfortunately. this is the place where the directory of SYS1.MSGCLASS=A. not to a member!!!.PARMLIB dataset contents unaccessible. you might code: //MYJOB JOB //BACKUP EXEC //SYSPRINT DD //SYSUT1 DD //SYSUT2 DD //SYSIN DD CLASS=A.LINKLIB. but now you want to make a backup of library SYS1.DSN=SYS1. AND NOT DISP=NEW. that you code DISP=SHR on the SYSUT2 DD statement.DSN=SYS1. each copying one member at a time to a new dataset? Surely not!. Okay.SYSPRINT Utility Message Data Set To make a backup copy of a member of a PDS.PARMLIB.PARMLIB(LNKLST00) DISP=SHR. Would you want to code several hundred jobs.

SYSUT1 and SYSUT2.MSGCLASS=A. sometimes you might want to use more than one pair of datasets for copying. In the second step all the members of SYS1.PARMLIB //SYSIN DD * COPY INDD=SOURCE.(100.500)).MSGLEVEL=(1. Commands and keywords can be abbreviated to one character codes.10.PARMLIB //PARMSAVE DD DISP=SHR.O=PARMSAVE What has changed? We added Utility Control Statements. The second command therefore tells IEBCOPY to copy all members from SYS1. The second control statement looks a bit more crypric.CATLG).DSN=SYS1. you can code: //MYJOB JOB //CLEANUP EXEC //SYS2LNK DD (0)). You could achieve this with multiple IEBCOPY steps. Finito. but actually. Can be DUMMY. the default operation is COPY from SYSUT1 to SYSUT2.VOL=SER=WORK01.1) PGM=IEFBR14 DISP=(MOD. DCB=SYS1.VOL=SER=WORK01 PGM=IEBCOPY SYSOUT=A DISP=SHR. Now.1) //BACKUP EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=A //SOURCE DD DISP=SHR.REGION=256K. no editing SYSPRINT Utility Message Data Set To make a backup copy of a partitioned dataset.DSN=SYS2.SPACE=(TRK.UNIT=3330.REGION=256K.LINKLIB //PARMLIB DD DISP=SHR.LINKLIB.PARMLIB.LINKLIB.PARMLIB to SYS2.LINKLIB will we copied to a newly created SYS2.DELETE). SPACE=(CYL.DSN=SYS1. i. we tell IEBCOPY to use different DDnames than the default ones.Utility control statements.MSGLEVEL=(1. But a more elegant way can be chosen: //MYJOB JOB CLASS=A.MSGCLASS=A.DSN=SYS2.OUTDD=TARGET C I=PARMLIB.LINKLIB. it isn't.DSN=SYS2. of course.DSN=SYS1.LINKLIB DUMMY The first step deletes a preexisting SYS2. Simple.LINKLIB DISP=(NEW. . DSN=SYS2. If DUMMY.LINKLIB.DELETE. UNIT=3330.LINKLIB //TARGET DD DISP=SHR. The first one tells IEBCOPY to copy from INput DDname SOURCE to the OUTput DDname TARGET. // //BACKUP EXEC //SYSPRINT DD //SYSUT1 DD //SYSUT2 DD // // // //SYSIN DD CLASS=A.e.

PARMLIB).REGION=256K.OUTDD=PARMPROC SELECT MEMBER=(ONEMEMBR) S M=(MEMBERA. But what if the target dataset does already exist? Then we must tell IEBCOPY explicitly that we want members to be overwritten: //MYJOB JOB CLASS=A. i.PROCLIB //PARMLIB DD DISP=SHR.PROCLIB //PARMPROC DD DISP=SHR.DSN=SYS1. they do not exist!! The correct way to copy just a few members is //MYJOB JOB CLASS=A. Obviously.DSN=SYS2. This is not a problem when the target dataset has just been created. like named members will not be overwritten.MSGLEVEL=(1. Keywords can be abbreviated again. you would also want to jsu copy a few member.1) //BACKUP EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=A //PROCLIB DD DISP=SHR.PARMPROC //SYSIN DD * COPY INDD=(PROCLIB.OUTDD=PARMPROC Very good.MEMBERB.DSN=SYS1.MSGLEVEL=(1.).1) //BACKUP EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=A //PROCLIB DD DISP=SHR. There are two possibilities. Look at the next example: . I have not been telling the truth.PROCLIB //PARMPROC DD DISP=SHR.MSGCLASS=A.DSN=SYS1. one using concatenation (see JCL in the N. So far you know how to copy complete libraries.D. Don't even think about wildcards.REGION=256K. or only one.DSN=SYS1.1) //BACKUP EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=A //PROCLIB DD DISP=SHR.PARMLIB //PARMPROC DD DISP=SHR.U.MSGLEVEL=(1.DSN=SYS1.REGION=256K.MEMBERC) with other words.R)).PARMPROC //SYSIN DD * COPY INDD=((PROCLIB.We can also copy several datasets into one target file.OUTDD=PARMPROC A list of DD-names is enclosed in brackets Actually.e.PARMPROC //SYSIN DD * COPY INDD=PROCLIB. you add another utility control statement where you tell IEBCOPY which members you want selected. and nothing but the truth. The other one by using a list of DDames //MYJOB JOB CLASS=A. Also.MSGCLASS=A.MSGCLASS=A. Members will only be copied when they do not already exist in the target dataset. you can copy a full library except for selected members. the whole truth.DSN=SYS1.E.

O=PARMPROC SELECT MEMBER=((MEMBERA.REGION=256K. overwriting an existing MEMBERB. this member is still part of the dataset..DSN=SYS1.O=PARMPROC SELECT MEMBER=((MEMBERA.. You might wonder what the pair of brackets commas is all about. Actually.MEMBERB.PROCLIB //PARMPROC DD DISP=SHR. even if it cannot easily be accessed.DSN=SYS1.PROCLIB and will copy it to SYS1.REGION=256K.PARMPROC //SYSIN DD * C I=PROCLIB.R)) This will take MEMBERA.R)) Note the double brackets again.MSGCLASS=A.//MYJOB JOB CLASS=A.REGION=256K.PROCLIB //PARMPROC DD DISP=SHR. code //MYJOB JOB CLASS=A.they indicate that a parameter has been omitted.O=PARMPROC EXCLUDE MEMBER=(ONEMEMBR) Again.PROCLIB //PARMPROC DD DISP=SHR.1) //BACKUP EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=A //PROCLIB DD DISP=SHR. When your datset fills up this way.MSGLEVEL=(1.1) //BACKUP EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=A //PROCLIB DD DISP=SHR.PARMPROC //SYSIN DD * C I=PROCLIB. This is done using IEBCOPY again..1) //BACKUP EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=A //PROCLIB DD DISP=SHR. every time you change or overwrite an existing member.PARMPROC.DSN=SYS1. This command will take MEMBERA from SYS1. and will store it as MEMBERB in the target dataset. a COMPRESS is required for garbage collection.DSN=SYS1.MSGCLASS=A. A compress (=garbage collection) is performed if and only if the input and the output dataset of IEBCOPY are identical: . If you really want to do this.DSN=SYS1. and will overwrite any existing MEMBERA in the process. The omitted parameter specifies the new name of a member in the target dataset: //MYJOB JOB CLASS=A. Compress Every so often (and more often than you like) a PDS fills up with garbage.PARMPROC //SYSIN DD * C I=PROCLIB.MSGLEVEL=(1. existing members in the target dataset will not be overwritten.DSN=SYS1.MSGLEVEL=(1.MSGCLASS=A.

To list a Volume Table of Contents.PROCLIB DUMMY IEHLIST provided by Kevin Shelly IEHLIST is a utility program used to list information from a VTOC (Volume Table of Contents).PROCLIB DISP=SHR.MSGLEVEL=(1.REGION=256K.VOL=SER=DLIB01.DSN=SYS1.//MYJOB JOB CLASS=A.MSGLEVEL=(1.1) PGM=IEBCOPY SYSOUT=A DISP=SHR. Required DD statements anyname A DD reference to a disk volume that IEHLIST requires in order to read stuff on that volume.VOL=3330=DLIB01 /* .REGION=256K. or a PDS (Partitioned Data Set) directory. SYSPRINT Utility message data set.MSGLEVEL=(1.MSGCLASS=A.MSGCLASS=A.DSN=SYS1.1) //LISTVTOC EXEC PGM=IEHLIST //SYSPRINT DD SYSOUT=A //VOLDD DD UNIT=SYSDA.REGION=256K. Another possibility to achieve the same result would have been //MYJOB JOB //BACKUP EXEC //SYSPRINT DD //SYSUT1 DD //SYSUT2 DD //SYSIN DD CLASS=A. SYSIN Utility control statements.PROCLIB //SYSIN DD * COPY INDD=PROCLIB. you can code: //MYJOB JOB CLASS=A. The utility doesn't care.MSGCLASS=A. Choose any DDNAME you want.PROCLIB dataset. a catalog.DSN=SYS1.1) //BACKUP EXEC PGM=IEBCOPY //SYSPRINT DD SYSOUT=A //PROCLIB DD DISP=SHR.DISP=OLD //SYSIN DD * LISTVTOC FORMAT.OUTDD=PROCLIB would reclaim space in the SYS1.

1) //LISTCTLG EXEC PGM=IEHLIST //SYSPRINT DD SYSOUT=A //VOLDD DD UNIT=SYSDA. If the DASD volume is mountable instead of permanently mounted.LINKLIB.SER=PUB001).MSGCLASS=A. the LISTPDS control card accepts either a FORMAT option or a DUMP option. why don't you send it to me? . The FORMAT option is for PDS members created by the linkage editor (load modules).// This will print a list of the datasets on that volume along with some of their attributes.1) //LISTPDS EXEC PGM=IEHLIST //SYSPRINT DD SYSOUT=A //VOLDD DD UNIT=SYSDA. IEHDASDR Sorry.MSGLEVEL=(1.PL1LIB).DISP=OLD //SYSIN DD * LISTCTLG VOL=3330=IPL001 /* // In order to list the contents of a PDS directory.DEFER). use something like: //VOLDD DD UNIT=(SYSDA. Any number of control statements can be included in one IEHLIST step as long as all the referenced volumes are mentioned in DD statements similar to the VOLDD DD statement shown above. The FORMAT option is formatted for easy reading.DISP=OLD instead.DISP=OLD //SYSIN DD * LISTPDS DSNAME=(SYS1. didn't het around to writing this chapter yet.MSGLEVEL=(1. The DUMP format shows each record of the VTOC in a dump-like format. To list the contents of the catalog on a particular volume.VOL=SER=IPL001.FORMAT /* // Like the LISTVTOC control card. There are two choices for the type of report generated. you can code: //MYJOB JOB CLASS=A.VOL=3330=MVTRES.VOL=(PRIVATE.MSGCLASS=A.SYS1.REGION=256K..VOL=SER=MVTRES. you can code: //MYJOB JOB CLASS=A. If you have a write-up on IEHDASDR.REGION=256K.

Enjoy your private hercules mainframe .