[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fix the log reopening by moving the code with all the races out of the signal
# HG changeset patch # User emellor@xxxxxxxxxxxxxxxxxxxxxx # Node ID 975aa9e4def35fa8059755129f03f078677355b6 # Parent 4982559d8fde3d0a4401766deb54c5cc1e1a0ec5 Fix the log reopening by moving the code with all the races out of the signal handler and into the main loop. The "self-pipe trick" is used to awaken the select() call on SIGHUP. Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx> diff -r 4982559d8fde -r 975aa9e4def3 tools/xenstore/xenstored_core.c --- a/tools/xenstore/xenstored_core.c Thu Nov 10 14:16:01 2005 +++ b/tools/xenstore/xenstored_core.c Thu Nov 10 15:20:27 2005 @@ -56,6 +56,7 @@ static bool verbose; LIST_HEAD(connections); static int tracefd = -1; +static int reopen_log_pipe[2]; static char *tracefile = NULL; static TDB_CONTEXT *tdb_ctx; @@ -243,20 +244,34 @@ talloc_free(str); } -void reopen_log() -{ - if (!tracefile) - return; - - if (tracefd > 0) - close(tracefd); - tracefd = open(tracefile, O_WRONLY|O_CREAT|O_APPEND, 0600); - if (tracefd < 0) { - perror("Could not open tracefile"); - return; - } - write(tracefd, "\n***\n", strlen("\n***\n")); -} + +/** + * Signal handler for SIGHUP, which requests that the trace log is reopened + * (in the main loop). A single byte is written to reopen_log_pipe, to awaken + * the select() in the main loop. + */ +static void trigger_reopen_log(int signal __attribute__((unused))) +{ + char c = 'A'; + write(reopen_log_pipe[1], &c, 1); +} + + +static void reopen_log() +{ + if (tracefile) { + if (tracefd > 0) + close(tracefd); + + tracefd = open(tracefile, O_WRONLY|O_CREAT|O_APPEND, 0600); + + if (tracefd < 0) + perror("Could not open tracefile"); + else + write(tracefd, "\n***\n", strlen("\n***\n")); + } +} + static bool write_messages(struct connection *conn) { @@ -331,29 +346,33 @@ return 0; } + +static void set_fd(int fd, fd_set *set, int *max) +{ + FD_SET(fd, set); + if (fd > *max) + *max = fd; +} + + static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock) { struct connection *i; - int max; + int max = -1; FD_ZERO(inset); FD_ZERO(outset); - FD_SET(sock, inset); - max = sock; - FD_SET(ro_sock, inset); - if (ro_sock > max) - max = ro_sock; - FD_SET(eventchn_fd, inset); - if (eventchn_fd > max) - max = eventchn_fd; + + set_fd(sock, inset, &max); + set_fd(ro_sock, inset, &max); + set_fd(eventchn_fd, inset, &max); + set_fd(reopen_log_pipe[0], inset, &max); list_for_each_entry(i, &connections, list) { if (i->domain) continue; - FD_SET(i->fd, inset); + set_fd(i->fd, inset, &max); if (!list_empty(&i->out_list)) FD_SET(i->fd, outset); - if (i->fd > max) - max = i->fd; } return max; } @@ -1570,6 +1589,10 @@ || listen(*ro_sock, 1) != 0) barf_perror("Could not listen on sockets"); + if (pipe(reopen_log_pipe)) { + barf_perror("pipe"); + } + /* Setup the database */ setup_structure(); @@ -1592,7 +1615,7 @@ close(STDERR_FILENO); } - signal(SIGHUP, reopen_log); + signal(SIGHUP, trigger_reopen_log); #ifdef TESTING signal(SIGUSR1, stop_failtest); @@ -1610,6 +1633,12 @@ if (errno == EINTR) continue; barf_perror("Select failed"); + } + + if (FD_ISSET(reopen_log_pipe[0], &inset)) { + char c; + read(reopen_log_pipe[0], &c, 1); + reopen_log(); } if (FD_ISSET(*sock, &inset)) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |