Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PDS member contention, spotting thereof

133 views
Skip to first unread message

Bob Bridges

unread,
Jun 16, 2017, 2:34:55 PM6/16/17
to
I have an external REXX routine named EXECIOST that I've used for years, probably for decades, to write the contents of the stack to a dataset or DD. Well, mostly I use it to read onto the stack, but in this case I’m concerned with the write function. I just discovered that if I’m editing the same PDS member in another ISPF screen, this routine WORKS ANYWAY, replacing the contents of the member that I'm editing elsewhere. How long has this been going on?!

(Part of the reason I didn't already encounter it, probably, is that I don't usually write to a catalogued dataset; most of my routines use VIEWQ, which allocates a temporary dataset, writes the stack to that and then displays it in View. It's only rarely that I write to a real DSN.)

/* Side hike: If you're skeptical - up till now I would have said it's not possible to overwrite a dataset that's being edited - herewith some details:

I have a few REXX programs that generate TSS commands. In some cases rather than execute the TSS commands live, I EXECIOST them to My.Clist.Library(TCMDS), then immediately Edit TCMDS with the expectation that I will examine the results on the spot, possibly make changes, and then say "save;tso tcmds".

Just now I have an unusual situation: I see from the results of one such REXX routine a situation that I want to fix by running another. The second routine creates new TSS commands, writes them to TCMDS, issues the Edit service for TCMDS, gets back RC 14 (meaning it's in use) and abends with that message.

This has been happening occasionally for a week or two now, and I've been carelessly assuming that the second EXECIOST failed as well as the Edit. It isn't until today I discovered that the second program was doing the write successfully; it's only the second Edit that failed.

To test this, I entered an Edit session of TCMDS, then split the screen and ran one of the commands that writes to it. When that command failed ("In use"), I went back to the Edit session and issued the Restore command, which showed me the contents had been changed successfully. */

So I'd like some way of knowing ~before~ I try to write to My.Clist.Library(TCMDS) whether it's being edited, so I won't write over the contents accidentally. Any ideas? Here are some possibilities:

1) Allocate the output dataset with disp=OLD instead of SHR. Nope, it makes no difference; with TCMDS in an Edit session, that ALLOCATE statement still returns rc 0.

2) ISPEXEC LMINIT ENQ(EXCLU)/LMOPEN OPTION(OUTPUT)/LMMFIND MEMBER(TCMDS). I thought I was on to something there, but it turns out LMMFIND works only with OPTION(INPUT), although I don't see that in the documentation. With OPTION(INPUT), LMMFIND returns RC 0.

3) ISRDDN apparently can detect enqueue conditions, but how can I get ISRDDN to talk to a REXX? Maybe this way: Issue ISRDDN with the ENQ argument, after creating a private copy of the panel ISRDENQG that a) does a VGET to see whether it's being called by my routine and if so b) VPUTs the desired data and c) exits instead of displaying. I'd have to experiment quite a bit to get that to work.

4) Use the LM services to write the data, instead of EXECIO. I think that'll work; presumably the LM services can tell whether the member is already in use before writing. But I'm hoping for an easier way.

5) I could try editing ~before~ I do the write; but that's no good because assuming TCMDS is not in contention I'd end up in an Edit session and the REXX couldn't continue until I hit <Enter>.

6) Hey, this'd work: Write a NOP Edit macro, one whose only purpose is to exit the Edit session immediately. Then Edit the dataset with MACRO(NOP); if the Edit succeeds then there's no contention, and if the RC is 14 then there is. If no one here has a better idea, I'll try that.

You'd think there'd be a routine somewhere around that can detect such situations, but I'm not finding it so far.

---
Bob Bridges
robhb...@gmail.com, cell 336 382-7313
rbri...@InfoSecInc.com

/* We never fail God's tests; we just keep taking them until we pass. -attributed to Francis Frangipane */

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX

Jeremy Nicoll

unread,
Jun 16, 2017, 3:30:59 PM6/16/17
to
On Fri, 16 Jun 2017, at 19:34, Bob Bridges wrote:
> I have an external REXX routine named EXECIOST that I've used for years,
> probably for decades, to write the contents of the stack to a dataset or
> DD. Well, mostly I use it to read onto the stack, but in this case I’m
> concerned with the write function. I just discovered that if I’m editing
> the same PDS member in another ISPF screen, this routine WORKS ANYWAY,
> replacing the contents of the member that I'm editing elsewhere. How
> long has this been going on?!

Probably for ever if you don't use ispf's member-level enqueue on the
pds
member. That's, IIRC, the spfdsn enqueue.

The way I used to do this was have my calling exec call ispf edit on the
target
pds(mem), specifying a purpose-written edit macro to handle the edit.
RC from
the invocation of edit told me whether or not I'd got access to the
member; if not
the exec would sleep a little then try again.

The macro would make the required changes, then issue a save to write
the file
back to disk, then set an ispf profile pool variable that that had
worked and vput
it. Then the macro exited.

The calling code would vget the variable and check that the response
from the
macro was as that application expected.

That leaves the problem of how the exec caller passes to the macro the
data that
has to be written. In your case with data on the stack... I dunno - is
that stack a
system/user session one, or something that only the calling exec had
access to?

I have a feeling that I used to allocate a vio file and write data to
that then pass
its ddname to the macro (in an ispf profile variable) which then read
data out of it
but I can't really remember. The overhead of that extra IO was minimal.

