MVS TOOLS & TRICKS Keeping up With the Unit Control Block: Part I By SAM GOLOB CALLOUT: The JES2 Remote Destination Table (RDT) is a list of remote connections in JES2. It also includes destination addresses that can be referred to by the DEST JCL parameter or a DEST keyword in a TSO command. CALLOUT: Serious UCB restructuring began at the MVS/ESA 4.1.0 level. A drastic change also occurred when MVS/XA was first introduced. What do most of us work on? Often the answer is "whatever needs fixing." I once made a service call to IBM Level 2. We were having trouble with a certain module. The problem was known, and the technician gave me a clear answer. Then I mentioned another module. The technician had never heard of that one, even though it was closely related to the one that needed fixing. The reason she probably had never heard of it was that it hadn't been changed in 10 years. I was familiar with it because I had fitted an enhancement zap to it. But, there was no way an IBM technician could have known about that zap. The moral of the story? System components that don't have problems usually don't get attention. This is why we have conversion notebooks. When a new version of the operating system comes out, people want to know what has changed. What still works is often of no concern to them. I really don't blame anyone for that attitude. The operating system is so big that most of us don't have time to pay attention to what is working properly. Our job is to keep the computer center running. Problems and changes alone will keep us busy enough. This month, I'll focus on an operating system area which has recently changed quite a bit, requiring us to adjust to the consequences. This is the UCB, or Unit Control Block. The UCB describes a physical peripheral device, and contains all the necessary information for the device to be used in performing I/O requests. On old systems, UCBs were statically generated during system generation, and the collection of UCBs, representing all peripheral devices known to the MVS system, was a fixed block of storage in the nucleus area. With the recent introduction of Dynamic I/O reconfigurations, Dynamic UCBs and four-digit unit addresses (some user programs and tools which used to work) have stopped doing their jobs, and must be fixed. But, by whom? Those who have maintained user-written code for years have an answer. If a program was not written by IBM or by another vendor, there is no "official" person to call. If the original source was on a public tape, such as the CBT MVS Utilities Tape or the NaSPA VIP tape, one can try and call the original author or the tape's proprietor. If possible, a user who considers this program important should fix it. Then, that person can send the updated program to the proprietor of the public tape where the source is kept. After the tape gets updated with the new source, everyone else will benefit from a version of the program that now works. This way, the job of fixing affected programs is divided among a number of people. Handling the Dynamic UCB Situation There are quite a few new topics that need to be discussed. This series of columns will examine several different types of code changes. I hope that these columns will provide a better understanding of what needs to be done, and give you a better handle on getting some old tools to work in this "era of Dynamic UCBs." Fundamentals In response to many customer suggestions, IBM is trying to make more system resources dynamically modifiable. Today, when numerous computer operations must continually be up, system down time for IPLs is scarce. We'd like to employ an operator command to change as many system parameters as possible "on the fly" instead of requiring an IPL. Coding-wise, what's involved in such a change? Here's a relatively simple example. The JES2 Remote Destination Table (RDT) is a list of remote connections in JES2. It also includes destination addresses that can be referred to by the DEST JCL parameter or a DEST keyword in a TSO command. The RDT used to be modifiable only by a JES2 WARM start, which meant an IPL. The ability to add and delete connection and destination addresses (with $ADD and $DELETE commands) was introduced in JES2 version 4.1. This involved the restructuring of the physical layout of RDT table entries. Formerly, the destination table entries were created in one large block of storage at JES2 startup time. The table was searched by starting at the beginning of its storage, and following it sequentially, entry by entry. This cannot work in a dynamic situation where you could add or delete new entries at will. Where would there be space to put an "unlimited" quantity of new table entries? RDT has been made dynamic. This is how it has been restructured: When a new RDT is built, a 4 KB block of storage is GETMAINed and marked with a header saying this will be storage for RDT table entries. Header fields are created to show how full the block of storage is. Then, the new table entries are built in this block of storage and are logically chained to each other, beginning from the first entry. To locate the beginning of the table, the address of the first entry is put into a known JES2 control block when the table was initially created, usually at startup time. Every time we run out of storage for RDT entries, a new 4 KB block of storage is GETMAINed, headed, and filled with new entries chained from the previous ones. Since the $DELETE command is also supported, we sometimes need to "zero out" some entries, re-chain the remaining ones to each other, and reuse the newly freed space. In a large JES2 network, RDT table entries in a chain might jump from one 4 KB block to another and back again several times. Clearly, a sequential search will no longer do the job. Old programs or JES2 exits that search the RDT that way will no longer work. The search algorithm must be rewritten to start at the first record and to follow the chain of record addresses for the desired entry. The RDT illustration makes things easier to see. The UCB situation is more complicated and hidden, but most of its principles are similar. JES2, which owns the RDT, makes much of its source code accessible to us. The base operating system code and IOS, which deal with the UCB, have mostly OCO (Object Code Only) modules. We cannot easily observe what those components are actually doing. To deal with UCB issues, IBM provides macro access to most services. Since these services have been changing between MVS releases recently, the MVS Conversion Notebook manuals are an excellent source for finding out what to do. UCB Structure Considerations There are two issues with which we have to deal. One is the actual structure of the UCB and how it is changing. The other is how to search for and obtain information from the particular UCBs which represent physical devices in which we are interested. The mapping macro for a UCB is called IEFUCBOB, which is found in SYS1.MACLIB. This macro details the structure of every type of UCB. IEFUCBOB also can limit itself to describing only UCBs of a certain device type. The allowable types are DASD (disk) devices, magnetic tape devices, unit record devices, communications equipment, CTCs, and graphics devices. Serious UCB restructuring began at the MVS/ESA 4.1.0 level. A drastic change also occurred when MVS/XA was first introduced. Therefore, it is worth discussing how an assembler program can determine the system level under which it is operating. The CVT (Communications Vector Table), the backbone of MVS control blocks, contains an old field, CVTDCB, which determines the level of OS running. At the ESA levels and above, there is another field called CVTOSLVL, which reserves no less than 16 bytes of bit flags, so IBM will never have any trouble telling you which level of the operating system is currently running. For an MVS/XA system, the CVTDCB field is set to X'93'. For an MVS/ESA system, CVTDCB is set to X'9B'. The extra bit X'08' indicates that the CVTOSLVL area is present and may be referenced. See the CVT mapping macro in SYS1.MACLIB at your system's level for further details. If you are on an MVS/ESA system, the X'08' bit called CVTUCBSV in flag CVTOSLV0 (indicating system level HBB4410 or above) will show that the new UCB macro services are available and ready for use. The actual structure of the UCB storage area(s) is determined by whether MVSCP, or HCD and IODF are used to create the system's I/O configuration. MVSCP is the old way. HCD (Hardware Configuration Dialog), which is used to build an IODF (I/O Definition File) is the new way. You no longer have a choice at the MVS/ESA Version 5 level. MVSCP no longer works, and you must use HCD. If MVSCP is used to define the I/O configuration, then the UCBs reside in member IOSUCBxx of SYS1.NUCLEUS, where xx is the identifier of the designated I/O configuration. The UCBs are created and initialized by the MVSCP and are loaded into the nucleus region (below the 16 MB line) during IPL. If HCD is used to build an IODF to represent the I/O configuration, then the UCBs are built in SQA during the IPL. In the latter case, they don't have to be contiguous. Everything we said before about dynamically modifiable control block chains can now apply. The UCB itself consists of a prefix, a common segment, and various device-dependent segments. There are also various extensions. In older systems, the UCB segments were physically contiguous, but IBM no longer guarantees that. For these reasons, the only recommended way of searching and scanning UCBs is through IBM-supplied macro services. UCB Searching and Scanning The remainder of this month's column will provide an overview of some new UCB searching and scanning services. This will help you find the UCBs you want, even in this new environment when some or all of the UCBs may be dynamic. Next month's discussion will examine how to convert existing programs to use new scanning and searching methods. Two principal macros that concern us are UCBLOOK and UCBSCAN, both of which may be found in SYS1.MACLIB. UCBLOOK is used to obtain the UCB common segment address of a given device number or volume serial. UCBSCAN is used to scan UCBs. The following types of scans are supported: all UCBs, or all UCBs within a particular device class. Device classes may include DASD devices, tape devices, unit record devices, etc. In a given UCB scan, we may restrict the scan further. Permissible restrictions are as follows: only report static (non-dynamic) UCBs, only report three-digit device addresses (excluding the new four-digit addresses), and specify the device number from which the scan should begin. Several more concepts in the dynamic UCB environment need mentioning. What can we do to prevent a UCB from disappearing during an I/O configuration change? Second, if we are in the middle of conducting a UCB scan operation, how can we detect that an I/O configuration change has been started, potentially upsetting and invalidating much of what we're looking at? In answer to the first question, the concept of fixing or "pinning" the UCB was invented. The UCBLOOK macro can optionally pin the UCB, or prevent its deletion if we're looking at it during a configuration change. UCBPIN is another macro specific to this purpose. The UCBPIN macro, also in SYS1.MACLIB, can be used either to pin or "unpin" a UCB when it needs to be fixed or freed. Any system component can pin a UCB. For a pinned UCB to be freed, it must be specifically unpinned using the UCBPIN macro. In answer to the second question, the concept of an IOC token was invented. This token is essentially a "configuration change identification number." The current I/O configuration's token may be discovered through the IOCINFO service, which is invoked by the IOCINFO macro. Both UCBLOOK and UCBSCAN macros may be invoked using the IOCTOKEN keyword. This allows the UCB lookup or scan to verify that a configuration change has not occurred recently. We first obtain the current I/O configuration's token using the IOCINFO macro, which returns the token value into a 48-byte storage field obtained for our program's use. Then, the UCBLOOK or UCBSCAN IOCTOKEN keyword is pointed to in this token field. If UCBSCAN gets a return code of 12 in Register 15, it indicates that a configuration change has occurred. So far, we've discussed many of the new concepts involved in the recent UCB changes. Next month's discussion will provide more practical applications. Good luck! Was this column of value to you? If so, please circle Reader Response Card No. Sam Golob is a senior systems programmer working in New York City.