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

ctdb-logging: Remove log ringbuffer

As far as we know, nobody uses this and it just complicates the
logging subsystem.

Remove all ringbuffer code and documentation.  Update the local
daemons startup code correspondingly.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Volker Lendecke <vl@samba.org>
This commit is contained in:
Martin Schwenke 2014-08-08 12:51:03 +10:00 committed by Volker Lendecke
parent 57bcb8055e
commit b544073653
16 changed files with 8 additions and 468 deletions

View File

@ -54,7 +54,7 @@ void ctdb_track_child(struct ctdb_context *ctdb, pid_t pid)
* This function forks a child process and drops the realtime
* scheduler for the child process.
*/
pid_t ctdb_fork_no_free_ringbuffer(struct ctdb_context *ctdb)
pid_t ctdb_fork(struct ctdb_context *ctdb)
{
pid_t pid;
@ -95,19 +95,6 @@ pid_t ctdb_fork_no_free_ringbuffer(struct ctdb_context *ctdb)
return pid;
}
pid_t ctdb_fork(struct ctdb_context *ctdb)
{
pid_t pid;
pid = ctdb_fork_no_free_ringbuffer(ctdb);
if (pid == 0) {
ctdb_log_ringbuffer_free();
}
return pid;
}
static void ctdb_sigchld_handler(struct tevent_context *ev,
struct tevent_signal *te, int signum, int count,
void *dont_care,

View File

@ -27,155 +27,6 @@ int LogLevel = DEBUG_NOTICE;
int this_log_level = 0;
const char *debug_extra = "";
int log_ringbuf_size;
#define MAX_LOG_SIZE 128
static int first_entry = 0;
static int ringbuf_count = 0;
struct ctdb_log_entry {
int32_t level;
struct timeval t;
char message[MAX_LOG_SIZE];
};
static struct ctdb_log_entry *log_entries;
/*
* this function logs all messages for all levels to a ringbuffer
*/
static void log_ringbuffer_v(const char *format, va_list ap)
{
int ret;
int next_entry;
if (log_entries == NULL && log_ringbuf_size != 0) {
/* Hope this works. We cant log anything if it doesnt anyway */
log_entries = malloc(sizeof(struct ctdb_log_entry) * log_ringbuf_size);
}
if (log_entries == NULL) {
return;
}
next_entry = (first_entry + ringbuf_count) % log_ringbuf_size;
if (ringbuf_count > 0 && first_entry == next_entry) {
first_entry = (first_entry + 1) % log_ringbuf_size;
}
log_entries[next_entry].message[0] = '\0';
ret = vsnprintf(&log_entries[next_entry].message[0], MAX_LOG_SIZE, format, ap);
if (ret == -1) {
return;
}
/* Log messages longer than MAX_LOG_SIZE are truncated to MAX_LOG_SIZE-1
* bytes. In that case, add a newline.
*/
if (ret >= MAX_LOG_SIZE) {
log_entries[next_entry].message[MAX_LOG_SIZE-2] = '\n';
}
log_entries[next_entry].level = this_log_level;
log_entries[next_entry].t = timeval_current();
if (ringbuf_count < log_ringbuf_size) {
ringbuf_count++;
}
}
void log_ringbuffer(const char *format, ...)
{
va_list ap;
va_start(ap, format);
log_ringbuffer_v(format, ap);
va_end(ap);
}
void ctdb_log_ringbuffer_free(void)
{
if (log_entries != NULL) {
free(log_entries);
log_entries = NULL;
}
log_ringbuf_size = 0;
}
TDB_DATA ctdb_log_ringbuffer_collect_log(TALLOC_CTX *mem_ctx,
enum debug_level max_level)
{
TDB_DATA data;
FILE *f;
long fsize;
int tmp_entry;
struct tm *tm;
char tbuf[100];
int i;
DEBUG(DEBUG_ERR,("Marshalling %d log entries\n", ringbuf_count));
/* dump to a file, then send the file as a blob */
f = tmpfile();
if (f == NULL) {
DEBUG(DEBUG_ERR,(__location__ " Unable to open tmpfile - %s\n",
strerror(errno)));
return tdb_null;
}
for (i=0; i<ringbuf_count; i++) {
tmp_entry = (first_entry + i) % log_ringbuf_size;
if (log_entries[tmp_entry].level > max_level) {
continue;
}
tm = localtime(&log_entries[tmp_entry].t.tv_sec);
strftime(tbuf, sizeof(tbuf)-1,"%Y/%m/%d %H:%M:%S", tm);
if (log_entries[tmp_entry].message[0] != '\0') {
fprintf(f, "%s:%s %s", tbuf,
get_debug_by_level(log_entries[tmp_entry].level),
log_entries[tmp_entry].message);
}
}
fsize = ftell(f);
if (fsize < 0) {
fclose(f);
DEBUG(DEBUG_ERR, ("Cannot get file size for log entries\n"));
return tdb_null;
}
rewind(f);
data.dptr = talloc_size(NULL, fsize);
if (data.dptr == NULL) {
fclose(f);
DEBUG(DEBUG_ERR, (__location__ " Memory allocation error\n"));
return tdb_null;
}
data.dsize = fread(data.dptr, 1, fsize, f);
fclose(f);
DEBUG(DEBUG_ERR,("Marshalling log entries into a blob of %d bytes\n", (int)data.dsize));
return data;
}
void ctdb_clear_log(struct ctdb_context *ctdb)
{
first_entry = 0;
ringbuf_count = 0;
}
int32_t ctdb_control_clear_log(struct ctdb_context *ctdb)
{
ctdb_clear_log(ctdb);
return 0;
}
struct debug_levels debug_levels[] = {
{DEBUG_EMERG, "EMERG"},
{DEBUG_ALERT, "ALERT"},

View File

@ -129,7 +129,6 @@ build_ctdb_options ()
maybe_set "--no-lmaster" "$CTDB_CAPABILITY_LMASTER" "no"
maybe_set "--lvs --single-public-ip" "$CTDB_LVS_PUBLIC_IP"
maybe_set "--script-log-level" "$CTDB_SCRIPT_LOG_LEVEL"
maybe_set "--log-ringbuf-size" "$CTDB_LOG_RINGBUF_SIZE"
maybe_set "--syslog" "$CTDB_SYSLOG" "yes"
maybe_set "--max-persistent-check-errors" "$CTDB_MAX_PERSISTENT_CHECK_ERRORS"
}

View File

@ -1184,44 +1184,6 @@ dbid:0xb775fff6 name:secrets.tdb path:/var/ctdb/persistent/secrets.tdb.0 PERSIST
</para>
</refsect2>
<refsect2>
<title>getlog [<parameter>LEVEL</parameter>] [recoverd]</title>
<para>
In addition to the normal logging to a log file, CTDB also
keeps a in-memory ringbuffer containing the most recent log
entries for all log levels (except DEBUG).
</para>
<para>
This is useful since it allows for keeping continuous logs to a file
at a reasonable non-verbose level, but shortly after an incident has
occured, a much more detailed log can be pulled from memory. This
can allow you to avoid having to reproduce an issue due to the
on-disk logs being of insufficient detail.
</para>
<para>
This command extracts all messages of level or lower log level
from memory and prints it to the screen. The level is not
specified it defaults to NOTICE.
</para>
<para>
By default, logs are extracted from the main CTDB daemon. If
the recoverd option is given then logs are extracted from the
recovery daemon.
</para>
</refsect2>
<refsect2>
<title>clearlog [recoverd]</title>
<para>
This command clears the in-memory logging ringbuffer.
</para>
<para>
By default, logs are cleared in the main CTDB daemon. If the
recoverd option is given then logs are cleared in the recovery
daemon.
</para>
</refsect2>
<refsect2>
<title>setdbreadonly <parameter>DB</parameter></title>
<para>

View File

@ -136,25 +136,6 @@
</listitem>
</varlistentry>
<varlistentry>
<term>--log-ringbuf-size=<parameter>NUM</parameter></term>
<listitem>
<para>
Set the size of the log ringbuffer to NUM entries.
</para>
<para>
CTDB uses an in-memory ringbuffer containing NUM most
recent log entries for all log levels (except DEBUG). The
ringbugger can be useful for extracting detailed logs even
if some entries are not logged to the regular logs.
</para>
<para>
Use the <command>ctdb getlog</command> command to retrieve
log entries from the ringbuffer.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>--lvs</term>
<listitem>

View File

@ -230,16 +230,6 @@
</listitem>
</varlistentry>
<varlistentry>
<term>CTDB_LOG_RINGBUF_SIZE=<parameter>NUM</parameter></term>
<listitem>
<para>
Default is 0. Corresponds to
<option>--log-ringbuf-size</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>CTDB_LVS_PUBLIC_IP=<parameter>IPADDR</parameter></term>
<listitem>

View File

@ -36,7 +36,7 @@ enum debug_level {
};
#define DEBUGLVL(lvl) ((lvl) <= LogLevel)
#define DEBUG(lvl, x) do { this_log_level = (lvl); if ((lvl) < DEBUG_DEBUG) { log_ringbuffer x; } if ((lvl) <= LogLevel) { do_debug x; }} while (0)
#define DEBUG(lvl, x) do { this_log_level = (lvl); if ((lvl) <= LogLevel) { do_debug x; }} while (0)
#define DEBUGADD(lvl, x) do { if ((lvl) <= LogLevel) { this_log_level = (lvl); do_debug_add x; }} while (0)
#endif /* _CTDB_LOGGING_H_ */

View File

@ -1096,7 +1096,6 @@ void reset_scheduler(void);
struct tevent_signal *ctdb_init_sigchld(struct ctdb_context *ctdb);
void ctdb_track_child(struct ctdb_context *ctdb, pid_t pid);
pid_t ctdb_fork(struct ctdb_context *ctdb);
pid_t ctdb_fork_no_free_ringbuffer(struct ctdb_context *ctdb);
void ctdb_set_child_info(TALLOC_CTX *mem_ctx, const char *child_name_fmt, ...);
bool ctdb_is_child_process(void);
int ctdb_kill(struct ctdb_context *ctdb, pid_t pid, int signum);
@ -1459,17 +1458,6 @@ struct ctdb_get_log_addr {
int32_t level;
};
extern int log_ringbuf_size;
enum debug_level;
TDB_DATA ctdb_log_ringbuffer_collect_log(TALLOC_CTX *mem_ctx,
enum debug_level max_level);
void ctdb_collect_log(struct ctdb_context *ctdb, struct ctdb_get_log_addr *log_addr);
void ctdb_clear_log(struct ctdb_context *ctdb);
int32_t ctdb_control_get_log(struct ctdb_context *ctdb, TDB_DATA addr);
int32_t ctdb_control_clear_log(struct ctdb_context *ctdb);
void ctdb_log_ringbuffer_free(void);
struct ctdb_log_state *ctdb_vfork_with_logging(TALLOC_CTX *mem_ctx,
struct ctdb_context *ctdb,
const char *log_prefix,

View File

@ -386,8 +386,8 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS = 0,
CTDB_CONTROL_REGISTER_NOTIFY = 114,
CTDB_CONTROL_DEREGISTER_NOTIFY = 115,
CTDB_CONTROL_TRANS2_ACTIVE = 116, /* obsolete */
CTDB_CONTROL_GET_LOG = 117,
CTDB_CONTROL_CLEAR_LOG = 118,
CTDB_CONTROL_GET_LOG = 117, /* obsolete */
CTDB_CONTROL_CLEAR_LOG = 118, /* obsolete */
CTDB_CONTROL_TRANS3_COMMIT = 119,
CTDB_CONTROL_GET_DB_SEQNUM = 120,
CTDB_CONTROL_DB_SET_HEALTHY = 121,

View File

@ -22,7 +22,6 @@
extern void (*do_debug_v)(const char *, va_list ap);
extern void (*do_debug_add_v)(const char *, va_list ap);
void log_ringbuffer(const char *format, ...);
void do_debug(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
void do_debug_add(const char *format, ...) PRINTF_ATTRIBUTE(1, 2);
void dump_data(int level, const uint8_t *buf1, size_t len);

View File

@ -619,11 +619,10 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
return ctdb_control_deregister_notify(ctdb, client_id, indata);
case CTDB_CONTROL_GET_LOG:
CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_get_log_addr));
return ctdb_control_get_log(ctdb, indata);
return control_not_implemented("GET_LOG", NULL);
case CTDB_CONTROL_CLEAR_LOG:
return ctdb_control_clear_log(ctdb);
return control_not_implemented("CLEAR_LOG", NULL);
case CTDB_CONTROL_GET_DB_SEQNUM:
CHECK_CONTROL_DATA_SIZE(sizeof(uint64_t));

View File

@ -643,45 +643,3 @@ int ctdb_init_tevent_logging(struct ctdb_context *ctdb)
ctdb);
return ret;
}
void ctdb_collect_log(struct ctdb_context *ctdb, struct ctdb_get_log_addr *log_addr)
{
TDB_DATA data;
data = ctdb_log_ringbuffer_collect_log(ctdb, log_addr->level);
DEBUG(DEBUG_ERR,("Send log to %d:%d\n", (int)log_addr->pnn, (int)log_addr->srvid));
ctdb_client_send_message(ctdb, log_addr->pnn, log_addr->srvid, data);
if (data.dptr) {
talloc_free(data.dptr);
}
}
int32_t ctdb_control_get_log(struct ctdb_context *ctdb, TDB_DATA addr)
{
struct ctdb_get_log_addr *log_addr = (struct ctdb_get_log_addr *)addr.dptr;
pid_t child;
/* spawn a child process to marshall the huge log blob and send it back
to the ctdb tool using a MESSAGE
*/
child = ctdb_fork_no_free_ringbuffer(ctdb);
if (child == (pid_t)-1) {
DEBUG(DEBUG_ERR,("Failed to fork a log collector child\n"));
return -1;
}
if (child == 0) {
ctdb_set_process_name("ctdb_log_collector");
if (switch_from_server_to_client(ctdb, "log-collector") != 0) {
DEBUG(DEBUG_CRIT, (__location__ "ERROR: failed to switch log collector child into client mode.\n"));
_exit(1);
}
/* do logging here */
ctdb_collect_log(ctdb, log_addr);
_exit(0);
}
return 0;
}