The internals of the macro could possible 'copy' the contents of the vio
file after
.zlast or something like that? Or else read the VIO file data into a
stem then loop
through that and append lines one by one.

--
Jeremy Nicoll - my opinions are my own.

Paul Gilmartin

unread,
Jun 16, 2017, 3:37:26 PM6/16/17
to
On 2017-06-16, at 12:34, Bob Bridges wrote:

> I have an external REXX routine named EXECIOST that I've used for years, probably for decades, to write the contents of the stack to a dataset or DD. Well, mostly I use it to read onto the stack, but in this case I’m concerned with the write function. I just discovered that if I’m editing the same PDS member in another ISPF screen, this routine WORKS ANYWAY, replacing the contents of the member that I'm editing elsewhere. How long has this been going on?!
>
Probably forever. Even if you allocate the member OLD in the same
job/session, allocation will simply quietly upgrade the existing ENQ.

> So I'd like some way of knowing ~before~ I try to write to My.Clist.Library(TCMDS) whether it's being edited, so I won't write over the contents accidentally. Any ideas? Here are some possibilities:
>
Probably none exists except (4) below.

> 4) Use the LM services to write the data, instead of EXECIO. I think that'll work; presumably the LM services can tell whether the member is already in use before writing. But I'm hoping for an easier way.
>
That's what I've used, successfully. LMCOPY. Shouldn't be too bad
if you already have ISPF active. An additional benefit is that it
doesn't fail on ENQ EXC even if another user on another system is
editing a different member, but properly fails if someone is editing
the same member.

Mostly. I once got an overwrite failure because MIM was down.

> You'd think there'd be a routine somewhere around that can detect such situations, but I'm not finding it so far.
>
Even if there were, you'd risk a TOCTTOU failure.

-- gil

Paul Gilmartin

unread,
Jun 16, 2017, 4:30:19 PM6/16/17
to
On 2017-06-16, at 12:34, Bob Bridges wrote:
> ...
> 4) Use the LM services to write the data, instead of EXECIO. I think that'll work; presumably the LM services can tell whether the member is already in use before writing. But I'm hoping for an easier way.
>
BTW, I believe I've seen that interleaved LMPUTs to different members of
the same PDSE work. Marvelous!

o Need multiple open DCBs.

o Must be in the same job because LMPUT requires ENQ EXC. Needless
restriction because PDSE does the necessary serialization.

-- gil

Bob Bridges

unread,
Jun 16, 2017, 4:49:37 PM6/16/17
to
I may not have described the problem correctly. The Edit is working fine; what surprises me is that while I'm in Edit I can run a REXX that successfully writes over the very PDS member I'm editing, replacing its contents. This I didn't expect.

I thought at first that there must be a problem with the way my output routine (EXECIOST) does the writing, that it was erroneously bypassing the enqueue-or-whatever. But now that I think about it, and especially because of what you say below, maybe the problem is how I'm getting into Edit.

The command I usually use to Edit a dataset is

address ISPEXEC 'EDIT DATASET(<dsn>)'

I hardly ever use the ISPF menu for it; partly I prefer a command-driven interface, and mostly the REXX I call to invoke Edit does lots of other things for me - look up DSN shortcuts, translate relative GDG numbers, determine whether it's really a DD name rather than a DSN and so on.

So is that command the problem? Do I need to do something in addition to the ISPEXEX EDIT command to enact this SPFEDIT member enqueue? I wouldn't have thought so, but what do I know?

---
Bob Bridges
robhb...@gmail.com, cell 336 382-7313
rbri...@InfoSecInc.com

/* Expecting the world to treat you fairly because you are a good person is a little like expecting the bull not to attack you because you are a vegetarian. -Dennis Wholey */


-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of Jeremy Nicoll
Sent: Friday, June 16, 2017 15:31

Probably forever if you don't use ispf's member-level enqueue on the pds member. That's, IIRC, the spfdsn enqueue.

The way I used to do this was have my calling exec call ispf edit on the target pds(mem), specifying a purpose-written edit macro to handle the edit. RC from the invocation of edit told me whether or not I'd got access to the member; if not the exec would sleep a little then try again.

The macro would make the required changes, then issue a save to write the file back to disk, then set an ispf profile pool variable that that had worked and vput it. Then the macro exited.

The calling code would vget the variable and check that the response from the macro was as that application expected.

That leaves the problem of how the exec caller passes to the macro the data that has to be written. In your case with data on the stack... I dunno - is that stack a system/user session one, or something that only the calling exec had access to?

I have a feeling that I used to allocate a vio file and write data to that then pass its ddname to the macro (in an ispf profile variable) which then read data out of it but I can't really remember. The overhead of that extra IO was minimal.

The internals of the macro could possible 'copy' the contents of the vio file after .zlast or something like that? Or else read the VIO file data into a stem then loop through that and append lines one by one.


---
> I have an external REXX routine named EXECIOST that I've used for
> years, probably for decades, to write the contents of the stack to a
> dataset or DD. Well, mostly I use it to read onto the stack, but in
> this case I’m concerned with the write function. I just discovered
> that if I’m editing the same PDS member in another ISPF screen, this
> routine WORKS ANYWAY, replacing the contents of the member that I'm
> editing elsewhere. How long has this been going on?!

Paul Gilmartin

unread,
Jun 16, 2017, 5:00:40 PM6/16/17
to
On 2017-06-16, at 14:49, Bob Bridges wrote:

