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

ctdb-logging: Remove duplicate logging code

ctdb_logging_init() now uses logging_init().

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
This commit is contained in:
Amitay Isaacs 2016-11-29 16:36:57 +11:00 committed by Martin Schwenke
parent c9124a001f
commit 02aa65cede
5 changed files with 5 additions and 508 deletions

View File

@ -676,12 +676,6 @@ struct lock_request *ctdb_lock_db(TALLOC_CTX *mem_ctx,
extern const char *debug_extra;
typedef int (*ctdb_log_setup_fn_t)(TALLOC_CTX *mem_ctx,
const char *logging,
const char *app_name);
void ctdb_log_register_backend(const char *prefix, ctdb_log_setup_fn_t init);
bool ctdb_logging_init(TALLOC_CTX *mem_ctx, const char *logging);
struct ctdb_log_state *ctdb_vfork_with_logging(TALLOC_CTX *mem_ctx,

View File

@ -20,7 +20,6 @@
#include "replace.h"
#include "system/filesys.h"
#include "system/network.h"
#include "system/syslog.h"
#include "system/time.h"
#include <talloc.h>
@ -40,12 +39,6 @@
const char *debug_extra = "";
struct ctdb_log_backend {
struct ctdb_log_backend *prev, *next;
const char *prefix;
ctdb_log_setup_fn_t setup;
};
struct ctdb_log_state {
const char *prefix;
int fd, pfd;
@ -53,62 +46,27 @@ struct ctdb_log_state {
uint16_t buf_used;
void (*logfn)(const char *, uint16_t, void *);
void *logfn_private;
struct ctdb_log_backend *backends;
};
/* Used by ctdb_set_child_logging() */
static struct ctdb_log_state *log_state;
void ctdb_log_register_backend(const char *prefix, ctdb_log_setup_fn_t setup)
{
struct ctdb_log_backend *b;
b = talloc_zero(log_state, struct ctdb_log_backend);
if (b == NULL) {
printf("Failed to register backend \"%s\" - no memory\n",
prefix);
return;
}
b->prefix = prefix;
b->setup = setup;
DLIST_ADD_END(log_state->backends, b);
}
/* Initialise logging */
bool ctdb_logging_init(TALLOC_CTX *mem_ctx, const char *logging)
{
struct ctdb_log_backend *b;
int ret;
log_state = talloc_zero(mem_ctx, struct ctdb_log_state);
if (log_state == NULL) {
printf("talloc_zero failed\n");
abort();
return false;
}
ctdb_log_init_file();
ctdb_log_init_syslog();
for (b = log_state->backends; b != NULL; b = b->next) {
size_t l = strlen(b->prefix);
/* Exact match with prefix or prefix followed by ':' */
if (strncmp(b->prefix, logging, l) == 0 &&
(logging[l] == '\0' || logging[l] == ':')) {
ret = b->setup(mem_ctx, logging, "ctdbd");
if (ret == 0) {
return true;
}
printf("Log init for \"%s\" failed with \"%s\"\n",
logging, strerror(ret));
return false;
}
ret = logging_init(mem_ctx, logging, NULL, "ctdbd");
if (ret != 0) {
return false;
}
printf("Unable to find log backend for \"%s\"\n", logging);
return false;
return true;
}
/* Note that do_debug always uses the global log state. */
@ -279,11 +237,6 @@ int ctdb_set_child_logging(struct ctdb_context *ctdb)
int old_stdout, old_stderr;
struct tevent_fd *fde;
if (log_state->fd == STDOUT_FILENO) {
/* not needed for stdout logging */
return 0;
}
/* setup a pipe to catch IO from subprocesses */
if (pipe(p) != 0) {
DEBUG(DEBUG_ERR,(__location__ " Failed to setup for child logging pipe\n"));

View File

@ -1,120 +0,0 @@
/*
ctdb logging code
Copyright (C) Andrew Tridgell 2008
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
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "replace.h"
#include "system/time.h"
#include "system/filesys.h"
#include "system/network.h"
#include <talloc.h>
#include "lib/util/debug.h"
#include "lib/util/sys_rw.h"
#include "lib/util/time_basic.h"
#include "ctdb_private.h"
#include "ctdb_client.h"
#define CTDB_LOG_FILE_PREFIX "file"
struct file_state {
int fd;
};
/*
log file logging function
*/
static void ctdb_log_to_file(void *private_ptr, int dbglevel, const char *s)
{
struct file_state *state = talloc_get_type(
private_ptr, struct file_state);
struct timeval tv;
struct timeval_buf tvbuf;
char *s2 = NULL;
int ret;
GetTimeOfDay(&tv);
timeval_str_buf(&tv, false, true, &tvbuf);
ret = asprintf(&s2, "%s [%s%5u]: %s\n",
tvbuf.buf,
debug_extra, (unsigned)getpid(), s);
if (ret == -1) {
const char *errstr = "asprintf failed\n";
sys_write(state->fd, errstr, strlen(errstr));
return;
}
if (s2) {
sys_write(state->fd, s2, strlen(s2));
free(s2);
}
}
static int file_state_destructor(struct file_state *state)
{
close(state->fd);
state->fd = -1;
return 0;
}
static int ctdb_log_setup_file(TALLOC_CTX *mem_ctx,
const char *logging,
const char *app_name)
{
struct file_state *state;
const char *logfile;
size_t l;
l = strlen(CTDB_LOG_FILE_PREFIX);
if (logging[l] != ':') {
return EINVAL;
}
logfile = &logging[0] + l + 1;
state = talloc_zero(mem_ctx, struct file_state);
if (state == NULL) {
return ENOMEM;
}
if (logfile == NULL || strcmp(logfile, "-") == 0) {
int ret;
state->fd = 1;
/* also catch stderr of subcommands to stdout */
ret = dup2(1, 2);
if (ret == -1) {
return errno;
}
} else {
state->fd = open(logfile, O_WRONLY|O_APPEND|O_CREAT, 0666);
if (state->fd == -1) {
return errno;
}
}
talloc_set_destructor(state, file_state_destructor);
debug_set_callback(state, ctdb_log_to_file);
return 0;
}
void ctdb_log_init_file(void)
{
ctdb_log_register_backend(CTDB_LOG_FILE_PREFIX, ctdb_log_setup_file);
}

View File

@ -1,328 +0,0 @@
/*
ctdb logging code - syslog backend
Copyright (C) Andrew Tridgell 2008
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
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "replace.h"
#include "system/network.h"
#include "system/syslog.h"
#include "lib/util/debug.h"
#include "lib/util/blocking.h"
#include "lib/util/time_basic.h"
#include "lib/util/samba_util.h" /* get_myname */
#include "ctdb_private.h"
#include "common/logging.h"
/* Linux and FreeBSD define this appropriately - try good old /dev/log
* for anything that doesn't... */
#ifndef _PATH_LOG
#define _PATH_LOG "/dev/log"
#endif
#define CTDB_LOG_SYSLOG_PREFIX "syslog"
#define CTDB_SYSLOG_FACILITY LOG_USER
struct ctdb_syslog_sock_state {
int fd;
const char *app_name;
const char *hostname;
int (*format)(int dbglevel, struct ctdb_syslog_sock_state *state,
const char *str, char *buf, int bsize);
};
/**********************************************************************/
static int ctdb_debug_to_syslog_level(int dbglevel)
{
int level;
switch (dbglevel) {
case DEBUG_ERR:
level = LOG_ERR;
break;
case DEBUG_WARNING:
level = LOG_WARNING;
break;
case DEBUG_NOTICE:
level = LOG_NOTICE;
break;
case DEBUG_INFO:
level = LOG_INFO;
break;
default:
level = LOG_DEBUG;
break;
}
return level;
}
/**********************************************************************/
/* Format messages as per RFC3164. */
/* It appears that some syslog daemon implementations do not allow a
* hostname when messages are sent via a Unix domain socket, so omit
* it. Similarly, syslogd on FreeBSD does not understand the hostname
* part of the header, even when logging via UDP. Note that most
* implementations will log messages against "localhost" when logging
* via UDP. A timestamp could be sent but rsyslogd on Linux limits
* the timestamp logged to the precision that was received on
* /dev/log. It seems sane to send degenerate RFC3164 messages
* without a header at all, so that the daemon will generate high
* resolution timestamps if configured. */
static int format_rfc3164(int dbglevel, struct ctdb_syslog_sock_state *state,
const char *str, char *buf, int bsize)
{
int pri;
int len;
pri = CTDB_SYSLOG_FACILITY | ctdb_debug_to_syslog_level(dbglevel);
len = snprintf(buf, bsize, "<%d>%s[%u]: %s%s",
pri, state->app_name, getpid(), debug_extra, str);
len = MIN(len, bsize - 1);
return len;
}
/* Format messages as per RFC5424
*
* <165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1
* myproc 8710 - - %% It's time to make the do-nuts.
*/
static int format_rfc5424(int dbglevel, struct ctdb_syslog_sock_state *state,
const char *str, char *buf, int bsize)
{
int pri;
struct timeval tv;
struct timeval_buf tvbuf;
int len, s;
/* Header */
pri = CTDB_SYSLOG_FACILITY | ctdb_debug_to_syslog_level(dbglevel);
GetTimeOfDay(&tv);
len = snprintf(buf, bsize,
"<%d>1 %s %s %s %u - - ",
pri, timeval_str_buf(&tv, true, true, &tvbuf),
state->hostname, state->app_name, getpid());
/* A truncated header is not useful... */
if (len >= bsize) {
return -1;
}
/* Message */
s = snprintf(&buf[len], bsize - len, "%s %s", debug_extra, str);
len = MIN(len + s, bsize - 1);
return len;
}
/**********************************************************************/
/* Non-blocking logging */
static void ctdb_log_to_syslog_sock(void *private_ptr,
int dbglevel, const char *str)
{
struct ctdb_syslog_sock_state *state = talloc_get_type(
private_ptr, struct ctdb_syslog_sock_state);
/* RFC3164 says: The total length of the packet MUST be 1024
bytes or less. */
char buf[1024];
int n;
n = state->format(dbglevel, state, str, buf, sizeof(buf));
if (n == -1) {
fprintf(stderr, "Failed to format syslog message %s\n", str);
return;
}
/* Could extend this to count failures, which probably
* indicate dropped messages due to EAGAIN or EWOULDBLOCK */
(void)send(state->fd, buf, n, 0);
}
static int
ctdb_syslog_sock_state_destructor(struct ctdb_syslog_sock_state *state)
{
if (state->fd != -1) {
close(state->fd);
state->fd = -1;
}
return 0;
}
static struct ctdb_syslog_sock_state *
ctdb_log_setup_syslog_common(TALLOC_CTX *mem_ctx,
const char *app_name)
{
struct ctdb_syslog_sock_state *state;
state = talloc_zero(mem_ctx, struct ctdb_syslog_sock_state);
if (state == NULL) {
return NULL;
}
state->fd = -1;
state->app_name = app_name;
talloc_set_destructor(state, ctdb_syslog_sock_state_destructor);
return state;
}
static int ctdb_log_setup_syslog_un(TALLOC_CTX *mem_ctx,
const char *app_name)
{
struct ctdb_syslog_sock_state *state;
struct sockaddr_un dest;
int ret;
state = ctdb_log_setup_syslog_common(mem_ctx, app_name);
if (state == NULL) {
return ENOMEM;
}
state->fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (state->fd == -1) {
int save_errno = errno;
talloc_free(state);
return save_errno;
}
dest.sun_family = AF_UNIX;
strncpy(dest.sun_path, _PATH_LOG, sizeof(dest.sun_path)-1);
ret = connect(state->fd,
(struct sockaddr *)&dest, sizeof(dest));
if (ret == -1) {
int save_errno = errno;
talloc_free(state);
return save_errno;
}
ret = set_blocking(state->fd, false);
if (ret != 0) {
int save_errno = errno;
talloc_free(state);
return save_errno;
}
state->hostname = NULL; /* Make this explicit */
state->format = format_rfc3164;
debug_set_callback(state, ctdb_log_to_syslog_sock);
return 0;
}
static int ctdb_log_setup_syslog_udp(TALLOC_CTX *mem_ctx,
const char *app_name,
bool rfc5424)
{
struct ctdb_syslog_sock_state *state;
struct sockaddr_in dest;
int ret;
state = ctdb_log_setup_syslog_common(mem_ctx, app_name);
if (state == NULL) {
return ENOMEM;
}
state->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (state->fd == -1) {
int save_errno = errno;
talloc_free(state);
return save_errno;
}
dest.sin_family = AF_INET;
dest.sin_port = htons(514);
dest.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
ret = connect(state->fd,
(struct sockaddr *)&dest, sizeof(dest));
if (ret == -1) {
int save_errno = errno;
talloc_free(state);
return save_errno;
}
state->hostname = get_myname(state);
if (state->hostname == NULL) {
/* Use a fallback instead of failing initialisation */
state->hostname = "localhost";
}
if (rfc5424) {
state->format = format_rfc5424;
} else {
state->format = format_rfc3164;
}
debug_set_callback(state, ctdb_log_to_syslog_sock);
return 0;
}
/**********************************************************************/
static void ctdb_log_to_syslog(void *private_ptr, int dbglevel, const char *s)
{
syslog(ctdb_debug_to_syslog_level(dbglevel),
"%s%s", debug_extra, s);
}
static int ctdb_log_setup_syslog(TALLOC_CTX *mem_ctx,
const char *logging,
const char *app_name)
{
size_t l = strlen(CTDB_LOG_SYSLOG_PREFIX);
if (logging[l] != '\0') {
/* Handle non-blocking extensions here */
const char *method;
if (logging[l] != ':') {
return EINVAL;
}
method = &logging[0] + l + 1;
if (strcmp(method, "nonblocking") == 0) {
ctdb_log_setup_syslog_un(mem_ctx, app_name);
return 0;
}
if (strcmp(method, "udp") == 0) {
ctdb_log_setup_syslog_udp(mem_ctx, app_name, false);
return 0;
}
if (strcmp(method, "udp-rfc5424") == 0) {
ctdb_log_setup_syslog_udp(mem_ctx, app_name, true);
return 0;
}
return EINVAL;
}
debug_set_callback(NULL, ctdb_log_to_syslog);
return 0;
}
void ctdb_log_init_syslog(void)
{
ctdb_log_register_backend(CTDB_LOG_SYSLOG_PREFIX,
ctdb_log_setup_syslog);
}

View File

@ -404,8 +404,6 @@ def build(bld):
ctdb_persistent.c ctdb_keepalive.c
ctdb_cluster_mutex.c
ctdb_logging.c
ctdb_logging_syslog.c
ctdb_logging_file.c
ctdb_uptime.c
ctdb_vacuum.c ctdb_banning.c
ctdb_statistics.c