resource manager: how to distinguish synthesized close() cal

Hi,

When a client application aborts with files left open, close calls are
issued in half of the client to close the open files.
Is there a way for a resource manager to tell the difference between the
close() by the client and the close() made in half the client?

The closest thing that I can see is the “rcvid” field in “resmgr_context_t”,
which is set to 0 in case of io_close_ocb()function. Is there anything that
indicates this in io_close message?

Thanks.
-chang

Chang Im <chim@cisco.com> wrote:

Hi,

When a client application aborts with files left open, close calls are
issued in half of the client to close the open files.
Is there a way for a resource manager to tell the difference between the
close() by the client and the close() made in half the client?

The closest thing that I can see is the “rcvid” field in “resmgr_context_t”,
which is set to 0 in case of io_close_ocb()function. Is there anything that
indicates this in io_close message?

Before getting into this, are you familiar with the issues of open()s,
dup()s, io_close() and the final close? (Take a look at the dup()
library routine if you’re not familiar with it. Also, remember, fds
are duped when ever a child is created.)

Essentially, io_close_ocb() is NOT generated by a particular message,
it is generated when the open/dup count for a particular OCB (fd)
goes to zero. There is nobody to reply to from a io_close_ocb(), which
is why the rcvid would be 0.

Next question, why do you need to know the difference between a
voluntary close() call, and an involuntary close() due to the
client exiting? What are you trying to do differently?

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:a8sgq3$ki9$1@nntp.qnx.com

Next question, why do you need to know the difference between a
voluntary close() call, and an involuntary close() due to the
client exiting? What are you trying to do differently?

Let say, a resource mananger make a copy of a file when the file is closed.
In order to avoid copying a potentially corrupted file, a resource manager
tries to detect if a file is cleanly closed. If a file is not closed by the
client, then
the file may be in an inconsistent state.

-chang.

Chang Im <chim@cisco.com> wrote:

“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:a8sgq3$ki9$> 1@nntp.qnx.com> …

Next question, why do you need to know the difference between a
voluntary close() call, and an involuntary close() due to the
client exiting? What are you trying to do differently?

Let say, a resource mananger make a copy of a file when the file is closed.
In order to avoid copying a potentially corrupted file, a resource manager
tries to detect if a file is cleanly closed. If a file is not closed by the
client, then
the file may be in an inconsistent state.

The close message generated from an explicit close() call, from the
implied close() call if exit() is called explicitly, and from the
implied cleanup if a process exits abnormally is the same in all
cases. (And, this is intentional.)

If you need this sort of handling, I would suggest doing something like
extending the OCB to include a “dirty” flag, mark this flag on anything
that would change the device (writes), and implement a devctl() that would
say clear the dirty flag (i.e. stable data state), then in your
iofunc_close_ocb() handler, you could check the state of the dirty flag
in the OCB to know which branch of handling to take.

This would allow the additional flexibility of a process to state that
“its sane” without having to do any closes – it could then do a later
update, mark as “sane”, update, mark as sane, etc… until it is finally
done, and does a close().

But, of course, there are still the issues of multiple processes opening
the same device – are you allowing this? Have you thought through the
implications for this sort of state-saving? Maybe you need this as a
per-device (iofunc_attr_t structure, or extension) flag, rather than a
per OCB flag. (filenames are basically mapped to devices or
iofunc_attr_t structues; UNIQUE opens are mapped to OCBs, with
dup()ed fds [including dups due to process creation] being mapped
to the same OCB as the previous open().)

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Hi David,

Thanks for your good suggestions. One concern I have is this requires
applications to add the new devctl calls.

I am wondering if QNX could add this distinction in the io_close message
so that resource managers can use this data optionally if it wants to. I
guess
this change would require modifying exit() and implicit cleanup routine.
Hofully
there would be only a few places to change and keep the applications in
tact.

-chang

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:a8so57$ps7$1@nntp.qnx.com

Chang Im <> chim@cisco.com> > wrote:

“David Gibbs” <> dagibbs@qnx.com> > wrote in message
news:a8sgq3$ki9$> 1@nntp.qnx.com> …

Next question, why do you need to know the difference between a
voluntary close() call, and an involuntary close() due to the
client exiting? What are you trying to do differently?

Let say, a resource mananger make a copy of a file when the file is
closed.
In order to avoid copying a potentially corrupted file, a resource
manager
tries to detect if a file is cleanly closed. If a file is not closed by
the
client, then
the file may be in an inconsistent state.

The close message generated from an explicit close() call, from the
implied close() call if exit() is called explicitly, and from the
implied cleanup if a process exits abnormally is the same in all
cases. (And, this is intentional.)

If you need this sort of handling, I would suggest doing something like
extending the OCB to include a “dirty” flag, mark this flag on anything
that would change the device (writes), and implement a devctl() that would
say clear the dirty flag (i.e. stable data state), then in your
iofunc_close_ocb() handler, you could check the state of the dirty flag
in the OCB to know which branch of handling to take.

This would allow the additional flexibility of a process to state that
“its sane” without having to do any closes – it could then do a later
update, mark as “sane”, update, mark as sane, etc… until it is finally
done, and does a close().

But, of course, there are still the issues of multiple processes opening
the same device – are you allowing this? Have you thought through the
implications for this sort of state-saving? Maybe you need this as a
per-device (iofunc_attr_t structure, or extension) flag, rather than a
per OCB flag. (filenames are basically mapped to devices or
iofunc_attr_t structues; UNIQUE opens are mapped to OCBs, with
dup()ed fds [including dups due to process creation] being mapped
to the same OCB as the previous open().)

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Chang Im <chim@cisco.com> wrote:

Hi David,

Thanks for your good suggestions. One concern I have is this requires
applications to add the new devctl calls.

I am wondering if QNX could add this distinction in the io_close message
so that resource managers can use this data optionally if it wants to. I
guess
this change would require modifying exit() and implicit cleanup routine.
Hofully
there would be only a few places to change and keep the applications in
tact.

This newsgroup, or any newsgroup, probably isn’t the best place for
a feature request – they’re probably best raised through your sales
channel contact.

I’d not be the person implementing this, but I can see some concerns
with it.

Technical: the io_close_t for the close message is is already defined,
and it doesn’t have any spare “room” in the message – it has two 16-bit
fields, both used. Changing the type field would definitely break
existing resource managers, maybe a bit in the combine-len could be
used, but I’d still worry about that breaking existing code, as would
the extending the size of a structure that is being used in
message passing.

Also technical: implementation of exit() and _exit(): these may call
close() to close the fds – I’m not sure, but if they do, that becomes
more difficult.

Compatibility: _exit() is defined as “closing all open file descriptors”.
From Posix point of view, this is considered a NORMAL close of an fd.
I think that providing different behaviour for close due to exit and
close due to explicit close would not be Posix approved – but I don’t
know the details of the specs well enough to track this down.
Something else that inclines me towards this: exit() also flushes
all stdio buffers that may be dirty – again, doing the equivalent
of an fclose() – making it again parallel a “normal” or “intentional”
close of the stream. But, POSIX also is extensible, so that might
not prevent some extra information be transmitted.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.