> I may not have described the problem correctly. The Edit is working fine; what surprises me is that while I'm in Edit I can run a REXX that successfully writes over the very PDS member I'm editing, replacing its contents. This I didn't expect.
>
> I thought at first that there must be a problem with the way my output routine (EXECIOST) does the writing, that it was erroneously bypassing the enqueue-or-whatever. But now that I think about it, and especially because of what you say below, maybe the problem is how I'm getting into Edit.
>
> The command I usually use to Edit a dataset is
>
> address ISPEXEC 'EDIT DATASET(<dsn>)'
>
> I hardly ever use the ISPF menu for it; partly I prefer a command-driven interface, and mostly the REXX I call to invoke Edit does lots of other things for me - look up DSN shortcuts, translate relative GDG numbers, determine whether it's really a DD name rather than a DSN and so on.
>
> So is that command the problem? Do I need to do something in addition to the ISPEXEX EDIT command to enact this SPFEDIT member enqueue? I wouldn't have thought so, but what do I know?
>
Experiment. Start an Edit session on an expendable member. Split screen.
From the other split, attempt to use ISPF 3.3 to overwrite the member
you're editing. That should fail. You should be able to automate this
with LMCOPY.

-- gil

Steve Thompson

unread,
Jun 16, 2017, 5:09:01 PM6/16/17
to
There are two ENQUEUEs done by ISPF.

1) DSN ENQUEUE
2) member ENQUEUE

The second one is to protect TSO users, using ISPF, from running
into each other. Therefore, since you didn't attempt such an
ENQUEUE with REXX, it didn't do anything to protect against the
write since the DSN ENQUEUE allowed access.

Look at the ISPF Customization (I think that is the manual -- it
might be the Services manual). In there it describes the ENQUEUEs
that are used.

Regards,
Steve Thompson

Bob Bridges

unread,
Jun 16, 2017, 6:07:07 PM6/16/17
to
I would have assumed - I ~did~ assume - that ISPF Edit issues the required enqueue(s) when it's invoked. Is there some valid design reason that it doesn't?

---
Bob Bridges
robhb...@gmail.com, cell 336 382-7313
rbri...@InfoSecInc.com

/* We never fail God's tests; we just keep taking them until we pass. -attributed to Francis Frangipane */


-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of Steve Thompson
Sent: Friday, June 16, 2017 17:09

There are two ENQUEUEs done by ISPF.

1) DSN ENQUEUE
2) member ENQUEUE

The second one is to protect TSO users, using ISPF, from running into each other. Therefore, since you didn't attempt such an ENQUEUE with REXX, it didn't do anything to protect against the write since the DSN ENQUEUE allowed access.

Look at the ISPF Customization (I think that is the manual -- it might be the Services manual). In there it describes the ENQUEUEs that are used.

--- On 06/16/2017 04:49 PM, Bob Bridges wrote:
> I may not have described the problem correctly. The Edit is working fine; what surprises me is that while I'm in Edit I can run a REXX that successfully writes over the very PDS member I'm editing, replacing its contents. This I didn't expect.
>
> I thought at first that there must be a problem with the way my output routine (EXECIOST) does the writing, that it was erroneously bypassing the enqueue-or-whatever. But now that I think about it, and especially because of what you say below, maybe the problem is how I'm getting into Edit.
>
> The command I usually use to Edit a dataset is
>
> address ISPEXEC 'EDIT DATASET(<dsn>)'
>
> I hardly ever use the ISPF menu for it; partly I prefer a command-driven interface, and mostly the REXX I call to invoke Edit does lots of other things for me - look up DSN shortcuts, translate relative GDG numbers, determine whether it's really a DD name rather than a DSN and so on.
>
> So is that command the problem? Do I need to do something in addition to the ISPEXEX EDIT command to enact this SPFEDIT member enqueue? I wouldn't have thought so, but what do I know?
>
>

Mickey Bee

unread,
Jun 16, 2017, 6:22:31 PM6/16/17
to
Allocate the file, as either MOD or OLD, before you start the edit session,
and this will not happen.

Mickey

Paul Gilmartin

unread,
Jun 16, 2017, 6:41:31 PM6/16/17
to
On 2017-06-16, at 16:21, Mickey Bee wrote:
>
> Allocate the file, as either MOD or OLD, before you start the edit session, and this will not happen.
>
True. But a consequence is that no other user will be able
to edit *any*other* member of that data set until Bob FREEs
the allocation.

If Bob allocates MOD, he will not be able to overwrite any existing
member, even if it's not otherwise in use.


On 2017-06-16, at 16:06, Bob Bridges wrote:
>
> I would have assumed - I ~did~ assume - that ISPF Edit issues the required enqueue(s) when it's invoked.
>
ISPF issues only the ENQs required to protect against other users or the
same user using ISPF services, or a different user issuing an EXC ENQ.

> Is there some valid design reason that it doesn't?
>
The intent of the design is that different users be able to
edit different members of the same PDS as long as all use
ISPF services. Judgment of validity is subjective.

ISPF-L is more focused on topics such as this.
https://listserv.nd.edu/cgi-bin/wa?SUBED1=ISPF-L

-- gil

Steve Thompson

unread,
Jun 16, 2017, 8:00:12 PM6/16/17
to
I guess I misread a post. I thought you had said you were using
EXECIO to write the member. The REXX I/O code, to my knowledge,
does not do the member ENQUEUE, and so allows you to override the
member while ISPF EDIT has the member "open".

But, if it is that you are actually using ISPF Edit for all of
this, I am baffled.

