--- src/logging/log_handler.c | 38 ++++++++++++++++++++++++++++++++++++-- src/logging/log_protocol.x | 5 +++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/logging/log_handler.c b/src/logging/log_handler.c index ca294a0..93b893b 100644 --- a/src/logging/log_handler.c +++ b/src/logging/log_handler.c @@ -23,6 +23,7 @@ #include <config.h> #include "log_handler.h" +#include "log_protocol.h" #include "virerror.h" #include "virobject.h" #include "virfile.h" @@ -54,10 +55,12 @@ struct _virLogHandlerLogFile { char *driver; unsigned char domuuid[VIR_UUID_BUFLEN]; char *domname; + char *path; }; struct _virLogHandler { virObjectLockable parent; + virCond condition; bool privileged; size_t max_size; @@ -102,6 +105,7 @@ virLogHandlerLogFileFree(virLogHandlerLogFilePtr file) VIR_FREE(file->driver); VIR_FREE(file->domname); + VIR_FREE(file->path); VIR_FREE(file); } @@ -137,6 +141,21 @@ virLogHandlerGetLogFileFromWatch(virLogHandlerPtr handler, } +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; +} + + static void virLogHandlerDomainLogFileEvent(int watch, int fd, @@ -179,6 +198,7 @@ virLogHandlerDomainLogFileEvent(int watch, error: handler->inhibitor(false, handler->opaque); virLogHandlerLogFileClose(handler, logfile); + virCondBroadcast(&handler->condition); virObjectUnlock(handler); } @@ -198,6 +218,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 +380,7 @@ virLogHandlerDispose(void *obj) virLogHandlerLogFileFree(handler->files[i]); } VIR_FREE(handler->files); + virCondDestroy(&handler->condition); } @@ -401,7 +425,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, @@ -492,10 +517,19 @@ virLogHandlerDomainReadLogFile(virLogHandlerPtr handler, char *data = NULL; ssize_t got; - virCheckFlags(0, NULL); + virCheckFlags(VIR_LOG_MANAGER_PROTOCOL_DOMAIN_READ_LOG_FILE_WAIT, NULL); virObjectLock(handler); + if (flags & VIR_LOG_MANAGER_PROTOCOL_DOMAIN_READ_LOG_FILE_WAIT) { + while (virLogHandlerGetLogFileFromPath(handler, path)) { + if (virCondWait(&handler->condition, &handler->parent.lock) < 0) { + virReportSystemError(errno, "%s", _("failed to wait for EOF")); + goto error; + } + } + } + if (!(file = virRotatingFileReaderNew(path, handler->max_backups))) goto error; diff --git a/src/logging/log_protocol.x b/src/logging/log_protocol.x index 2434043..194bc2e 100644 --- a/src/logging/log_protocol.x +++ b/src/logging/log_protocol.x @@ -34,6 +34,11 @@ enum virLogManagerProtocolDomainOpenLogFileFlags { VIR_LOG_MANAGER_PROTOCOL_DOMAIN_OPEN_LOG_FILE_TRUNCATE = 1 }; +enum virLogManagerProtocolDomainReadLogFileFlags { + /* wait until EOF from writing side */ + VIR_LOG_MANAGER_PROTOCOL_DOMAIN_READ_LOG_FILE_WAIT = 1 +}; + /* Obtain a file handle suitable for writing to a * log file for a domain */ -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list