Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

SOLVED
Go to solution
Claus Olesen
Advisor

sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

We had some strange errors in some of our C-programs ported from AXP to IA64 - programs that each use both sockets and simple synchrounous single reader/writer mailboxes. One is that the mailbox reader suddenly hangs in the mailbox not reading what the mailbox writer just wrote and the writer moving on with the iosb saying that process pid 0 read what it just wrote. Another is out-of the-blue "peer closed" on socket connections.
In trying to get to the bottom of this I checked the OpenVMS documentation and saw the new event flag EFN$C_ENF.
To eliminate eventflag contention as cause I did as the doc says - use that flag in all sys$qiow's instead 0.

For the mailboxes we had this

sys$qiow(0,MbxChan,IO$_READVBLK,0,0,0,&MsgBuf,MsgSize,0,0,0,0);

and that worked on the AXP.

I replaced the event flag no.

sys$qiow(EFN$C_ENF,MbxChan,IO$_READVBLK,0,0,0,&MsgBuf,MsgSize,0,0,0,0);

but the programs still misbehave.

In
http://forums1.itrc.hp.com/service/forums/questionanswer.do?threadId=1084916
I think Hoff's entry says to always use the iosb.

So I then tried with add of the iosb
sys$qiow(EFN$C_ENF,MbXChan,IO$_READVBLK,&MbxIosb,0,0,&MsgBuf,MsgSize,0,0,0,0);

and with that all problems have vanished!

My question is for a confirmation. Must the iosb always be specified in (the wait form of) calls like the above when using EFN$C_ENF?
My worry is that we perhaps have a memory overwrite somewhere in our code and that the shifting of things in the executables due to add of the iosb just somehow pushed the problem below the surface.
12 REPLIES
Hein van den Heuvel
Honored Contributor
Solution

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

You must specify an IOSB.
It is the only reasonably thing to do.


The best documenation it possibly under $SYNCH:

http://h71000.www7.hp.com/doc/83FINAL/4527/4527pro_119.html#jun_584

And of couse the entries in the OpenVMS Programming book:

http://h71000.www7.hp.com/doc/82FINAL/5841/5841pro_020.html#enf_lef

http://h71000.www7.hp.com/doc/82FINAL/5841/5841pro_020.html#index_x_604

The 'old' practice for QIO was too often to not provide an EFN and no IOSB. However, you can/could not not specify an EFN. You would get ENF=0 which was too easily shared with timers and the likes. The resolution is to use the IOSB and with that in place you might as well not specify an ENF. Thus EFN$C_ENF was born.

Now spefically for a mailbox read, surely you want to knwo how many bytes were read? That will be returned in the IOSB along with the writing process PID.

fwiw,
Hein.
Robert Gezelter
Honored Contributor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

Claus,

One should always use an IOSB when doing a QIO or similar operation. Additionally, the IOSB should be used by only one outstanding operation at a time.

The IOSB is written as part of IO completion processing on all versions of OpenVMS (and members of the RSX-11 family; from which the QIO mechanism is derived). For security and integrity (pun unintended) reasons, the user space IOSB is a write-only data structure, insofar as the operating system is concerned.

A change in relative positioning could well have happened, I have seen that type of bug many times.

I note that EFN$C pre-dates the Itanium versions of OpenVMS. It cures the overuse of event flag 0 (which in turn caused accidents).

Setting watch points on several variables in the debugger may be one effective way of locating a wild overwrite problem.

- Bob Gezelter, http://www.rlgsc.com
Jur van der Burg
Respected Contributor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

What's worse if you don't specify an iosb is that you never know the correct exit status from the call. The return value of sys$qio indicates if the request was queued correctly, but that may be different from the completion status that is in the iosb. This may depend on the driver you're talking to, but in general ALWAYS check the qio return status AND check the status in the iosb. Not doing so may lead to unreliable software.

Jur.
Robert Brooks_1
Honored Contributor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

I am a bit confused.

While I certainly agree with the other responders regarding the use of an IOSB, are you saying that you simply added the IOSB param to the call and the code now worked?

In other words, did you check iosb$w_status for a non-zero status (either success or failure)?