Decades ago I worked on a product where I had to add the "ISPF"
ENQUEUE so that ISPF Edit and that other product would work
together nicely.

Regards,
Steve Thompson

Paul Gilmartin

unread,
Jun 17, 2017, 12:16:56 PM6/17/17
to
On 2017-06-16, at 17:59, Steve Thompson wrote:

> I guess I misread a post. I thought you had said you were using EXECIO to write the member. The REXX I/O code, to my knowledge, does not do the member ENQUEUE, and so allows you to override the member while ISPF EDIT has the member "open".
>
> But, if it is that you are actually using ISPF Edit for all of this, I am baffled.
>
It might be simpler to use LMCOPY rather than Edit for this. LMPUT,
however, does not ENQ on the member but requires ENQ EXC on SYSDSN.

-- gil

Bob Bridges

unread,
Jun 18, 2017, 2:14:57 PM6/18/17
to
Allocate it before I edit it? Doesn't Edit allocate it, then?

---
Bob Bridges
robhb...@gmail.com, cell 336 382-7313
rbri...@InfoSecInc.com

/* We never fail God's tests; we just keep taking them until we pass. -attributed to Francis Frangipane */

Bob Bridges

unread,
Jun 18, 2017, 2:28:35 PM6/18/17
to
ISPEXEC ENQUEUE? I don't remember seeing that service in the ISPF Services manual. I'll look again.

I'm not sure you misread, but just in case let me start over to be sure. Like this:

1) I'm editing a member. I'm not using the Edit menu for that; instead I'm using a REXX that invokes the ISPEXEC EDIT service, so I imagine all the same things happen, including an enqueue for My.Clist(TCMDS).

2) While I'm still in that Edit session I run a REXX from the command line that uses EXECIO to write data to the very same member. To my surprise, the EXECIO DISKW succeeds.

I'm not ~intentionally~ writing over the same member, you understand; I didn't notice the problem until recently. I didn't even look for the problem, because I always believed that an attempt to write to a dataset would fail if someone was in the middle of editing it.

---
Bob Bridges
robhb...@gmail.com, cell 336 382-7313
rbri...@InfoSecInc.com

/* We never fail God's tests; we just keep taking them until we pass. -attributed to Francis Frangipane */


-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of Steve Thompson
Sent: Friday, June 16, 2017 20:00

I guess I misread a post. I thought you had said you were using EXECIO to write the member. The REXX I/O code, to my knowledge, does not do the member ENQUEUE, and so allows you to override the member while ISPF EDIT has the member "open".

But, if it is that you are actually using ISPF Edit for all of this, I am baffled.

Decades ago I worked on a product where I had to add the "ISPF" ENQUEUE so that ISPF Edit and that other product would work together nicely.


--- On 06/16/2017 06:06 PM, Bob Bridges wrote:
> I would have assumed - I ~did~ assume - that ISPF Edit issues the required enqueue(s) when it's invoked. Is there some valid design reason that it doesn't?
>
>

Bob Bridges

unread,
Jun 18, 2017, 2:55:21 PM6/18/17
to
I'm rereading this and I want to rephrase in case I misunderstood you:

First I run REXX1, which
1a) creates a set of TSO commands,
1b) uses EXECIO to write the commands to a PDS member and
1c) Edits the member for me to examine them.

While I'm in that Edit session, looking at the commands created by REXX1, I realize I have to fix something else before I can continue; so I run REXX2, which

2a) creates a set of TSO commands,
2b) uses EXECIO to write the commands to a PDS member and
2c) Edits the member for me to examine them.

REXX1 and REXX2 use the same output member, so the Edit command at 2c) fails because REXX1 already has that member locked up in Edit.

I've always believed than an attempt to write to a dataset would fail if the target dataset is being Edited, so when I first saw REXX2 abending I assumed carelessly that step 2b) was failing - that the EXECIO at 2b) was not writing data. It was only a week later that I discovered, to my surprise, that step 2b) succeeded! That's when I decided I really need an enqueue detector: Before any REXX attempts to write to a catalogued dataset, I want to be able to see whether the attempt should fail - since ISPF / MVS apparently aren't doing that job properly.

---
Bob Bridges
robhb...@gmail.com, cell 336 382-7313
rbri...@InfoSecInc.com

/* Be careful of your thoughts; they may become words at any moment. -Ira Gassen */


-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of Mickey Bee
Sent: Friday, June 16, 2017 18:22

Allocate the file, as either MOD or OLD, before you start the edit session, and this will not happen.

-----Original Message-----
From: Bob Bridges
Sent: Friday, June 16, 2017 4:49 PM

I may not have described the problem correctly. The Edit is working fine; what surprises me is that while I'm in Edit I can run a REXX that successfully writes over the very PDS member I'm editing, replacing its contents. This I didn't expect.

I thought at first that there must be a problem with the way my output routine (EXECIOST) does the writing, that it was erroneously bypassing the enqueue-or-whatever. But now that I think about it, and especially because of what you say below, maybe the problem is how I'm getting into Edit.

The command I usually use to Edit a dataset is

address ISPEXEC 'EDIT DATASET(<dsn>)'

I hardly ever use the ISPF menu for it; partly I prefer a command-driven interface, and mostly the REXX I call to invoke Edit does lots of other things for me - look up DSN shortcuts, translate relative GDG numbers, determine whether it's really a DD name rather than a DSN and so on.

