Обсуждение: fork() and dynamically loaded c functions....
Hi there, I have some functions written in C that are dynamically loaded. I persist some state between function calls, initialised by _PG_init. This works fine I now fork() a process in _PG_Init() (both processes interact), but when I shutdown postgre I get: LOG: failed to find proc 0x1331110 in ProcArray Basically the child process stays alive after postgre exists (as verified by ps -A) I was thinking that I could use _PG_fini for the cleanup, but the manual says that it "will only be called during an unload of the file, not during process termination." Is there any way to either a) insert some cleanup code when the server shuts down; or b) instruct postgres to kill the child process? Thanks!
Jay Flattery <jaycode@rocketmail.com> writes: > I have some functions written in C that are dynamically loaded. I persist some > state between function calls, initialised by _PG_init. This works fine OK... > I now fork() a process in _PG_Init() (both processes interact), but when I > shutdown postgre I get: LOG: failed to find proc 0x1331110 in ProcArray What exactly is that child process doing? It sure sounds like it thinks it's a valid backend. You can fork something if you like, but it had absolutely better not touch any part of shared memory afterwards. regards, tom lane
Thanks for your reply >> I now fork() a process in _PG_Init() (both processes interact), but when I >> shutdown postgre I get: LOG: failed to find proc 0x1331110 in ProcArray >What exactly is that child process doing? It sure sounds like it thinks >it's a valid backend. Actually it's not doing anything, as I'm just trying to work it all out - just a bunch of printfs and waits. But the library is a PG_MAGIC_MODULE. I tried killing it with pg_terminate_backend(pid) - but I get WARNING: PID 1166738497 is not a PostgreSQL server process. (Interestingly the child pid=28629, which was printed in the line before) >You can fork something if you like, but it had absolutely better not >touch any part of shared memory afterwards. Sure - it is intended to run independently. Is there an internal pfork() or something similar I should use instead?
Jay Flattery <jaycode@rocketmail.com> writes: >> What exactly is that child process doing? It sure sounds like it thinks >> it's a valid backend. > Actually it's not doing anything, as I'm just trying to work it all out - just a > bunch of printfs and waits. > But the library is a PG_MAGIC_MODULE. > I tried killing it with pg_terminate_backend(pid) - but I get WARNING: PID > 1166738497 is not a PostgreSQL server process. (Interestingly the child > pid=28629, which was printed in the line before) The forked process still thinks it's a backend, so when you try to kill it it's going to try to disconnect from shared memory. This is bad, since the parent still thinks the same thing, but the child will have zapped the parent's entries in shared memory. Offhand the only clean way I can see to launch a child process is to fork *and exec something*. There is way too much state lying around in a backend process that could rise up to bite you if you don't. You might find that doing on_exit_reset() in the child would fix the worst problems, but it still sounds chancy as heck. regards, tom lane
Excerpts from Tom Lane's message of mar ago 10 19:49:18 -0400 2010: > Offhand the only clean way I can see to launch a child process is to > fork *and exec something*. You probably should close any open file descriptors too, just to be safe. (Or do we set FD_CLOEXEC on them?) -- Álvaro Herrera <alvherre@commandprompt.com> The PostgreSQL Company - Command Prompt, Inc. PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Alvaro Herrera <alvherre@commandprompt.com> writes: > You probably should close any open file descriptors too, just to be > safe. (Or do we set FD_CLOEXEC on them?) We don't. It'd take an extra syscall per open(), which seems like rather a lot of overhead to deal with a case we aren't even trying to support. regards, tom lane
>You might find that doing on_exit_reset() in the child would fix the >worst problems, but it still sounds chancy as heck. Thanks for that. The fork() is certainly more convenient than exec'g something else - hopefully OK since we're just prototyping something. Quick question: where is _exit_reset() located? Searched doxygen (and google), but couldn't find anything on it