If you didn't actually use the value provided in the IOSB, it's not clear to me why simply adding that param to the QIO would now make your program work. If that's the case, I'd do a "deep dive" of the code to see whatever oddball synchronisation issues may exist.

efn$c_enf isn't new; it's just gotten a bit more "publicity" in the documentation.

-- Rob
Jon Pinkley
Honored Contributor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

"While I certainly agree with the other responders regarding the use of an IOSB, are you saying that you simply added the IOSB param to the call and the code now worked?"

======================

The $QIOW is equivalent to

$QIO
$SYNCH

And $SYNCH does an implicit check of the IOSB. See the references Hein provided. Specifically in the description of $SYNCH

"The service whose completion status is to be checked must have been called with the efn and iosb arguments specified, because the $SYNCH service uses the event flag and I/O status block of the service to be checked. ... The synchronous services such as $QIOW execute code that checks for the true completion status in the same way that $SYNCH does."

So it does look plausible that just adding the IOSB could make the program's behavior change. Why it appeared to be working correctly on Alpha is a question to still be answered, and I agree that the program should be explicitly checking for errors in the status returned in the IOSB.
it depends
Hoff
Honored Contributor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

At its simplest, always, always, always assume the IOSB is not optional.

Always specify the IOSB.

Always, always, always.

This includes if you've used event flag zero like half of the code on the system, or used the "don't care" EFN$C_ENF (available on V7.1 and later), or even if you've used the synchronous wait form of the service.

Sure, there can be (and are) cases where the IOSB is not strictly necessary. This consistent usage makes for a very simple rule. The IOSB never hurts. The IOSB can help. Why gamble?

One side note for asynchronous calls: always ensure that the buffers and related arguments and the IOSB are all allocated from storage that is non-volatile over the lifetime of the call. Be particularly aware of and cautious around stack-local allocations.

For a list of common coding bugs suitable for use in reviewing an application, see topic (1661) over in the old Ask The Wizard area.

And FWIW, there's not enough code here to discern whether the $qiow calls are correct. Your description certainly implies there might be a Heisenbug lurking here -- Rob's on the same trail.

Stephen Hoffman
HoffmanLabs LLC
Robert Brooks_1
Honored Contributor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

For V8.3, the documentation for several of the system services that take an IOSB was updated. It was done pretty much at the last minute, so all the services weren't "fixed".

Even though I'm no longer in VMS Engineering, I sit next to the doc writers, and hope to make further corrections over time.

The wording may look familiar to readers here, as well as comp.os.vms, as a frequent contributor of those fora. (Thanks, Steve).

The formatting of the below text may be a bit odd, as I cut-and-pasted from the web-based documentation for $GETDVI


Though this argument is optional, HP strongly recommends that you specify it, for the following reasons:

* If you are using an event flag to signal the completion of the service, you can test the I/O status block for a condition value to be sure that the event flag was not set by an event other than service completion.
* If you are using the $SYNCH service to synchronize completion of the service, the I/O status block is a required argument for $SYNCH.
* The condition value returned in R0 and the condition value returned in the I/O status block provide information about different aspects of the call to the $GETDVI service. The condition value returned in R0 gives you information about the success or failure of the service call itself; the condition value returned in the I/O status block gives you information about the success or failure of the service operation. Therefore, to accurately assess the success or failure of the call to $GETDVI, you must check the condition values returned in both R0 and the I/O status block.
Claus Olesen
Advisor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

Thank you for all your replies.

We're using v8.2-1 - fully up2date with the latest patches.

I posted also for discoveries of deviations (idiosyncracies?) if any on IA64 relative to AXP.

But from your replies I get that there aren't any, that the iosb is still a fully optional argument to the QIOW service also on IA64 - even with EFN$C_ENF (besides, if it was not the case then the QIOW ought to return error. Which it does not). But that for the callers sake (not the callee's) the iosb should be (specified and) used.

To Robert Brooks - yes, that is what I am experiencing. One of the programs works with efn=0 and pIosb=0 - as it did on the AXP. Changing from efn=0 to efn=efn$c_enf makes the program misbehave. In addition changing from pIosb=0 to pIosb!=0 without actually doing anything with the iosb makes the program again behave. But why change it? For consistency across programs as the change in other programs made them behave.