So is that command the problem? Do I need to do something in addition to the ISPEXEX EDIT command to enact this SPFEDIT member enqueue? I wouldn't have thought so, but what do I know?


Paul Gilmartin

unread,
Jun 18, 2017, 3:06:44 PM6/18/17
to
On 2017-06-18, at 12:14, Bob Bridges wrote:

> Allocate it before I edit it? Doesn't Edit allocate it, then?
>
ISPF allocates it SHR.

> -----Original Message-----
> From: Mickey Bee
> Sent: Friday, June 16, 2017 18:22
>
> Allocate the file, as either MOD or OLD, before you start the edit session, and this will not happen.

-- gil

Paul Gilmartin

unread,
Jun 18, 2017, 3:13:31 PM6/18/17
to
On 2017-06-18, at 12:28, Bob Bridges wrote:

> ISPEXEC ENQUEUE? I don't remember seeing that service in the ISPF Services manual. I'll look again.
>
In • z/OS V2R2 ISPF Planning and Customizing
• ISPF enqueue processing for data integrity
• Member name enqueue

I see "ENQ SPFEDIT,rname,E,52,SYSTEMS", which is probably what he meant.

> -----Original Message-----
> From: Steve Thompson
> Sent: Friday, June 16, 2017 20:00
> ...
> Decades ago I worked on a product where I had to add the "ISPF" ENQUEUE so that ISPF Edit and that other product would work together nicely.
>
Issuing the ENQ ad hoc is the hard way. Use LMCOPY.

-- gil

Paul Gilmartin

unread,
Jun 18, 2017, 3:32:42 PM6/18/17
to
On 2017-06-18, at 12:54, Bob Bridges wrote:
> ...
> I've always believed than an attempt to write to a dataset would fail if the target dataset is being Edited, so when I first saw REXX2 abending I assumed carelessly that step 2b) was failing - that the EXECIO at 2b) was not writing data. It was only a week later that I discovered, to my surprise, that step 2b) succeeded! That's when I decided I really need an enqueue detector:
>
An "enqueue detector" is the wrong approach. At best, it leaves you
exposed to a TOCTTOU failure.

> Before any REXX attempts to write to a catalogued dataset, I want to be able to see whether the attempt should fail - since ISPF / MVS apparently aren't doing that job properly.
>
ISPF/MVS is working as designed. The design provides integrity protection
only if all processes are using ISPF services, or if different jobs (not
the same job) use DISP=OLD. Within a single job, DISP=OLD allows both
ISPF Edit and EXECIO to write to the same member with no integrity protection.
Again: • z/OS V2R2 ISPF Planning and Customizing
• ISPF enqueue processing for data integrity
• Member name enqueue

I'm not sure that ISPF provides protection among processes within a single
job -- your gun; your foot. This is an ISPF matter, not a Rexx matter.
You'll get better information from ISPF-L:
https://listserv.nd.edu/cgi-bin/wa?SUBED1=ISPF-L

-- -- gil

Don Poitras

unread,
Jun 18, 2017, 4:48:09 PM6/18/17
to
The SPFEDIT ENQ will prevent concurrent editing of a member. Before writing
the data though, you must also RESERVE the dataset name. See:

https://www.ibm.com/support/knowledgecenter/SSLTBW_2.2.0/com.ibm.zos.v2r2.f54pc00/isppcaxdsie.htm

I had to do all this when I added support for SAS/C to handle writing to a
PDS without allocating DISP=OLD.

https://support.sas.com/documentation/onlinedoc/sasc/doc/changes/z0292248.htm


In article <E30FA5B1-73B2-477C...@aim.com> you wrote:
> On 2017-06-18, at 12:28, Bob Bridges wrote:

> > ISPEXEC ENQUEUE? I don't remember seeing that service in the ISPF Services manual. I'll look again.
> >
> In ? z/OS V2R2 ISPF Planning and Customizing
> ? ISPF enqueue processing for data integrity
> ? Member name enqueue

> I see "ENQ SPFEDIT,rname,E,52,SYSTEMS", which is probably what he meant.

> > -----Original Message-----
> > From: Steve Thompson
> > Sent: Friday, June 16, 2017 20:00
> > ...
> > Decades ago I worked on a product where I had to add the "ISPF" ENQUEUE so that ISPF Edit and that other product would work together nicely.
> >
> Issuing the ENQ ad hoc is the hard way. Use LMCOPY.

> -- gil

--
Don Poitras - SAS Development - SAS Institute Inc. - SAS Campus Drive
sas...@sas.com (919) 531-5637 Cary, NC 27513

Steve Thompson

unread,
Jun 18, 2017, 7:26:14 PM6/18/17
to
On 06/18/2017 03:31 PM, Paul Gilmartin wrote:
> On 2017-06-18, at 12:54, Bob Bridges wrote:
>> ...
>> I've always believed than an attempt to write to a dataset would fail if the target dataset is being Edited, so when I first saw REXX2 abending I assumed carelessly that step 2b) was failing - that the EXECIO at 2b) was not writing data. It was only a week later that I discovered, to my surprise, that step 2b) succeeded! That's when I decided I really need an enqueue detector:
>>
> An "enqueue detector" is the wrong approach. At best, it leaves you
> exposed to a TOCTTOU failure.
>
>> Before any REXX attempts to write to a catalogued dataset, I want to be able to see whether the attempt should fail - since ISPF / MVS apparently aren't doing that job properly.
>>
> ISPF/MVS is working as designed. The design provides integrity protection
> only if all processes are using ISPF services, or if different jobs (not
> the same job) use DISP=OLD. Within a single job, DISP=OLD allows both
> ISPF Edit and EXECIO to write to the same member with no integrity protection.
> Again: • z/OS V2R2 ISPF Planning and Customizing
> • ISPF enqueue processing for data integrity
> • Member name enqueue
>
> I'm not sure that ISPF provides protection among processes within a single
> job -- your gun; your foot. This is an ISPF matter, not a Rexx matter.
> You'll get better information from ISPF-L:
> https://listserv.nd.edu/cgi-bin/wa?SUBED1=ISPF-L
<SNIPPAGE>

