[libvirt] [PATCH 2/2] log: drain log of exiting qemu process carefully

Daniel P. Berrange berrange at redhat.com
Mon Sep 12 11:36:43 UTC 2016


On Mon, Sep 12, 2016 at 02:12:10PM +0300, Nikolay Shirokovskiy wrote:
> Read API call of logger daemon is used to get extra
> information from terminated qemu process. For this purpose
> we need to wait until qemu process finishes its writing to log.
> We need to:
> 
> 1. Read until EOF.
> 2. Don't stop reading on hangup.
> 
> virtlogd will not receive EOF as both qemu and libvirtd
> keep logging pipe descriptor. Thus let's close it after
> qemu process startup is finished as it will not be used
> anymore. All following logging on behalf of qemu by libvirt
> is done either thru daemon API or by receiving new
> writing descriptor.
> 
> Beware, qemuDomainLogContextFree is unref actually.
> ---
>  src/logging/log_handler.c | 39 +++++++++++++++++++++++++++++++++++++--
>  src/qemu/qemu_domain.c    |  4 ++++
>  src/qemu/qemu_domain.h    |  1 +
>  src/qemu/qemu_process.c   |  2 ++
>  4 files changed, 44 insertions(+), 2 deletions(-)

Any virtlogd changes should really be in separate commits from
any QEMU changes. virtlogd is intended to be a reusable component
of libvirt for multiple use cases, so any changes to it need to
described & justifiable independently of any QEMU changes.


> +static virLogHandlerLogFilePtr
> +virLogHandlerGetLogFileFromPath(virLogHandlerPtr handler,
> +                                const char* path)
> +{
> +    size_t i;
> +
> +    for (i = 0; i < handler->nfiles; i++) {
> +        if (STREQ(handler->files[i]->path, path))
> +            return handler->files[i];
> +    }
> +
> +    return NULL;
> +}

> @@ -167,11 +185,14 @@ virLogHandlerDomainLogFileEvent(int watch,
>          goto error;
>      }
>  
> +    if (len == 0)
> +        goto error;
> +
>      if (virRotatingFileWriterAppend(logfile->file, buf, len) != len)
>          goto error;
>  
>      if (events & VIR_EVENT_HANDLE_HANGUP)
> -        goto error;
> +        goto reread;

This patch hunk seems to be indendant of the other changes in this
file. It is a straightfoward bugfix to ensure we full read all data
before handling the hangup. So it should be a separate commit too.

>  
>      virObjectUnlock(handler);
>      return;
> @@ -179,6 +200,7 @@ virLogHandlerDomainLogFileEvent(int watch,
>   error:
>      handler->inhibitor(false, handler->opaque);
>      virLogHandlerLogFileClose(handler, logfile);
> +    virCondBroadcast(&handler->condition);
>      virObjectUnlock(handler);
>  }
>  
> @@ -198,6 +220,9 @@ virLogHandlerNew(bool privileged,
>      if (!(handler = virObjectLockableNew(virLogHandlerClass)))
>          goto error;
>  
> +    if (virCondInit(&handler->condition) < 0)
> +        goto error;
> +
>      handler->privileged = privileged;
>      handler->max_size = max_size;
>      handler->max_backups = max_backups;
> @@ -357,6 +382,7 @@ virLogHandlerDispose(void *obj)
>          virLogHandlerLogFileFree(handler->files[i]);
>      }
>      VIR_FREE(handler->files);
> +    virCondDestroy(&handler->condition);
>  }
>  
>  
> @@ -401,7 +427,8 @@ virLogHandlerDomainOpenLogFile(virLogHandlerPtr handler,
>      pipefd[0] = -1;
>      memcpy(file->domuuid, domuuid, VIR_UUID_BUFLEN);
>      if (VIR_STRDUP(file->driver, driver) < 0 ||
> -        VIR_STRDUP(file->domname, domname) < 0)
> +        VIR_STRDUP(file->domname, domname) < 0 ||
> +        VIR_STRDUP(file->path, path) < 0)
>          goto error;
>  
>      if ((file->file = virRotatingFileWriterNew(path,
> @@ -496,6 +523,14 @@ virLogHandlerDomainReadLogFile(virLogHandlerPtr handler,
>  
>      virObjectLock(handler);
>  
> +    while (virLogHandlerGetLogFileFromPath(handler, path)) {
> +        if (virCondWait(&handler->condition, &handler->parent.lock) < 0) {
> +            virReportSystemError(errno, "%s",
> +                                 _("failed to wait for EOF"));
> +            goto error;
> +        }
> +    }

Ewww no - this code is not only intended for use from codepath where
QEMU is shutdown. It absolutely should be able to read from a log
where QEMU is still running.

Regards,
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 :|




More information about the libvir-list mailing list