[libvirt] [PATCH v2 08/13] qemu: convert log file creation to use qemuDomainLogContextPtr

Daniel P. Berrange berrange at redhat.com
Thu Nov 12 17:19:05 UTC 2015


Convert the places which create/open log files to use the new
qemuDomainLogContextPtr object instead.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 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




More information about the libvir-list mailing list