Re: [HACKERS] on_exit_reset fails to clear DSM-related exit actions

2014-03-07 Thread Peter LaDow
On Fri, Mar 7, 2014 at 12:55 PM, Peter LaDow  wrote:
> Just to be clear, what do you mean by "nontrivial code"?  Do you mean
> C library calls, other than fork/exec/_exit?

I think I've answered my own question:

http://man7.org/linux/man-pages/man7/signal.7.html

The 'Async-signal-safe functions' are the nontrivial C calls that may be called.

Pete


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] on_exit_reset fails to clear DSM-related exit actions

2014-03-07 Thread Peter LaDow
On Fri, Mar 7, 2014 at 12:17 PM, Andres Freund  wrote:
> Forking twice is ok as well, as long as you just use _exit() after the
> fork. The thing is that you shouldn't run any nontrivial code in the
> fork, as long as you're connected to the original environment (fd's,
> memory mappings and so forth).

Just to be clear, what do you mean by "nontrivial code"?  Do you mean
C library calls, other than fork/exec/_exit?

Pete


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] on_exit_reset fails to clear DSM-related exit actions

2014-03-07 Thread Peter LaDow
On Fri, Mar 7, 2014 at 12:17 PM, Andres Freund  wrote:
> Man. The point is that that the library code is carefully written to not
> use exit() but _exit() after a fork failure, that's it.

I understand your point.  I understand that in the case of the
postmaster we don't want to invoke behavior that can cause problems by
calling exit(). But how does this jive with Tom's point (on the bug
list) about other 3rd party libraries perhaps registering atexit
handlers?

If the convention is that only fork/exec/_exit is permissible after a
fork (what about on_exit_reset?), then third party libraries also need
to be aware of that convention and not depend on their atexit handlers
being called.

And I'm not advocating a certain solution.  I'm only trying to clarify
what the solution is so that we "comply" with the convention.  We
don't want to break posgres or any other "well behaved" third party
libraries.  I don't know the internals of postgres (hence original bug
report and this thread), so I of course defer to you and the other
experts here.  So, in our case we call on_exit_reset() after the fork
in the child, and then from there on only use fork, exec, or _exit, as
you mention above.

Pete


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] on_exit_reset fails to clear DSM-related exit actions

2014-03-07 Thread Peter LaDow
On Friday, March 7, 2014, Andres Freund  wrote:
>
> If the third party library is suitably careful it will only use fork()
> and then exec() or _exit(), otherwise there are other things that'll be


But that is not possible* in our case of trying to spawn an asynchronous
backgound process. The goal here is for the extension to spawn the process
and return immediately. If we exec in the first level child, and
immediately return, who reaps the child when done?

This is why we fork twice and exit in the first level child so that the
extension can reap the first.

Unless Postgres happily reaps all children perhaps through a SIGCHLD
handler?

(* I suppose we could exec a program that itself forks/execs a background
process. But that is essentially no different than what we are doing now,
other than trying to meet this fork/exec/_exit requirement. And that's fine
if that is to be the case. We just need to know what it is.)


> Both perl and glibc seem to do just that in system() btw...
>

I don't know about Perl, but system is blocking. What if you don't want to
wait for the child to exit?

Pete


Re: [HACKERS] atexit_callback can be a net negative

2014-03-07 Thread Peter LaDow
Sorry for the bit of top-posting, but I wanted to make some things
clear.  Also, I wasn't subscribed to pgsql-hackers at the time this
thread began, so I apologize for the missing headers that might cause
threading issues.

I'm the submitter of bug #9464.  Here's the background on what we are
doing.  We are on a limited resource, embedded device.  We make use of
the database as an event driven system.  In the case of an incoming
event, such as a settings change, we make use of this fork/exec
procedure to spawn an asynchronous process to handle certain events.
Some of these external processes are long running, some need to run
outside the current transaction context, and some we don't care about
the result--we just want it to run.

Also, the on_exit_reset() does clear up the issue, and we have
implemented it as suggested in this thread (calling it immediately
after the fork() in the child).  And Andres' keen eye noted we were
calling exit() after an exec() failure, rather than _exit(). Thank
you, Andres, for pointing out this error.

Andres Freund  2ndquadrant.com> writes:
> On 2014-03-07 09:49:05 -0500, Tom Lane wrote:
> > Andres Freund  2ndquadrant.com> writes:
> > > What are you proposing to do in that case? This is only one of the
> > > failure cases of forking carelessly, right?

Just to be clear, we intended to fork careFULLy, not careLESSly.
Hence the reason for the double fork with an eventual exec().  We
intended to be clearly separated from the backend and executing in our
own clean, unrelated context.

> I don't think it's a reasonable pattern run background processes that
> aren't managed by postgres with all shared memory still
> accessible. You'll have to either also detach from shared memory and

In this case we definitely did NOT want to be managed by postgres.
Hence the double fork.  The intent was that the first level child
would NOT be managed by postgres, hence the exit().

> related things, or you have to fork() and exec(). At the very least, not

Which is _exactly_ what we were trying to do.  The first fork was only
so that we could fork again and spawn a subprocess completely detached
from the postmaster.  And also to have something for the postmaster to
reap via waitpid and prevent a zombie from hanging around.  The
typical daemon stuff.

> integrating the child with the postmaster's lifetime will prevent
> postgres from restarting because there's still a child attached to the
> shared memory.

Which is _exactly_ what we were NOT trying to do.  We did not want to
integrate with postmaster.

> I don't see any way it's be safe for a pg unaware library to start
> forking around and doing similar random things inside normal
> backends.

We aren't exactly "forking around."  We were trying to spawn an
asynchronous process without any ties to the postmaster.  This was
expected to be well-defined, clean behavior.  A fork/exec isn't an
unusual thing to do, and we didn't expect that exiting a child would
invoke behavior that would cause problems.

Thanks,

Pete


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers