Admin Alert: CL Programming Techniques for Solving Backup Problems
by Joe Hertvik
Managing backups correctly is one of the most important duties a system administrator faces. With OS/400, this involves a number of detailed tasks that have been documented in earlier editions of Admin Alert. However, there are always different procedures for making OS/400 backups more flexible and easier to run. This week, let's examine three CL programming techniques that solve different backup problems.
1. Initializing multiple tapes with one program call. When you're using the green-screen Initialize Tape (INZTAP) command to format backup tapes, the command is limited, in that it can format only one tape at a time. This can become time-consuming when you want to quickly format a number of tapes in a particular manner. To automate tape initialization, here's some CL code that formats ten tapes in a row using a particular tape drive designated as an input variable:
PGM PARM(&TAPDEV) DCL VAR(&TAPDEV) TYPE(*CHAR) LEN(6) DCL VAR(&COUNT) TYPE(*DEC) LEN(10 0) VALUE(0) INITTAPE: INZTAP DEV(&TAPDEV) CHECK(*NO) + ENDOPT(*UNLOAD) CLEAR(*NO) IF COND(&COUNT *LE 10) THEN(DO) CHGVAR VAR(&COUNT) VALUE(&COUNT + 1) GOTO CMDLBL(INITTAPE) ENDDO ENDPGM
This program comes in handy for initializing volumes on any OS/400-connected tape drive that processes multiple tapes, including IBM 3570, 3580, and 3590 units. Because the program accepts the device name as an input variable, it allows you to substitute different tape drive names, such as TAP01 or TAP02, without recompiling the code. Upon activation, the program performs a simple initialization for each of your tapes, unloads each tape after the INZTAP command completes (which is done through the command's End of Tape parameter, or ENDOPT, value of *UNLOAD), and then uses the tape drive's autoloader capability to load the next tape as it cycles through its INZTAP processing loop. This program is also easy to extend, so you can add code to pass in the number of tapes to initialize or to create customized volume identifier or owner identifier values for each tape.
2. Converting OS/400 tape drive device names into Integrated File System (IFS) names. Most OS/400 green-screen save commands--such as Save Library (SAVLIB), Save Document Library Object (SAVDLO), or Save System (SAVSYS)--use a native OS/400 device name, such as TAP01 or TAP02, to designate the media unit to back up to. However, when you're using the Save Object (SAV) command to back up IFS files to tape, you need to designate the IFS device name of your backup unit, rather than the OS/400 device name. This means that the device name has to contain the iSeries or AS/400 file system where the drive resides (which is always /QSYS.LIB/), as well as a device identifier of .DEVD appended to the end of the name.
So if your SAV command is backing up IFS files to device TAP01, you need to convert the name TAP01 to its IFS counterpart and enter the converted name in the Device parameter (DEV) of the SAV command, as follows:
SAV DEV('/QSYS.LIB/TAP01.DEVD') OBJ(('/*') ('/QSYS.LIB' + *OMIT) ('/QDLS' *OMIT)) ENDOPT(*LEAVE)
To automate this process, you can use the following CL program code that accepts the native OS/400 device name (TAP01, for example), converts it to its IFS format, and then uses the converted tape drive name in a SAV backup:
PGM PARM(&TAPDEV) DCL VAR(&TAPDEV) TYPE(*CHAR) LEN(6) DCL VAR(&TAPDEVLNG) TYPE(*CHAR) LEN(40) + VALUE('/QSYS.LIB/') DCL VAR(&TAPDEVEND) TYPE(*CHAR) LEN(5) + VALUE('.DEVD') CHGVAR VAR(&TAPDEVLNG) VALUE(&TAPDEVLNG *TCAT + &TAPDEV *TCAT &TAPDEVEND) SAV DEV(&TAPDEVLNG) OBJ(('/*') ('/QSYS.LIB' + *OMIT) ('/QDLS' *OMIT)) ENDOPT(*LEAVE) MONMSG MSGID(CPF0000) ENDPGM
Like most OS/400 save commands, SAV supports using a CL variable for the Device parameter (DEV). Again, the advantage is that this code allows you to easily use different tape drives in your backup without having to recompile your program.
3. Saving most of your OS/400 libraries without going into restricted mode. When using the green-screen Save Library (SAVLIB) command, a common technique is to specify *NONSYS in the Library parameter (LIB) so that you can save your entire native OS/400 library set, as shown here:
SAVLIB LIB(*NONSYS) DEV(TAP01) ENDOPT(*LEAVE)
A *NONSYS backup saves all your OS/400 libraries--including user-created libraries, the QGPL and QUSRSYS libraries, and licensed program libraries--but its limiting requirement is that your iSeries or AS/400 must be in restricted mode to use it. You can't run a *NONSYS backup in save-while-active mode. There is a solution, however. To save your entire OS/400 library set while processing is occurring, you can split your *NONSYS SAVLIB command into two SAVLIB commands, each of which backs up part of the *NONSYS save set, providing an almost complete *NONSYS save without being in restricted mode.
Here's how it works.
Instead of running a *NONSYS SAVLIB command, you can run two SAVLIB commands: one to backup all IBM libraries (*IBM) and another to back up all user libraries (*ALLUSR). IBM specifies that performing a SAVLIB LIB(*IBM), followed by a SAVLIB LIB(*ALLUSR), saves the same libraries as a SAVLIB LIB(*NONSYS) command. If you combine this technique with save-while-active processing, you can save most of your OS/400 library data without putting your system into restricted state. Here's some CL code you can use to do this:
SAVLIB LIB(*ALLUSR) DEV(TAP01) ENDOPT(*LEAVE) SAVACT(*SYSDFN) + SAVACTMSGQ(QSYSOPR) MONMSG MSGID(CPF0000) SAVLIB LIB(*IBM) DEV(TAP01) ENDOPT(*LEAVE) SAVACT(*SYSDFN) + SAVACTMSGQ(QUSRSYS/ISJOEH) MONMSG MSGID(CPF0000)
The ALLUSR backup saves all licensed and program data, as well as some IBM libraries that begin with the letter Q. The IBM backup saves all IBM-provided "Q" libraries, with a few exceptions. The Save Active (SAVACT) parameter value of *SYSDFN performs save-while-active processing and allows objects in each library to reach checkpoints at different times, which eliminates some size restrictions that might prevent you from saving all objects in some libraries with the SAVACT(*LIB) parameter. SAVACT(*LIB) requires that all objects in a library reach their save-while-active checkpoints together, which uses more memory. By using these two commands together, you can almost perform the equivalent of a SAVLIB LIB(*NONSYS) backup.
But there are a few downsides to this technique, so I recommend you consider it carefully before implementing it in your environment. First, some objects in use may not be saved by using the *ALLUSR or *IBM techniques in an active environment. There are also a few IBM libraries that the *IBM backup will not save (check the help text on the SAVLIB Library parameter for a list of these libraries). Because objects in the same library may reach their save checkpoints at different times, the other major downside is that a SAVACT(*LIB) parameter save may not provide the coordinated backup data set you need for disaster recovery. So evaluate this technique carefully and be sure it's right for your organization. It's also important to know that, while this is a nice technique to use on a regular basis, it shouldn't be used as a replacement for regular restricted-mode, full-system backups, which save other objects than your OS/400 libraries.
Contact the Editors
Last Updated: 1/6/03
Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved.