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 <[email protected]>
---
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
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list