From 29745543566ef66c1f2972fd5cd68e17ddf4de4f Mon Sep 17 00:00:00 2001 From: Martin Schwenke Date: Fri, 8 Aug 2014 20:57:05 +1000 Subject: [PATCH] ctdb-logging: Replace logd code with a basic syslog(3) implementation It is much simpler for most cases to have a syslog backend that doesn't need a separate CTDB-specific logging daemon. This loses the lossy, non-blocking mode provided by logd. However, a corresponding feature with a completely different implemention (not requiring an extra daemon) will be re-added into the syslog backend. In an ideal world the new implementation would be added first but unfortunately that is hard to do because the logd code is hooked in at more than one place. Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- ctdb/include/ctdb_private.h | 6 +- ctdb/server/ctdb_daemon.c | 8 +- ctdb/server/ctdb_logging_syslog.c | 218 +----------------------------- ctdb/server/ctdbd.c | 2 +- 4 files changed, 10 insertions(+), 224 deletions(-) diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 7d454cec5e3..3d6f487ff5b 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -514,7 +514,6 @@ struct ctdb_context { const char *default_public_interface; pid_t ctdbd_pid; pid_t recoverd_pid; - pid_t syslogd_pid; enum ctdb_runstate runstate; struct ctdb_monitor_state *monitor; int start_as_disabled; @@ -775,8 +774,8 @@ struct ctdb_call_state *ctdb_call_local_send(struct ctdb_db_context *ctdb_db, TDB_DATA *data); -int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork, - bool use_syslog); +int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork); + struct ctdb_call_state *ctdbd_call_send(struct ctdb_db_context *ctdb_db, struct ctdb_call *call); int ctdbd_call_recv(struct ctdb_call_state *state, struct ctdb_call *call); @@ -1448,7 +1447,6 @@ int32_t ctdb_control_register_notify(struct ctdb_context *ctdb, uint32_t client_ int32_t ctdb_control_deregister_notify(struct ctdb_context *ctdb, uint32_t client_id, TDB_DATA indata); -int start_syslog_daemon(struct ctdb_context *ctdb); struct ctdb_log_state *ctdb_vfork_with_logging(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb, const char *log_prefix, diff --git a/ctdb/server/ctdb_daemon.c b/ctdb/server/ctdb_daemon.c index 65b7109620f..254b1ca8195 100644 --- a/ctdb/server/ctdb_daemon.c +++ b/ctdb/server/ctdb_daemon.c @@ -1142,7 +1142,7 @@ static void ctdb_create_pidfile(pid_t pid) /* start the protocol going as a daemon */ -int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork, bool use_syslog) +int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork) { int res, ret = -1; struct fd_event *fde; @@ -1215,12 +1215,6 @@ int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork, bool use_syslog) } ctdb_set_child_logging(ctdb); - if (use_syslog) { - if (start_syslog_daemon(ctdb)) { - DEBUG(DEBUG_CRIT, ("Failed to start syslog daemon\n")); - exit(10); - } - } /* initialize statistics collection */ ctdb_statistics_init(ctdb); diff --git a/ctdb/server/ctdb_logging_syslog.c b/ctdb/server/ctdb_logging_syslog.c index b2cb261c47c..382c7916e5a 100644 --- a/ctdb/server/ctdb_logging_syslog.c +++ b/ctdb/server/ctdb_logging_syslog.c @@ -2,7 +2,7 @@ ctdb logging code - syslog backend Copyright (C) Andrew Tridgell 2008 - Copyright (C) Ronnie Sahlberg 2009 + Copyright (C) Martin Schwenke 2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,24 +18,10 @@ along with this program; if not, see . */ -#include "includes.h" -#include "../include/ctdb_client.h" -#include "../include/ctdb_private.h" +#include "replace.h" #include "system/syslog.h" - -struct syslog_message { - uint32_t level; - uint32_t len; - char message[1]; -}; - - -struct ctdb_syslog_state { - int syslog_fd; - int fd[2]; -}; - -static int syslogd_is_started = 0; +#include "lib/util/debug.h" +#include "ctdb_logging.h" static int ctdb_debug_to_syslog_level(int dbglevel) { @@ -62,202 +48,10 @@ static int ctdb_debug_to_syslog_level(int dbglevel) return level; } -/* called when child is finished - * this is for the syslog daemon, we can not use DEBUG here - */ -static void ctdb_syslog_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *p) -{ - struct ctdb_syslog_state *state = talloc_get_type(p, struct ctdb_syslog_state); - - int count; - char str[65536]; - struct syslog_message *msg; - - if (state == NULL) { - return; - } - - count = recv(state->syslog_fd, str, sizeof(str), 0); - if (count < sizeof(struct syslog_message)) { - return; - } - msg = (struct syslog_message *)str; - if (msg->len >= (sizeof(str) - offsetof(struct syslog_message, message))) { - msg->len = (sizeof(str)-1) - offsetof(struct syslog_message, message); - } - msg->message[msg->len] = '\0'; - - syslog(msg->level, "%s", msg->message); -} - - -/* called when the pipe from the main daemon has closed - * this is for the syslog daemon, we can not use DEBUG here - */ -static void ctdb_syslog_terminate_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *p) -{ - syslog(LOG_ERR, "Shutting down SYSLOG daemon with pid:%d", (int)getpid()); - _exit(0); -} - - - -/* - * this is for the syslog daemon, we can not use DEBUG here - */ -int start_syslog_daemon(struct ctdb_context *ctdb) -{ - struct sockaddr_in syslog_sin; - struct ctdb_syslog_state *state; - struct tevent_fd *fde; - int startup_fd[2]; - int ret = -1; - - state = talloc(ctdb, struct ctdb_syslog_state); - CTDB_NO_MEMORY(ctdb, state); - - if (pipe(state->fd) != 0) { - printf("Failed to create syslog pipe\n"); - talloc_free(state); - return -1; - } - - if (pipe(startup_fd) != 0) { - printf("Failed to create syslog startup pipe\n"); - close(state->fd[0]); - close(state->fd[1]); - talloc_free(state); - return -1; - } - - ctdb->syslogd_pid = ctdb_fork(ctdb); - if (ctdb->syslogd_pid == (pid_t)-1) { - printf("Failed to create syslog child process\n"); - close(state->fd[0]); - close(state->fd[1]); - close(startup_fd[0]); - close(startup_fd[1]); - talloc_free(state); - return -1; - } - - if (ctdb->syslogd_pid != 0) { - ssize_t n; - int dummy; - - DEBUG(DEBUG_ERR,("Starting SYSLOG child process with pid:%d\n", (int)ctdb->syslogd_pid)); - - close(state->fd[1]); - set_close_on_exec(state->fd[0]); - - close(startup_fd[1]); - n = sys_read(startup_fd[0], &dummy, sizeof(dummy)); - close(startup_fd[0]); - if (n < sizeof(dummy)) { - return -1; - } - - syslogd_is_started = 1; - return 0; - } - - debug_extra = talloc_asprintf(NULL, "syslogd:"); - talloc_free(ctdb->ev); - ctdb->ev = event_context_init(NULL); - - syslog(LOG_ERR, "Starting SYSLOG daemon with pid:%d", (int)getpid()); - ctdb_set_process_name("ctdb_syslogd"); - - close(state->fd[0]); - close(startup_fd[0]); - set_close_on_exec(state->fd[1]); - set_close_on_exec(startup_fd[1]); - fde = event_add_fd(ctdb->ev, state, state->fd[1], EVENT_FD_READ, - ctdb_syslog_terminate_handler, state); - tevent_fd_set_auto_close(fde); - - state->syslog_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (state->syslog_fd == -1) { - printf("Failed to create syslog socket\n"); - close(startup_fd[1]); - return ret; - } - - set_close_on_exec(state->syslog_fd); - - syslog_sin.sin_family = AF_INET; - syslog_sin.sin_port = htons(CTDB_PORT); - syslog_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - if (bind(state->syslog_fd, (struct sockaddr *)&syslog_sin, - sizeof(syslog_sin)) == -1) - { - printf("syslog daemon failed to bind to socket. errno:%d(%s)\n", errno, strerror(errno)); - close(startup_fd[1]); - _exit(10); - } - - - fde = event_add_fd(ctdb->ev, state, state->syslog_fd, EVENT_FD_READ, - ctdb_syslog_handler, state); - tevent_fd_set_auto_close(fde); - - /* Tell parent that we're up */ - ret = 0; - sys_write(startup_fd[1], &ret, sizeof(ret)); - close(startup_fd[1]); - - event_loop_wait(ctdb->ev); - - /* this should not happen */ - _exit(10); -} - -/* - syslog logging function - */ static void ctdb_log_to_syslog(void *private_ptr, int dbglevel, const char *s) { - struct syslog_message *msg; - int len; - int syslog_fd; - struct sockaddr_in syslog_sin; - - len = offsetof(struct syslog_message, message) + strlen(debug_extra) + strlen(s) + 1; - msg = malloc(len); - if (msg == NULL) { - return; - } - msg->level = ctdb_debug_to_syslog_level(dbglevel); - msg->len = strlen(debug_extra) + strlen(s); - strcpy(msg->message, debug_extra); - strcat(msg->message, s); - - if (syslogd_is_started == 0) { - syslog(msg->level, "%s", msg->message); - } else { - syslog_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (syslog_fd == -1) { - printf("Failed to create syslog socket\n"); - free(msg); - return; - } - - syslog_sin.sin_family = AF_INET; - syslog_sin.sin_port = htons(CTDB_PORT); - syslog_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - (void) sendto(syslog_fd, msg, len, 0, - (struct sockaddr *)&syslog_sin, - sizeof(syslog_sin)); - /* no point in checking here since we cant log an error */ - - close(syslog_fd); - } - - free(msg); + syslog(ctdb_debug_to_syslog_level(dbglevel), + "%s%s", debug_extra, s); } int ctdb_log_setup_syslog(void) diff --git a/ctdb/server/ctdbd.c b/ctdb/server/ctdbd.c index 1e5e380a225..16a647ac48c 100644 --- a/ctdb/server/ctdbd.c +++ b/ctdb/server/ctdbd.c @@ -318,5 +318,5 @@ int main(int argc, const char *argv[]) } /* start the protocol running (as a child) */ - return ctdb_start_daemon(ctdb, interactive?false:true, options.use_syslog); + return ctdb_start_daemon(ctdb, interactive?false:true); }