View File

@ -2339,47 +2339,6 @@ DEBUG(DEBUG_ERR, ("recovery master memory dump\n"));
talloc_free(tmp_ctx);
}
/*
handler for getlog
*/
static void getlog_handler(struct ctdb_context *ctdb, uint64_t srvid,
TDB_DATA data, void *private_data)
{
struct ctdb_get_log_addr *log_addr;
pid_t child;
if (data.dsize != sizeof(struct ctdb_get_log_addr)) {
DEBUG(DEBUG_ERR, (__location__ " Wrong size of return address.\n"));
return;
}
log_addr = (struct ctdb_get_log_addr *)data.dptr;
child = ctdb_fork_no_free_ringbuffer(ctdb);
if (child == (pid_t)-1) {
DEBUG(DEBUG_ERR,("Failed to fork a log collector child\n"));
return;
}
if (child == 0) {
ctdb_set_process_name("ctdb_rec_log_collector");
if (switch_from_server_to_client(ctdb, "recoverd-log-collector") != 0) {
DEBUG(DEBUG_CRIT, (__location__ "ERROR: failed to switch log collector child into client mode.\n"));
_exit(1);
}
ctdb_collect_log(ctdb, log_addr);
_exit(0);
}
}
/*
handler for clearlog
*/
static void clearlog_handler(struct ctdb_context *ctdb, uint64_t srvid,
TDB_DATA data, void *private_data)
{
ctdb_clear_log(ctdb);
}
/*
handler for reload_nodes
*/
@ -4172,12 +4131,6 @@ static void monitor_cluster(struct ctdb_context *ctdb)
/* register a message port for sending memory dumps */
ctdb_client_set_message_handler(ctdb, CTDB_SRVID_MEM_DUMP, mem_dump_handler, rec);
/* register a message port for requesting logs */
ctdb_client_set_message_handler(ctdb, CTDB_SRVID_GETLOG, getlog_handler, rec);
/* register a message port for clearing logs */
ctdb_client_set_message_handler(ctdb, CTDB_SRVID_CLEARLOG, clearlog_handler, rec);
/* register a message port for recovery elections */
ctdb_client_set_message_handler(ctdb, CTDB_SRVID_RECOVERY, election_handler, rec);
@ -4308,7 +4261,7 @@ int ctdb_start_recoverd(struct ctdb_context *ctdb)
return -1;
}
ctdb->recoverd_pid = ctdb_fork_no_free_ringbuffer(ctdb);
ctdb->recoverd_pid = ctdb_fork(ctdb);
if (ctdb->recoverd_pid == -1) {
return -1;
}
@ -4329,9 +4282,6 @@ int ctdb_start_recoverd(struct ctdb_context *ctdb)
srandom(getpid() ^ time(NULL));
/* Clear the log ringbuffer */
ctdb_clear_log(ctdb);
ctdb_set_process_name("ctdb_recovered");
if (switch_from_server_to_client(ctdb, "recoverd") != 0) {
DEBUG(DEBUG_CRIT, (__location__ "ERROR: failed to switch recovery daemon into client mode. shutting down.\n"));

View File

@ -134,7 +134,6 @@ int main(int argc, const char *argv[])
{ "max-persistent-check-errors", 0, POPT_ARG_INT,
&options.max_persistent_check_errors, 0,
"max allowed persistent check errors (default 0)", NULL },
{ "log-ringbuf-size", 0, POPT_ARG_INT, &log_ringbuf_size, 0, "Number of log messages we can store in the memory ringbuffer", NULL },
{ "sloppy-start", 0, POPT_ARG_NONE, &fast_start, 0, "Do not perform full recovery on start", NULL },
POPT_TABLEEND
};

