IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

Replace repeated JCL with looping REXX


IBM Mainframe Forums -> CLIST & REXX
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
prino

Senior Member


Joined: 07 Feb 2009
Posts: 1315
Location: Vilnius, Lithuania

PostPosted: Thu Oct 13, 2016 5:30 am
Reply with quote

I've got a job consisting of 54 steps, 18 of them executing a PGM, 36 of them executing a PROC, which in turn contains 26 steps executing a PGM... Needlessly to say, the job actually runs as four jobs, and that, at the moment, for 179 different input datasets... (So 716 jobs, ouch...)

Now it would be nice if I could reduce it to just 19 steps, merging the 36 PROCs into a nice looping bit of REXX, and some preliminary testing seems to confirm that this is indeed very well possible. However, the JCL uses sh*tload of SET VAR=value statements, and I don't really want to pass sh*tloads of parameters to the REXX exec, so I've been trying to find a smart way of encoding them, as there doesn't(?) seem to be any way of actually accessing them via control blocks, which makes sense as they're only needed at the JCL conversion stage.

FWIW, the job currently runs 36 versions of a program that produces 6 output files (it used to produce 4), and the steps following the EXEC PGM=version[NN] uses SuperC to zap the output datasets of "version[NN-1]" if they are the same as the current ones, or saves them into a PDS(E). For what it's worth here are the abbreviated JCL:

Code:
//PRINOXXX JOB (PRINO),
//             'DIFFS DEV - EQ',
//             CLASS=A,
//             MSGCLASS=H,
//             MSGLEVEL=(2,0),
//             NOTIFY=&SYSUID
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  8 Line(s) not Displayed
//*!WAIT00500!*********************************************************
//PROCS JCLLIB ORDER=(PRINO.RAHP.PROC)
//*********************************************************************
//     INCLUDE MEMBER=IMOI
//*
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  4 Line(s) not Displayed
//         SET SRCE='TRXXX' QQQ  'WORKLIFT'
//         SET TID='XXX' QQQ     'ALL'
//*
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  4 Line(s) not Displayed
//         SET TY='TR' -+- TRIP
//         SET L='L'    |
//         SET P='P'   -+
//*
//         SET OTEXT='PRINO.LIFT.TEMP'           Must be PDSE!
//*
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  1 Line(s) not Displayed
//         SET PRE='EQ'                          Enterprise PL/I
//*
//         SET SYSOUT1='*'
//         SET SYSOUTD='*'
//         SET DIFFS='PRINO.RAHP.DIFFS.COPY'     Must be PDSE!
//*
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  4 Line(s) not Displayed
//         SET OUTSORT='DUMMY'
//         SET OUTSUPC='DUMMY'
//         SET OLDDEL='(OLD,DELETE)'
//*********************************************************************
//DEL     EXEC PGM=IEFBR14
//*
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 12 Line(s) not Displayed
//SUPERS    DD DSN=&SYSUID..SUPER.S&TID,
//             DISP=(MOD,DELETE),
//             UNIT=&DASD,
//             SPACE=(TRK,1),
//             DCB=(RECFM=FB,LRECL=202,BLKSIZE=0)
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 18 Line(s) not Displayed
//*
//SYSIN     DD DSN=&SYSUID..SYSIN.SUPERC.&TY.&TID,
//             DISP=(MOD,DELETE),
//             UNIT=&DASD,
//             SPACE=(TRK,1),
//             DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
//*
//SYSIN     DD DSN=&SYSUID..SYSIN.SUPERCS.&TY.&TID,
//             DISP=(MOD,DELETE),
//             UNIT=&DASD,
//             SPACE=(TRK,1),
//             DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
//*********************************************************************
//ALLOC   EXEC PGM=IEFBR14
//*
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 12 Line(s) not Displayed
//SUPERS    DD DSN=&SYSUID..SUPER.S&TID,
//             DISP=(,CATLG),
//             UNIT=&DASD,
//             SPACE=(TRK,(30,60),RLSE),
//             DCB=(RECFM=FB,LRECL=202,BLKSIZE=0)
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 18 Line(s) not Displayed
//*********************************************************************
//CARDS1  EXEC PGM=SORT
//*
//SORTIN    DD *
 worksize 262144
 dpline ' Totals per '
