I'm not sure where to go with this question, but I'm hoping "Dev Ops" has something to do with applications development and someone here can direct me to the right forum.
I'm cleaning out a bunch of datasets that used to belong to users whose Top-Secret ACIDs no longer exist. A high proportion of those datasets belong to Librarian (at this installation every developer got his own), and I don't want to delete those until a coworker has had a chance to examine them.
But a good many of them I can delete anyway, for either of two reasons: 1) Some of them are improperly allocated or initialized in some way: ISPF says these have no extents, and when I try to open them in Librarian it abends with IEC138I 020-08. My REXX program can spot these with LISTDSI; no problem there. 2) Many of the rest have no members. If I can find some way of identifying those in my REXX instead of making my coworker look at each one individually in ELIPS—there are scores of them at least—it'd save her a lot of trouble.
So how do I get at this information inside a program? The ELIPS manual has a section on running it from a CLIST, but upon careful reading it turns out it's talking only about firing up ELIPS, not interacting with it. I thought the File Access Interface Routines Guide looked hopeful, but I don't see a routine I could use to tell me whether any members exist in the library. Must I write a screen-scraper in the emulation's VBA, or is this something I can do with a REXX?
Here is what I would suggest.
1) run a Master Index Statistical report and write it out to a Temp file:
//INDEX EXEC PGM=AFOLIBR,PARM='NRJS,NJTA' //SYSPRINT DD SYSOUT=* //INDEX DD DSN=&&TEMP,DISP=(,PASS),
DCB=(LRECL=133,RECFM=FB,DSORG=PS,BLKSIZE=26600) //MASTER DD DISP=SHR,DSN=your.Librarian.Master.file//OSJOB DD DUMMY //SYSIN DD * -OPT INDEX(S) -END //*
2) Have your REXX routine parse the Temp file and look for the line --
THE TOTAL NUMBER OF MODULES ON THE MASTER FILE.............128
3) If Master file contains no modules, feel free to delete.
*** ONLY AFTER YOU HAVE MADE THE APPROPRIATE BACK UPS****
That's great for one such library, but as I said, I have scores to examine. I was hoping for some way my program could do this rather than submitting scores of batch jobs. Still, I'm sure there are ways:
1) The crudest and most certain is to write a program in the language of the 3270 emulator, some flavor of VB. It would act like a human typing and reading at my terminal, albeit very, very fast :-). That would break up the process into three parts, though; first collect the DSNs; then the emulator program reads the names from a file, examines each one and writes the results to a file; then back to a mainframe program that'll delete the files that are empty.
2) I can have a program generate the JCL and submit one job for each of the many Librarian files, and another that'll interact with SYSVIEW to read and act on the results. Presumably each job would run very quickly, so I could even have the program submit each job and read the results on the fly rather than doing all the submits and later read and analyze all the results.
3) The best way, though, may be to figure out how to run AFOLIBR in the foreground: Run it on a single library, read SYSPRINT, act on the results, then around again for the next library.I'm interested in your thoughts (or those of anyone else), but if not then what you've given me so far should be enough for me to go on. Thanks.
Librarian does not have any type of repository that identifies all the Librarian Master files so there is no automated why to get a list of the Master files. If you have a list of the Master files, #2 is probably the way to go. Yes, the Master Index report runs quickly if the Master file is not archived.
Right, I already have a list. (I just got ISPF to show me a list of datasets that start certain prefixes, such as CX*; that takes only a few seconds. Then the program goes through the list and discards anything whose HLQ doesn't look like a user ID, and also anything that actually is a user ID. The survivors are datasets that probably belonged to an old ID, and that should have been cleaned up when the ID was deleted from TSS.) The Librarian datasets are all named somebody.DEV.LIBR; any of those that have no extents can be deleted as having been improperly allocated in the first place. Now I want to eliminate any that have no members, and the rest can be turned over to that coworker for examination.
I think I'll experiment with option #3, because if it'll work it's a handy thing to know. I've already written foreground calls for TSSSIM and CA-Cleanup, both big time-savers; I suspect I can do the same with AFOLIBR. If not I'll fall back on #2.
Sounds like a plan.
In case anyone cares, option 3 (using your JCL as a model) works like a champ. It turns out I need UPDATE access to a Librarian dataset in order to get AFOLIBR to show me its member list, but since I'm the security admin I can give myself that access, and since I'm cleaning up old libraries belonging to users long departed there's no problem with my doing that. So among other things, when my program works its way down the list of old datasets and gets to a Librarian, it a) give me the necessary access to it, if I don't already have it, then b) allocates the necessary DDs and runs AFOLIBR. Then it checks the contents of the output, finds the member count and decides accordingly. If the member count is 0 I can mark the dataset for deletion; if not, I'll rename it so that a coworker can examine it and decide whether she wants to keep it.
The program can deal with several hundred defunct datasets, including a couple dozen Librarians, in 15 or 30 seconds; not bad at all even in the foreground.
The correct Community for CA Librarian is --
CA Mainframe Community
Ok, and I was able to move it too, somewhat to my surprise. Thanks.