View File

@ -97,7 +97,7 @@ daemons_start_1 ()
fi
local node_ip=$(sed -n -e "$(($pnn + 1))p" "$CTDB_NODES")
local ctdb_options="--sloppy-start --reclock=${TEST_VAR_DIR}/rec.lock --nlist $CTDB_NODES --nopublicipcheck --listen=${node_ip} --event-script-dir=${TEST_VAR_DIR}/events.d --logfile=${TEST_VAR_DIR}/daemon.${pnn}.log -d 3 --log-ringbuf-size=10000 --dbdir=${TEST_VAR_DIR}/test.db --dbdir-persistent=${TEST_VAR_DIR}/test.db/persistent --dbdir-state=${TEST_VAR_DIR}/test.db/state --nosetsched"
local ctdb_options="--sloppy-start --reclock=${TEST_VAR_DIR}/rec.lock --nlist $CTDB_NODES --nopublicipcheck --listen=${node_ip} --event-script-dir=${TEST_VAR_DIR}/events.d --logfile=${TEST_VAR_DIR}/daemon.${pnn}.log -d 3 --dbdir=${TEST_VAR_DIR}/test.db --dbdir-persistent=${TEST_VAR_DIR}/test.db/persistent --dbdir-state=${TEST_VAR_DIR}/test.db/state --nosetsched"
if [ $pnn -eq $no_public_ips ] ; then
ctdb_options="$ctdb_options --public-addresses=/dev/null"

