Re: [PATCH 6/6] Dump the debug buffer to libvirtd.log on fatal signal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Mar 03, 2011 at 06:22:17PM +0800, Daniel Veillard wrote:
> 
> 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 <veillard@xxxxxxxxxx>
> ---
>  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;
> +}

I think this code should really be part of the logging.c file. eg create
an API like:

   void virLogEmergencyDumpAll(int signum)


And have that dump the cached log buffer to all registered log outputs.
We'd have to excluding any syslog one which isn't async signal safe, but
the 'stderr' or 'file' log outputs can be made async signal safe.

Then, the libvirtd signal handler would just be

    static void sig_fatal(int sig, siginfo_t * siginfo ATTRIBUTE_UNUSED,
                      void* context ATTRIBUTE_UNUSED) {
         virLogEmergencyDumpAll(sig);
    }

Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]