Yes ISPF does. This is how one can be operation in split screen
mode and attempt to edit a member that is already being edited in
a different SPLIT and be told that the member is already being
edited (or words to that effect).

But, again, one has to be using the functions/features of ISPF
that do the member enqueuing so that it can detect that the
member is already "busy" or "in use" etc.

If one doesn't follow that protocol, ISPF can't tell that the
member is in use, or is busy, etc.

This is why there were some fights between Roscoe and WYLBUR and
ISPF back in the day. And this is why we put that kind of code
into certain products that I came to work on (such as
Connect:Direct for z/OS -- Pre IBM acquisition).

Regards,
Steve Thompson

Robert Zenuk

unread,
Jun 18, 2017, 8:26:34 PM6/18/17
to
Hopefully, I followed the issue correctly... Have you tried the ISPF QUERYENQ service to check for the SPFEDIT ENQ? Here is an example.

/* QUERYENQ demo for SPFEDIT ENQ */
arg dsn mem
major = 'SPFEDIT'
minor = left(dsn,44) || left(mem,8)
mlq = 'EDITENQ'
address ISPEXEC "QUERYENQ TABLE(QUERYENQ) QNAME(MAJOR)",
"RNAME(MINOR) REQ("userid()") SAVE("mlq") XSYS"
QRC = RC
select
when QRC < 8 then exit 0 /* SPFEDIT ENQ exists for DSN(MEM) */
when QRC = 8 then exit 8 /* NO SPFEDIT ENQ edits for DSN(MEM) */
otherwise exit 12 /* Some Error */
end

If the SPFEDIT ENQ exists for the DSN(MEM) combination, you get RC=0
If the SPFEDIT ENQ does NOT exists for the DSN(MEM) combination, you get RC=8

This service can have problems if you have MIM when there is a holder on another LPAR. In your case though, it sounds like you are the user on the same LPAR, so it should not be a problem. I have some MIM code also to detect cross LPAR ENQ's within a Sysplex, but unfortunately, it requires MVS command executions and can be site dependent due to command recognition characters...

Hope this helps,

Rob

Bill Turner, WB4ALM

unread,
Jun 19, 2017, 7:26:14 AM6/19/17
to
As previously stated, ISPF is working as designed...
...but then again, so is REXX EXECIO, and TSO EDIT, and ...

You probably need to look up the ENQUE mechanism and understand how it
REALLY works...
an ENQUE is nothing more than an "data" entry in a table, and it
basically has two components,
a major enque name, and a minor enque name.
It has been a while, so I do not remember what the maximum length of
these two fields are.

When you try to "allocate" or process or "whatever" if you issue an
enque request then the table is searched, and your processing might be
"held" while the resource you are looking for can be satisfied.
Eventually your "enque" is added to the table
and your processing is allowed to continue.

A basic flaw in ENQUE processing, is that if an application processes
more than one enque, it must check them in the same sequence as they
were "requested". Not doing so, CAN (will) result in a deadly embrace,
and neither task will ever complete.

For this and many other reasons (including the fact that, in my
environment, many systems were interconnected (sysplex) and each system
supported hundreds (maybe a thousand or more?) TSO development
programmers) I adopted my own unique way of editing and/or reading
"shared" or "sharable" files...

1. I "copied" the data to be edited to a temporary file.
2. The editing or update processing was done against the temp file.
3. The original file was "deleted" and then rebuilt from the update.
(Note: If the edit/update was for a member, then the PDS was never
really deleted for obvious reasons.)

Enque processing (of SHR/OLD) prevented me from replacing the file,
until all other processes were done with their "reading"..
I then had exclusive control of the file, where it was deleted, and then
replaced.

If the "reading" process was a rexx exec, then my recommendation was to:

(1) alloc,
(2) read the file into memory and an "array" (stem).
(3) free.

This overall process worked well, and occurred so fast that any
processing delays for almost all "updates" was quite minimal (and safe).

Just remember, each of the major applications (ISPF, TSO EDIT,
ALLOC/FREE) uses a different set of Major/Minor names an while you will
be "protected" against simular use in the SAME APPLICATION, you might
not be protected from a different one...

Just my 2 cents worth..

/s/ Bill Turner, wb4alm

Jeremy Nicoll

unread,
Jun 19, 2017, 7:27:35 AM6/19/17
to
On Sun, 18 Jun 2017, at 19:28, Bob Bridges wrote:

> 1) I'm editing a member. I'm not using the Edit menu for that; instead
> I'm using a REXX that invokes the ISPEXEC EDIT service, so I imagine all
> the same things happen, including an enqueue for My.Clist(TCMDS).

Ispf edit will have a shared enqueue on the whole pds (thus allowing
other people
access to the whole pds at the same time), but an exclusive
ispf-services-specific
enqueue on the member.

