[libvirt] [PATCH REPOST 24/38] virlog: Make use of virLogOutputExists

Erik Skultety eskultet at redhat.com
Wed May 4 14:30:35 UTC 2016


Start using the method that was introduced and described by commit 29d0068b.
---
 src/util/virlog.c | 83 ++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 58 insertions(+), 25 deletions(-)

diff --git a/src/util/virlog.c b/src/util/virlog.c
index 204372f..62533b1 100644
--- a/src/util/virlog.c
+++ b/src/util/virlog.c
@@ -344,10 +344,17 @@ virLogResetOutputs(void)
 void
 virLogOutputFree(virLogOutputPtr output)
 {
+    virLogOutputPtr tmp = NULL;
+
     if (!output)
         return;
 
-    if (output->c)
+    /* @output shall be closed only if such output does not already exist
+     * in the global list of outputs or @output itself is part of the global
+     * list of outputs
+     */
+    tmp = virLogOutputExists(output->dest, output->name);
+    if (output->c && (!tmp || tmp == output))
         output->c(output->data);
     VIR_FREE(output->name);
     VIR_FREE(output);
@@ -733,16 +740,21 @@ virLogNewOutputToFile(virLogPriority priority,
                       const char *file)
 {
     int fd;
-    virLogOutputPtr ret = NULL;
+    virLogOutputPtr gref, ret = NULL;
 
-    fd = open(file, O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
-    if (fd < 0)
-        return NULL;
+    if ((gref = virLogOutputExists(VIR_LOG_TO_FILE, file))) {
+        fd = (intptr_t) gref->data;
+    } else {
+        fd = open(file, O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
+        if (fd < 0)
+           return NULL;
+    }
 
     if (!(ret = virLogOutputNew(virLogOutputToFd, virLogCloseFd,
                                 (void *)(intptr_t)fd,
                                 priority, VIR_LOG_TO_FILE, file))) {
-        VIR_LOG_CLOSE(fd);
+        if (!gref)
+            VIR_LOG_CLOSE(fd);
         return NULL;
     }
     return ret;
@@ -818,21 +830,39 @@ static virLogOutputPtr
 virLogNewOutputToSyslog(virLogPriority priority,
                         const char *ident)
 {
-    virLogOutputPtr ret = NULL;
-
-    /*
-     * ident needs to be kept around on Solaris
+    virLogOutputPtr gref, ret = NULL;
+
+    /* syslog suffers from several issues:
+     * 1) Every other call to openlog would be a NOOP, but we can't close the
+     * existing connection just yet, because we're not holding the lock and
+     * the output cannot be changed until we're sure nothing can go wrong and
+     * we just swap our new list of outputs with the old global one.
+     *
+     * 2) Syslog keeps the open file descriptor private, so we can't just copy
+     * it like we do it with files if an output to syslog already exists and
+     * even if it did, there is no other way than to issue openlog if user
+     * wants to change ident.
+     *
+     * Therefore, dealing with syslog has to be special-cased and postponed
+     * until the very last moment.
      */
-    VIR_FREE(current_ident);
-    if (VIR_STRDUP(current_ident, ident) < 0)
-        return NULL;
+    if (!(gref = virLogOutputExists(VIR_LOG_TO_SYSLOG, NULL))) {
+        /*
+         * rather than copying @ident, syslog uses caller's reference instead
+         */
+        VIR_FREE(current_ident);
+        if (VIR_STRDUP(current_ident, ident) < 0)
+            return NULL;
+
+        openlog(current_ident, 0, 0);
+    }
 
-    openlog(current_ident, 0, 0);
     if (!(ret = virLogOutputNew(virLogOutputToSyslog, virLogCloseSyslog,
-                                NULL, priority, VIR_LOG_TO_SYSLOG,
-                                ident))) {
-        closelog();
-        VIR_FREE(current_ident);
+                                NULL, priority, VIR_LOG_TO_SYSLOG, ident))) {
+        if (!gref) {
+            closelog();
+            VIR_FREE(current_ident);
+        }
         return NULL;
     }
     return ret;
@@ -1043,19 +1073,22 @@ static void virLogCloseJournald(void *data ATTRIBUTE_UNUSED)
 
 static virLogOutputPtr virLogNewOutputToJournald(int priority)
 {
-    virLogOutputPtr ret = NULL;
+    virLogOutputPtr gref, ret = NULL;
 
-    if ((journalfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
-        return NULL;
-    if (virSetInherit(journalfd, false) < 0) {
-        VIR_LOG_CLOSE(journalfd);
-        return NULL;
+    if (!(gref = virLogOutputExists(VIR_LOG_TO_JOURNALD, NULL))) {
+        if ((journalfd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
+            return NULL;
+        if (virSetInherit(journalfd, false) < 0) {
+            VIR_LOG_CLOSE(journalfd);
+            return NULL;
+        }
     }
 
     if (!(ret = virLogOutputNew(virLogOutputToJournald,
                                 virLogCloseJournald, NULL,
                                 priority, VIR_LOG_TO_JOURNALD, NULL))) {
-        VIR_LOG_CLOSE(journalfd);
+        if (!gref)
+            VIR_LOG_CLOSE(journalfd);
         return NULL;
     }
 
-- 
2.4.11




More information about the libvir-list mailing list