Re: [HACKERS] on_exit_reset fails to clear DSM-related exit actions
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
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
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
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
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