//*
//SORTOUT   DD DSN=&SYSUID..SYSIN.SUPERC.&TY.&TID,
//             DISP=(,CATLG),
//             UNIT=&DASD,
//             SPACE=(TRK,1),
//             DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
//*
//SYSIN     DD DSN=&DATA(SORTCOPY),
//             DISP=SHR
//*
//SYSOUT    DD &OUTSORT
//*********************************************************************
//CARDS2  EXEC PGM=SORT
//*
//SORTIN    DD DSN=&SYSUID..SYSIN.SUPERC.&TY.&TID,
//             DISP=SHR
//          DD *
 ochgt ':','.'
 nchgt ':','.'
//*
//SORTOUT   DD DSN=&SYSUID..SYSIN.SUPERCS.&TY.&TID,
//             DISP=(,CATLG),
//             UNIT=&DASD,
//             SPACE=(TRK,1),
//             DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
//*
//SYSIN     DD DSN=&DATA(SORTCOPY),
//             DISP=SHR
//*
//SYSOUT    DD DUMMY
//*********************************************************************
//SA01    EXEC RUN2PDS,
//             PID='01',
//             OPID='01',
//             CALLER='SA01.',SKIPF='4095'
//*
//SA0201  EXEC RUN2PDS,
//             PID='02',
//             OPID='01',
//             CALLER='SA0201.'
//*
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -   302 Line(s) not Displayed
//*********************************************************************
//* Between 32 & 33 SUPC must be SET to 'S' (Times to ISO 8601)
//*********************************************************************
//SA3332  EXEC RUN2PDS,
//             SUPC='S',
//             PID='33',
//             OPID='32',
//             CALLER='SA3332.'
//*
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 10 Line(s) not Displayed
//SA3635  EXEC RUN2PDS,
//             PID=,
//             OPID='35',
//             CALLER='SA3635.'
//*
//         SET PID=
//         SET CALLER='SA3635.'
//*********************************************************************
//IF110     IF &CALLER.SA020.RC = 0 THEN
//*
//COPYS   EXEC PGM=SORT
//*
//SORTIN    DD DSN=&SYSUID..&TY.&TID..&L.S&PID,
//             DISP=&OLDDEL
//*
//SORTOUT   DD DSN=&OTEXT(T&TID.S&P.99),
//             DISP=SHR
//*
//SYSIN     DD DSN=&DATA(SORTCOPY),
//             DISP=SHR
//*
//SYSOUT    DD DUMMY
//*********************************************************************
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 65 Line(s) not Displayed
//MODSUP  EXEC PGM=IKJEFT01,
//             DYNAMNBR=50,
//             REGION=0M,
//             PARM='%ISPFBAT EHHDIFF'
//*
//     INCLUDE MEMBER=ISPF@ICI
//*
//SUMM      DD DSN=&SYSUID..SUPER.S&TID,
//             DISP=SHR
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 10 Line(s) not Displayed
//*********************************************************************
//SUPERS  EXEC PGM=SORT
//*
//SORTIN    DD DSN=&SYSUID..SUPER.S&TID,
//             DISP=&OLDDEL
//*
//SORTOUT   DD DSN=&DIFFS(LS&TID),
//             DISP=SHR
//*
//SYSIN     DD DSN=&DATA(SORTCOPY),
//             DISP=SHR
//*
//SYSOUT    DD DUMMY
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 65 Line(s) not Displayed
//*
//IF110E    ENDIF
//*********************************************************************
//SA120   EXEC PGM=IEFBR14
//*
//SYSIN     DD DSN=&SYSUID..SYSIN.SUPERC.&TY.&TID,
//             DISP=&OLDDEL
//*
//SYSIN     DD DSN=&SYSUID..SYSIN.SUPERCS.&TY.&TID,
//             DISP=&OLDDEL

