Thursday, August 5, 2010

HOW TO COMPILE AND LINK EDIT MULTIPLE ASSEMBLER MODULES AT THE SAME TIME

This is the best way I could come up with. If someone has something better (a way to do it from within the JCL perhaps?) please let me know. We are going to create three files:

1) a text file that contains the names and locations of the modules you are going to work with

2) JCL that will compile and link edit the modules

3) a REXX exec that will read data from the environment file, edit the JCL accordingly, then submit the JCL for each member in the environment file. Essentially, you are going to submit a job for each module you want compiled, and the REXX will do that for you automatically via the parameters you specify in the environment file.

Here is the environment file sample:

/*********************************************************************/
/* ASMCLENV - ENVIRIONMENT FILE USED BY ASMCLREX */
/* */
/* 04AUG10 */
/* */
/*********************************************************************/

*1
[location of source module to be compiled]
[where to put the compiled module]
[where to put the link edited load module]

*2
[same format as above]



The REXX exec is going to look for an '*' in column one as it reads this file to tell it where the data it's looking for is. Also, make sure to include the high-level qualifier in the data set name.


Here is the JCL:


//ASMCL JOB 'COMPILE AND BIND ASSY',MSGLEVEL=(1,1),
// NOTIFY=&SYSUID,MSGCLASS=H,CLASS=1
//*
//*** HLASMCL
//*
//* THIS PROCEDURE RUNS THE HIGH LEVEL ASSEMBLER
//* AND LINK-EDITS THE NEWLY ASSEMBLED PROGRAM
//*
//*********************************************************************
//* COMPILE STEP *
//*********************************************************************
//C EXEC PGM=ASMA90,PARM=(OBJECT,NODECK)
//SYSLIB DD DSN=SYS1.MACLIB,DISP=SHR
//*
//SYSUT1 DD DSN=&&SYSUT1,SPACE=(4096,(120,120),,,ROUND),UNIT=SYSDA,
// DCB=BUFNO=1
//*
//SYSIN DD DSN= LOCATION OF SOURCE ASSY PGM **
//*
//SYSLIN DD DSN= WHERE OBJECT MODULE SHOULD BE WRITTEN **
//*
//SYSPRINT DD SYSOUT=*
//*********************************************************************
//* LINK STEP *
//*********************************************************************
//L EXEC PGM=HEWL,COND=(8,LT,C),
// PARM='NOMAP,NOLET,NOLIST,NCAL'
//*
//SYSLIN DD DSN= LOCATION OF MODULE TO BE LINKED **
//*
//SYSLMOD DD DSN= WHERE LINKED MODULE SHOULD BE WRITTEN **
//*
//SYSUT1 DD DSN=&&SYSUT1,SPACE=(1024,(120,120),,,ROUND),UNIT=SYSDA,
// DCB=BUFNO=1
//*
//SYSPRINT DD SYSOUT=*



This you shouldn't have to do anything with, just cut and paste, but be careful! JCL is very picky about operands being in the correct row/column. Make sure the lines that are continuations (the part of the statement that is continued on the next line) begins in column 16 or you'll get a big fat error!


Here is the REXX that drives the whole thing:

/* REXX */
/*********************************************************************/
/* CREATED 04AUG10 */
/* */
/* THE PURPOSE OF THIS EXEC IS TO DRIVE ASMCL (JCL TO COMPILE AND */
/* LINK EDIT AN ASSEMBLER MODULE). ASMCLREX WILL READ ASMCLENV TO */
/* GET A LIST OF ASSEMBLER SOURCE FILES TO COMPILE AND LINK. IT WILL */
/* THEN UPDATE ASMCL WITH THE DATA FROM ASMCLENV, SUBMIT THE JOB, */
/* AND REPEAT FOR EACH ENTRY IN ASMCLENV. THIS WAY WE CAN COMPILE AND*/
/* LINK MULTIPLE SOURCE FILES AT A TIME. */
/* */
/*********************************************************************/

ADDRESS TSO


/*READ ENVIRONMENT DATA***********************************************/

"ALLOC DD (INDDENV) DA('LOCATION OF ENVIRONMENT FILE') SHR REUSE"
'EXECIO * DISKR INDDENV (STEM ENVDATA. FINIS'
"FREE DD(INDDENV)"
ENVSIZE = ENVDATA.0
SYSIN = "//SYSIN DD DSN="
SYSLIN = "//SYSLIN DD DSN="
SYSLMOD = "//SYSLMOD DD DSN="
DISP = ",DISP=SHR"


/*LOOP THROUGH ENVIRONMENT DATA TO PULL OUT RELEVANT INFORMATION*****/

DO I = 1 TO ENVSIZE

/*IF ENTRY MARKER IS FOUND, UPDATE ASMCL AND SUBMIT THE JOB**********/

IF(SUBSTR(ENVDATA.I,1,1)) = '*' THEN DO
"ALLOC DD (INDDACL) DA('LOCATION OF TEMPLATE JCL') SHR REUSE"
'EXECIO * DISKR INDDACL (STEM ACLDATA. FINIS'
"FREE DD(INDDACL)"