View File

@ -4503,127 +4503,6 @@ static int control_chktcpport(struct ctdb_context *ctdb, int argc, const char **
}
static void log_handler(struct ctdb_context *ctdb, uint64_t srvid,
TDB_DATA data, void *private_data)
{
DEBUG(DEBUG_ERR,("Log data received\n"));
if (data.dsize > 0) {
printf("%s", data.dptr);
}
exit(0);
}
/*
display a list of log messages from the in memory ringbuffer
*/
static int control_getlog(struct ctdb_context *ctdb, int argc, const char **argv)
{
int ret, i;
bool main_daemon;
struct ctdb_get_log_addr log_addr;
TDB_DATA data;
struct timeval tv;
/* Process options */
main_daemon = true;
log_addr.pnn = ctdb_get_pnn(ctdb);
log_addr.level = DEBUG_NOTICE;
for (i = 0; i < argc; i++) {
if (strcmp(argv[i], "recoverd") == 0) {
main_daemon = false;
} else {
if (isalpha(argv[i][0]) || argv[i][0] == '-') {
log_addr.level = get_debug_by_desc(argv[i]);
} else {
log_addr.level = strtol(argv[i], NULL, 0);
}
}
}
/* Our message port is our PID */
log_addr.srvid = getpid();
data.dptr = (unsigned char *)&log_addr;
data.dsize = sizeof(log_addr);
DEBUG(DEBUG_ERR, ("Pulling logs from node %u\n", options.pnn));
ctdb_client_set_message_handler(ctdb, log_addr.srvid, log_handler, NULL);
sleep(1);
DEBUG(DEBUG_ERR,("Listen for response on %d\n", (int)log_addr.srvid));
if (main_daemon) {
int32_t res;
char *errmsg;
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_GET_LOG,
0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
if (ret != 0 || res != 0) {
DEBUG(DEBUG_ERR,("Failed to get logs - %s\n", errmsg));
talloc_free(tmp_ctx);
return -1;
}
talloc_free(tmp_ctx);
} else {
ret = ctdb_client_send_message(ctdb, options.pnn,
CTDB_SRVID_GETLOG, data);
if (ret != 0) {
DEBUG(DEBUG_ERR,("Failed to send getlog request message to %u\n", options.pnn));
return -1;
}
}
tv = timeval_current();
/* this loop will terminate when we have received the reply */
while (timeval_elapsed(&tv) < (double)options.timelimit) {
event_loop_once(ctdb->ev);
}
DEBUG(DEBUG_INFO,("Timed out waiting for log data.\n"));
return 0;
}
/*
clear the in memory log area
*/
static int control_clearlog(struct ctdb_context *ctdb, int argc, const char **argv)
{
int ret;
if (argc == 0 || (argc >= 1 && strcmp(argv[0], "recoverd") != 0)) {
/* "recoverd" not given - get logs from main daemon */
int32_t res;
char *errmsg;
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_CLEAR_LOG,
0, tdb_null, tmp_ctx, NULL, &res, NULL, &errmsg);
if (ret != 0 || res != 0) {
DEBUG(DEBUG_ERR,("Failed to clear logs\n"));
talloc_free(tmp_ctx);
return -1;
}
talloc_free(tmp_ctx);
} else {
TDB_DATA data; /* unused in recoverd... */
data.dsize = 0;
ret = ctdb_client_send_message(ctdb, options.pnn, CTDB_SRVID_CLEARLOG, data);
if (ret != 0) {
DEBUG(DEBUG_ERR,("Failed to send clearlog request message to %u\n", options.pnn));
return -1;
}
}
return 0;
}
/* Reload public IPs on a specified nodes */
static int control_reloadips(struct ctdb_context *ctdb, int argc, const char **argv)
{
@ -6356,8 +6235,6 @@ static const struct {
{ "enablemonitor", control_enable_monmode, true, false, "set monitoring mode to ACTIVE" },
{ "setdebug", control_setdebug, true, false, "set debug level", "<EMERG|ALERT|CRIT|ERR|WARNING|NOTICE|INFO|DEBUG>" },
{ "getdebug", control_getdebug, true, false, "get debug level" },
{ "getlog", control_getlog, true, false, "get the log data from the in memory ringbuffer", "[<level>] [recoverd]" },
{ "clearlog", control_clearlog, true, false, "clear the log data from the in memory ringbuffer", "[recoverd]" },
{ "attach", control_attach, true, false, "attach to a database", "<dbname> [persistent]" },
{ "detach", control_detach, false, false, "detach from a database", "<dbname|dbid> [<dbname|dbid> ...]" },
{ "dumpmemory", control_dumpmemory, true, false, "dump memory map to stdout" },