(This column is the same as the previous one, but it had to be broken into two parts. The previous version was the one I wrote originally. SG) MVS TOOLS AND TRICKS OF THE TRADE by Sam Golob MAKING YOUR OWN PTFS: A VALUABLE TECHNIQUE This is part one of a two-part series that focuses on PTFs and how you can create your own. This article examines the techniques necessary to create an SMP sysmod to install load modules to your system. Part two will focus on the actual creation of PTFs. A central theme in my system programming endeavors is the following principle: "One must be able to discover as much about the operation of a system from the system itself, as from its documentation or from any other external description." The machine is reading the code and 'looking at' the system structure. Therefore the code itself and the system structure must be harnessed to tell us as much as possible about how they actually work. An Example of the Principle An illustration of this principle is the challenge of creating an SMP sysmod to install software, starting from the actual software itself. Let's illustrate the situation further. Starting from a load module, you want to construct an SMP sysmod -- a PTF, a FUNCTION or a USERMOD -- to install that load module on a new system or to reinstall it on your current system. What about non-load module software? If you have panels, macros or source code you want to make sysmods to re-install those things as SMP elements on any SMP system. Can this be done? If it can, then how is it done? Why and when should it be done? To tell you the truth, when I first considered this subject for study, I didn't really care why such SMP sysmod creation should be done. I really just had a big desire to pretend that I was IBM and to dissect the structure behind IBM's maintenance packaging procedures. Later, I came across situations in my work, where doing these procedures myself was of great practical value. I also came across other system programmers trying this same kind of activity. That is why I want to show you these techniques now. I want to point out situations where they will save you grief and teach you a lot. Making Your Own PTFs From Installed Software It's best to teach programming principles from practical examples. Here's one case to show how we profitted from packaging our own PTF. A lot of installations "frontend" IEBCOPY. This involves linkediting some non-IBM CSECT into the IEBCOPY load module. After gaining control and doing some processing, the "frontend" module might then link to the normal IBM-supplied IEBCOPY software afterwards. Often, frontending is used in IEBCOPY for the purpose of throwing out enqueues. The "frontend" module will enqueue on the dataset(s) being "copied to" or "compressed". Then IEBCOPY is called upon to do its normal work. At the end, control is returned to the "frontend", which releases its enqueues to the dataset name(s). I recently had some trouble installing a usermod that hooked a frontend CSECT into the load module IEBCOPY. We were running DFP Release 2.4. During the SMP processing, I messed up the load module IEBCOPY on my SMP library very badly. The only obvious recovery was to reinstall all of DFP Release 2.4 data management, because that was the "product" to which IEBCOPY belonged. It strikes me as overkill to reinstall all of data management, rather than to reinstall one load module. Fortunately, there was a way out which worked well for us. IEBCOPY was the only load module affected. Since our problem was with this one load module only, I decided to look at "how IBM does things", when they want to completely replace one load module in the operating system. IBM recently shipped PTF UY50707, for DFP Release 3.2, as a complete reinstall and repackaging of the entire load module IEBCOPY. IBM had needed to rewrite much of IEBCOPY, because IEBCOPY needed the capability of copying their new "PDSE" library structures. PTF UY50707 employs many SMP packaging features, so we shall use PTF UY50707 as our model. You can probably order PTF UY50707 from IBM if you want a better look at it. Just order that PTF number specifically, no matter what level of the operating system you are running. Following the principle we outlined above, we will construct our own PTF from the system itself. Our only starting point will be the good IEBCOPY load module from a running SYS1.LINKLIB library. The SMP-maintained IEBCOPY load module from the most recent backup taken before the mishap, should be exactly right for our needs. Getting Started How can we start? To correct any SMP errors, we have to parallel IBM's original install of IEBCOPY by SMP, which was built a CSECT at a time. A mere SMP copy of the entire IEBCOPY load module from another library to LINKLIB will not correct the SMP errors on a module level. To do that, we need to build a CSECT-by-CSECT reconstruction of our IEBCOPY load module from individual object decks, following the way that PTF UY50707 does it. Where can we get the required object decks? Further, how can we obtain linkedit JCL to feed into SMP via JCLIN (following PTF UY50707) so that our IEBCOPY load module will be correctly rebuilt by SMP from our object decks? The answers come from tools that learn about IEBCOPY from IEBCOPY. There are enough of these tools in the public domain to do the job we require. Two functions need to be done that require tools: creating JCLIN, which instructs SMP how to properly linkedit IEBCOPY, and creating object decks for each CSECT in IEBCOPY. The PDS product from either the CBT MVS Tape or the L.A. MVS Users Group Tape, can generate JCLIN, or something close to it. "PDS" has an amazing function which is done by its "MAP" subcommand with the optional "RELINK" keyword. This "MAP-RELINK" function of "PDS" will generate accurate re-linkedit JCL for a load module, starting only from the load module itself. Figure 1 shows the output of the PDS command: "MAP IEBCOPY RELINK". Now what about creating object decks for the IEBCOPY CSECTs? Object decks for the IEBCOPY CSECTs can be created from the IEBCOPY load module, one CSECT at a time, using the DELINK0 utility that is on the CBT MVS Tape. The DELINK0 utility creates object decks from a load module. This is the reverse process to linkage editing. To determine the names of the IEBCOPY CSECTs to delink, use the PDS MAP subcommand (without any extra keywords), or IBM's AMBLIST service aid against your IEBCOPY load module. See Figure 2 for JCL to run the DELINK0 utility. The PDS product can be found on File 182 of the CBT Tape. DELINK0 can be found on File 316. The CBT Tape is obtainable from NaSPA in Milwaukee, (414) 423-2420, or from SPLA at the University of Miami in Florida, (305) 284-6257. The L.A. MVS Users Group Tape is administered by Tom Beuthin at (310) 812-4421. Next month, I will focus on the actual PTF creation. Figure 1: Sample output of the PDS product's "MAP" subcommand with RELINK option. Input to the command is the load module IEBCOPY from our DFP Release 2.4 system. There are no other inputs. This is a good illustration of a tool that helps you learn about the system, from the system itself. >map iebcopy relink //LKED EXEC PGM=IEWL //SYSUT1 DD UNIT=SYSDA,SPACE=(1024,(200,20)) //SYSPRINT DD SYSOUT=* //SYSLMOD DD DISP=SHR,DSN=SYS1.LINKLIB //SYSLIN DD * INCLUDE SYSLIB(IEBCOPY) ORDER IEBDSMCA(P),IEBDSCPY,IEBVTM,IEBWSAM,IEBBAM,IEBCNVT,IEBCPMOD ORDER IEBDRB,IEBDRD,IEBDSCP2,IEBDSU,IEBDV1,IEBDV1MG,IEBDWR ORDER IEBIOE,IEBIOEMG,IEBLDUL,IEBMCM,IEBRSAM,IEBSCN,IEBVCT ORDER IEBVDM,IEBVMS,IEBVMTXT,IEBVTT,IEBWSU,IEBWSUMG SETCODE AC(1) ENTRY IEBDSCPY NAME IEBCOPY(R) /* Figure 2: JCL to execute the DELINK0 program. DELINK0 starts with a load module and creates an object deck for one CSECT at a time. The process is the reverse of linkage editing. Source code for DELINK0 in assembler language may be found on File 316 of the CBT MVS Tape. The JCL below will "delink" one CSECT from load module IEBCOPY. For our purposes, the process has to be repeated for all of the CSECTs in IEBCOPY. You can use the AMBLIST service aid distributed by IBM, or the "PDS" package's "MAP" subcommand, to determine the names of all the CSECTs in a load module. //TSTXDLNK JOB ,'TECH.SUPP-SAM.GOLOB',CLASS=M,NOTIFY=TSTBSSG, // MSGLEVEL=(1,1),MSGCLASS=T TYPRUN=HOLD //* //DELINK EXEC PGM=DELINK0,REGION=2000K //STEPLIB DD DISP=SHR,DSN=TST.TSO.CMDLIB //SYSPRINT DD SYSOUT=* //SYSLIB DD DISP=SHR,DSN=SYS1.LINKLIB <=== load library //SYSPUNCH DD DISP=(NEW,PASS),DSN=&&TEMP,UNIT=SYSDA, // DCB=(RECFM=F,LRECL=80,BUFNO=255),SPACE=(TRK,(5,20)) //SYSIN DD * IEBCOPY IEBVMTXT //* //GENER EXEC PGM=IEBGENER //SYSPRINT DD SYSOUT=* //SYSIN DD DUMMY //SYSUT1 DD DSN=&&TEMP,DISP=(OLD,PASS) //SYSUT2 DD DISP=SHR,DSN=TST.DELINK.PUNCH(IEBVMTXT) <== object deck * * * * * * * * * * * * * * * * * * * * * * * MVS Tools & Tricks August Making Your Own PTFs: A Valuable Technique. Part II. Review of Part I. Last month, we introduced discussion on the topic of creating your own PTF, if and when such action would help your installation. If you acquire understanding of how IBM constructs their maintenance fixes, your own ability to keep the shop's maintenance structure in order, will grow. Our present discussion will be limited to constructing a complete SMP/E install of a system load module. This example will provide a rich model on which to build more SMP knowledge. A central skill for all system programmers to acquire, is the ability to learn about operating system structure, from the system itself. This skill is directly applicable to our current task. We will show how to repair a load module IEBCOPY whose SMP installation was "irreparably damaged" by the faulty install of a usermod. Load module IEBCOPY will be completely reinstalled using SMP and our own PTF that we'll make ourselves. The materials needed for this work are minimal. All we shall need, is the good load module IEBCOPY (from before the usermod was installed), a tool to generate its linkedit structure (to be able to build JCLIN) and a "delinking tool" to construct object decks for the separate CSECTs of IEBCOPY, directly from the load module itself. These tools are readily available in the public domain (from the CBT MVS Utilities Tape) or in the vendor product PDS/E Sysprog Utilities, if you happen to have that product already. IBM has helped us by providing an example to follow. The IBM PTF UY50707 is a complete reinstall of the load module IEBCOPY, which also contains much SMP packaging knowledge. No matter what level of MVS you are running, you can probably order PTF UY50707 from IBM by its number. The tool we shall use to generate JCLIN is the "MAP" subcommand of the "PDS" program product, with its "RELINK" keyword. The tool to generate object decks for the individual modules of IEBCOPY is the DELINK0 program, originally from IBM, which is public, and also on the CBT MVS Tape. The CBT Tape itself can be ordered either from NaSPA (414) 423-2420, or from SPLA at the University of Miami in Florida, (305) 284-6257. The PDS product is on File 182 of the CBT Tape, and DELINK0 may be found on File 316. PDS/E Sysprog Utilities (if you have it) has its own delinker and it contains all the functions we will need. Putting the Pieces Together Our aim is to make a PTF that is patterned after IBM's UY50707, but which re-installs our own release of IEBCOPY exactly. When our PTF is APPLYed and ACCEPTed on our SMP system, all of the IEBCOPY CSECTs will be renewed on the DISTLIB, and the load module IEBCOPY on LINKLIB will be completely replaced and cleaned up. See Figure 1 for our starting point, and Figure 2 for our approximate ending point. The following paragraphs will describe some of the intervening details. We will follow Figure 1's description of the various segments comprising PTF UY50707. Some of UY50707's parts are essential to our work. Other parts are unnecessary for us to be concerned about. Let's start. Every PTF needs a "++PTF" and a "++VER" statement. It is sufficient to pattern these from an existing IBM PTF. The PRE and SUP statements are crucial. You should be scrupulous not to SUP any IBM sysmods in your user-written sysmod. Keep the PRE's to an absolute minimum, too. You may write your documentation in comments, the way IBM does. IBM usually uses the ++VER statement as a place to insert its descriptions. You may wish to write a ++HOLD statement for later reference by your installation. However, you'll have to BYPASS it during the APPLY. Probably enough adequate documentation can be put into normal comments. Make your own decision on a ++HOLD statement. I'd shy away from including the ++DELETE for the LMOD of IEBCOPY. As long as you're replacing all of the CSECTS and you're supplying complete new JCLIN, the entire load module will probably be replaced anyway. In UY50707, IBM was radically changing the structure of the IEBCOPY load module, and they wanted to be sure that the unnecessary pieces from the old version were blown away. Inline JCLIN must be carefully done. The MAP-RELINK output generated by the "PDS" command is a good and accurate starting point. Just make sure that your JCLIN is similar in format to the JCLIN in UY50707. There is one difference to be noted. SMP recognizes the "SYSGEN-type" linkage editing procedure called "LINKS", which is supplied by IBM for IOGEN or SYSGEN purposes. A perfectly good alternative to using the "LINKS" procedure in JCLIN is to put an EXEC card for the program "IEWL" directly in the JCLIN. Look at Figure 2 again, to see how we did it. We are not changing the form of our IEBCOPY load module, so the SYSGEN macros relating to IEBCOPY linkedit JCL generation need not be modified. We are also not deleting any of the individual MOD entries for CSECTs within IEBCOPY, so the second set of ++DELETE statements in UY50707 (referring to the MOD entries) are not relevant to us, unless we want to get rid of an extra "frontend" CSECT. In that case, we should code a ++DELETE card to get rid of the frontend's MOD entry. The final part of the PTF consists of ++MOD SMP statements, each followed by an object deck. If your SMP records aren't badly messed up, you may inquire on the RMIDs (i.e. PTF levels) of all your MOD entries belonging to IEBCOPY CSECTs. If the old PTFs are still around, you can possibly obtain non-base-level object decks by lifting them from the original PTFs. For CSECTs at base level, or in all other cases, the object decks will have to be obtained by the process of "delinking". See Figure 3 for JCL to run the DELINK0 program. DELINK0 only produces a CSECT at a time, so the process will have to be repeated for all CSECTs in IEBCOPY for which you don't have an object deck. One thing needs to be noted here. DELINK0 in its current form produces object decks with ESD's that are AMODE 24 and RMODE 24 only. This "mode" problem (for the public domain delinker) is being worked on. PDS/E has its own delinker which does not have this problem. But PDS/E can do our entire process "automagically" anyway, using its "SMPGEN" subcommand with the appropriate keywords. We'll briefly mention this "PDS/E" feature at the end. After the ++MOD cards pointing to DISTLIB(AOSU0) have been created, and the appropriate object decks have been placed carefully below each of these, the PTF has been constructed. It must be slowly and scrupulously checked over. If you are only overlaying existing SMP MOD entries, and are not deleting any MODs, an APPLY run with REDO should write over any mistakes you make on the first try. Because of the "REDO" keyword, your APPLY can be done over and over again. You should not need to try a RESTORE. But remember to always be very careful. Always do an APPLY CHECK before a real APPLY of your own PTF. An APPLY CHECK will often uncover silly sysmod construction mistakes. After the APPLY of your PTF, look at the resulting IEBCOPY load module with AMBLIST or with the "PDS" MAP subcommand, and compare its CSECT structure to that of the original "good" IEBCOPY load module. They should be exactly the same. If you have a byte-by-byte or CSECT-by-CSECT comparison utility, now is the time to use it. Try to test the new load module any other way you can. For shops that have the vendor product, PDS/E Sysprog Utilities, much of the above process is automated by its subcommand: SMPGEN IEBCOPY MOD DISTLIB(AOSU0) SYSLMOD(LINKLIB) INLINE CSECT Conclusion SMP "disasters" do not have to result in laborious restores from backups. If the problem is localized, such as being restricted to one load module, it may be easier to fix by making a complete replacement for the load module. It helps to know how to construct your own PTF, to accurately do the replacement. Minimal software resources are required for this procedure. That's because we're using available tools to find out "about the software, from the software itself". Good luck in these endeavors, and in all your other ones. See you next month. Figure 1: This shows the structure of PTF UY50707 which re-ships the entire IEBCOPY load module. This PTF adds function to IEBCOPY so that it will copy the new PDSE libraries. Our reason for using this PTF is to illustrate how IBM will package a complete reshipment of an existing load module. We wish to distill the elements of IBM's packaging, so that we can re-install our own IEBCOPY load module with SMP at our own currently installed level. Parts of the PTF are: (1) The ++PTF and ++VER statements with the PTF documentation. (2) ++HOLD statement and ++DELETE statement for the IEBCOPY LMOD entry (unnecessary for our purposes). (3) ++JCLIN (crucial for us). (4) ++DELETE statements for MODs being eliminated in the rewrite (unnecessary for us unless we're deleting the MOD entry for a frontend module). (5) ++MAC statement to revise the SYSGEN macro for IEBCOPY (unnecessary if you don't change the linkedit structure of IEBCOPY). (6) ++MOD statements for each CSECT in IEBCOPY followed by the object deck for each CSECT (crucial to replace the working software properly). ++ PTF (UY50707) /* 5665-28445-HDP3320- //UY50707 JOB 5665-50707-0,28445,MSGLEVEL=(1,1),CLASS=A */ . ++ VER (Z038) FMID(HDP3320) PRE (UY44382) SUP (UY43696,AY27240,AY27237,AY24733) /* ( DOCUMENTATION FOR THE PTF IS INSERTED HERE. ) */. ++ HOLD(UY50707) SYS FMID(HDP3320) REASON(DELETE) DATE(90146) COMMENT (THIS PTF CONTAINS A ++DELETE MCS FOR THE FOLLOWING LMOD: IEBCOPY SMP/E WILL NOT RESTORE THIS PTF.). ++DELETE IEBCOPY SYSLIB(LINKLIB). ++ JCLIN . //SYSGEN0 JOB 1,'SYSTEM GENERATION', // MSGLEVEL=1,MSGCLASS=A, // CLASS=A //SG22 EXEC LINKS, // PARM='NCAL,LIST,XREF', // UNIT='3380',SER=SYSRES,N=SYSX,NAME=LINKLIB,P1=' ', // MOD=,P2=' ',OBJ=MACLIB,CLASS=A //AOSU0 DD DISP=SHR,VOLUME=(,RETAIN),DSNAME=SYS1.AOSU0 //SYSLIN DD * INCLUDE AOSU0(IEBCFAMS) INCLUDE AOSU0(IEBCMSG) INCLUDE AOSU0(IEBCNVT) INCLUDE AOSU0(IEBCOMCA) INCLUDE AOSU0(IEBCPMOD) INCLUDE AOSU0(IEBCRDC) INCLUDE AOSU0(IEBDRB) INCLUDE AOSU0(IEBDRD) INCLUDE AOSU0(IEBDSCPY) INCLUDE AOSU0(IEBDSU) INCLUDE AOSU0(IEBDV0) INCLUDE AOSU0(IEBDWR) INCLUDE AOSU0(IEBIOE) INCLUDE AOSU0(IEBMCM) INCLUDE AOSU0(IEBPRINT) INCLUDE AOSU0(IEBRSAM) INCLUDE AOSU0(IEBSCM) INCLUDE AOSU0(IEBVCT) INCLUDE AOSU0(IEBVDM) INCLUDE AOSU0(IEBVTM) INCLUDE AOSU0(IEBVTT) INCLUDE AOSU0(IEBWSAM) INCLUDE AOSU0(IEBWSU) ORDER IEBCOMCA(P),IEBCOMCB(P) SETCODE AC(1) MODE AMODE(24),RMODE(24) ENTRY IEBDSCPY NAME IEBCOPY(R) /* ++ MOD(IEBDV1) DISTLIB(AOSU0 ) DELETE . ++ MOD(IEBBAM) DISTLIB(AOSU0 ) DELETE . ++ MOD(IEBLDUL) DISTLIB(AOSU0 ) DELETE . ++ MOD(IEBVMS) DISTLIB(AOSU0 ) DELETE . ++ MAC (SGIEH402) DISTLIB(AGENLIB ). (CONTENTS OF MACRO FOR SYSGEN SUPPORT OF IEBCOPY.) ++ MOD(IEBCFAMS) DISTLIB(AOSU0) . - - - Object deck for module IEBCFAMS - - - ++ MOD(IEBCMSG ) DISTLIB(AOSU0) . - - - Object deck for module IEBCMSG - - - ++ MOD(IEBCNVT ) DISTLIB(AOSU0) . - - - Object deck for module IEBCNVT - - - ++ MOD(IEBCOMCA) DISTLIB(AOSU0) . - - - Object deck for module IEBCOMCA - - - ++ MOD STATEMENTS FOR EACH OF THE CSECTS, FOLLOWED BY OBJECT DECKS - - - Data abbreviated for brevity - - - * * * * * * * * * * * * * * * * * * * * * * * FIGURE 2: Our PTF to reinstall IEBCOPY at the DFP Release 2.4 level. The "++PTF" and "++VER" part has been patterned after an IBM PTF. The JCLIN can be generated by the "PDS" subcommand, "MAP IEBCOPY RELINK", and edited a bit to add the ddname for the distribution library, AOSU0. The "PDS" subcommand, "MAP IEBCOPY" will supply the names of the CSECTs in IEBCOPY to delink. The DELINK0 program can be used to create object decks for these CSECTs to be placed below the "++MOD" cards. If you are licensed for the PDS/E product which has its own "delink" capability, all of the data from the ++JCLIN and below, can be created with the one PDS/E subcommand: "SMPGEN IEBCOPY MOD DISTLIB(AOSU0) SYSLMOD(LINKLIB) INLINE CSECT". The only input for the entire procedure is the good load module, SYS1.LINKLIB(IEBCOPY). ++ PTF (UY24CPY) /* 5665-28445-HDP2240-DP9 //UY24CPY JOB 5665-44388-0,28445,MSGLEVEL=(1,1),CLASS=A */ . ++ VER (Z038) FMID(HDP2240) /* (You can write your own PTF documentation here. ) */. ++JCLIN . //LKED EXEC PGM=IEWL, // PARM='NCAL,MAP,LIST,LET' //SYSUT1 DD UNIT=SYSDA,SPACE=(2048,(200,20)) //SYSPRINT DD SYSOUT=* //AOSU0 DD DISP=SHR,DSN=SYS1.AOSU0 //SYSLMOD DD DISP=SHR,DSN=SYS1.LINKLIB //SYSLIN DD * INCLUDE AOSU0(IEBDSMCA) INCLUDE AOSU0(IEBDSCPY) INCLUDE AOSU0(IEBVTM) - - - INCLUDE statements for the other IEBCOPY CSECTs - - - ORDER IEBDSMCA(P) ORDER IEBDSCPY ORDER IEBVTM - - - ORDER statements for the other IEBCOPY CSECTs - - - SETSSI 01113798 SETCODE AC(1) ENTRY IEBDSCPY NAME IEBCOPY(R) ++MOD(IEBDSMCA) DISTLIB(AOSU0) . - - - Object deck for module IEBDSMCA - - - ++MOD(IEBDSCPY) DISTLIB(AOSU0) . - - - Object deck for module IEBDSCPY - - - ++MOD(IEBVTM ) DISTLIB(AOSU0) . - - - Object deck for module IEBVTM - - - ++MOD statements for the other IEBCOPY CSECTs . . . . . - - - Each ++MOD is followed by an object deck. - - - FIGURE 3: JCL to execute the DELINK0 program. DELINK0 starts with a load module and creates an object deck for one CSECT at a time. The process is the reverse of linkage editing. Source code for DELINK0 in assembler language may be found on File 316 of the CBT MVS Tape. The JCL below will "delink" one CSECT from load module IEBCOPY. For our purposes, the process has to be repeated for all of the CSECTs in IEBCOPY. You can use the AMBLIST service aid distributed by IBM, or the "PDS" package's "MAP" subcommand, to determine the names of all the CSECTs in a load module. //TSTXDLNK JOB ,'TECH.SUPP-SAM.GOLOB',CLASS=M,NOTIFY=TSTBSSG, // MSGLEVEL=(1,1),MSGCLASS=T TYPRUN=HOLD //* //DELINK EXEC PGM=DELINK0,REGION=2000K //STEPLIB DD DISP=SHR,DSN=TST.TSO.CMDLIB //SYSPRINT DD SYSOUT=* //SYSLIB DD DISP=SHR,DSN=SYS1.LINKLIB <=== load library //SYSPUNCH DD DISP=(NEW,PASS),DSN=&&TEMP,UNIT=SYSDA, // DCB=(RECFM=F,LRECL=80,BUFNO=255),SPACE=(TRK,(5,20)) //SYSIN DD * IEBCOPY IEBVMTXT //* //GENER EXEC PGM=IEBGENER //SYSPRINT DD SYSOUT=* //SYSIN DD DUMMY //SYSUT1 DD DSN=&&TEMP,DISP=(OLD,PASS) //SYSUT2 DD DISP=SHR,DSN=TST.DELINK.PUNCH(IEBVMTXT) <== object deck * * * * * * * * * * * * * * * * * * * * * * *