View previous topic :: View next topic
|
Author |
Message |
superk
Global Moderator
Joined: 26 Apr 2004 Posts: 4652 Location: Raleigh, NC, USA
|
|
|
|
Does anyone have experience using the BPXWDYN program to dynamically allocate GDG datasets using a relative generation number?
I've been experimenting some with the possibility, but I've run into a snag that I'm not sure how to resolve. The tests are being done in native TSO.
Here's the code I'm working with:
Code: |
/* REXX */
allocstr = "ALLOC DD(SYSUT2) DSN('THE.GDG(+1)')",
"NEW CATALOG REUSE RELEASE",
"RECFM(F,B) UNIT(SYSDA) DSORG(PS) RTDDN(THEDDN) RTDSN(THEDSN)"
Call BPXWDYN(allocstr)
Do i = 1 To 10
Queue "Record"Right(i,3)" of 10"
End
"EXECIO "Queued()" DISKW SYSUT1 (FINIS"
"CALL *(ICEGENER)"
x = LISTDSI(SYSUT2 FILE)
Say THEDDN THEDSN
Say SYSDSNAME
Do n = 1 To S99MSG.0
Say S99MSG.n
End
allocstr = "FREE DD(SYSUT2)"
Call BPXWDYN(allocstr)
Exit 0
|
The code is working, as in I'm getting a new generation cataloged. The problem is that I have to change the value from +1 to +2 to +3, and so on, to make the code continue to work properly. |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19243 Location: Inside the Matrix
|
|
|
|
Hi Kevin,
What happens if you log out of tso between iterations?
Not a solution, but might be interesting to see if the conditon persists. |
|
Back to top |
|
|
superk
Global Moderator
Joined: 26 Apr 2004 Posts: 4652 Location: Raleigh, NC, USA
|
|
|
|
You suspected the same thing I did. Logging off between runs makes it work fine. The same goes for a batch execution. One job, two calls the the same exec, doesn't work. Two jobs, one call each, no problems. |
|
Back to top |
|
|
expat
Global Moderator
Joined: 14 Mar 2007 Posts: 8796 Location: Welsh Wales
|
|
|
|
Don't forget that the +1 doesn't become 0 within that job until the end of the job in which it was created, in this case your TSO session. So yes, logging off and on will be the end of job that slips +1 into 0.
Here's one I prepared earlier
Never tried it for more than one new generation though.
Code: |
GDG = "gdg base name"
DSN = STRIP(GDG!!".G0000V00") /* DEFAULT IF NOT EXIST */
X=OUTTRAP(LST.) /* LISTCAT GDG BASE */
" LISTC ENT('"GDG"')"
X=OUTTRAP(OFF)
DO A = LST.0 TO 1 BY -1 /* FIRST FIND = 0 GDG */
IF POS('NONVSAM',LST.A) > 0 THEN DO
DSN = SUBSTR(LST.A,POS('NONVSAM',LST.A)+13,44)
A = 0
END
END
VX = LENGTH(STRIP(DSN)) - 6
NG = STRIP(OVERLAY(RIGHT(1+SUBSTR(DSN,VX,4),4,'0'),DSN,VX,4))
"ALLOC FI(MST) NEW TRACKS SPACE(5 3) RECFM(F B) LRECL(80)
DA('"NG"')"
"FREE FI(MST)"
DROP LST.
|
|
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19243 Location: Inside the Matrix
|
|
|
|
Hi Kevin,
It might be worth a try to do the FREE inline, without invoking BPXWDYN. |
|
Back to top |
|
|
expat
Global Moderator
Joined: 14 Mar 2007 Posts: 8796 Location: Welsh Wales
|
|
|
|
Dick,
I would say no to that, as the generation will remain as relative +1 throughout the life of the job/TSO session.
Just one of the little quirks with GDG's I suppose. |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19243 Location: Inside the Matrix
|
|
|
|
Yup, agreed, my brain was on sideways. . .
Why would online work differently than batch. . . |
|
Back to top |
|
|
expat
Global Moderator
Joined: 14 Mar 2007 Posts: 8796 Location: Welsh Wales
|
|
|
|
Never mind Dick, the hat always seems to be in right place |
|
Back to top |
|
|
ganeshanm2000
New User
Joined: 17 Jul 2009 Posts: 1 Location: Brighton
|
|
|
|
following code will be helpful to get the convert the relative gdg to absolute GDG.
Code: |
********************************* Top of Data *********************************
/* REXX */
/* This exec will take in GDGGEN and determine the actual dsn */
/* associated with the generation. The GDGDSN variable is VPUT to */
/* the shared pool to make it available to the calling routine. */
/* GDGERR is VPUT to shared pool to indicate errors below. */
/* */
/* sample code to call this routine */
/* -------------------------------- */
/* "SELECT CMD(%GDGDSN BCOW.GDG(-1))" */
/* gdgdsn_rc = rc */
/* "VGET (GDGDSN GDGERR) SHARED" */
/* IF gdgdsn_rc = 0 THEN */
/* SAY "GDG DSN =" gdgdsn */
/* ELSE */
/* SAY "GDGDSN error -" gdgerr */
/* */
/* Developed by Brian Olsen - Developer Services */
/********************************************************************/
PARSE UPPER ARG GDGGEN DEBUG
IF debug = "DEBUG" THEN
TRACE I
ELSE
ADDRESS ISPEXEC "CONTROL ERRORS RETURN"
CALL A0000_INIT
CALL B0000_GET_GDG_DSN_LIST
SELECT
WHEN listc_rc > 0 THEN exit_code = 20 /* bad GDG */
WHEN gdg_count = 0 & POS("+1",gdggen) > 0 THEN
DO
gdgdsn = gdg_base || ".G0001V00"
END
WHEN gdg_count = 0 THEN exit_code = 4 /* no generations */
WHEN POS("+1",gdggen) > 0 THEN CALL C0000_DETERMINE_GDG_DSN
WHEN gdg_gen_num > gdg_count - 1 THEN exit_code = 8 /* not found */
OTHERWISE
CALL C0000_DETERMINE_GDG_DSN
END
SIGNAL ENDIT
/*--------------------------------------------------------------------*/
/* Initialize and verify input parms */
/*--------------------------------------------------------------------*/
A0000_INIT:
exit_code = 0
gdgdsn = ""
gdg_count = 0
gdggen = STRIP(gdggen,"B","'") /* remove quotes */
PARSE VAR GDGGEN GDG_BASE "(" GDG_GEN_NUM ")" rest
IF gdg_base = "" | gdg_gen_num = "" THEN
DO
SAY "GDGDSN tool requires GDGGEN to be passed in. For example:",
"YOUR.GDG(-1)"
exit_code = 8
SIGNAL ENDIT
END
IF LEFT(gdg_gen_num,1) = "+" | LEFT(gdg_gen_num,1) = "-" THEN
DO
gdg_sign = SUBSTR(gdg_gen_num,1,1)
gdg_gen_num = SUBSTR(gdg_gen_num,2)
END
ELSE
gdg_sign = ""
IF gdg_sign = "+" & gdg_gen_num /= "1" THEN
DO
SAY "GDGDSN tool requires generation to be +1, 0, -n"
exit_code = 12
SIGNAL ENDIT
END
IF gdg_sign = "" & gdg_gen_num /= "0" THEN
DO
SAY "GDGDSN tool requires generation to be +1, 0, -n"
exit_code = 12
SIGNAL ENDIT
END
IF DATATYPE(gdg_gen_num) /= "NUM" THEN
DO
SAY "GDGDSN tool requires generation to be +1, 0, -n"
exit_code = 12
SIGNAL ENDIT
END
RETURN
/*--------------------------------------------------------------------*/
/* Invoke the LISTC command on the gdg_base to obtain list of dsnames */
/*--------------------------------------------------------------------*/
B0000_GET_GDG_DSN_LIST:
x = OUTTRAP("LISTC.","*")
ADDRESS TSO "LISTC ENTRIES('"gdg_base"') GDG ALL"
listc_rc = rc
x = OUTTRAP("OFF")
IF listc_rc = 0 THEN
DO ctr = 1 TO listc.0
IF POS("NONVSAM--",listc.ctr) > 0 THEN
DO
gdg_line = TRANSLATE(listc.ctr," ","-")
gdg_count = gdg_count + 1
PARSE var gdg_line literal gdg_dsn.gdg_count
END
END
RETURN
/*--------------------------------------------------------------------*/
/* Determine the dsname based on generation passed in GDGGEN parm */
/*--------------------------------------------------------------------*/
C0000_DETERMINE_GDG_DSN:
SELECT
WHEN gdg_gen_num = 0 THEN
DO
gdgdsn = gdg_dsn.gdg_count /* 0 generation is last in list */
END
WHEN gdg_sign = "+" & gdg_gen_num = 1 THEN
DO
gdgdsn = gdg_dsn.gdg_count /* 0 generation is last in list */
nxtgen = ABS(SUBSTR(gdgdsn,LASTPOS(".",gdgdsn)+2,4))+1
nxtgen = RIGHT(nxtgen,4,"0")
gdgdsn = OVERLAY(nxtgen,gdgdsn,LENGTH(gdgdsn)-6,4)
END
OTHERWISE
DO
gdg_pos = gdg_count - gdg_gen_num /* calc relative gen number */
gdgdsn = gdg_dsn.gdg_pos
END
END
gdgdsn = SPACE(gdgdsn,0) /* remove spaces */
RETURN
/*--------------------------------------------------------------------*/
/* Exit this routine */
/*--------------------------------------------------------------------*/
ENDIT:
SELECT
WHEN exit_code = 0 THEN gdgerr = ""
WHEN exit_code = 4 THEN gdgerr = "No generations exist for" gdggen
WHEN exit_code = 8 THEN gdgerr = "Generation not found for" gdggen
WHEN exit_code = 12 THEN gdgerr = "Bad parms passed to GDGDSN"
WHEN exit_code = 20 THEN gdgerr = "GDG base not found for" gdggen
OTHERWISE gdgerr = "Unknown error from GDGDSN"
END
ADDRESS ISPEXEC "VPUT (GDGDSN GDGERR) SHARED"
EXIT(exit_code)
******************************** Bottom of Data ******************************** |
|
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8700 Location: Dubuque, Iowa, USA
|
|
|
|
Ganeshan, any particular reason why you feel the need to add to a topic with no activity for over two years? Especially since the original post had nothing to do with converting relative generations to absolute? |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19243 Location: Inside the Matrix
|
|
|
|
Hello Ganeshan and welcome to the forum,
Thank you for posting your code. This is tested, right?
If you would, please start a new topic with your code (with a new title) as others may find this useful. |
|
Back to top |
|
|
MBabu
Active User
Joined: 03 Aug 2008 Posts: 400 Location: Mumbai
|
|
|
|
also, you only need to add the rtdsn() parameter to bpxwdyn and you get the name automatically. One line of code. Less actually. |
|
Back to top |
|
|
enrico-sorichetti
Superior Member
Joined: 14 Mar 2007 Posts: 10886 Location: italy
|
|
|
|
before posting the code did You get the proper authorizations
I see ...
Quote: |
Developed by Brian Olsen - Developer Services |
|
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19243 Location: Inside the Matrix
|
|
|
|
Oops - i missed that
Yup, it would be good to get permission. . .
d |
|
Back to top |
|
|
shanbalasay
New User
Joined: 22 May 2007 Posts: 19 Location: Belfast, UK
|
|
|
|
expat's explanation had very much helped me today in getting a GDG allocated through REXX.
Very much appreciate, expat. |
|
Back to top |
|
|
don.leahy
Active Member
Joined: 06 Jul 2010 Posts: 765 Location: Whitby, ON, Canada
|
|
|
|
I know this is an old topic, but I did a search for the GDGNT keyword and didn't find anything. So, here is my 2 cents:
An easy way around this is to add the "GDGNT" parameter to the ALLOC statement. This causes BPXWYDN to scan for the latest generation of the data set before determining the generation associated with (+1).
Code: |
do 5
x = BPXWDYN("ALLOC DD(XXX) DA('xxxx.aaaaaa.testGDG(+1)') " ,
"NEW SPACE(1,1) RECFM(F,B) LRECL(80) DSORG(PS) CATALOG REUSE" ,
"GDGNT")
end |
This fragment will create 5 generations of XXXX.AAAAAA.TESTGDG |
|
Back to top |
|
|
superk
Global Moderator
Joined: 26 Apr 2004 Posts: 4652 Location: Raleigh, NC, USA
|
|
|
|
Now that's a helpful hint! |
|
Back to top |
|
|
don.leahy
Active Member
Joined: 06 Jul 2010 Posts: 765 Location: Whitby, ON, Canada
|
|
|
|
I still have scars on my head from beating it against the wall trying to solve this problem 3 years ago (before I joined this forum). Apparently GDGNT was introduced with z/OS 1.6. |
|
Back to top |
|
|
superk
Global Moderator
Joined: 26 Apr 2004 Posts: 4652 Location: Raleigh, NC, USA
|
|
|
|
I posted a question on the IBM z/OS forum a few years ago concerning the use of the BPXWDYN program and if they could confirm that the support for relative GDG processing would be fully supported down the line. They never responded to me, but it would appear that it will be. It kind of seems as if they should look into modifying the TSO ALLOCATE command to perform the same functions. |
|
Back to top |
|
|
R Cherrington
New User
Joined: 10 May 2011 Posts: 1 Location: Australia
|
|
|
|
Sorry, repeated a previous post |
|
Back to top |
|
|
dick scherrer
Moderator Emeritus
Joined: 23 Nov 2006 Posts: 19243 Location: Inside the Matrix
|
|
|
|
g'Day and welcome to the forum,
If this is the worst thing that ever happens, yours will be very good time here |
|
Back to top |
|
|
|