In case of imminent crash or upon request (signal USR2), dump the logging buffer to the libvirtd.log file for post-mortem analysis * daemon/libvirtd.c: create a sig_fatal() handler connected to SIGFPE SIGSEGV SIGILL SIGABRT SIGBUS and SIGUSR2, just dumping the log buffer to the libvirtd.log open file descriptor
Signed-off-by: Daniel Veillard <veill...@redhat.com> --- daemon/libvirtd.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index 42e8585..3338336 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -248,6 +248,45 @@ static void sig_handler(int sig, siginfo_t * siginfo, errno = origerrno; } +static int sig_fatal_dump(void *data ATTRIBUTE_UNUSED, + const char *buf, int len) { + int r; + + r = safewrite(logFD, buf, len); + return(r); +} + +static void sig_fatal(int sig, siginfo_t * siginfo ATTRIBUTE_UNUSED, + void* context ATTRIBUTE_UNUSED) { + struct sigaction sig_action; + int origerrno; + int r; + char buf[100]; + + origerrno = errno; + snprintf(buf, sizeof(buf) - 1, + "Caught signal %d, dumping internal log buffer:\n", sig); + buf[sizeof(buf) - 1] = 0; + r = safewrite(logFD, buf, strlen(buf)); + snprintf(buf, sizeof(buf) - 1, "\n\n ====== start of log =====\n\n"); + r = safewrite(logFD, buf, strlen(buf)); + virLogDump(NULL, sig_fatal_dump); + snprintf(buf, sizeof(buf) - 1, "\n\n ====== end of log =====\n\n"); + r = safewrite(logFD, buf, strlen(buf)); + fsync(logFD); + + /* + * If the signal is fatal, avoid looping over this handler + * by desactivating it + */ + if (sig != SIGUSR2) { + sig_action.sa_flags = SA_SIGINFO; + sig_action.sa_handler = SIG_IGN; + sigaction(sig, &sig_action, NULL); + } + errno = origerrno; +} + static void qemudDispatchClientEvent(int watch, int fd, int events, void *opaque); static void qemudDispatchServerEvent(int watch, int fd, int events, void *opaque); static int qemudStartWorker(struct qemud_server *server, struct qemud_worker *worker); @@ -3099,6 +3138,18 @@ daemonSetupSignals(struct qemud_server *server) sigaction(SIGQUIT, &sig_action, NULL); sigaction(SIGTERM, &sig_action, NULL); + /* + * catch fatal errors to dump a log, also hook to USR2 for dynamic + * debugging purposes or testing + */ + sig_action.sa_sigaction = sig_fatal; + sigaction(SIGFPE, &sig_action, NULL); + sigaction(SIGSEGV, &sig_action, NULL); + sigaction(SIGILL, &sig_action, NULL); + sigaction(SIGABRT, &sig_action, NULL); + sigaction(SIGBUS, &sig_action, NULL); + sigaction(SIGUSR2, &sig_action, NULL); + sig_action.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sig_action, NULL);
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list