and PROC:
Code:

//RUN2PDS PROC LOAD='PRINO.RAHP.LOAD',
//             STEP1='PRINO.RAHP.LOAD',
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  1 Line(s) not Displayed
//             CALLER=,
//             SUPC=,
//             SKIPF='0'
//*********************************************************************
//SA010   EXEC PGM=IEFBR14
//*
//SUMMOUT   DD DSN=&SYSUID..&TY.&TID..&L.S&PID,
//             DISP=(MOD,DELETE),
//             UNIT=&DASD,
//             SPACE=(TRK,0),
//             DCB=(RECFM=FBA,LRECL=121,BLKSIZE=0)
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 36 Line(s) not Displayed
//*********************************************************************
//SA020   EXEC PGM=&PRE.01&PID
//*
//STEPLIB   DD DSN=&STEP1,
//             DISP=SHR
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  2 Line(s) not Displayed
//          DD DSN=&LOAD,
//             DISP=SHR
//*
//LIFTIN    DD DSN=&VEXT(&SRCE),
//             DISP=SHR
//*
//SUMMOUT   DD DSN=&SYSUID..&TY.&TID..&L.S&PID,
//             DISP=(,CATLG),
//             UNIT=&DASD,
//             SPACE=(TRK,(10,10),RLSE),
//             DCB=(RECFM=FBA,LRECL=121,BLKSIZE=0)
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 42 Line(s) not Displayed
//*********************************************************************
//IFPLI     IF &CALLER.SA020.RC = 0 & &CALLER.SA020.RC = &SKIPF THEN
//*********************************************************************
//LS030   EXEC PGM=ISRSUPC,
//             PARM=(DELTAL,LINECMP,
//             'DPBLKCL FMVLNS REFMOVR LONGLN NOPRTCC')
//*
//NEWDD     DD DSN=&SYSUID..&TY.&TID..&L.S&PID,DISP=SHR
//OLDDD     DD DSN=&SYSUID..&TY.&TID..&L.S&OPID,DISP=SHR
//*
//SYSIN     DD DSN=&SYSUID..SYSIN.SUPERC&SUPC..&TY.&TID,
//             DISP=SHR
//*
//OUTDD     DD &OUTSUPC
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  5 Line(s) not Displayed
//*********************************************************************
//IFRUN     IF &CALLER.LS030.RUN THEN
//*
//IF031     IF &CALLER.LS030.RC = 1 THEN
//*
//LS031   EXEC PGM=ISRSUPC,
//             PARM=(DELTAL,LINECMP,
//             'DPBLKCL FMVLNS REFMOVR NOSUMS LONGLN NOPRTCC APNDLST')
//*
//NEWDD     DD DSN=&SYSUID..&TY.&TID..&L.S&PID,DISP=SHR
//OLDDD     DD DSN=&SYSUID..&TY.&TID..&L.S&OPID,DISP=SHR
//*
//OUTDD     DD DSN=&SYSUID..SUPER.S&TID,
//             DISP=MOD
//*
//IF031E    ENDIF
//*********************************************************************
//IF040     IF &CALLER.LS030.RC =  0 |
//             &CALLER.LS030.RC = 28 THEN
//*
//LS040   EXEC PGM=IEFBR14
//S         DD DSN=&SYSUID..&TY.&TID..&L.S&OPID,
//             DISP=(MOD,DELETE),
//             UNIT=&DASD,
//             SPACE=(TRK,1),
//             DCB=(RECFM=FBA,LRECL=121,BLKSIZE=0)
//*
//        ELSE
//*
//IF041     IF &CALLER.LS030.RC = 1 THEN
//*
//LS041   EXEC PGM=SORT
//*
//SORTIN    DD DSN=&SYSUID..&TY.&TID..&L.S&OPID,
//             DISP=&OLDDEL
//*
//SORTOUT   DD DSN=&OTEXT(T&TID.S&P.&OPID),
//             DISP=SHR
//*
//SYSIN     DD DSN=&DATA(SORTCOPY),
//             DISP=SHR
//*
//SYSOUT    DD &OUTSORT
//*
//        ELSE
//*
//IF041E    ENDIF
//IF040E    ENDIF
//*
//IFRUNE    ENDIF
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -   335 Line(s) not Displayed
//*
//IFPLIE    ENDIF
//*
//RUN2PDS PEND


