------------------------------------------------------ Week 11 Notes for DAT2330 - Ian Allen - idallen@ncf.ca ------------------------------------------------------ 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 Winter 2003 These notes are largely based on lectures by Harold Smith: - DAT2330 - Harold Smith Class - Thu Jan 27, 2000 [NOTE: The Unix Final exam (two separate hours) also takes place this week.] --------------------------------------- MVS JCL Example 1 and attached homework --------------------------------------- - the written instructions are to test a program (usually COBOL) - how do we actually code the JCL (as on the job)? - we will assume many defaults - few things to learn to start out - this will be a real, working job - look up each of the parameters in the text as you first use it - start with a flow diagram (not formal; only to help visualize) - flow diagrams are never required, never marked, usually helpful Step One - Flow Diagram ----------------------- - EXEC PROC=COBOLCLG step - what are we being asked to do? - develop JCL to compile and run a program - start with title on flow diagram - JOB name is 8 chars - read chapter 4 as you code (I won't teach it) - flow diagram: put the JOB title on top: CBLTSTE1 - Your Name - how many boxes for compile, link, and run COBOL? - C.L.G. requires three programs: 1. compiler, 2. linker, 3. my program - refer to "the CLG process" flow diagram Figure 3.5 on p.44 - three programs means three steps (three EXEC PGM= needed) - but I can do all three steps in one EXEC, using a single system PROC - use a "catalogued procedure" (a "PROC") named: COBOLCLG - system procedures come from SYS1.PROCLIB (remember this name) - wc can call in this already-written procedure (similar to a "macro") - use one box for this CGL step, a dotted box in the flow diagram - EXEC PGM= uses solid boxes in diagram; EXEC PROC= uses dotted boxes - find out the three step names (C.L.G.) used inside the PROC - the three C.L.G. step names are given in the JCL specifications: Compile: COMP; Link: LINK; Go: TEST - these are the names of the three hidden steps inside the PROC - our DDnames must be given *in this step order* in our own JCL - all the COMP DD statements must come before the TEST DD statements when we code the JCL, because step COMP happens before step TEST - different coding for procedure (PROC=) and program (PGM=) steps - a PROC has most of the JCL; but, not all the info about the job - e.g. missing OUTLIM for printing? - e.g. what kind of test data is needed? - e.g. where does output go? - e.g. where does the input come from? - our JCL can supply DD statements for information not given in the PROC - e.g. from where does the COBOL source come? - our JCL can specify information that over-rides default assumptions made by the PROC; we can over-ride DD statements used in the PROC - e.g. we could over-ride the default destination for the compile listing - flow diagram for a PROC: create a dotted box - we get to choose our own step name for the dotted box: CLG - put the name of the PROC in the middle of the box: COBOLCLG - order of DDnames we specify in our JCL must match order of steps in the PROC: - the internal PROC steps are given as: COMP, LINK, TEST - draw instream COBOL source program as an oval labelled "cobol source" - program is on SYSIN DDname, but SYSIN to which step in the PROC? - must qualify DD name; must know names of three steps inside the PROC - we *must* use the step name (COMP) chosen by PROC writer - how to find out what step name was used by the PROC writer? - ask the sysadmin; or, just try something and look at the errors! - JCL error messages will tell us if our step guess doesn't match PROC (it is a JCL error because the JES processor can't match up the step we code with the step actually hidden in the PROC) - arrow labelled COMP.SYSIN goes from source oval to main PROC box - COMP is the step name already coded inside the PROC - SYSIN is the DDname used by the compiler in the COMP step - you must supply compiler input using the expected DDname - HINT: cross out each sentence in the specification as you do it on a test - anything left over will need doing - nothing more to do for the COMP step in the PROC - the only item missing from the PROC was the SYSIN DDname used by the compiler to read the source program that needs compiling - the rest of JCL for the COMP step is supplied by the PROC - there is nothing at all to do for the LINK step in the PROC - the default JCL used for linking already in the PROC will work for us - later, we will see how to modify the JCL of the link step - the "Go" step of CLG is named "TEST" according to the specifications - the specifications indicate that it will require four DDnames - the DDnames are: INDATA, UPDTMST, LSTIN, PRINTOP - code this in the JCL as: TEST.INDATA, TEST.UPDTMST, TEST.LSTIN, etc. - draw another oval for instream Test Data, label "test data" - where does test data come from? From DD name INDATA in step TEST - DD name is TEST.INDATA on arrow from oval to dotted box - "dotted boxes require dotted DDnames on their arrows" - why not test programs with live data on datasets? - maybe it might damage the real data (could back it up?) - live data may not test all my conditions - may only test the IF part of IF ELSE - design the test data to exercise all parts of the program - an "update" step is both input and output - dataset must already exist for an update step - actual dataset has a name (DSN=) of TESTMAST - find the DDname needed by examining the actual COBOL source code - find the DDname used at the end of the COBOL "SELECT" statement - SELECT MAST-FILE ASSIGN TO UPDTMST <= UPDTMST is the DDname FD MAST-FILE <== MAST-FILE is the internal, COBOL name RECORD CONTAINS 100 CHARACTERS BLOCK CONTAINS 10 RECORDS - we must specify a dataset for the DDname UPDTMST in step TEST - arrow labelled as TEST.UPDTMST points to TESTMAST disk symbol - why not put DSname (actual name of dataset) right in the source? - would hard-wire the program to that dataset - have to rewrite the program to change datasets - want one level of indirection: DDname to dataset name - another level of redirection gives COBOL a MAST-FILE name - the DSname may have to change if we port to another o/s - insulate COBOL from change in DDname - tape dataset name is PRODLIST for the LSTIN DDname - draw a tape symbol and label it with the name PRODLIST - we must specify the DDname LSTIN, used in step TEST - draw an arrow labelled TEST.LSTIN - print some output - DDname is PRINTOP in step TEST - flow diagram arrow is labelled TEST.PRINTOP - Remember: dotted boxes (PROCs) require dotted DDnames - write the DDnames for PROC's with dots, as . Step Two - Flow Diagram ----------------------- - EXEC PGM=VERDATA step - this is an actual program, not a cataloged procedure (not a PROC) - draw a solid (not dotted) box for a PGM= step - label the step box "VERIFY" and put the program name VERDATA inside - draw an input arrow from disk symbol and the dataset labelled TESTMAST that was created in the previous step (step one) - the arrow needs a DDname (the VERDATA program expects to use it); but, the input DDname is not given in the specifications! - you cannot invent your own DDName - you must use the DDname expected by the given program (VERDATA) - go "fish" for name of DDname for program VERDATA - program probably in SYS1.LINKLIB - find the documentation - old production programs may not have source code any more - you can always: run the job and see what run-time errors you get - make a *guess* at INPUT or SYSIN for the DDname, label the arrow - when VERDATA runs, it will look for its correct DDnames and will issue run-time error messages if it cannot find them - also need the missing the DDname for print output (to be held for TSO) - the output DDname is also not given in the specifications! - guess at OUTPUT or SYSPRINT for the DDname, label the arrow - run-time errors will tell us what DDname the program (VERDATA) expects - VERDATA must actually execute before the error will be found (a DDname error is *not* a JCL error; it is a run-time error) - end of Flow Diagram Coding the JCL for Example 1 ---------------------------- - UPPER CASE ONLY (run your JCL through a Unix tr command!) - use fixed-width (monospace) font for JCL so that blanks are clear - UNIX VI does this automatically (text only) - choose a Courier or Terminal font, if using a word processor - don't go past column 71 - use ":set ruler" in Unix VIM (not available in VI) - no blanks after commas! (blanks start JCL comments!) - continuation cards must start in cols 4-16 - blanks start comments after third column - be careful Start of Step One ----------------- First is the JOB statement. It always has two positional parameters (account code and programmer name) and is followed by optional keyword parameters. We always select and code a CLASS= parameter for the job. //CBLTSTE1 JOB 1000EX,'MY NAME',CLASS=B - you get to choose a meaningful 8-character job name for this job - watch out for positional parameters on JOB statement - keyword parms follow two positional parameters on JOB card - use specified account code - job account billing is often done even if it's your own computer - the MVS shop tracks which team uses more/less CPU Picking a CLASS= for the JOB card - not a random choice - you must calculate this correctly - CLASS: indicates resources required by the *entire* job (all steps) - similar to priority, but technically not a priority - classes are defined by each MVS shop; check with your sysadmin (classes will be different for each homework and on tests) - see the JCL examples for sample job classes - complex jobs may take longer to set up and run - use class letter closest to 'A' for best turn-around time - calculate which class satisfies job, closest to A - operator may kill or extend job when it runs out of resources - automated software may do this, not a human - Depending on the resource limits of your job classes, chosing a job CLASS is determined by ether the *maximum* or the *total* resources used by your job. Job CLASS is determined by: - the sum *total* number of print (SYSOUT) lines, in all steps, no matter whether the lines are sent to a real printer or back to you via to TSO - the sum *total* amount of computer time used, in all steps - the *maximum* number of tape drives being used *simultaneously* in any *one* step - NOTE: *not* the *total* number, only the *maximum* number - NOTE: PROCs containing multiple steps are seen as multiple steps; three tape drives used in a step that calls a PROC may still only count as "one tape drive per step" if the PROC only uses one tape drive at a time in each of the internal steps in the PROC - a job that uses ten tapes may be a "one-tape-drive" job, if the job has ten steps and only uses one tape drive in each step - the *maximum* memory used in any one step NOTE: *not* the sum total of all memory, only the *maximum* memory //CLG EXEC PROC=COBOLCLG - you get to choose a meaningful 8-character step name for this step - don't call it an unhelpful name such as STEP1 or FIRST - a catalogued PROC must be from the system library (use the exact name) - remember the name: SYS1.PROCLIB is where PROC's come from - check your flow diagram to count DD statements (one for each arrow) - we count 5 DD statements (two output, three input) - all three internal proc step names were given in the specification: COBOL, LINK, and TEST (compile step, link-edit step, go step) - if these weren't given, you'd have to fish for them by asking around or by running your JCL and looking at the PROC listing when it aborts - bad guesses for step names generate JCL errors, not run-time errors (because the JES processor can't match the step name used in your JCL with the the step name actually used in the PROC) - what is the output of the COBOL step inside the COBOLCLG proc? - what output does a compiler produce (refer to CLG diagram p.44)? - should I put in my JCL a DD statement to handle this output? - no, that's handled by the PROC (which is why we use a PROC!) - don't specify DD statements for things done correctly by the PROC - what is the ordering of DD statements for MVS? - order of DD statements when using a PROC must be in PROC step order - put COBOL DD statements before LINK statements before TEST statements - the DD order *within* each step doesn't matter to MVS - however, it matters to instructors who want large instream data *last* (Guideline: put output DD before input DD, with instream data very last) //COMP.SYSIN DD * ...your actual COBOL source program goes here (see example p.76)... ...this is fed to the COBOL compiler via the SYSIN DDname... /* - This instream data DD has to come first, because it's part of the COMP step. All the COMP DD statements must precede all the TEST DD statements; because, that's the order of the steps in the COBOLCLG PROC we're using. - you must specify DD statements in the order of the steps in the PROC - this is an MVS rule - remember the /* delimiter to end the COBOL (and all other) instream data - see also the COBOL "COBUCLG" example at the end of Chapter 5 (p.76) The order of the DD statements within the TEST step can follow the guideline of "output first, input last, instream data very last". (MVS doesn't care; it's just good style to put instream data at the bottom where it doesn't break up your JCL as much.) //TEST.PRINTOP DD SYSOUT=A - the SYSOUT parameter always means an output DD (output spool queue) - SYSOUT= classes are different from job CLASS= classes - don't get JOB CLASS= classes confused with SYSOUT= classes - both classes are defined locally for each MVS shop (and each test) - use the classes given and defined for this example - pick the SYSOUT class that matches the output and the requirements - how much output? special forms? hold the output or not? //TEST.UPDTMST DD DSN=TESTMAST,DISP=(OLD,PASS) - output DD: this is an "update" - write or read/write an existing dataset - OLD is used to read or update an existing dataset in place - MOD is only used to "extend the length of a sequential dataset" - MOD is never used in this course - DISP has positional parameters (but it, itself, is not positional) - second parm says what to do with dataset if step succeeds - third says what to do if step fails (default is usually okay; leave it out) - leave it out; but, no trailing commas allowed (see Chapter 4) - DISP=(OLD,KEEP) would have the dataset deallocated - a tape would be dismounted and put back in storage - next step would request the same tape and the operator would have to go back to the store room and get it again (annoying) - don't leave the tape mounted unnecessarily; but, don't dismount it if it will be needed in the next step - this abbreviated JCL only works because dataset is *cataloged* - no need to specify more detail to find the dataset because the catalog has the VOL, SER, UNIT, etc. (see p.121 for list) - no need to type in parameters that are retained in catalog - even offline (dismounted; in storage) datasets are catalogued - existing dataset has DCB information stored in its label - no need to specify output DCB information here either - see p.121 for list of DD parameters stored in dataset label - cataloged datasets are easy to find and use! //TEST.LSTIN DD DSN=PRODLIST,DISP=(OLD,KEEP) - input DD: dataset is cataloged, making it easy to find - never need to specify DCB parameters for an input dataset - the DCB info is in the existing dataset label (see p.121) - what do we do with the dataset after the step ends - question doesn't say what to do - safe thing is to keep it - if you code "PASS" at end of a job it means "KEEP" //TEST.INDATA DD * ...lots of test data appears in the input stream here... ...this data is fed to the test program via DDname INDATA... /* - Instream data goes *last* in the JCL stream, so that it doesn't separate the rest of the JCL. (This is a style guideline; not an MVS JCL rule.) End of Step One - Beginning of Step Two --------------------------------------- //* Note: I am guessing both of the VERDATA DDnames; they were not provided. //* Note: An incorrect guess will cause a RUN TIME error (not a JCL error). //* //VERIFY EXEC PGM=VERDATA //SYSPRINT DD SYSOUT=D //SYSIN DD DSN=TESTMAST,DISP=(OLD,DELETE) // - you get to choose a meaningful 8-character step name for this step - check your flow diagram to count DD statements (one for each arrow) - we count 2 DD statements (one output, one input) - prefer output statements to go first (style issue; not a JCL rule) - we are guessing at the DDnames used by the VERDATA program - the DDnames weren't given in the specifications - program run-time error messages will tell us the real names - IMPORTANT: JES JCL processor cannot detect incorrect DDnames - only when you *run* the program will it detect the missing DDname - see example specification for classes of SYSOUT spool queues - we are asked to hold the printe output for TSO viewing - choose the sysout hold class: SYSOUT=D - do NOT choose class A, or job will end up on paper! - the dataset is PASSed in from a previous step - don't need to code anything except DSN and DISP for a PASSed dataset - the specification says to DELETE the dataset at the end of the job - this is the last job step, we code "DELETE" here - the null statement "//" marks the end of this JOB To get a listing of just the JCL from this file, use the Unix command: $ grep '^/' thisfile Do the "MVS JCL Example 1" homework question; we will review it next class.