Convert the places which create/open log files to use the new qemuDomainLogContextPtr object instead. Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/qemu/qemu_domain.c | 100 +++++------------------------------------------- src/qemu/qemu_domain.h | 2 - src/qemu/qemu_process.c | 78 +++++++++++++++++-------------------- 3 files changed, 46 insertions(+), 134 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e92f8b4..f3bb8d4 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2406,108 +2406,29 @@ void qemuDomainLogContextFree(qemuDomainLogContextPtr ctxt) } -static int -qemuDomainOpenLogHelper(virQEMUDriverConfigPtr cfg, - virDomainObjPtr vm, - int oflags, - mode_t mode) -{ - char *logfile; - int fd = -1; - bool trunc = false; - - if (virAsprintf(&logfile, "%s/%s.log", cfg->logDir, vm->def->name) < 0) - return -1; - - /* To make SELinux happy we always need to open in append mode. - * So we fake O_TRUNC by calling ftruncate after open instead - */ - if (oflags & O_TRUNC) { - oflags &= ~O_TRUNC; - oflags |= O_APPEND; - trunc = true; - } - - if ((fd = open(logfile, oflags, mode)) < 0) { - virReportSystemError(errno, _("failed to create logfile %s"), - logfile); - goto cleanup; - } - if (virSetCloseExec(fd) < 0) { - virReportSystemError(errno, _("failed to set close-on-exec flag on %s"), - logfile); - VIR_FORCE_CLOSE(fd); - goto cleanup; - } - if (trunc && - ftruncate(fd, 0) < 0) { - virReportSystemError(errno, _("failed to truncate %s"), - logfile); - VIR_FORCE_CLOSE(fd); - goto cleanup; - } - - cleanup: - VIR_FREE(logfile); - return fd; -} - - -int -qemuDomainCreateLog(virQEMUDriverPtr driver, virDomainObjPtr vm, - bool append) -{ - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); - int oflags; - int ret; - - oflags = O_CREAT | O_WRONLY; - /* Only logrotate files in /var/log, so only append if running privileged */ - if (virQEMUDriverIsPrivileged(driver) || append) - oflags |= O_APPEND; - else - oflags |= O_TRUNC; - - ret = qemuDomainOpenLogHelper(cfg, vm, oflags, S_IRUSR | S_IWUSR); - virObjectUnref(cfg); - return ret; -} - - -int -qemuDomainOpenLog(virQEMUDriverPtr driver, virDomainObjPtr vm) -{ - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); - int fd; - - fd = qemuDomainOpenLogHelper(cfg, vm, O_RDONLY, 0); - virObjectUnref(cfg); - if (fd < 0) - return -1; - - return fd; -} - - int qemuDomainAppendLog(virQEMUDriverPtr driver, virDomainObjPtr obj, int logFD, const char *fmt, ...) { - int fd = logFD; va_list argptr; char *message = NULL; int ret = -1; + qemuDomainLogContextPtr logCtxt = NULL; va_start(argptr, fmt); - if ((fd == -1) && - (fd = qemuDomainCreateLog(driver, obj, true)) < 0) - goto cleanup; + if (logFD == -1) { + logCtxt = qemuDomainLogContextNew(driver, obj, + QEMU_DOMAIN_LOG_CONTEXT_MODE_ATTACH); + if (!logCtxt) + goto cleanup; + logFD = qemuDomainLogContextGetWriteFD(logCtxt); + } if (virVasprintf(&message, fmt, argptr) < 0) goto cleanup; - if (safewrite(fd, message, strlen(message)) < 0) { + if (safewrite(logFD, message, strlen(message)) < 0) { virReportSystemError(errno, _("Unable to write to domain logfile %s"), obj->def->name); goto cleanup; @@ -2518,8 +2439,7 @@ int qemuDomainAppendLog(virQEMUDriverPtr driver, cleanup: va_end(argptr); - if (fd != logFD) - VIR_FORCE_CLOSE(fd); + qemuDomainLogContextFree(logCtxt); VIR_FREE(message); return ret; diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index fa0b14c..51820d8 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -371,8 +371,6 @@ off_t qemuDomainLogContextGetPosition(qemuDomainLogContextPtr ctxt); void qemuDomainLogContextRef(qemuDomainLogContextPtr ctxt); void qemuDomainLogContextFree(qemuDomainLogContextPtr ctxt); -int qemuDomainCreateLog(virQEMUDriverPtr driver, virDomainObjPtr vm, bool append); -int qemuDomainOpenLog(virQEMUDriverPtr driver, virDomainObjPtr vm); int qemuDomainAppendLog(virQEMUDriverPtr driver, virDomainObjPtr vm, int logFD, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index c09e9dc..e433548 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1907,16 +1907,18 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob, virQEMUCapsPtr qemuCaps, - off_t pos) + qemuDomainLogContextPtr logCtxt) { int ret = -1; virHashTablePtr info = NULL; qemuDomainObjPrivatePtr priv; int logfd = -1; + off_t pos = -1; - if (pos != (off_t)-1 && - (logfd = qemuDomainOpenLog(driver, vm)) < 0) - goto cleanup; + if (logCtxt) { + logfd = qemuDomainLogContextGetReadFD(logCtxt); + pos = qemuDomainLogContextGetPosition(logCtxt); + } VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name); if (qemuConnectMonitor(driver, vm, asyncJob, logfd, pos) < 0) @@ -1953,9 +1955,6 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver, ret = -1; } - - VIR_FORCE_CLOSE(logfd); - return ret; } @@ -4114,9 +4113,8 @@ int qemuProcessStart(virConnectPtr conn, { int ret = -1; int rv; - off_t pos = -1; - char ebuf[1024]; int logfile = -1; + qemuDomainLogContextPtr logCtxt = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; virCommandPtr cmd = NULL; struct qemuProcessHookData hookData; @@ -4354,8 +4352,10 @@ int qemuProcessStart(virConnectPtr conn, } VIR_DEBUG("Creating domain log file"); - if ((logfile = qemuDomainCreateLog(driver, vm, false)) < 0) + if (!(logCtxt = qemuDomainLogContextNew(driver, vm, + QEMU_DOMAIN_LOG_CONTEXT_MODE_START))) goto error; + logfile = qemuDomainLogContextGetWriteFD(logCtxt); if (vm->def->virtType == VIR_DOMAIN_VIRT_KVM) { VIR_DEBUG("Checking for KVM availability"); @@ -4522,11 +4522,7 @@ int qemuProcessStart(virConnectPtr conn, qemuDomainObjCheckTaint(driver, vm, logfile); - if ((pos = lseek(logfile, 0, SEEK_END)) < 0) { - VIR_WARN("Unable to seek to end of logfile: %s", - virStrerror(errno, ebuf, sizeof(ebuf))); - pos = 0; - } + qemuDomainLogContextMarkPosition(logCtxt); VIR_DEBUG("Clear emulator capabilities: %d", cfg->clearEmulatorCapabilities); @@ -4620,11 +4616,11 @@ int qemuProcessStart(virConnectPtr conn, VIR_DEBUG("Waiting for handshake from child"); if (virCommandHandshakeWait(cmd) < 0) { /* Read errors from child that occurred between fork and exec. */ - int logfd = qemuDomainOpenLog(driver, vm); + int logfd = qemuDomainLogContextGetReadFD(logCtxt); + off_t pos = qemuDomainLogContextGetPosition(logCtxt); if (logfd >= 0) { qemuProcessReportLogError(logfd, pos, _("Process exited prior to exec")); - VIR_FORCE_CLOSE(logfd); } goto error; } @@ -4691,7 +4687,7 @@ int qemuProcessStart(virConnectPtr conn, goto error; VIR_DEBUG("Waiting for monitor to show up"); - if (qemuProcessWaitForMonitor(driver, vm, asyncJob, priv->qemuCaps, pos) < 0) + if (qemuProcessWaitForMonitor(driver, vm, asyncJob, priv->qemuCaps, logCtxt) < 0) goto error; /* Failure to connect to agent shouldn't be fatal */ @@ -4854,7 +4850,7 @@ int qemuProcessStart(virConnectPtr conn, cleanup: virCommandFree(cmd); - VIR_FORCE_CLOSE(logfile); + qemuDomainLogContextFree(logCtxt); virObjectUnref(cfg); virObjectUnref(caps); VIR_FREE(nicindexes); @@ -4868,6 +4864,9 @@ int qemuProcessStart(virConnectPtr conn, * pretend we never started it */ if (priv->mon) qemuMonitorSetDomainLog(priv->mon, -1, -1); + /* Must close log now to allow ProcessSto to re-open it */ + qemuDomainLogContextFree(logCtxt); + logCtxt = NULL; qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags); goto cleanup; @@ -4919,11 +4918,11 @@ void qemuProcessStop(virQEMUDriverPtr driver, virDomainDefPtr def; virNetDevVPortProfilePtr vport = NULL; size_t i; - int logfile = -1; char *timestamp; char *tmppath = NULL; char ebuf[1024]; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + qemuDomainLogContextPtr logCtxt = NULL; VIR_DEBUG("Shutting down vm=%p name=%s id=%d pid=%llu flags=%x", vm, vm->def->name, vm->def->id, @@ -4952,12 +4951,9 @@ void qemuProcessStop(virQEMUDriverPtr driver, /* Wake up anything waiting on domain condition */ virDomainObjBroadcast(vm); - if ((logfile = qemuDomainCreateLog(driver, vm, true)) < 0) { - /* To not break the normal domain shutdown process, skip the - * timestamp log writing if failed on opening log file. */ - VIR_WARN("Unable to open logfile: %s", - virStrerror(errno, ebuf, sizeof(ebuf))); - } else { + if ((logCtxt = qemuDomainLogContextNew(driver, vm, + QEMU_DOMAIN_LOG_CONTEXT_MODE_STOP))) { + int logfile = qemuDomainLogContextGetWriteFD(logCtxt); if ((timestamp = virTimeStringNow()) != NULL) { if (safewrite(logfile, timestamp, strlen(timestamp)) < 0 || safewrite(logfile, SHUTDOWN_POSTFIX, @@ -4968,10 +4964,7 @@ void qemuProcessStop(virQEMUDriverPtr driver, VIR_FREE(timestamp); } - - if (VIR_CLOSE(logfile) < 0) - VIR_WARN("Unable to close logfile: %s", - virStrerror(errno, ebuf, sizeof(ebuf))); + qemuDomainLogContextFree(logCtxt); } /* Clear network bandwidth */ @@ -5232,6 +5225,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, size_t i; char ebuf[1024]; int logfile = -1; + qemuDomainLogContextPtr logCtxt = NULL; char *timestamp; qemuDomainObjPrivatePtr priv = vm->privateData; bool running = true; @@ -5326,8 +5320,10 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, goto error; VIR_DEBUG("Creating domain log file"); - if ((logfile = qemuDomainCreateLog(driver, vm, false)) < 0) + if (!(logCtxt = qemuDomainLogContextNew(driver, vm, + QEMU_DOMAIN_LOG_CONTEXT_MODE_ATTACH))) goto error; + logfile = qemuDomainLogContextGetWriteFD(logCtxt); VIR_DEBUG("Determining emulator version"); virObjectUnref(priv->qemuCaps); @@ -5356,22 +5352,20 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, goto error; } - if ((timestamp = virTimeStringNow()) == NULL) { + if ((timestamp = virTimeStringNow()) == NULL) goto error; - } else { - if (safewrite(logfile, timestamp, strlen(timestamp)) < 0 || - safewrite(logfile, ATTACH_POSTFIX, strlen(ATTACH_POSTFIX)) < 0) { - VIR_WARN("Unable to write timestamp to logfile: %s", - virStrerror(errno, ebuf, sizeof(ebuf))); - } - VIR_FREE(timestamp); + if (safewrite(logfile, timestamp, strlen(timestamp)) < 0 || + safewrite(logfile, ATTACH_POSTFIX, strlen(ATTACH_POSTFIX)) < 0) { + VIR_WARN("Unable to write timestamp to logfile: %s", + virStrerror(errno, ebuf, sizeof(ebuf))); } + VIR_FREE(timestamp); qemuDomainObjTaint(driver, vm, VIR_DOMAIN_TAINT_EXTERNAL_LAUNCH, logfile); VIR_DEBUG("Waiting for monitor to show up"); - if (qemuProcessWaitForMonitor(driver, vm, QEMU_ASYNC_JOB_NONE, priv->qemuCaps, -1) < 0) + if (qemuProcessWaitForMonitor(driver, vm, QEMU_ASYNC_JOB_NONE, priv->qemuCaps, NULL) < 0) goto error; /* Failure to connect to agent shouldn't be fatal */ @@ -5449,7 +5443,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, goto error; } - VIR_FORCE_CLOSE(logfile); + qemuDomainLogContextFree(logCtxt); VIR_FREE(seclabel); VIR_FREE(sec_managers); virObjectUnref(cfg); @@ -5466,7 +5460,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, if (active && virAtomicIntDecAndTest(&driver->nactive) && driver->inhibitCallback) driver->inhibitCallback(false, driver->inhibitOpaque); - VIR_FORCE_CLOSE(logfile); + qemuDomainLogContextFree(logCtxt); VIR_FREE(seclabel); VIR_FREE(sec_managers); if (seclabelgen) -- 2.5.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list