Remember ENQ usually only work at the whole-dataset level. If the
standard ENQ
mechanism was is use you'd only be able to edit any member of a pds if
you had
exclusive use of the whole pds.


When you then run an exec that uses EXECIO, the allocation that precedes
that is
presumably a shared one - because you wouldn't have got exclusive access
to the pds
if anyone else is using it - but the EXECIO method doesn't issue
ispf-like ENQs to protect
the member. EXECIO is really only safe when targeting a sequential
file.

Jeremy Nicoll

unread,
Jun 19, 2017, 7:31:42 AM6/19/17
to
On Mon, 19 Jun 2017, at 01:26, Robert Zenuk wrote:
> Hopefully, I followed the issue correctly... Have you tried the ISPF
> QUERYENQ service to check for the SPFEDIT ENQ? Here is an example.

Querying ENQ is pointless. No matter what it tells you, it can't make
it safe to go
ahead and use the wrong approach to write data into a member, a few
nanoseconds
later.

The perhaps-convoluted method I outlined earlier (or something using
LMservices)
works and is safe because it uses the proper mechanisms.

--
Jeremy Nicoll - my opinions are my own.

Don Poitras

unread,
Jun 19, 2017, 7:38:47 AM6/19/17
to
I'm not sure what good querying for the ENQ will do. If you get RC=8 thinking
it's safe to read/write the member, you're still leaving yourself open to
data corruption as there's nothing stopping someone from using ISPF edit
after that, but before you've written your output. I noted in a separate
post that you need to ENQ (and RESERVE) to get the proper protection.
> > this case I?m concerned with the write function. I just discovered
> > that if I?m editing the same PDS member in another ISPF screen, this
> > routine WORKS ANYWAY, replacing the contents of the member that I'm
> > editing elsewhere. How long has this been going on?!

--
Don Poitras - SAS Development - SAS Institute Inc. - SAS Campus Drive
sas...@sas.com (919) 531-5637 Cary, NC 27513

Paul Gilmartin

unread,
Jun 19, 2017, 10:11:44 AM6/19/17
to
On 2017-06-19, at 05:38, Don Poitras wrote:

> I'm not sure what good querying for the ENQ will do. If you get RC=8 thinking
> it's safe to read/write the member, you're still leaving yourself open to
> data corruption as there's nothing stopping someone from using ISPF edit
>
(TOCTTOU)

> after that, but before you've written your output. I noted in a separate
> post that you need to ENQ (and RESERVE) to get the proper protection.
>
I believe GRS can be configured to convert RESERVE to ENQ SYSTEMS. If
you don't do this, RESERVE is overkill because it locks the entire volume.

Does LMINIT SHRW protect Edit against LMCOPY, even within the *same* job?
To do this I believe it wold need to issue ENQ SPFEDIT EXC without the
RET=HAVE option, I believe. Am I right?

Is the ENQ active only for the duration of the LMCOPY, or only from
the LMINIT to the LMFREE?

-- gil

Jesse 1 Robinson

unread,
Jun 19, 2017, 2:36:20 PM6/19/17
to
I've only skimmed the posts in this thread, but AFAIK IBM gave up long ago on trying to protect PDS (DSORG=PO) from the evils of concurrent update. So they invented PDSE. Love it or hate it, PDSE is nearly impervious to this problem. It may conjure up different problems, but they are at least APARable. This problem is not.

.
.
J.O.Skip Robinson
Southern California Edison Company
Electric Dragon Team Paddler
SHARE MVS Program Co-Manager
323-715-0595 Mobile
626-543-6132 Office ⇐=== NEW
robi...@sce.com

Binyamin Dissen

unread,
Jun 19, 2017, 3:27:43 PM6/19/17
to
On Mon, 19 Jun 2017 18:35:04 +0000 Jesse 1 Robinson <Jesse1....@SCE.COM>
wrote:

:>I've only skimmed the posts in this thread, but AFAIK IBM gave up long ago on trying to protect PDS (DSORG=PO) from the evils of concurrent update. So they invented PDSE. Love it or hate it, PDSE is nearly impervious to this problem. It may conjure up different problems, but they are at least APARable. This problem is not.

I take it that you have not met my little friend, abendS213-30

--
Binyamin Dissen <bdi...@dissensoftware.com>
http://www.dissensoftware.com

Should you use the mailblocks package and expect a response from me,
you should preauthorize the dissensoftware.com domain.

I very rarely bother responding to challenge/response systems,
especially those from irresponsible companies.

Jesse 1 Robinson

unread,
Jun 19, 2017, 3:40:40 PM6/19/17
to
I do consider your friend my friend also. At one time or another we all need that friend who will slap you upside the head when you're about to do something you will regret. S213-30 is that slap. Getting your data overwritten is what can land you in the drunk tank. Or worse.

.
.
J.O.Skip Robinson
Southern California Edison Company
Electric Dragon Team Paddler
SHARE MVS Program Co-Manager
323-715-0595 Mobile
626-543-6132 Office ⇐=== NEW
robi...@sce.com


-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of Binyamin Dissen
Sent: Monday, June 19, 2017 12:27 PM
To: TSO-...@VM.MARIST.EDU
Subject: (External):Re: [TSO-REXX] PDS member contention, spotting thereof

Paul Gilmartin

unread,
Jun 19, 2017, 4:51:39 PM6/19/17
to
On 2017-06-19, at 12:35, Jesse 1 Robinson wrote:

