Week 15-A 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 23, 2000 --------------------------------------------------------- Today: review the homework - "MVS JCL Example 4 Homework" --------------------------------------------------------- Approach: Cross out every line in job specification as you add it to JCL. Use a Flow Diagram if you find it useful. (It is never required.) Review ------ What is the difference between a PROC and a program? - proc is a set of JCL (it is text; it can't be executed as machine code) - program is machine code (binary; it can't be included as a PROC) - a PROC contains steps that execute programs Where does MVS find cataloged procedures? - these are specified by saying EXEC PROC= - in SYS1.PROCLIB Where does MVS find programs (e.g. IDCAMS, COBOL compiler, linker)? - these are specified by saying EXEC PGM= - in SYS1.LINKLIB How can I make EXEC PGM= find my own program in my own library? - use a JOBLIB or STEPLIB DD statement for your library Coding the JCL for Example 4 Homework ------------------------------------- No guesses were made in coding this job. Where information was missing in the job spec, we could find it by looking it up in the given PROC listing. Step One -------- //COBTSTH4 JOB 4111HW,'MY NAME',CLASS=D - CLASS= specifies the JES job queue - this is not a SYSOUT queue - total lines output looks like less than 5000 but more than 500 - we do use tapes - we will be coding a REGION that fits under 100M - based on the job requirements, we choose job CLASS=D Real World Suggestions (these were not given in the job spec): - these are not required on a test or exam; use them on the job if helpful - MSGCLASS= specifies sysout print queue for *JCL/JES* messages only - on the job, always send it to TSO if possible, to class A if not - TSO sysout queue is class D in the job spec: MSGCLASS=D - MSGLEVEL was not specified in job specification, so you can leave it out (use the system default). On the job, code whatever you think is reasonable. Since we already have the PROC listing, it might be better to code MSGLEVEL=(0,1); but, if you send the JCL to TSO using MSGCLASS=D, no paper is wasted either way. You choose. //TESTGEN EXEC PGM=TESTGEN,PARM=(PAYROLL,HOURLY) //STEPLIB DD DSN=TEAM1.PVTLIB,DISP=(SHR,KEEP) - program TESTGEN: - this is a binary program, not a PROC - using your own program to generate test data is common - need to test all your program boundary conditions - real data may not be varied enough for testing - the TESTGEN program uses PARMs for "command line parameters" - PARM always goes on an EXEC statement - the IDCAMS program uses DDname SYSIN to read its parameters (options) - no need to qualify (with a step name) a PARM used on a PGM= - this is not a PROC; there is only one program being executed - there is only one program (PGM=) in one step here - need to get TESTGEN executable program from a private library - PGM= will look for programs in library given by JOBLIB or STEPLIB - PGM= will find the TESTGEN program in the given STEPLIB library - these libraries contain *executable* modules, not object files - object file libraries are used by link-editors (linkers) - only one program (TESTGEN) comes from the private library of executables - use STEPLIB for the one step, not JOBLIB for the whole job - no need for COND on the EXEC statement of the first step of a job - there is no previous step for COND to check! //TSTOUT DD DSN=TESTDATA,DISP=(NEW,PASS), // UNIT=DASD,SPACE=(4000,(125,10)) - we choose the output dataset name (this is not a "guess") - output DCB (DSORG, LRECL, BLKSIZE, and RECFM) is fully given in job spec - the TESTGEN program specifies the whole DCB for us - no need for DCB at all in the JCL - the program has it all - don't code things in the JCL that are already correct in the program - calculate SPACE needed for the NEW disk dataset: 10,000 records of 50 bytes each = 500,000 bytes 500,000 bytes divided by 4000 bytes in a block = 125 blocks (primary extent) - no secondary extent size suggested (on the job - ask around) - I picked a round number a bit less than 10% Step Two -------- //CLG EXEC PROC=COBOLCLG,COND=(3,LT), - COND defaults to test against return codes of *all* previous steps - there is only one previous step at this point - COND is reversed - encode it as follows: English: Execute, provided that the TSTGEN program of the previous step did not set a return code greater than 3." Simplify: execute IF NOT RC > 3 (simplify) Simplify: execute IF RC <= 3 (apply negation logic) Step 1: execute IF RC <= 3 Step 2: execute IF 3 >= RC (put number on left) Step 3: skip IF 3 < RC (complement to make into "skip") Step 4: COND=(3,LT) - Check it: decode the COND=(3,LT) as follows: IF 3 < RC THEN skip this step IF 3 >= RC THEN execute this step IF RC <= 3 THEN execute this step - that's correct // PARM.COB2=(XREF,OBJ), - PARMs could be applied to pass options to any step in a proc - but the job spec says to only affect the compiler step, not all steps - the compiler executes in PROC step name COB2 - therefore: add step name suffix to PARM --> PARM.COB2= - job spec says this PARM is to be completely over-riding - no need to copy the other PARM values from the PROC listing - NOTE: Just like DD statements, PARMs must appear in the order that the internal steps appear in the PROC (text p.249) - all the COB2 PARMs must come before the LKED PARMs before all the GO PARMs. // COND.GO=(4,LE,CLG.COB2), - job spec says to execute the GO step only if the compile step (internal PROC step name COB2) sets a code less than 4 - must affect only the GO step in the PROC, not all the steps - we code COND.GO= to set the COND on only the GO step in the PROC - COND is reversed - encode it as follows: English: Execute only if the compile step sets a condition code of less than 4" Step 1: execute IF RC < 4 (simplify) Step 2: execute IF 4 > RC (put the number on the left) Step 3: skip IF 4 <= RC (complement to make into "skip") Step 4: COND=(4,LE,CLG.COB2) (remember the step to test) - Check it: decode COND=(4,LE,CLG.COB2) as follows: IF 4 <= RC THEN skip this step IF 4 > RC THEN execute this step IF RC < 4 THEN execute this step - that's correct - this COND must check the return code from the compile step - don't check all the steps (default); only check the compile step - need to code the step name to check as: mystepname.procstepname - step name is coded as: CLG.COB2 - write: COND=(4,LE,CLG.COB2) // TIME.GO=(,30),REGION.GO=4M,ADDRSPC.GO= - these EXEC parameters need step name .GO on the end - must affect only the GO step in the PROC, not all the steps - remove ADDRSPC if/when you find it - specifying an empty value removes the parameter //COB2.SYSLIB DD DSN=TEAM1.SRCLIB,DISP=SHR - SYSLIB libraries often come before input and output statements (a guideline - not a rule) - job spec says to use our own COBOL source library - it is the compiler program that will get source from a *source* library - source is not an executable program - source is not an object module - this library is not a linklib-style library - this library is a library of *source code* - this is not an object library! - compilers do not read object modules; compilers read source code - read the given PROC to locate the DDname for the source library - locate the compiler step in the PROC: step name COB2 - locate the source library DDname in the PROC: DDname SYSLIB --> we code //COB2.SYSLIB DD to over-ride it with our own library //COB2.SYSPRINT DD SYSOUT=D - job spec says hold compiler output for TSO - To send compiler output to TSO, we need to over-ride the default SYSOUT specification set inside the PROC we are using. - look in the PROC to discover where the PROC sends compiler output - look in the PROC to find the step name that uses the compiler program - proc step COB2 has compiler EXEC in it - the DDname for the compiler listing is given there as SYSPRINT - over-ride this line using //COB2.SYSPRINT in our own JCL //COB2.SYSIN DD * [...instream COBOL source goes here...] /* - we prefer to put instream data last (of all the COB2 DD statements) //LKED.SYSLIB DD DSN=Y2K.OBJLIB,DISP=SHR - job spec says over-ride (replace) the library used by the link editor - read the given PROC to locate the DDname for the linker library - step LKED, DDname SYSLIB --> //LKED.SYSLIB - the LKED step over-ride must come *after* the COB2 over-rides and *before* the GO step over-rides (MVS rules for PROCs!) //GO.DATOUT DD DSN=TESTOUT,DISP=(NEW,CATLG), // BLKSIZE=4000,RECFM=FB, // UNIT=DASD,SPACE=(4000,(250,10)) - we choose the output dataset name (this is not a "guess") - catalog this dataset now, since we don't use it later in this job - check my COBOL source to see what DCB it specifies - don't specify DCB parameters that the COBOL already specifies - but always code RECFM if you have to code BLKSIZE - int(4K / 100) * 100 = 4000 bytes per block - 10,000 records of 100 bytes each = 1,000,000 bytes 1,000,000 bytes divided by 4000 bytes per block = 250 blocks (primary extent) - secondary extent size was not given; I estimate 10 blocks (4%) as a nice round number //GO.SUMM DD DSN=SUMMTAPE,DISP=(NEW,PASS), // BLKSIZE=2000,RECFM=FB, // LABEL=(,AL), // UNIT=TAPES,VOL=SER=123456 - we choose the output dataset name (this is not a "guess") - ANSI label tapes have 2k blocksize limit - int(2K / 100) * 100 = 2000 bytes per block - no SPACE= needed for tapes - must specify UNIT and VOL=SER= for uncataloged tapes //GO.DATIN DD DSN=TESTDATA,DISP=(OLD,DELETE) - this is the dataset PASSed in from the first step - PASSed datasets need nothing except DSN and DISP - job spec says to delete this after its last use Step Three ---------- //SHOWTAPE EXEC PGM=IDCAMS,COND=(0,NE) //SYSPRINT DD SYSOUT=D //OUT DD SYSOUT=(C,,GRLN),COPIES=2 //IN DD DSN=SUMMTAPE,DISP=(OLD,KEEP) //SYSIN DD * REPRO INFILE(IN) OUTFILE(OUT) /* - all previous steps must work correctly: calculate COND for this step English: "Execute as long as all previous steps have worked correctly" Step 1: execute IF RC = 0 (reword and simplify) Step 2: execute IF 0 = RC (put the number on the left) Step 3: skip IF 0 != RC (complement to make into "skip") Step 4: COND=(0,NE) - PASSed datasets need nothing except DSN and DISP // - End of Job. To get a listing of just the JCL from this file, use the Unix command: $ grep '^/' thisfile Notes on Optimal Blocking ------------------------- SMS will let you leave out BLKSIZE if you run SMS in your MVS shop - but not all MVS shops run it! - leave out BLKSIZE only if SMS is running - 4K is a good compromise; but, it isn't always best - want one full track for best disk use - hence, "half-track" blocking is often suggested --------------------------- Extra Questions and Answers related to JCL Example 4 --------------------------- Here are some job specification statements with answers on how to code them. 1) Change the compiler output to go to spool queue B? Add this DD statement to our JCL: //COB2.SYSPRINT DD SYSOUT=B We know the step name and SYSPRINT DDname used by the compiler because we can read the PROC listing. Our COB2 DD statement must come before any DD statements for the LKED or GO steps. (DD statements for PROCs must be in PROC step order.) 2) Change the linker output to go to spool queue C? Add this DD statement to our JCL: //LKED.SYSPRINT DD SYSOUT=C We know the step name and SYSPRINT DDname used by the linker because we can read the PROC listing. Our LKED DD statement must come between any DD statements for the COB2 and GO steps. (DD statements for PROCs must be in PROC step order.) 3) Delete the REGION specification from the compiler? Add REGION.COB2= (equals nothing) to the EXEC PROC=COBOLCLG statement. This REGION.COB2 must come before any LKED or GO parameters on the EXEC statement for the PROC. 4) Change the linker memory to 32MB? Add REGION.LKED=32M to the EXEC PROC=COBOLCLG statement. This REGION.LKED must come between any parameters for the COB2 and GO steps. (Parameters must be in PROC step order.) 5) Change the source library used by the compiler to TEAM1.SRCLIB? Add this DD statement to our JCL: //COB2.SYSLIB DD DSN=TEAM1.SRCLIB,DISP=(SHR,KEEP) We know the step name and SYSLIB DDname used by the compiler because we can read the PROC listing. Our COB2 DD statement must come before any DD statements for the LKED or GO steps. (DD statements for PROCs must be in PROC step order.) 6) Add the options OPT and LINUX to the linker? The linker (step two in the PROC, with program name IEWL) doesn't currently have any PARM options. Add PARM.LKED=(OPT,LINUX) to the EXEC PROC=COBOLCLG statement. This PARM.LKED must come between any parameters for the COB2 and GO steps. (Parameters must be in PROC step order.) 7) Add the options NODUMP and NOCHECK to the running COBOL program? The COBOL program (in the GO step) doesn't currently have any PARM options. Add PARM.GO=(NODUMP,NOCHECK) to the EXEC PROC=COBOLCLG statement. This PARM.GO must come after any parameters for the COB2 and LKED steps. (Parameters must be in PROC step order.) 8) The link-editor step should execute only if all previous steps have no errors? Translate an "execute" into a "skip" using simple steps: Step 1: execute IF RC = 0 (summarize and simplify the English) Step 2: execute IF 0 = RC (put number on left, RC on right) Step 3: skip IF 0 != RC (complement both sides to make into "skip") Step 4: COND=(0,NE) (this is the JCL form of the condition) We are applying this COND to only one of the steps in the PROC, not to all the steps. So we must qualify the COND as COND.LKED so that it gets applied only to the LKED step inside the PROC. The job specification says "all previous steps", so we do *not* use a third parameter to COND.LKED: Add COND.LKED=(0,NE) to the EXEC PROC=COBOLCLG statement. This COND.LKED must come between any parameters for the COB2 and GO steps. (Parameters must be in PROC step order.) 9) The link-editor step should execute only if the compiler step has no errors? Translate an "execute" into a "skip" using simple steps: Step 1: execute IF RC = 0 (summarize and simplify the English) Step 2: execute IF 0 = RC (put number on left, RC on right) Step 3: skip IF 0 != RC (complement both sides to make into "skip") Step 4: COND=(0,NE) (this is the JCL form of the condition) We are applying this COND to only one of the steps in the PROC, not to all the steps. So we must qualify the COND as COND.LKED so that it gets applied only to the LKED step inside the PROC. The job specification says "the compiler step" (not "all steps"), so we must use a third parameter to COND.LKED to specify that only the compiler step should be tested: Add COND.LKED=(0,NE,CLG.COB2) to the EXEC PROC=COBOLCLG statement. CLG is the name we gave (see the JCL, above), in our JCL, to the step using the COBOLCLG PROC. (CLG identifies which PROC we are talking about.) COB2 is the internal step name, inside the COBOLCLG PROC, that our COND should check. This COND.LKED must come between any parameters for the COB2 and GO steps. (Parameters must be in PROC step order.) *** FIN *** EOF *** END OF DAT2330 NOTES *** EOF *** FIN ***