You mention documentation. Under $QIOW on this page
http://h71000.www7.hp.com/DOC/83FINAL/4527/4527pro_094.html
it says
"...Digital recommends that you use an IOSB with this service to avoid premature completion."
In other words - if you don't specify an iosb then the qiow (notice the w) may complete prematurely?
I wouldn't think so. Rephrase?

You mention $synch. Does the fact that $qiow = $qio + $synch include the condition code returned? Or should/must the condition code in the iosb be checked in addition to the condition code returned by $qiow (again please notice the w). I couldn't find the answer in the doc.


Robert Gezelter
Honored Contributor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

Claus,

The premature completion occurs if some other call referenced the same event flag. There is nothing magical about QIOW as opposed to a QIO followed by a WAIT for an event flag. The WAIT is on the event flag, not the QIO.

- Bob Gezelter, http://www.rlgsc.com
Jur van der Burg
Respected Contributor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

>(besides, if it was not the case then the
>QIOW ought to return error. Which it does
>not).

How do you know if there was no error if you did not specify an iosb???? Just checking the $qio return status is by no means a complete check.

>In other words - if you don't specify an
>iosb then the qiow (notice the w) may
>complete prematurely?
>I wouldn't think so. Rephrase?

That's what may happen if another part of the software uses the same event flag.

>You mention $synch. Does the fact that $qiow
> = $qio + $synch include the condition code
>returned? Or should/must the condition code
>in the iosb be checked in addition to the
>condition code returned by $qiow (again
>please notice the w). I couldn't find the
>answer in the doc.

As said before, check both the $qio return status AND the iosb status. that's the ONLY way to be certain in all cases. If you want to write software that behaves predictable do it this way.

Jur.
Jon Pinkley
Honored Contributor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

>>>You mention $synch. Does the fact that $qiow = $qio + $synch include the condition code returned?<<<

No, $qiow does not copy the value from the iosb into the value retuned as the $qio status. I suppose that would have been possible, but it would have made the behavior of $QIOW different than $QIO. But if you are put off by that, then you probably wouldn't be using $QIO in the first place, instead using something at a higher level.

Note that these are two types of errors.

The status returned by the $QUI is telling you whether VMS has accepted your request as valid. I.e. you have access to the buffer you specified, you have specified correct io function modifiers, etc.

The status returned in the IOSB is set after the IO is complete (or has failed). It reports things like insufficient buffer for the amount of data that was returned, or some error status from a device.

These are analogous to compile time errors vs. run time errors in a program.

>>>Or should/must the condition code in the iosb be checked in addition to the condition code returned by $qiow (again please notice the w). I couldn't find the answer in the doc.<<<

Yes, as Jur stated, you MUST check the condition code if you want to be able to handle errors that occur after the I/O request packet has been queued to the driver, regardless of whether it was a $qio or $qiow.

Jon
it depends
John Gillings
Honored Contributor

Re: sys$qiow(efn$c_enf,...,iosb,...) - must iosb be specified?

The IOSB might be documented to be "optional", but if you want your code to work, you will always specify an IOSB, stored in a place that will be in scope when the operation completes (not an issue with $QIOW, but worth reminding yourself of everytime - the IOSB is written asynchronously, possibly AFTER the service has returned). That's true of all system services that have an IOSB or analogous structure.

One way of thinking about it is, the definition of completion of the operation is when the IOSB is written. Without an IOSB you can't be certain the operation has completed at all, let alone know if it's completed successfully. As Jur has stressed, you should always check the IOSB to confirm success.

There are all kinds of circumstances under which you can get a spurious completions of asynch operations (and therefore also the synch operations). EFN$C_ENF eliminates overloaded event flags from causing issues, BUT also prevents the use of the event flag being used to signal completion. You're therefore left with ONLY the IOSB to tell you when the operation has completed.

So, the answer to your question "Must the iosb always be specified in (the wait form of) calls like the above when using EFN$C_ENF?" is YES.

If you've specified an event flag, you might get away without an IOSB most of the time, but I'm fairly sure when using ENF, it just plain won't work without an IOSB.

Regardless, as Hoff has said, ALWAYS, ALWAYS, ALWAYS use an IOSB.
A crucible of informative mistakes