The branch, master has been updated via 41c964f ctdb-recovery: Start recovery helper with ctdb_vfork_exec via 1b7f0a7 ctdb-locking: Start locking helper using ctdb_vfork_exec via c438563 ctdb-daemon: Add ctdb_vfork_exec() via ecf3f56 ctdb-daemon: Log to stderr when running in interactive mode via d53dbd0 ctdb-daemon: Initialize logging in recovery daemon via 74ccc72 ctdb-recoverd: Log a message when terminating via e2413a0 ctdb-logging: Get rid of debug_extra via aaeef14 ctdb-daemon: Remove setting of debug_extra via 3d6860b ctdb-daemon: Remove setting of debug_extra from switch_from_server_to_client() via ca55652 ctdb-daemon: Remove setting of debug_extra via ctdb_set_child_info() via 9ae62f1 ctdb-daemon: Don't depend on debug_extra in exit handler via 4108f47 ctdb-daemon: Fix debug messages via 28b6a90 ctdb-daemon: Consolidate initialization of logging and debug level via 02aa65c ctdb-logging: Remove duplicate logging code via c9124a0 ctdb-logging: Refactor logging code via c54943f ctdb-logging: Use Samba's debug levels via 657f2c6 ctdb-scripts: Update CTDB_SCRIPT_DEBUGLEVEL to be symbolic via 4f9d50e ctdb-tests: Use symbolic debug levels in tool tests via 5abc994 ctdb-tests: Use symbolic debug levels in eventscript tests via 8eaa0d8 ctdb-tests: Use symbolic debug level for local daemons via 3a395b6 ctdb-tests: Use symbolic debug levels in takeover tests via ccbd559 ctdb-tests: Support symbolic debug level in takeover tests via dbc6cf7 ctdb-doc: Don't advertise numeric debug levels via 2650f37 ctdb-logging: Drop enum debug_level via 9b7308b ctdb-daemon: Remove tevent debug logging from 3de13cb debug: Add minimalist D_* macros
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 41c964fdbca552b045568967a2bb5dae0e878b7c Author: Amitay Isaacs <ami...@gmail.com> Date: Wed Nov 30 12:23:04 2016 +1100 ctdb-recovery: Start recovery helper with ctdb_vfork_exec The recovery helper does it's own logging, so there is no need to pass logfd. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> Autobuild-User(master): Martin Schwenke <mart...@samba.org> Autobuild-Date(master): Mon Dec 5 11:59:42 CET 2016 on sn-devel-144 commit 1b7f0a7bbbf52cc1e4f6539934f5dc0b1c12fba6 Author: Amitay Isaacs <ami...@gmail.com> Date: Wed Nov 30 12:22:02 2016 +1100 ctdb-locking: Start locking helper using ctdb_vfork_exec This avoids the extra argument of logfd to ctdb_lock_helper. The log messages from lock helper are captured by ctdbd. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit c43856342f3780ef5cf748606bc3179ffcd5873f Author: Amitay Isaacs <ami...@gmail.com> Date: Wed Nov 30 12:15:11 2016 +1100 ctdb-daemon: Add ctdb_vfork_exec() This will replace ctdb_vfork_with_logging(). Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit ecf3f56138b903ac37dc6d2ff18bb7a64f8337fe Author: Amitay Isaacs <ami...@gmail.com> Date: Tue Nov 29 17:52:00 2016 +1100 ctdb-daemon: Log to stderr when running in interactive mode Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit d53dbd0dcc6c3d65012d1309c45b5f78077162e3 Author: Amitay Isaacs <ami...@gmail.com> Date: Tue Nov 29 16:49:41 2016 +1100 ctdb-daemon: Initialize logging in recovery daemon Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit 74ccc7280a83e1073f9bb0e5cd355f86a5f08f1e Author: Amitay Isaacs <ami...@gmail.com> Date: Fri Nov 25 14:57:30 2016 +1100 ctdb-recoverd: Log a message when terminating Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit e2413a0567ae0952d086ec4f79da43ca4bf6c214 Author: Amitay Isaacs <ami...@gmail.com> Date: Tue Nov 29 17:59:32 2016 +1100 ctdb-logging: Get rid of debug_extra Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit aaeef14ae5bba159f5527b96306f4d818ff91714 Author: Amitay Isaacs <ami...@gmail.com> Date: Fri Nov 25 14:50:01 2016 +1100 ctdb-daemon: Remove setting of debug_extra Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit 3d6860b2753b0c4e76c042fab42562dd2dbc46ef Author: Amitay Isaacs <ami...@gmail.com> Date: Fri Nov 25 14:44:10 2016 +1100 ctdb-daemon: Remove setting of debug_extra from switch_from_server_to_client() Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit ca5565257531cc5e41aea84666bdd5b354c5138f Author: Amitay Isaacs <ami...@gmail.com> Date: Fri Nov 25 14:37:17 2016 +1100 ctdb-daemon: Remove setting of debug_extra via ctdb_set_child_info() Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit 9ae62f15322fecd05cd9d925c5f359334155aed0 Author: Amitay Isaacs <ami...@gmail.com> Date: Fri Nov 25 14:54:07 2016 +1100 ctdb-daemon: Don't depend on debug_extra in exit handler Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit 4108f47bcfc91812f6ca064fee774771270fc27b Author: Amitay Isaacs <ami...@gmail.com> Date: Wed Nov 30 17:04:54 2016 +1100 ctdb-daemon: Fix debug messages - Use fprintf() before logging is initialized - replace DEBUG_ALERT with DEBUG_ERR Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit 28b6a90a159f78abb37dba04ee4f178cc5dde647 Author: Amitay Isaacs <ami...@gmail.com> Date: Wed Nov 30 16:46:19 2016 +1100 ctdb-daemon: Consolidate initialization of logging and debug level Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit 02aa65cede61da7d53087bc3c836c6c101d5bf36 Author: Amitay Isaacs <ami...@gmail.com> Date: Tue Nov 29 16:36:57 2016 +1100 ctdb-logging: Remove duplicate logging code ctdb_logging_init() now uses logging_init(). Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit c9124a001f5abf7bb577a8f5341da4cc7411ed22 Author: Amitay Isaacs <ami...@gmail.com> Date: Tue Nov 29 16:17:23 2016 +1100 ctdb-logging: Refactor logging code This extracts the code from following files: - server/ctdb_logging.c - server/ctdb_logging_file.c - server/ctdb_logging_syslog.c This is in preparation for each daemon (and some processes) doing their own loging instead of relying on CTDB. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit c54943f8bb1e5d23502cb594d1b16f253cddf722 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 23 19:03:23 2016 +1100 ctdb-logging: Use Samba's debug levels Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 657f2c687c60af18ba32a7612da354109cb6e400 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 23 21:36:36 2016 +1100 ctdb-scripts: Update CTDB_SCRIPT_DEBUGLEVEL to be symbolic Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 4f9d50e2e3d1ad075cc79bf2128fb68b395dbc72 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 23 21:38:14 2016 +1100 ctdb-tests: Use symbolic debug levels in tool tests Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 5abc9942e224b87287b34fef2772b1afa7b71ad7 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 23 21:37:45 2016 +1100 ctdb-tests: Use symbolic debug levels in eventscript tests Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 8eaa0d80fffb6d60b8d6c64275cad065c356d573 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 23 17:01:54 2016 +1100 ctdb-tests: Use symbolic debug level for local daemons Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 3a395b67a3915e97a88ac0668eac51a167207df9 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 23 20:40:50 2016 +1100 ctdb-tests: Use symbolic debug levels in takeover tests Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit ccbd55986a3ae179aa3195eda731e9b767bcd279 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 23 19:16:56 2016 +1100 ctdb-tests: Support symbolic debug level in takeover tests Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit dbc6cf7a5583310a2ddb451930e188379a601291 Author: Martin Schwenke <mar...@meltin.net> Date: Wed Nov 23 16:51:53 2016 +1100 ctdb-doc: Don't advertise numeric debug levels The plan is to switch to Samba's (incompatible) debug levels, so just expect CTDB users to use the symbolic name for the debug level. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 2650f37018e36a9d59046098e519a662d394950e Author: Martin Schwenke <mar...@meltin.net> Date: Fri Nov 25 13:23:11 2016 +1100 ctdb-logging: Drop enum debug_level We are switching to Samba-style integer debug levels. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 9b7308b20295f1670c40d46aa087763698a3c1fa Author: Amitay Isaacs <ami...@gmail.com> Date: Mon Oct 24 16:53:12 2016 +1100 ctdb-daemon: Remove tevent debug logging Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> ----------------------------------------------------------------------- Summary of changes: ctdb/client/client.h | 4 +- ctdb/client/client_control_sync.c | 4 +- ctdb/common/logging.c | 466 +++++++++++++++++++++++- ctdb/common/logging.h | 26 +- ctdb/config/functions | 2 +- ctdb/doc/ctdb.1.xml | 2 +- ctdb/doc/ctdb.7.xml | 10 +- ctdb/doc/ctdbd.1.xml | 2 +- ctdb/doc/ctdbd.conf.5.xml | 12 +- ctdb/include/ctdb_private.h | 21 +- ctdb/protocol/protocol_api.h | 4 +- ctdb/protocol/protocol_client.c | 8 +- ctdb/server/ctdb_call.c | 3 +- ctdb/server/ctdb_daemon.c | 24 +- ctdb/server/ctdb_fork.c | 62 +++- ctdb/server/ctdb_lock.c | 6 +- ctdb/server/ctdb_lock_helper.c | 53 ++- ctdb/server/ctdb_logging.c | 107 +----- ctdb/server/ctdb_logging_file.c | 120 ------ ctdb/server/ctdb_logging_syslog.c | 328 ----------------- ctdb/server/ctdb_monitor.c | 1 - ctdb/server/ctdb_recoverd.c | 13 +- ctdb/server/ctdb_recovery_helper.c | 44 +-- ctdb/server/ctdb_takeover.c | 3 +- ctdb/server/ctdb_traverse.c | 3 +- ctdb/server/ctdb_update_record.c | 1 - ctdb/server/ctdb_vacuum.c | 2 +- ctdb/server/ctdbd.c | 39 +- ctdb/tests/eventscripts/50.samba.monitor.107.sh | 2 +- ctdb/tests/eventscripts/stubs/ctdb | 2 +- ctdb/tests/simple/13_ctdb_setdebug.sh | 18 +- ctdb/tests/simple/scripts/local_daemons.bash | 2 +- ctdb/tests/src/ctdb_takeover_tests.c | 11 +- ctdb/tests/src/fake_ctdbd.c | 12 +- ctdb/tests/src/test_options.c | 4 +- ctdb/tests/takeover/lcp2.001.sh | 2 +- ctdb/tests/takeover/lcp2.002.sh | 2 +- ctdb/tests/takeover/lcp2.003.sh | 2 +- ctdb/tests/takeover/lcp2.004.sh | 2 +- ctdb/tests/takeover/lcp2.005.sh | 2 +- ctdb/tests/takeover/lcp2.006.sh | 2 +- ctdb/tests/takeover/lcp2.007.sh | 2 +- ctdb/tests/takeover/lcp2.008.sh | 2 +- ctdb/tests/takeover/lcp2.009.sh | 2 +- ctdb/tests/takeover/lcp2.010.sh | 2 +- ctdb/tests/takeover/lcp2.011.sh | 2 +- ctdb/tests/takeover/lcp2.012.sh | 2 +- ctdb/tests/takeover/lcp2.013.sh | 2 +- ctdb/tests/takeover/lcp2.014.sh | 2 +- ctdb/tests/takeover/lcp2.015.sh | 2 +- ctdb/tests/takeover/lcp2.016.sh | 2 +- ctdb/tests/takeover/lcp2.017.sh | 2 +- ctdb/tests/takeover/lcp2.018.sh | 2 +- ctdb/tests/takeover/lcp2.019.sh | 2 +- ctdb/tests/takeover/lcp2.020.sh | 2 +- ctdb/tests/takeover/lcp2.021.sh | 2 +- ctdb/tests/takeover/lcp2.022.sh | 2 +- ctdb/tests/takeover/lcp2.023.sh | 2 +- ctdb/tests/takeover/lcp2.024.sh | 2 +- ctdb/tests/takeover/lcp2.025.sh | 2 +- ctdb/tests/takeover/lcp2.026.sh | 2 +- ctdb/tests/takeover/lcp2.027.sh | 2 +- ctdb/tests/takeover/lcp2.028.sh | 2 +- ctdb/tests/takeover/lcp2.029.sh | 2 +- ctdb/tests/takeover/lcp2.030.sh | 2 +- ctdb/tests/takeover/lcp2.031.sh | 2 +- ctdb/tests/takeover/lcp2.032.sh | 2 +- ctdb/tests/takeover/lcp2.033.sh | 2 +- ctdb/tests/tool/ctdb.setdebug.003.sh | 10 +- ctdb/tests/tool/scripts/local.sh | 2 +- ctdb/tools/ctdb.c | 6 +- ctdb/tools/ctdb_killtcp.c | 6 +- ctdb/wscript | 4 +- 73 files changed, 711 insertions(+), 804 deletions(-) delete mode 100644 ctdb/server/ctdb_logging_file.c delete mode 100644 ctdb/server/ctdb_logging_syslog.c Changeset truncated at 500 lines: diff --git a/ctdb/client/client.h b/ctdb/client/client.h index 3d6292c..ea41cbe 100644 --- a/ctdb/client/client.h +++ b/ctdb/client/client.h @@ -240,12 +240,12 @@ int ctdb_ctrl_getvnnmap(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int ctdb_ctrl_getdebug(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, int destnode, struct timeval timeout, - uint32_t *loglevel); + int *loglevel); int ctdb_ctrl_setdebug(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, int destnode, struct timeval timeout, - uint32_t loglevel); + int loglevel); int ctdb_ctrl_get_dbmap(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, diff --git a/ctdb/client/client_control_sync.c b/ctdb/client/client_control_sync.c index 07f23bf..ac453b0 100644 --- a/ctdb/client/client_control_sync.c +++ b/ctdb/client/client_control_sync.c @@ -183,7 +183,7 @@ int ctdb_ctrl_getvnnmap(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int ctdb_ctrl_getdebug(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, int destnode, struct timeval timeout, - uint32_t *loglevel) + int *loglevel) { struct ctdb_req_control request; struct ctdb_reply_control *reply; @@ -212,7 +212,7 @@ int ctdb_ctrl_getdebug(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int ctdb_ctrl_setdebug(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, int destnode, struct timeval timeout, - uint32_t loglevel) + int loglevel) { struct ctdb_req_control request; struct ctdb_reply_control *reply; diff --git a/ctdb/common/logging.c b/ctdb/common/logging.c index 4b7b4e5..3d586bf 100644 --- a/ctdb/common/logging.c +++ b/ctdb/common/logging.c @@ -1,6 +1,8 @@ /* Logging utilities + Copyright (C) Andrew Tridgell 2008 + Copyright (C) Martin Schwenke 2014 Copyright (C) Amitay Isaacs 2015 This program is free software; you can redistribute it and/or modify @@ -17,23 +19,39 @@ along with this program; if not, see <http://www.gnu.org/licenses/>. */ -#include <replace.h> -#include <system/locale.h> +#include "replace.h" +#include "system/network.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/syslog.h" + +#include "lib/util/time_basic.h" +#include "lib/util/sys_rw.h" +#include "lib/util/debug.h" +#include "lib/util/blocking.h" +#include "lib/util/samba_util.h" /* get_myname() */ #include "common/logging.h" struct { - enum debug_level log_level; + int log_level; const char *log_string; } log_string_map[] = { { DEBUG_ERR, "ERROR" }, { DEBUG_WARNING, "WARNING" }, + { 2, "WARNING" }, { DEBUG_NOTICE, "NOTICE" }, + { 4, "NOTICE" }, { DEBUG_INFO, "INFO" }, + { 6, "INFO" }, + { 7, "INFO" }, + { 8, "INFO" }, + { 9, "INFO" }, { DEBUG_DEBUG, "DEBUG" }, }; -bool debug_level_parse(const char *log_string, enum debug_level *log_level) +bool debug_level_parse(const char *log_string, int *log_level) { int i; @@ -45,7 +63,7 @@ bool debug_level_parse(const char *log_string, enum debug_level *log_level) int level = atoi(log_string); if (level >= 0 && level < ARRAY_SIZE(log_string_map)) { - *log_level = debug_level_from_int(level); + *log_level = level; return true; } return false; @@ -62,7 +80,7 @@ bool debug_level_parse(const char *log_string, enum debug_level *log_level) return false; } -const char *debug_level_to_string(enum debug_level log_level) +const char *debug_level_to_string(int log_level) { int i; @@ -74,10 +92,10 @@ const char *debug_level_to_string(enum debug_level log_level) return "UNKNOWN"; } -enum debug_level debug_level_from_string(const char *log_string) +int debug_level_from_string(const char *log_string) { bool found; - enum debug_level log_level; + int log_level; found = debug_level_parse(log_string, &log_level); if (found) { @@ -88,20 +106,436 @@ enum debug_level debug_level_from_string(const char *log_string) return DEBUG_ERR; } -int debug_level_to_int(enum debug_level log_level) +/* + * file logging backend + */ + +struct file_log_state { + const char *app_name; + int fd; + char buffer[1024]; +}; + +static void file_log(void *private_data, int level, const char *msg) +{ + struct file_log_state *state = talloc_get_type_abort( + private_data, struct file_log_state); + struct timeval tv; + struct timeval_buf tvbuf; + int ret; + + if (state->fd == STDERR_FILENO) { + ret = snprintf(state->buffer, sizeof(state->buffer), + "%s[%u]: %s\n", + state->app_name, (unsigned)getpid(), msg); + } else { + GetTimeOfDay(&tv); + timeval_str_buf(&tv, false, true, &tvbuf); + + ret = snprintf(state->buffer, sizeof(state->buffer), + "%s %s[%u]: %s\n", tvbuf.buf, + state->app_name, (unsigned)getpid(), msg); + } + if (ret < 0) { + return; + } + + state->buffer[sizeof(state->buffer)-1] = '\0'; + + sys_write_v(state->fd, state->buffer, strlen(state->buffer)); +} + +static int file_log_state_destructor(struct file_log_state *state) +{ + if (state->fd != -1 && state->fd != STDERR_FILENO) { + close(state->fd); + state->fd = -1; + } + return 0; +} + +static int file_log_setup(TALLOC_CTX *mem_ctx, const char *option, + const char *app_name) +{ + struct file_log_state *state; + + state = talloc_zero(mem_ctx, struct file_log_state); + if (state == NULL) { + return ENOMEM; + } + + state->app_name = app_name; + + if (option == NULL || strcmp(option, "-") == 0) { + int ret; + + state->fd = STDERR_FILENO; + ret = dup2(STDERR_FILENO, STDOUT_FILENO); + if (ret == -1) { + int save_errno = errno; + talloc_free(state); + return save_errno; + } + + } else { + state->fd = open(option, O_WRONLY|O_APPEND|O_CREAT, 0644); + if (state->fd == -1) { + int save_errno = errno; + talloc_free(state); + return save_errno; + } + + if (! set_close_on_exec(state->fd)) { + int save_errno = errno; + talloc_free(state); + return save_errno; + } + } + + talloc_set_destructor(state, file_log_state_destructor); + debug_set_callback(state, file_log); + + return 0; +} + +/* + * syslog logging backend + */ + +/* Copied from lib/util/debug.c */ +static int debug_level_to_priority(int level) +{ + /* + * map debug levels to syslog() priorities + */ + static const int priority_map[] = { + LOG_ERR, /* 0 */ + LOG_WARNING, /* 1 */ + LOG_NOTICE, /* 2 */ + LOG_NOTICE, /* 3 */ + LOG_NOTICE, /* 4 */ + LOG_NOTICE, /* 5 */ + LOG_INFO, /* 6 */ + LOG_INFO, /* 7 */ + LOG_INFO, /* 8 */ + LOG_INFO, /* 9 */ + }; + int priority; + + if( level >= ARRAY_SIZE(priority_map) || level < 0) + priority = LOG_DEBUG; + else + priority = priority_map[level]; + + return priority; +} + +struct syslog_log_state { + int fd; + const char *app_name; + const char *hostname; + int (*format)(int dbglevel, struct syslog_log_state *state, + const char *str, char *buf, int bsize); + /* RFC3164 says: The total length of the packet MUST be 1024 + bytes or less. */ + char buffer[1024]; +}; + +/* 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 syslog_log_state *state, + const char *str, char *buf, int bsize) +{ + int pri; + int len; + + pri = LOG_DAEMON | debug_level_to_priority(dbglevel); + len = snprintf(buf, bsize, "<%d>%s[%u]: %s", + pri, state->app_name, getpid(), str); + buf[bsize-1] = '\0'; + 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 syslog_log_state *state, + const char *str, char *buf, int bsize) +{ + int pri; + struct timeval tv; + struct timeval_buf tvbuf; + int len, s; + + /* Header */ + pri = LOG_DAEMON | debug_level_to_priority(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", str); + buf[bsize-1] = '\0'; + len = MIN(len + s, bsize - 1); + + return len; +} + +static void syslog_log(void *private_data, int level, const char *msg) +{ + syslog(debug_level_to_priority(level), "%s", msg); +} + +static void syslog_log_sock(void *private_data, int level, const char *msg) +{ + struct syslog_log_state *state = talloc_get_type_abort( + private_data, struct syslog_log_state); + int n; + + n = state->format(level, state, msg, state->buffer, + sizeof(state->buffer)); + if (n == -1) { + return; + } + + sys_write_v(state->fd, state->buffer, n); +} + +static int syslog_log_setup_syslog(TALLOC_CTX *mem_ctx, const char *app_name) +{ + openlog(app_name, LOG_PID, LOG_DAEMON); + + debug_set_callback(NULL, syslog_log); + + return 0; +} + +static int syslog_log_state_destructor(struct syslog_log_state *state) +{ + if (state->fd != -1) { + close(state->fd); + state->fd = -1; + } + return 0; +} + +static int syslog_log_setup_common(TALLOC_CTX *mem_ctx, const char *app_name, + struct syslog_log_state **result) +{ + struct syslog_log_state *state; + + state = talloc_zero(mem_ctx, struct syslog_log_state); + if (state == NULL) { + return ENOMEM; + } + + state->fd = -1; + state->app_name = app_name; + talloc_set_destructor(state, syslog_log_state_destructor); + + return 0; +} + +#ifdef _PATH_LOG +static int syslog_log_setup_nonblocking(TALLOC_CTX *mem_ctx, + const char *app_name) { - return (int)log_level; + struct syslog_log_state *state = NULL; + struct sockaddr_un dest; + int ret; + + ret = syslog_log_setup_common(mem_ctx, app_name, &state); + if (ret != 0) { + return ret; + } + + 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; + } + + if (! set_close_on_exec(state->fd)) { + int save_errno = errno; + talloc_free(state); + return save_errno; + } + + state->hostname = NULL; /* Make this explicit */ + state->format = format_rfc3164; + + debug_set_callback(state, syslog_log_sock); + + return 0; } +#endif /* _PATH_LOG */ -enum debug_level debug_level_from_int(int level) +static int syslog_log_setup_udp(TALLOC_CTX *mem_ctx, const char *app_name, + bool rfc5424) { - enum debug_level log_level; + struct syslog_log_state *state = NULL; + struct sockaddr_in dest; + int ret; + + ret = syslog_log_setup_common(mem_ctx, app_name, &state); + if (ret != 0) { + return ret; + } + + 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; + } + + if (! set_close_on_exec(state->fd)) { + int save_errno = errno; + talloc_free(state); + return save_errno; + } - if (level >= 0 && level < ARRAY_SIZE(log_string_map)) { - log_level = log_string_map[level].log_level; + 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 { - log_level = DEBUG_ERR; + state->format = format_rfc3164; + } + + debug_set_callback(state, syslog_log_sock); + + return 0; +} + +static int syslog_log_setup(TALLOC_CTX *mem_ctx, const char *option, + const char *app_name) +{ + if (option == NULL) { + return syslog_log_setup_syslog(mem_ctx, app_name); -- Samba Shared Repository