ACLSIZE = ACLDATA.0

K = I + 1
ENVDATA.K = STRIP(ENVDATA.K)
ACLDATA.18 = SYSIN || ENVDATA.K || DISP
K = K + 1
ENVDATA.K = STRIP(ENVDATA.K)
ACLDATA.20 = SYSLIN || ENVDATA.K || DISP
ACLDATA.29 = SYSLIN || ENVDATA.K || DISP
K = K + 1
ENVDATA.K = STRIP(ENVDATA.K)
ACLDATA.31 = SYSLMOD || ENVDATA.K || DISP

"ALLOC DD (OUTDD) DA('LOCATION OF TEMPLATE JCL') SHR REUSE"

'EXECIO * DISKW OUTDD (FINIS STEM ACLDATA.'
"FREE DD(OUTDD)"

"SUBMIT 'LOCATION OF TEMPLATE JCL'"

END

END

Friday, July 30, 2010

A QUICK WAY TO CREATE A MEMBER IN AN EMPTY DATASET

Normally, if you are working with a PDS that is populated with members, you can create a new member by going to ISPF option 3.4, entering the data set name, then typing S [new member name] and the command line. Unfortunately, this doesn't work if the PDS is empty. To get around this, go to ISPF option 2 (EDIT), and enter the data set name with the name of the member you want to create like this:
OTHER PARTITIONED OR SEQUENTIAL DATA SET:
DATA SET NAME ===> 'data.set.name(newmemb)'

I found this gem and some other neat ISPF tricks here.

Tuesday, June 22, 2010

HOW TO TRANSFER AN ENTIRE PDS FROM ONE SYSTEM TO ANOTHER WHEN THEY AREN'T DIRECTLY CONNECTED

Ran into this issue the other day:

I had a need to move a PDS from one mainframe to another and the two systems were not connected. I tried a simple FTP to my workstation then up to the other system, but the PDS members became malformed. A coworker suggested I XMIT (see this post if you need help on how to XMIT) the PDS to myself, FTP the XMITed PDS to my workstation, up to the target system, then unload it there.

I know that's a bit confusing so let's break this down:

1) XMIT the PDS from the source system to a new dataset on the source system. This will package the PDS into a format that can be transported. Let's say you called it (DSX)

2) FTP the packaged PDS from the source mainframe to your workstation (your PC, MAC, LCARS, whatever)

3) FTP the packaged PDS from your workstation to the target mainframe.

4) issue a RECEIVE INDS(dsx) command on the target system.


That should do it, hope it helps :-)

Tuesday, February 16, 2010

Friday, August 28, 2009

2009 Master the Mainframe Contest!

The 2009 contest is just around the corner. If you are a high school or college kid and want to participate (no experience necessary, I promise!), click here.

Wednesday, July 22, 2009

Notes on How to Create a RACF Database

First, here is a quick list of some of the RACF utilities and what they do:

IRRMIN00 RACF database initialization utility
IRRUT400 RACF database split/merge/extend utility
IRRDBU00 RACF database unload utility
IRRUT200 RACF database verification utility
IRRUT100 RACF cross-reference utility
IRRRID00 RACF remove ID utility
IRRADU00 RACF SMF data unload utility

To create a new RACF database, you're going to use IRRMIN00. Just whip up some JCL (check out 'z/OS Security Server RACF System Programmer's Guide' if nobody in your shop has some canned JCL you can cut and paste) and the utility will create a fresh database for you to use. Note that you have to reIPL before you can use this new database, as it is completely empty. At IPL time, a user entry for IBMUSER will be added so you can log in and start populating your new database.

After you've done this, there are two commands you probably want to issue against your new database. They are:

SETR GENERIC(DATASET)

and

SETR EGN

The first activates generic profile checking (see this post for a bit more on RACF profiles) and the second activates Enhanced Generic Naming. "When you activate this option, RACF allows you to specify the generic character ** (in addition to the generic characters * and %) when you define data set profile names and entries in the global access checking table. " (Security Server RACF Command Language Reference).

Tuesday, April 7, 2009

Some Random Goodies

I've picked up a few tricks I thought I'd share:

1) In a previous post I talk about sending messages and data sets to other users. The command requires you to know the node name of the system the recipient is on. You can find out what the node name is by going into SDSF and typing NODE on the command line.

2) From within SDSF, after you've run a job and you are reading the results, if you want to edit and or reissue the same JCL, you can do so from within SDSF. When you are looking at the job output, type SJ at the command field to access your job. From there you can edit and resubmit. Here are a few screen shots of what to put where:





3) Recalling migrated data sets can be a pain in the arse, especially when you need several of them to perform a particular task. If you want to recall a bunch of stuff at once, you can do so from within the ISPF data set listing (option 3.4) by typing HRECALL on the command field then = at every subsequent data set you want recalled. The equals sign tells ISPF that you want to repeat the previous command you've entered. Here's another screen shot that illustrates what I'm talking about.