1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

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 <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
This commit is contained in:
Martin Schwenke 2014-08-08 20:57:05 +10:00 committed by Amitay Isaacs
parent 38c8e15690
commit 2974554356
4 changed files with 10 additions and 224 deletions

View File

@ -514,7 +514,6 @@ struct ctdb_context {
const char *default_public_interface; const char *default_public_interface;
pid_t ctdbd_pid; pid_t ctdbd_pid;
pid_t recoverd_pid; pid_t recoverd_pid;
pid_t syslogd_pid;
enum ctdb_runstate runstate; enum ctdb_runstate runstate;
struct ctdb_monitor_state *monitor; struct ctdb_monitor_state *monitor;
int start_as_disabled; 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); TDB_DATA *data);
int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork, int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork);
bool use_syslog);
struct ctdb_call_state *ctdbd_call_send(struct ctdb_db_context *ctdb_db, struct ctdb_call *call); 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); 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); 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_log_state *ctdb_vfork_with_logging(TALLOC_CTX *mem_ctx,
struct ctdb_context *ctdb, struct ctdb_context *ctdb,
const char *log_prefix, const char *log_prefix,

View File

@ -1142,7 +1142,7 @@ static void ctdb_create_pidfile(pid_t pid)
/* /*
start the protocol going as a daemon 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; int res, ret = -1;
struct fd_event *fde; 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); 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 */ /* initialize statistics collection */
ctdb_statistics_init(ctdb); ctdb_statistics_init(ctdb);

View File

@ -2,7 +2,7 @@
ctdb logging code - syslog backend ctdb logging code - syslog backend
Copyright (C) Andrew Tridgell 2008 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 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 it under the terms of the GNU General Public License as published by
@ -18,24 +18,10 @@
along with this program; if not, see <http://www.gnu.org/licenses/>. along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#include "includes.h" #include "replace.h"
#include "../include/ctdb_client.h"
#include "../include/ctdb_private.h"
#include "system/syslog.h" #include "system/syslog.h"
#include "lib/util/debug.h"
struct syslog_message { #include "ctdb_logging.h"
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;
static int ctdb_debug_to_syslog_level(int dbglevel) static int ctdb_debug_to_syslog_level(int dbglevel)
{ {
@ -62,202 +48,10 @@ static int ctdb_debug_to_syslog_level(int dbglevel)
return level; 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) static void ctdb_log_to_syslog(void *private_ptr, int dbglevel, const char *s)
{ {
struct syslog_message *msg; syslog(ctdb_debug_to_syslog_level(dbglevel),
int len; "%s%s", debug_extra, s);
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);
} }
int ctdb_log_setup_syslog(void) int ctdb_log_setup_syslog(void)

View File

@ -318,5 +318,5 @@ int main(int argc, const char *argv[])
} }
/* start the protocol running (as a child) */ /* 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);
} }