MVS TOOLS AND TRICKS OF THE TRADE MAY 2006 Sam Golob MVS Systems Programmer P.O. Box 906 Tallman, New York 10982 Sam Golob is a Senior Systems Programmer. He also participates in library tours and book signings with his wife, author Courtney Taylor. Sam can be contacted at sbgolob@cbttape.org. Information about the CBT MVS Tapes can be found on the web, at http://www.cbttape.org. WHY CONTROL BLOCKS? Everybody who has the slightest acquaintance with MVS internals, will quickly notice that many of the storage areas in a running MVS system are called "control blocks". Control blocks are defined (by IBM) as blocks of data in computer storage, which are somehow related to each other by function. It really goes much further than that, as we will show. Often, a definition of a term does not really tell you all the consequences and the details which are implied by that term. In many cases, the definition does not tell you the WHY. Someone who is really familiar with the usage of control blocks in MVS, will tell you that this basic definition of control blocks actually leaves most of the information out. I'll show you another IBM definition, just to make my point. The other definition is in the area of SMP/E, something that most MVS sysprogs have to deal with sooner or later. SMP/E is IBM's program package to install updates and fixes to the MVS system. The usual basic SMP/E definitions: RECEIVE, APPLY, and ACCEPT, are easy enough to understand intuitively, even for a novice. RECEIVE means "getting a fix (technically known as a SYSMOD) into the system." APPLY means to actually install the fix into executable libraries. And ACCEPT means (very roughly) making the fix permanent. Those concepts are pretty easy to grasp. But what about the concept of JCLIN? JCLIN is defined (in the IBM books) roughly, as "a job stream of assembly, linkedit, and IEBCOPY job steps. ... This job stream is used as input to a JCLIN command to update or create entries in a target zone." That definition doesn't really tell you what JCLIN does. It just tells you roughly, that it is JCL which you feed into an APPLY job. The definition doesn't tell you the WHY of JCLIN. The WHY of JCLIN really is, that SMP/E needs to know the structure of all the executables in the system, and how they hang together. That's what the linkedit jobs in JCLIN do. And SMP/E also needs to know the library locations where all the pieces of the system, as shipped by IBM, are supposed to reside. That's what the IEBCOPY jobs (and the SYSLMOD DD of the linkedit jobs) do. This is really the purpose of the "JCL" which has been fed "in" to the APPLY job. When you've dealt with SMP/E a lot, you know this. Otherwise, you probably don't. The basic definition of JCLIN doesn't give you much of a clue in any case, and it doesn't explain itself. The situation is similar with control blocks. The WHAT of control blocks, that they are related pieces of data which the system needs, is something that it doesn't take long for a new MVS sysprog to learn. But the WHY is a slightly longer story. To give a hint toward an answer, we might ask the rhetorical question: "What came first? The controlling data structures or the programs?" And the answer is: Probably they were designed together. Then another question: "What if you change the controlling data, and not the programs?" Answer: Then you've got all the flexibility that you need. And that, folks, shows you the value of control blocks. The data in the MVS control blocks allows you to wield all the flexibility and control that was designed into the system. The control blocks "give the orders". The system programs just carry out the orders. AN EXAMPLE A few months ago, we wrote about "TSO/E control blocks" in this column. To show an example, one of the TSO/E control blocks is the INMXPARM control block. The INMXPARM control block regulates how much output a single TSO TRANSMIT (XMIT) command, executed in a single MVS instance, is allowed to produce. If 5 million lines is in the control block, then the XMIT command output gets cut off after writing 5000000 lines. If 30000 lines is in the control block, then an XMIT command can only produce 30000 lines of output. If 0 (zero) is stuffed into the control block, then XMIT will not be able to produce any output. The XMIT program has not changed. But its behavior has changed, because of a controlling value that has been stored in the appropriate place, in the appropriate control block, located externally to the XMIT program. In actual fact, a lot more controlling information is present in the INMXPARM control block, and this affects a lot of the behavior of the TSO XMIT command. The dataset name that logs the XMIT command outputs is determined there. The warning threshold and warning intervals are specified there. And a lot of other controlling information is there. Although the INMXPARM control block is not described by a publicly specified macro, you can see a good guess at its contents by looking at the IKJXPRM member in the MODGEN member of File 731 of the CBT MVS Utilities Tape. But the bottom line idea is, that all of the possible varied behaviors of the TSO TRANSMIT program are controlled by the values and quantities in the INMXPARM control block. The control block controls the behavior of the program. Now, we're getting a clearer idea about what control blocks do. But we'll even do better than that! PASSING CONTROL DATA BETWEEN MULTIPLE PROGRAMS Sometimes (read USUALLY), the state of an ongoing process in MVS, is completely described by the contents of one or more control blocks. These control blocks, and the data quantities within them, completely describe and keep track of what is going on in the process. Such a program design is often implemented within the MVS components. And that is how many MVS components actually work. If a program wants to "know" about the current status of the process, it need merely query the contents of the relevant control blocks. The program does not need to have access to any data areas that are located within some other program. In this design, all of the controlling data is located externally to any of the processing programs. And now, we have really begun to understand why MVS has so many control blocks. The purpose of the control blocks is to keep the controlling data EXTERNAL to any of the processing (system) programs. So when a system program wants to affect how some system process is being executed, it need merely change the relevant quantities in the appropriate control blocks. In other words, when this program design is implemented (as it is in most of MVS internals), the control of the processes is completely carried out by data that is external to the running programs. Most of MVS has been designed to work this way. Now, we are really zeroing into the REAL REASON why MVS has control blocks. The real purpose of control blocks is to keep all of the controlling data external to all of the processing programs. Then, if a programming change is necessary to one of the processing programs, that change will not directly force a corresponding change to any other programs, except in how they affect the external data that is within the control blocks. If a new field is required by the programming change, it is added to (or changed within) the control block, and any other programs which need to read or change that new field, must be adjusted accordingly. This will give you much insight into understanding IBM fixes. If you spend time reading APARs and PTFs as they come from IBM, you will notice that they usually change the contents of a control block, and then they will also supply new copies of all the relevant programs so these programs will properly access that new (or changed) control block field in the new way. MACROS Control blocks, and the data fields contained in them, are almost always described by macros. Macros are Assembler (or PL/X) statements which are centrally packaged in macro libraries, and which describe the detailed structure of all the fields in a given control block to a processing program. The MVS data areas books, which contain descriptions of all the publicly available control blocks for a given release of MVS, are actually constructed by automated processes (from within IBM) from actual macros in SYS1.MACLIB, SYS1.MODGEN, or in the specialized macro libraries that are sometimes distributed with less common MVS components. Knowledge of many MVS control blocks is publicly available. And you can learn about the structure of these control blocks, either by looking in the MVS Data Areas books, or in the actual macro libraries (usually SYS1.MACLIB or SYS1.MODGEN). Some of the MVS control block descriptions are not publicly available. IBM calls these control blocks "OCO" (Object Code Only distribution), but it really means that IBM does not want to publicly disclose the details of their contents. The macros which describe OCO control blocks are kept internally within IBM, and are not distributed in the system macro libraries. So IBM can assemble programs which refer to those control blocks, but (officially) you can't. Since most of MVS is coded using this design, with the controlling data being external to the processing programs, and with this data being located in "control blocks", you can understand much of what is going on within any MVS component by studying the contents of the relevant control blocks. Often, you don't even need to know any of the details about how the processing programs work. That is one of the beautiful things about MVS. Since the controlling data is external to the programs, you can follow the progress of much of MVS processing, just by having an understanding of the contents of the relevant control blocks. Detailed knowledge of the actual programming is usually unnecessary, if you are a sysprog trying to solve a system problem. I'VE DONE IT TOO I've implemented this "control block" design in several of the utilities that I've written myself. I'll briefly describe what I've done, and how I've done it. For all the details, you can download File 533 from the free CBT Tape collection. (Do a www.google.com search on "CBT Tape" to find our website, which should come out near the top of the search.) The two relevant programs are called VTT2TAPE and VTT2DISK. Both programs are designed to run on any MVS system, and they convert the contents of any physical tape, to (what I call) FB-80 AWS disk format. VTT2DISK reads in a tape, and converts its entire contents to AWS format (the data being folded over into FB-80 record format in MVS). And the other program, VTT2TAPE, reads this FB-80 folded AWS disk file, and can re-create the original tape from it. You can export the contents of the FB-80 AWS file from MVS to another system, like a P390 or a FLEX-ES system, using FTP, and that file (on OS/2 disk for the P390, or on Linux disk for FLEX-ES) can then be directly read as a tape by either of those systems. Since all disk data in MVS has to be blocked somehow, and there isn't the concept of a continuous "tape" file containing (say) a gig or two of data on MVS DASD, I had to pick an arbitrary way of folding all of the continuous tape data, and the AWS "header" data that was sandwiched in between that, into a blocked MVS disk file. I picked 80-byte fixed blocked "card image" format. Fixed blocked 80-byte card image data is probably the easiest data to deal with, and transport, within MVS systems. I don't like VB, because it introduces extra data into the "tape" file. So let us illustrate what I wanted to do in the VTT2DISK program. I would use EXCP to read a block of data from the actual tape on the tape drive. This data is read into a buffer that is located in my program's storage. Then I have to measure how much data is actually in the block, construct an appropriate AWS header to precede the block in the AWS file, fold that header into the FB-80 output file, and then fold the data in afterwards. Although I could have done this job "quick and dirty" using the MVCL instruction, I wanted to keep careful track of the process, and to be able to debug any part of it. Therefore I wrote a subprogram (called FOLDEM) to do the actual data folding. The main VTT2DISK program communicates with the FOLDEM subprogram using only a control block that I designed. The current state of how the data folding has progressed, is completely described by the fields in this FLDAREA control block. The calling program does not have to refer to any data in the subroutine. It only has to have a current copy of the FLDAREA control block. Same with the subroutine. It only needs to have a current copy of FLDAREA. Both routines update the control block, which keeps complete and perfect track (hopefully) of all the data folding proceedings. Again, for the actual code, you have to look at CBT Tape File 533. But you get the idea. SUMMARY Today, I've talked about the REAL purpose of MVS control blocks, which is to implement a programming design in which all of the controlling quantities of an MVS process reside OUTSIDE all of the processing programs. All relevant controlling data is in one place in system storage, and any programs needing the data, have to access that storage and refer to its (carefully designed and formatted) contents. Since most of the "amateur" Assembler language programming that we do, is not done in this style, I have to spell out how MVS program design is different. Only then, can we understand the real purpose of MVS control blocks--the WHY of MVS control blocks. Once we understand that, we can look at the structure of most IBM PTFs or APARs, and understand what they do. Often a control block is changed, and all the processing programs that refer to this control block, are supplied in new versions, which refer to the changed control block in its new, changed way. I wish all of you a good month, and all good things in general. And I'm certainly looking forward to seeing you here again, next month.