virLogEmergencyDumpAll() allows to dump the content of the debug buffer from within a signal handler. It saves to all log file or stderr if none is found * src/util/logging.h src/util/logging.c: add the new API and cleanup the old virLogDump code * src/libvirt_private.syms: exports it as a private symbol Signed-off-by: Daniel Veillard <veillard@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/logging.c | 87 +++++++++++++++++++++++++++------------------ src/util/logging.h | 2 +- 3 files changed, 54 insertions(+), 36 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5e63a12..7c4b33a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -541,6 +541,7 @@ virRegisterStorageDriver; # logging.h virLogDefineFilter; virLogDefineOutput; +virLogEmergencyDumpAll; virLogGetDefaultPriority; virLogGetFilters; virLogGetNbFilters; diff --git a/src/util/logging.c b/src/util/logging.c index b946285..98e175e 100644 --- a/src/util/logging.c +++ b/src/util/logging.c @@ -129,6 +129,9 @@ static virLogPriority virLogDefaultPriority = VIR_LOG_DEFAULT; static int virLogResetFilters(void); static int virLogResetOutputs(void); +static int virLogOutputToFd(const char *category, int priority, + const char *funcname, long long linenr, + const char *str, int len, void *data); /* * Logs accesses must be serialized though a mutex @@ -277,50 +280,64 @@ static void virLogStr(const char *str, int len) { virLogUnlock(); } -#if 0 -/* - * Output the ring buffer +static void virLogDumpAllFD(const char *msg, int len) { + int i, found = 0; + + for (i = 0; i < virLogNbOutputs;i++) { + if (virLogOutputs[i].f == virLogOutputToFd) { + int fd = (long) virLogOutputs[i].data; + + if (fd >= 0) + ignore_value (safewrite(fd, msg, len)); + } + } + if (!found) + ignore_value (safewrite(STDERR_FILENO, msg, len)); +} + +/** + * virLogEmergencyDumpAll: + * @signum: the signal number + * + * Emergency function called, possibly from a signal handler. + * It need to output the debug ring buffer through the log + * output which are safe to use from a signal handler. + * In case none is found it is emitted to standard error. */ -static int virLogDump(void *data, virLogOutputFunc f) { - int ret = 0, tmp; +void +virLogEmergencyDumpAll(int signum) { + int ret = 0, len; + char buf[100]; + + if (virLogLen == 0) + return; - if ((virLogLen == 0) || (f == NULL)) - return 0; virLogLock(); - if (virLogStart + virLogLen < LOG_BUFFER_SIZE) { -push_end: - virLogBuffer[virLogStart + virLogLen] = 0; - tmp = f(data, &virLogBuffer[virLogStart], virLogLen); - if (tmp < 0) { - ret = -1; - goto error; - } - ret += tmp; - virLogStart += tmp; - virLogLen -= tmp; - } else { - tmp = LOG_BUFFER_SIZE - virLogStart; - ret = f(data, &virLogBuffer[virLogStart], tmp); - if (ret < 0) { - ret = -1; - goto error; - } - if (ret < tmp) { - virLogStart += ret; - virLogLen -= ret; + snprintf(buf, sizeof(buf) - 1, + "Caught signal %d, dumping internal log buffer:\n", signum); + buf[sizeof(buf) - 1] = 0; + virLogDumpAllFD(buf, strlen(buf)); + snprintf(buf, sizeof(buf) - 1, "\n\n ====== start of log =====\n\n"); + virLogDumpAllFD(buf, strlen(buf)); + while (virLogLen > 0) { + if (virLogStart + virLogLen < LOG_BUFFER_SIZE) { + virLogBuffer[virLogStart + virLogLen] = 0; + virLogDumpAllFD(&virLogBuffer[virLogStart], virLogLen); + ret += virLogLen; + virLogStart += virLogLen; + virLogLen = 0; } else { + len = LOG_BUFFER_SIZE - virLogStart; + virLogBuffer[LOG_BUFFER_SIZE] = 0; + virLogDumpAllFD(&virLogBuffer[virLogStart], len); + virLogLen -= len; virLogStart = 0; - virLogLen -= tmp; - /* dump the second part */ - if (virLogLen > 0) - goto push_end; } } -error: + snprintf(buf, sizeof(buf) - 1, "\n\n ====== end of log =====\n\n"); + virLogDumpAllFD(buf, strlen(buf)); virLogUnlock(); - return ret; } -#endif /** * virLogSetDefaultPriority: diff --git a/src/util/logging.h b/src/util/logging.h index 2e2734e..c168dff 100644 --- a/src/util/logging.h +++ b/src/util/logging.h @@ -133,5 +133,5 @@ extern int virLogParseOutputs(const char *output); extern void virLogMessage(const char *category, int priority, const char *funcname, long long linenr, int flags, const char *fmt, ...) ATTRIBUTE_FMT_PRINTF(6, 7); - +extern void virLogEmergencyDumpAll(int signum); #endif
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list