Week 12-B Notes for DAT2330 - Ian Allen Supplement to Text, outlining the material done in class and lab. Remember - knowing how to find out the answer is more important than memorizing the answer. Learn to fish! RTFM![*] ([*] Read The Fine Manual) ==================================== MVS - O/S 390 - Job Control Language ==================================== -IAN! idallen@ncf.ca Spring 2002 These notes are largely based on lectures by Harold Smith: - DAT2330 - Harold Smith Class - Wed Feb 3, 2000 --------------------------------------- MVS JCL Example 2 and attached homework --------------------------------------- Using IDCAMS ------------ - what are the IDCAMS control statements used for? - tell the IDCAMS program what to do - the control statements choose among many possible options - similar to command line arguments and flags - IDCAMS could take parameters; but, there are too many - instead, it reads a dataset (file) containing the options - dataset always comes on DDname SYSIN (compiled into IDCAMS) - we usually write JCL to make SYSIN connect to "instream data" - real-world use may have 10-15 lines of control statements - what DDnames are used in the copy (IBM calls it "REPRO") step? - you get to pick the two DDnames used by IDCAMS - the two DDnames are given in the IDCAMS "REPRO" control statement - IDCAMS will expect to find those two DDnames in the JCL - if you make a spelling error, you won't know until IDCAMS runs - this will cause a run-time error, not a JCL error - IDCAMS prints a report of what it did (or did not do) on DDname SYSPRINT - to make sure the operation worked and say how much was copied - less than 100 lines (more like 10 to 20) - real-world use would probably be to hold this for TSO viewing - specification doesn't say what to do - use the best SYSOUT queue (for less than 100 lines) Review: Compile, Link, and Go ----------------------------- - what step name and DDname is needed for the instream COBOL source program? - not specified in the job specifications - we have to ask or guess - choosing the right step name is a JCL issue - choosing the right DDname within the step is a run-time issue - to see the step name, we will need to set MSGLEVEL to get maximum JCL information about the proc printed from our test run - we want to see the JCL inside the proc, to see the step names hiddin therein - running the compiler will tell us what the correct DDname is - we guess at "COMP" for the step and "SYSIN" for the DDname: COMP.SYSIN - the "COMP" part of the name was chosen by the author of the COBOLCLG proc - the "SYSIN" part of the name was chosen by the author of the COBOL compiler program itself - since the compiler is an IBM utility, we guess at "SYSIN" - guessing the wrong step name will generate a JCL error - guessing the wrong DDname will generate a run-time error from the compiler (but we won't see the run-time error until we fix the JCL error!) - what part of our CLG job wants to read dataset TAPEDATA? - not the compiler (review: what does compiler do) - not the linker (review: what does linker do) - must be the "go" step (where my compiled program executes) - what is the internal step name of this "go" step in the COBOLCLG proc? - what internal step name is used in the COBOLCLG proc to execute my program? - not specified in the job specifications - we have to ask or guess - set MSGLEVEL to display contents of proc and then run the job - guessing the wrong step name will generate a JCL error - JCL listing will show proc, from which we can read the right step name - fix the JCL and resubmit Note that you can't "watch the program run" as you do with Unix, Windows - batch programming only - prepare the JCL and send it off - it works or fails! New Parameters -------------- New keyword parameters for the JOB card: - MSGCLASS=, MSGLEVEL=, PRTY=, TYPRUN= MSGCLASS (p.69) - specifies which sysout spool queue to use for JES/JCL messages - installation default usually sends output to queue for the "A" printer - may need to spool to TSO queue (especially if we know job will fail) - choose letter closest to A for best turn-around time - we choose sysout class "dog" ("D") for this job because we know the job will fail (because we are guessing at some step and DDnames) MSGLEVEL (p.74) - level of JOB processing detail coming from JES and JCL - this does not affect output (SYSOUT) from any programs run by the JCL - only affects output of the JES/JCL/allocation messages - default is set by each MVS shop (differs from shop to shop) - (1,1) is maximum (uses positional parameters) - (,1) means use default for 1st parameter (see Chapter 4 syntax) - we choose verbose level (1,1) so that we see proc listing - we could use (1,0) and still would see the proc listing - once we know the correct proc step names, we can choose the bare minimum set out in the first paragraph of the job specification: (0,0) PRTY (p.292) - choose your priority among various CLASS= jobs - not strictly FIFO - actual value depends on MVS version, e.g. 0 to 14 or 15, with 15 highest - remember which version of JES uses which high priority! - some account codes probably cannot use some priorities - some priorities may increase the cost of your job run - we are asked to choose a "medium-high" priority: e.g. 11 (out of 15) TYPRUN (p.75) - SCAN: used to scan JCL for JCL errors (verify correct JCL) - the job is not actually run - HOLD: can be used to hold a job in the input queue - the job is not run until released - need to use this parameter for the homework JCL assignment New keyword parameters for the DD card: - DCB=(DSORG=,LRECL=,BLKSIZE=,RECFM=) - LABEL=(,AL) - UNIT= - VOL=SER= (see the text; all are described in the commentary below) Detecting Errors ---------------- There are two major types of errors: JCL errors and run-time errors. - coding TYPRUN=SCAN will not find run-time errors - it only finds errors in the JCL, not in the instream data JCL Errors: - syntax errors; misspelled JCL parameters; etc. - a wrong step name in a compound DDname when using a proc is a JCL error - the JCL processor detects that your step name doesn't match any step name in the proc when it fetches the proc from SYS1.PROCLIB Run-Time Errors: - you have to *run some program* to detect an input or DDname error - run the compiler; run IDCAMS; run your COBOL program; etc. - run-time error: IDCAMS control statement errors (input error) - run-time error: errors in spelling of DDnames - instream data (including IDCAMS instream control statements) are not subject to JES or JCL rules or syntax checking - instream data is not read by the JCL processor; it cannot cause a JCL error - instream data is read by some *program*, and only when the program *runs* - instream data can only cause run-time errors - a wrong DDname is a run-time error, not detected by the JCL processor - you must run the program to have the program look for its DDnames - incorrectly matching DDnames can only cause run-time errors - BUT: a DDname that is too long (more than 8 chars) would be a JCL error Coding the JCL for Example #2 ----------------------------- - UPPER CASE ONLY, etc. - continuation lines: start with "// ", indent to 16 or less. - remember the trailing commas on lines being continued - one missing comma throws the job out - don't indent past column 16 - some posted examples violate this rule so that they read more clearly to the novice eye - don't code this way! - review previous examples Step One -------- In what order do we write DD statements? - output before input (but obey MVS rules for over-riding PROC's) - professors want instream DD statements last (but obey PROC rules) - put biggest instream last (but obey PROC rules) Guesses are documented using comments before the associated statement. Commentary on the JCL is listed after the step, below: //* There are some Real World Suggestions that apply to this step; //* see the commentary below the step. //* //CBLTSTE2 JOB 2000EX,'MY NAME',CLASS=D,MSGLEVEL=(0,0),PRTY=11 //MAKETAPE EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=A //OUT DD DSN=MYTSTDAT,DISP=(NEW,PASS), // DCB=(BLKSIZE=4080,RECFM=FB), // UNIT=SCRATCH //SYSIN DD * REPRO INFILE(IN) OUTFILE(OUT) /* //IN DD * ... Many test records go here. The syntax of these lines is dictated by ... the input requirements of the COBOL program that will be reading them. /* - style: choose a good job name and step name - choosing a good name is a *choice*, not a *guess* - JOB CLASS= - this JOB class is not a SYSOUT print queue class! - this CLASS tells JES about all the resources used by the whole job - JOB classes (letters) change from MVS shop to MVS shop - and from example to example and from test to test - do not write these classes on your test crib sheets - check the list of classes specified for this example - based on resource needs, we choose class "Dog" ("D") for this job - JOB MSGCLASS= - MSGCLASS *is* a SYSOUT print queue class (for the JCL listing)! - this was not required in specification (but see Real World, below) - JOB PRTY= - "medium" would be approximately 7, so "medium-high" would be about 11 Real World Suggestions (not given in job specification) - these are suggestions, not given in the job specification, that you would probably do "on the job" to make your life easier - suggestions are not required on tests or exams (but may be bonus points) - Suggestion: add MSGCLASS=D to the JOB card - hold the JCL listing for viewing by TSO; because, we are making some (probably wrong) guesses at step and DDnames - don't want to print a failed job on paper; send it to TSO instead - the SYSOUT hold queue class is "Dog" ("D") for this example - when the job is working, we can let it print (remove MSGCLASS) - Suggestion: use MSGLEVEL=(1,0) to see the PROC listing - we are making some guesses about the step names used inside the PROC - we should get a PROC listing, to find out what the real step names are - without the PROC listing, we can't fix our incorrect step guesses! - when we know the correct PROC step names, return to using job spec (0,0) - DSN=MYTSTDAT: we choose an output dataset name for the NEW temporary tape - a name we choose is *not* a "guess"; it is a *choice* - we are not *guessing* this name; we are making it up - a DCB parameter block describes the characteristics of the NEW dataset - we concentrate on 4 DCB subparameters: DSORG, LRECL, BLKSIZE, RECFM - look up each of these new parameters in the book - we usually write them in this order: DSORG, LRECL, BLKSIZE, RECFM - a logical order; but, MVS doesn't care about keyword parameter order - you can optionally omit the DCB=() around these subparameters - DCB only needed for a NEW dataset that does not exist yet - existing datasets keep their DCB inside the dataset "label" - no need to specify DCB for existing datasets, only NEW ones - DD SYSOUT= statements are print queues; they don't normally need a DCB - some DCB defaults apply when a program doesn't specify all of a DCB - IDCAMS copies all of input DCB to output DCB if you don't specify - COBOL programs have clauses that set some or all DCB parameters - DSORG: tapes must be specified as physical sequential (PS) - DSORG=PS is the only DSORG we use in this course - since we are using IDCAMS, and IDCAMS by default copies the input DCB to the output DCB, and the DSORG of the input (instream data) is the same as the DSORG of the output (tape), we do not code DSORG in the JCL - LRECL: the input is instream data, so we use a record length of 80 - instream data is always 80 characters (LRECL=80) [punch cards!] - since we are using IDCAMS and the input LRECL is the same as the output LRECL, we do not code LRECL in the JCL - BLKSIZE: pick largest multiple of LRECL that fits output medium block size - tape inter-block gap takes sizeable space; don't want a lot of them - why not use really huge block sizes to minimize inter-block gaps? - uses up too much memory in I/O buffers - IDCAMS would copy the input DCB BLKSIZE to the output DCB BLKSIZE - instream data has BLKSIZE=80 which is terrible for a tape - must "re-block" the data for the output tape - a block size less than or equal to 4K fits in IBM paging buffer nicely - output block must be multiple of LRECL (80) less than 4K (4096) - choose the largest multiple of LRECL that fits in 4K - Formula: integer(4096 / 80) * 80 = 4080 - RECFM: we are defining fixed length records with blocking: FB - the other less common use is RECFM=F (no blocking used, e.g. instream) - IDCAMS input instream data uses RECFM=F; but, we must use FB for output - we must code this in the JCL, to over-ride the IDCAMS default - UNIT: we must specify onto what kind of device we wish to write our NEW data - tape drive type "3480" is a possible tape UNIT; but, it's too specific - use MVS system-defined "device group names" instead - chosen by system programmers at SYSGEN time when MVS was installed - consult shop for names (names will differ from shop to shop) - group SCRATCH was specified as an appropriate UNIT for a non-specific tape - no need for VOL or SER parms since we use *any* tape (UNIT=SCRATCH) - operator will select a tape for us from the SCRATCH pile - no need for tape LABEL parm if using standard IBM tape labels (we are) - Note: this new temporary tape is PASSed and not put in the system catalog - when this job ends, there is no way of finding this tape again, which is okay, since it's a temporary tape and will be re-used IDCAMS DCB handling ------------------- IDCAMS defaults its output DCB specifications to be equal to input specs - this is almost always terrible when copying instream data to disk or tape! - instream input data has the following DCB: DCB=(DSORG=PS,LRECL=80,BLKSIZE=80,RECFM=F) [not FB!] - writing a tape with these default DCB parms would waste a *lot* of tape - remember to re-block your IDCAMS output when reading from instream! - specify DCB parameters for the output DD statement when using IDCAMS - you never need to specify DCB for an input dataset or an existing output dataset (the DCB is kept in the label of the dataset) - you must only specify the DCB for an output dataset that doesn't already exist (or that you are re-creating as you write it) Finding Uncataloged Datasets ---------------------------- In all our previous examples, all dataset names were always cataloged: - the name of the dataset was put into the system catalog along with the location (UNIT, VOL, SER) of the dataset - when you reference a cataloged name in your JCL, the system can find out the UNIT (e.g. disk or tape) and VOL=SER (which disk or which tape) based on stored catalog information for the dataset name - you never need to code UNIT or VOL=SER for a cataloged dataset If a dataset name is *not* in the system catalog, you must specify UNIT and VOL=SER so that the system can find it. Once an uncataloged dataset is found in a JCL job step, it can be PASSed to a following job step without requiring UNIT and VOL=SER again (see p.121 for other retained parameters). If you forget where an uncataloged dataset is (unknown UNIT or unknown VOL=SER), you've lost it until you tell the systems people to go find it for you! Cataloged datasets are easier to use in JCL; but, you are charged a space and time fee for each catalog entry. Step Two -------- MVS rules require us to order DD statements for a PROC in same order as the internal steps in the PROC. Find out the step names! We have to guess the PROC step names here, since they weren't provided in the spec: //* NOTE: I am guessing both of the PROC step names; they were not provided. //* I am also guessing the compiler input DDname; it was not provided. //* Incorrect step names will trigger JCL errors. //* Incorrect DDnames will trigger run time errors. //CLG EXEC PROC=COBOLCLG //COMP.SYSIN DD * ...COBOL program source goes here... /* //GO.PRINTOP DD SYSOUT=B //GO.MSTOUT20 DD DSN=TSTOUT,DISP=(NEW,PASS), // DCB=(BLKSIZE=4000,RECFM=FB), // UNIT=SCRATCH //GO.TAPEDATA DD DSN=MYTSTDAT,DISP=(OLD,DELETE) //GO.LSTIN DD DSN=PRODLIST,DISP=(OLD,KEEP), // LABEL=(,AL),UNIT=SYSSQ,VOL=SER=201111 - style: choose a good step name (Remember: a choice is not a guess) - style: document your guesses, so you know what to change when it fails - state whether the guess causes a JCL or run-time error - MSTOUT20 DCB: look inside COBOL program source to see what the author decided for the output data format (output DCB parameters): - COBOL program itself specifies DSORG ("is sequential") - no need for us to code DSORG in JCL - COBOL program itself specifies LRECL ("record contains") - no need for us to code LRECL in JCL - "block contains 0 records" means let JCL set the block size - don't want to hard code the size inside the COBOL program - want to choose best block size based on output device characteristics - choose largest multiple of LRECL that fits in output device block - Formula: int(4096 / 100) * 100 = 4000 - therefore: we only need to code BLKSIZE and RECFM in the DCB - always code RECFM if you code BLKSIZE (they are a pair) - no need for VOL or SER parms since we use *any* tape (UNIT=SCRATCH) - the operator will find us a scratch tape to use - we will catalog this tape at the end of the job when we are done - this tape will become one of "our" tapes (billed to us) - the specifications don't give the name of this output dataset; we choose one: "TSTOUT" (Remember: a choice is not a guess) - TAPEDATA: the MYTSTDAT dataset name is not in the system catalog; but, it was PASSsed from a previous step, so UNIT and VOL=SER are remembered - input datasets and passed datasets don't need to specify DCB - much of DCB is kept in dataset label for existing datasets - see p.121 for list of retained catalog and passed parms - only need to code DSN and DISP for this uncataloged input dataset - specification says to delete the tape after the job ends - this is the last step using the tape; we delete it here - LSTIN: the PRODLIST dataset is an uncataloged ANSI (non-IBM) tape dataset - the exact location of the uncataloged PRODLIST dataset must be specified - need to specify UNIT and VOL=SER to find it - VOL takes keyword subparameters - you can reorder them - don't need parentheses if using only one subparameter (Chapter 4) - we only use VOL=SER= in this course - the type of non-IBM LABEL must be specified - ANSI: American National Standards Institute - non-IBM standard; used to share tapes with non-IBM sites - LABEL parameter takes positional parameters! - cannot reorder the parameters, need leading commas - need second parameter to set ANSI Labels: LABEL=(,AL) - you must specify LABEL to *read or write* a non-IBM tape! (you can't store the type of the tape in the label, because you need to know the type of the tape to even read the label) - the specification doesn't say what to do with this tape when we're done, so we do the safe thing and KEEP it Start of Step Three ------------------- Use IDCAMS to copy the tape to the printer hold spool queue. We know that IDCAMS needs four DDnames for a copy (REPRO) operation. //VERIFYCP EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=A //OUT DD SYSOUT=D //IN DD DSN=TSTOUT,DISP=(OLD,CATLG) //SYSIN DD * REPRO INFILE(IN) OUTFILE(OUT) /* // - style: choose a good step name - style: output DD before input DD - style: instream DD come last (professor preference) - job spec doesn't say where to send the IDCAMS status messages - use the best SYSOUT queue (for less than 100 lines of messages) - Real World Suggestion: could send them to the same TSO hold queue - no need to code a DCB for a PASSed or input dataset - DCB only needed for NEW datasets (output) if the DCB info is not already set in the program creating the dataset - PASSed dataset UNIT and VOL=SER are remembered between steps (p.121) - no need to code location of a PASSed (or cataloged) dataset - The specifications say to catalog the tape; we do this in the last step that uses the tape. (If we did it in an earlier step, it would cause the tape to be dismounted and put in storage. The operator would have to go back to storage to get the tape out for the next step that used it. This is annoying.) - putting the name TSTOUT in the catalog means future references to this name don't need to specify UNIT or VOL=SER (the parms will be in the catalog). (Note: Real-world cataloged dataset names are much longer!) End of job. To get a listing of just the JCL from this file, use the Unix command: $ grep '^/' thisfile Do the "MVS JCL Example 2 Homework" question; we will review it next class.