ctdb-daemon: Check PID in ctdb_remove_pidfile(), not unreliable flag
authorMartin Schwenke <martin@meltin.net>
Mon, 30 Jun 2014 07:22:14 +0000 (17:22 +1000)
committerAmitay Isaacs <amitay@samba.org>
Sat, 5 Jul 2014 04:51:13 +0000 (06:51 +0200)
If something unexpectedly uses fork() then an exiting child will
remove the PID file while the main daemon is still running.  The real
test is whether the current process has the PID of the main CTDB
daemon, which is the process that calls setsid().

This could be done using getpgrp() instead.  At the moment the
eventscript handler harmlessly calls setpgid() - harmless because the
atexit() handlers are cleared upon exec().  However, it is possible
that process groups will be used more in future so it is probably
better to rely on the session ID.

Thanks to Sumit Bose <sbose@redhat.com> for the idea.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/common/ctdb_fork.c
ctdb/server/ctdb_daemon.c

index aa9bcf01bc4926f038133760acdb522dbd7eb0ae..d7eef76c78ddbdff3b6b84ae1e95e4a6aa1d303a 100644 (file)
 #include "../include/ctdb_private.h"
 #include "../common/rb_tree.h"
 
-static bool is_child = false;
-
 void ctdb_set_child_info(TALLOC_CTX *mem_ctx, const char *child_name_fmt, ...)
 {
-       is_child = true;
        if (child_name_fmt != NULL) {
                va_list ap;
                char *t;
@@ -40,11 +37,6 @@ void ctdb_set_child_info(TALLOC_CTX *mem_ctx, const char *child_name_fmt, ...)
        }
 }
 
-bool ctdb_is_child_process(void)
-{
-       return is_child;
-}
-
 void ctdb_track_child(struct ctdb_context *ctdb, pid_t pid)
 {
        char *process;
index eb42e18886cd9f75332061987f1090a2a1abd8b5..448e7dcc98ef18bc72423be61694f0954615ec04 100644 (file)
@@ -1109,7 +1109,8 @@ static void ctdb_tevent_trace(enum tevent_trace_point tp,
 
 static void ctdb_remove_pidfile(void)
 {
-       if (ctdbd_pidfile != NULL && !ctdb_is_child_process()) {
+       /* Only the main ctdbd's PID matches the SID */
+       if (ctdbd_pidfile != NULL && getsid(0) == getpid()) {
                if (unlink(ctdbd_pidfile) == 0) {
                        DEBUG(DEBUG_NOTICE, ("Removed PID file %s\n",
                                             ctdbd_pidfile));