> I've only skimmed the posts in this thread, but AFAIK IBM gave up long ago on trying to protect PDS (DSORG=PO) from the evils of concurrent update. So they invented PDSE. Love it or hate it, PDSE is nearly impervious to this problem. It may conjure up different problems, but they are at least APARable. This problem is not.
>
From a single job, ISPF supports concurrently creating multiple
members of the same PDSE with LMPUTs, which may even be interleaved;
Yaaay! This facility is new with PDSE.

Attempting the same with classic PDS, only one member is created but
no error is reported; yes, as you say, "gave up".

The operation is not possible from different jobs, even though PDSE
should support it, because LMPUT requires ENQ EXC (I believe on SYSDSN).
ISPF hasn't caught up with the times.

-- gil

Robert Zenuk

unread,
Jun 19, 2017, 7:34:48 PM6/19/17
to
Way back in the original post, Bob asked if there was something he could do in his REXX EXEC (that exposed the issue to him) to avoid the overwrite possibility for himself...

"So I'd like some way of knowing ~before~ I try to write to My.Clist.Library(TCMDS) whether it's being edited, so I won't write over the contents accidentally. Any ideas?"

I was responding to that specific request. Since the SPFEDIT ENQ is visible and detectable, he could consciously decide to avoid his own code overwriting his own data.

Granted, not a solution for everyone in all situations, but seemed appropriate for Bob's request.

My two cents... You get what you pay for...

Rob

Jeremy Nicoll

unread,
Jun 20, 2017, 7:45:00 AM6/20/17
to
On Tue, 20 Jun 2017, at 00:34, Robert Zenuk wrote:
> Way back in the original post, Bob asked if there was something he could
> do in his REXX EXEC (that exposed the issue to him) to avoid the
> overwrite possibility for himself...
>
> "So I'd like some way of knowing ~before~ I try to write to
> My.Clist.Library(TCMDS) whether it's being edited, so I won't write over
> the contents accidentally. Any ideas?"
>
> I was responding to that specific request. Since the SPFEDIT ENQ is
> visible and detectable, he could consciously decide to avoid his own code
> overwriting his own data.
>
> Granted, not a solution for everyone in all situations, but seemed
> appropriate for Bob's request.

BUT, no use, because it can only tell you what the situation was when
you query the
enqueue. It can't look into the future to see what the situation will
be at the instant
that anyone other's code tries a future write.

--
Jeremy Nicoll - my opinions are my own.

Robert Zenuk

unread,
Jun 21, 2017, 9:58:06 PM6/21/17
to
Did you read his use case? He is doing something to a member while in edit then while still in edit he decides to do something to that same member using his own code that creates his problem. No prognostication required...

I fully admit in a Sysplex environment a second user on a second LPAR can swoop in undetected if he decided to ignore a warning of an existing SPFEDIT ENQ and overwrite an in use dataset.

Rob


-----Original Message-----
From: Jeremy Nicoll <jn.ls....@LETTERBOXES.ORG>
To: TSO-REXX <TSO-...@VM.MARIST.EDU>
Sent: Tue, Jun 20, 2017 4:44 am
Subject: Re: PDS member contention, spotting thereof

Bob Bridges

unread,
Jul 5, 2017, 5:14:11 PM7/5/17
to
In case anyone cares, the solution I ended up with works like this. The output data is in the stack. The variable named "dsn" contains the DSN of the target PDS member, say "GEN.CLIST(XYZ)". Then:

/* If writing to a real DSN (not temp), check first whether it's
enqueued; if so use viewq instead. */
rck=ed(dsn 'MACRO=NOPM')
select
when rck=14 then call viewq
when rck<=4 then do
call execiost dsn,'W'
call ed dsn; end
otherwise call abend 'RC='rck'!','I tried to edit' dsn,
'and got RC' rck'.'; end

The first statement calls an external REXX that Edits the member with NOPM as the macro. NOPM simply cancels the Edit session, returning RC 4. So:

RC=14: That's the Edit session reporting that the member is currently locked up by another Edit. I could generate an error message, but in this case I choose to View the dataset instead.

RC=4: The Edit succeeded. Call EXECIOST to write the contents of the stack to the PDS member, then call the Ed REXX for a normal Edit session.

RC=anything else: Unpredicted problem; abend with an ad-hoc ISPF popup message and let the operator figure it out.

---
Bob Bridges
robhb...@gmail.com, cell 336 382-7313
rbri...@InfoSecInc.com

/* If you refuse to accept anything but the best you often get it. -unknown
The rest of the time you get nothing. The really good trick is knowing when you should settle. -Bob Bridges */


-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of Jeremy Nicoll
Sent: Tuesday, June 20, 2017 07:45

BUT, no use, because it can only tell you what the situation was when you query the enqueue. It can't look into the future to see what the situation will be at the instant that anyone other's code tries a future write.

--- On Tue, 20 Jun 2017, at 00:34, Robert Zenuk wrote:
> Way back in the original post, Bob asked if there was something he
> could do in his REXX EXEC (that exposed the issue to him) to avoid the
> overwrite possibility for himself...
>
> "So I'd like some way of knowing ~before~ I try to write to
> My.Clist.Library(TCMDS) whether it's being edited, so I won't write
> over the contents accidentally. Any ideas?"
>
> I was responding to that specific request. Since the SPFEDIT ENQ is
> visible and detectable, he could consciously decide to avoid his own
> code overwriting his own data.
>
> Granted, not a solution for everyone in all situations, but seemed
> appropriate for Bob's request.

0 new messages