From rusty:
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Mon, 14 Dec 2009 23:23:58 +0000 (10:23 +1100)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Mon, 14 Dec 2009 23:23:58 +0000 (10:23 +1100)
Subject: eventscript: fix spinning at 100% cpu when child exits.

ctdbd was spinning reading 0 from a pipe, as soon as the first
eventscript finishes.

This was caused by the intersection between a78b8ea7168e "Run only one
event for each epoll_wait/select call" and 32cfdc3aec34 "eventscript:
ctdb_fork_with_logging()".  Unavoidable mid-air collision, since both
worked fine and both were developed simultaneously.

When the script exits, we have two pipes open to it: one for any
stdout/stderr for logging (ctdb_log_handler), and one for the result
(ctdb_event_script_handler).  The latter frees everything, including
the log fd and event structure.

We used to get one callback to ctdb_log_handler, which got a harmless
0-length read, then one to ctdb_event_script_handler which cleaned up.
Now we only do one callback per poll, we need the logging function to
clean itself up so we can make process.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
server/ctdb_logging.c

index 7dadbfd77689f06ecc0ee5fc85916ee070737486..9aba7f839c131e5cc7f6bf0ea12b1886135af997 100644 (file)
@@ -381,6 +381,9 @@ static void ctdb_log_handler(struct event_context *ev, struct fd_event *fde,
                 sizeof(log->buf) - log->buf_used);
        if (n > 0) {
                log->buf_used += n;
+       } else if (n == 0) {
+               talloc_free(log);
+               return;
        }
 
        this_log_level = script_log_level;