As you can see, the number of SET VAR=value statements is pretty large, and even more (my default libraries) are included in the "INCLUDE MEMBER=IMOI" member. I could obviously put all of them into a text member that is read by the replacement REXX exec, but that would mean that I need to update two datasets if I ever want to port these jobs to another system. I have thought about a dirty trick, adding a

Code:

//DUMMY DSN=&CNTL(this-member),DISP=SHR

and read that in inside the replacement REXX exec, parsing out the relevant SET statements.

Any other thoughs on this?

I'm also curious as to the efficiency of running this as a straight BATCH job (as it is at the moment), or as a job that runs ISPF in batch - at one site another smart-ass programmer thought using an edit-macro in batch was an ideal way to massage some output, but after just one run in production that approach was abandoned do to an excessive CPU usage. Here the REXX exec would only be allocating files (rather a lot...), running the program to be tested, ISRSUPC and SORT, be it under ISPF...

And as a PS, the current JCL member is submitted by an edit macro that updates the three 'XXX' strings to 001..178, the 178 input files and with a slight delay (0.5 sec) between the four jobs that make up one test, to avoid starting a later one before an earlier one.
Back to top
View user's profile Send private message
enrico-sorichetti

Superior Member


Joined: 14 Mar 2007
Posts: 10888
Location: italy

PostPosted: Thu Oct 13, 2016 1:37 pm
Reply with quote

You know the logic better than anybody else,
so I' ll just stick to the SET stuff.

what liberty do You have in installing free software on the system.

I have tested both on MVS 3.8 an on zOS 10
the Control Card subsystem in file 364 of the cbt tape

that would solve in a simple and elegant fashion
the problem of reading as a dataset the SET stuff

if You are interested It should take just couple of hours to test it again

for a proc the jcl would look like

Code:

//CCSSTEST JOB (CCSS),
//             CLASS=A,
//             MSGCLASS=A,
//             MSGLEVEL=(1,1),
//             REGION=4096K
//*********************************************************************
//*
//ZTEST   PROC               
//CCSS    EXEC PGM=IEBGENER               
//SYSPRINT  DD SYSOUT=*                       
//SYSIN     DD DUMMY                           
//SYSUT1    DD SUBSYS=(CCSS,
//             'START OF FILE',
//             ' X &PAR1. X',
//             ' Y &PAR2. Y',
//             &PAR3.,'+',
//             &PAR4.,
//             &PAR5.,
//             &PARZ.,
//             'END   OF FILE'),
//             DCB=(LRECL=80)
//SYSUT2   DD SYSOUT=*                         
//       PEND                                       
//TEST   EXEC ZTEST,
//            PAR1=A,
//            PAR2=BB,
//            PAR3=CCC,
//            PAR4=DDDD,
//            PAR5=EEEEE,
//            PARZ=ZZZZZZ


the only bother would to write the ddname with the SET vars

You could always test it on that icon_wink.gif system

if You want it I will send You my streamlined version
Back to top
View user's profile Send private message
prino

Senior Member


Joined: 07 Feb 2009
Posts: 1315
Location: Vilnius, Lithuania

PostPosted: Fri Oct 14, 2016 1:55 am
Reply with quote

enrico-sorichetti wrote:
You know the logic better than anybody else, so I' ll just stick to the SET stuff.

what liberty do You have in installing free software on the system.

Rhetorical question, I presume? icon_cool.gif

enrico-sorichetti wrote:

I have tested both on MVS 3.8 an on zOS 10
the Control Card subsystem in file 364 of the cbt tape

that would solve in a simple and elegant fashion
the problem of reading as a dataset the SET stuff

if You are interested It should take just couple of hours to test it again

