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:
parent
38c8e15690
commit
2974554356
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user