Continuing with the effort to split output parsing and defining, these new
functions return a logging object reference instead of defining the output.
Eventually, these functions will replace the existing ones (virLogAddOutputTo*)
which will then be dropped. Also, make the new functions non-static, so they
can be introduced prior to usage and the compiler won't complain (will be
switched back to static once the usage is sorted out by later patches).

Signed-off-by: Erik Skultety <eskul...@redhat.com>
---
 src/libvirt_private.syms |  4 ++
 src/util/virlog.c        | 98 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virlog.h        |  6 +++
 3 files changed, 108 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0bceba7..39b0270 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1857,6 +1857,10 @@ virLogGetNbOutputs;
 virLogGetOutputs;
 virLogLock;
 virLogMessage;
+virLogNewOutputToFile;
+virLogNewOutputToJournald;
+virLogNewOutputToStderr;
+virLogNewOutputToSyslog;
 virLogOutputFree;
 virLogOutputListFree;
 virLogOutputNew;
diff --git a/src/util/virlog.c b/src/util/virlog.c
index a74967b..c0b8b9a 100644
--- a/src/util/virlog.c
+++ b/src/util/virlog.c
@@ -780,6 +780,14 @@ virLogAddOutputToStderr(virLogPriority priority)
 }
 
 
+virLogOutputPtr
+virLogNewOutputToStderr(virLogPriority priority)
+{
+    return virLogOutputNew(virLogOutputToFd, NULL, (void *)2L, priority,
+                           VIR_LOG_TO_STDERR, NULL);
+}
+
+
 static int
 virLogAddOutputToFile(virLogPriority priority,
                       const char *file)
@@ -799,6 +807,27 @@ virLogAddOutputToFile(virLogPriority priority,
 }
 
 
+virLogOutputPtr
+virLogNewOutputToFile(virLogPriority priority,
+                      const char *file)
+{
+    int fd;
+    virLogOutputPtr ret = NULL;
+
+    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);
+        return NULL;
+    }
+    return ret;
+}
+
+
 #if HAVE_SYSLOG_H || USE_JOURNALD
 
 /* Compat in case we build with journald, but no syslog */
@@ -886,6 +915,51 @@ virLogAddOutputToSyslog(virLogPriority priority,
 }
 
 
+virLogOutputPtr
+virLogNewOutputToSyslog(virLogPriority priority,
+                        const char *ident)
+{
+    virLogOutputPtr ret = NULL;
+    int at = -1;
+
+    /* There are a couple of issues with syslog:
+     * 1) If we re-opened the connection by calling openlog now, it would 
change
+     * the message tag immediately which is not what we want, since we might be
+     * in the middle of parsing of a new set of outputs where anything still 
can
+     * go wrong and we would introduce an inconsistent state to the log. We're
+     * also not holding a lock on the logger if we tried to change the tag
+     * while other workers are actively logging.
+     *
+     * 2) Syslog keeps the open file descriptor private, so we can't just dup()
+     * it like we would do with files if an output already existed.
+     *
+     * If a syslog connection already exists changing the message tag has to be
+     * therefore special-cased and postponed until the very last moment.
+     */
+    if ((at = virLogFindOutput(virLogOutputs, virLogNbOutputs,
+                               VIR_LOG_TO_SYSLOG, NULL)) < 0) {
+        /*
+         * 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);
+    }
+
+    if (!(ret = virLogOutputNew(virLogOutputToSyslog, virLogCloseSyslog,
+                                NULL, priority, VIR_LOG_TO_SYSLOG, ident))) {
+        if (at < 0) {
+            closelog();
+            VIR_FREE(current_ident);
+        }
+        return NULL;
+    }
+    return ret;
+}
+
+
 # if USE_JOURNALD
 #  define IOVEC_SET(iov, data, size)            \
     do {                                        \
@@ -1102,6 +1176,30 @@ static int virLogAddOutputToJournald(int priority)
     }
     return 0;
 }
+
+
+virLogOutputPtr
+virLogNewOutputToJournald(int priority)
+{
+    virLogOutputPtr 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 (!(ret = virLogOutputNew(virLogOutputToJournald,
+                                virLogCloseJournald, NULL,
+                                priority, VIR_LOG_TO_JOURNALD, NULL))) {
+        VIR_LOG_CLOSE(journalfd);
+        return NULL;
+    }
+
+    return ret;
+}
 # endif /* USE_JOURNALD */
 
 int virLogPriorityFromSyslog(int priority)
diff --git a/src/util/virlog.h b/src/util/virlog.h
index e0fe008..e3d5243 100644
--- a/src/util/virlog.h
+++ b/src/util/virlog.h
@@ -239,5 +239,11 @@ int virLogFindOutput(virLogOutputPtr *outputs, size_t 
noutputs,
                      virLogDestination dest, const void *opaque);
 int virLogDefineOutputs(virLogOutputPtr *outputs, size_t noutputs);
 int virLogDefineFilters(virLogFilterPtr *filters, size_t nfilters);
+virLogOutputPtr virLogNewOutputToStderr(virLogPriority priority);
+virLogOutputPtr virLogNewOutputToFile(virLogPriority priority,
+                                      const char *file);
+virLogOutputPtr virLogNewOutputToSyslog(virLogPriority priority,
+                                        const char *ident);
+virLogOutputPtr virLogNewOutputToJournald(int priority);
 
 #endif
-- 
2.5.5

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to