for a proc the jcl would look like

Code:

//CCSSTEST JOB (CCSS),
//             CLASS=A,
//             MSGCLASS=A,
//             MSGLEVEL=(1,1),
//             REGION=4096K
//*********************************************************************
//*
//ZTEST   PROC               
//CCSS    EXEC PGM=IEBGENER               
//SYSPRINT  DD SYSOUT=*                       
//SYSIN     DD DUMMY                           
//SYSUT1    DD SUBSYS=(CCSS,
//             'START OF FILE',
//             ' X &PAR1. X',
//             ' Y &PAR2. Y',
//             &PAR3.,'+',
//             &PAR4.,
//             &PAR5.,
//             &PARZ.,
//             'END   OF FILE'),
//             DCB=(LRECL=80)
//SYSUT2   DD SYSOUT=*                         
//       PEND                                       
//TEST   EXEC ZTEST,
//            PAR1=A,
//            PAR2=BB,
//            PAR3=CCC,
//            PAR4=DDDD,
//            PAR5=EEEEE,
//            PARZ=ZZZZZZ


the only bother would to write the ddname with the SET vars

You could always test it on that icon_wink.gif system

if You want it I will send You my streamlined version


I'm interested, but I will probably use a somewhat easier route and add a

Code:
//PARMDD DD DSN=&SYSUID.$SET1..&SET2..&SETn,
//          DISP=(MOD,DELETE),
//          SPACE=(TRK,0)

and parse the DSN obtained via LISTDSI() and with REXX it's obviously far easier to allocate different SYSIN members for ISRSUPC for those n+1 versus n compares where I need to mask "irrelevant" changes.

I find thatI'm using "that" system a lot less than the same 1.10 system you also seem to be using. icon_lol.gif
Back to top
View user's profile Send private message
prino

Senior Member


Joined: 07 Feb 2009
Posts: 1315
Location: Vilnius, Lithuania

PostPosted: Sun Oct 16, 2016 2:30 am
Reply with quote

I've got it working, but I've stumbled upon a subtle difference between JCL and REXX regarding the allocation of datasets that are never opened.

Take the JCL:
Code:
//WEEKOUT   DD DSN=&SYSUID..&TY.&TID..&L.W&PID,
//             DISP=(,CATLG),
//             UNIT=&DASD,
//             SPACE=(TRK,(10,10),RLSE),
//             DCB=(RECFM=FBA,LRECL=121,BLKSIZE=0)

and the REXX that I used to replace it:
Code:
"alloc f("ll.i") da("!g.0dsn_n.i") " ||,
                "new reu "           ||,
                "dsorg(ps) "         ||,
                "space(180,60) "     ||,
                "recfm(f b) lrecl(121) blksize(0)"

They should be equivalent, but they are not!

The dataset in the JCL is not opened until version 36 of the program and at that stage it's compared to the previous one (which of course was never opened). In both cases ISRSUPC (SuperC) doesn't care, and it produces a file with just I(nserts) as differences and ends with an RC=1. This signals that the process needs to change the old file and that's done using SORT.

And there the difference occurs, in the JOB, SORT falls over with an RC=16
Code:
ICE043A 3 INVALID DATA SET ATTRIBUTES: SORTIN   BLKSIZE - REASON CODE IS 12

as the dataset was never opened.

However, the datset allocated in the REXX exec (both with, and without the "DSORG(PS)") is OK, and SORT copies an empty dataset.

I solved the "problem" by removing the
Code:
recfm(f b) lrecl(121) blksize(0)
from the TSO alloc command, but as for the why?

Why?
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> CLIST & REXX

 


Similar Topics
Topic Forum Replies
No new posts Run rexx with JCL Job CLIST & REXX 1
No new posts Run rexx in batch job CLIST & REXX 7
No new posts Does anyone know rexx for VSE CLIST & REXX 3
No new posts TSO ALLOC In REXX Needs Improvement JCL & VSAM 3
No new posts REXX/CMS How to place command console... CLIST & REXX 4
Search our Forums:

Back to Top