]> xenbits.xensource.com Git - libvirt.git/commitdiff
virlog: Introduce virLogParseOutput
authorErik Skultety <eskultet@redhat.com>
Tue, 16 Aug 2016 14:27:47 +0000 (16:27 +0200)
committerErik Skultety <eskultet@redhat.com>
Mon, 10 Oct 2016 06:27:24 +0000 (08:27 +0200)
Introduce a method to parse an individual logging output. The difference
compared to the virLogParseAndDefineOutput is that this method does not define
the output, instead it makes use of the virLogNewOutputTo* methods introduced
in the previous patch and just returns the virLogOutput object that has to be
added to a list of object which then can be defined as a whole via
virLogDefineOutputs. The idea remains still the same - split parsing and
defining of the logging primitives (outputs, filters).
Additionally, since virLogNewOutputTo* methods are now finally used,
ATTRIBUTE_UNUSED can be successfully removed from the methods' definitions,
since that was just to avoid compiler complaints about unused static functions.

Signed-off-by: Erik Skultety <eskultet@redhat.com>
src/libvirt_private.syms
src/util/virlog.c
src/util/virlog.h

index 4a0acdf90b02e2aa1bc55984e06b2d8b59556a94..baeaef8d1850c73c8a7cdaf86313e1da2eaff40f 100644 (file)
@@ -1890,6 +1890,7 @@ virLogOutputNew;
 virLogParseAndDefineFilters;
 virLogParseAndDefineOutputs;
 virLogParseDefaultPriority;
+virLogParseOutput;
 virLogPriorityFromSyslog;
 virLogProbablyLogMessage;
 virLogReset;
index 9c98588f89daeb245c8f21a3598f4eb89fd5fb3d..9879c4fc6ad3e3e826d4091fcb559bdf33c24d30 100644 (file)
@@ -782,7 +782,7 @@ virLogAddOutputToStderr(virLogPriority priority)
 }
 
 
-static virLogOutputPtr ATTRIBUTE_UNUSED
+static virLogOutputPtr
 virLogNewOutputToStderr(virLogPriority priority)
 {
     return virLogOutputNew(virLogOutputToFd, NULL, (void *)STDERR_FILENO,
@@ -809,7 +809,7 @@ virLogAddOutputToFile(virLogPriority priority,
 }
 
 
-static virLogOutputPtr ATTRIBUTE_UNUSED
+static virLogOutputPtr
 virLogNewOutputToFile(virLogPriority priority,
                       const char *file)
 {
@@ -917,7 +917,7 @@ virLogAddOutputToSyslog(virLogPriority priority,
 }
 
 
-static virLogOutputPtr ATTRIBUTE_UNUSED
+static virLogOutputPtr
 virLogNewOutputToSyslog(virLogPriority priority,
                         const char *ident)
 {
@@ -1178,7 +1178,7 @@ static int virLogAddOutputToJournald(int priority)
 }
 
 
-static virLogOutputPtr ATTRIBUTE_UNUSED
+static virLogOutputPtr
 virLogNewOutputToJournald(int priority)
 {
     int journalfd;
@@ -1853,3 +1853,112 @@ virLogDefineFilters(virLogFilterPtr *filters, size_t nfilters)
 
     return 0;
 }
+
+
+/**
+ * virLogParseOutput:
+ * @src: string defining a single output
+ *
+ * The format of @src should be one of the following:
+ *    x:stderr - output is sent to stderr
+ *    x:journald - output is sent to journald
+ *    x:syslog:name - output is sent to syslog using 'name' as the message tag
+ *    x:file:abs_file_path - output is sent to file specified by 'abs_file_path'
+ *
+ *      'x' - minimal priority level which acts as a filter meaning that only
+ *            messages with priority level greater than or equal to 'x' will be
+ *            sent to output @src; supported values for 'x' are as follows:
+ *              1: DEBUG
+ *              2: INFO
+ *              3: WARNING
+ *              4: ERROR
+ *
+ * Parses @src string into a logging object type. If running in setuid mode,
+ * then only destination of type 'stderr' is permitted.
+ *
+ * Returns a newly created logging object from @src on success or NULL in case
+ * of an error.
+ */
+virLogOutputPtr
+virLogParseOutput(const char *src)
+{
+    virLogOutputPtr ret = NULL;
+    char **tokens = NULL;
+    char *abspath = NULL;
+    size_t count = 0;
+    virLogPriority prio;
+    int dest;
+    bool isSUID = virIsSUID();
+
+    VIR_DEBUG("output=%s", src);
+
+    /* split our format prio:destination:additional_data to tokens and parse
+     * them individually
+     */
+    if (!(tokens = virStringSplitCount(src, ":", 0, &count)) || count < 2) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Malformed format for output '%s'"), src);
+        return NULL;
+    }
+
+    if (virStrToLong_uip(tokens[0], NULL, 10, &prio) < 0 ||
+        (prio < VIR_LOG_DEBUG) || (prio > VIR_LOG_ERROR)) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Invalid priority '%s' for output '%s'"),
+                       tokens[0], src);
+        goto cleanup;
+    }
+
+    if ((dest = virLogDestinationTypeFromString(tokens[1])) < 0) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Invalid destination '%s' for output '%s'"),
+                       tokens[1], src);
+        goto cleanup;
+    }
+
+    if (((dest == VIR_LOG_TO_STDERR ||
+          dest == VIR_LOG_TO_JOURNALD) && count != 2) ||
+        ((dest == VIR_LOG_TO_FILE ||
+          dest == VIR_LOG_TO_SYSLOG) && count != 3)) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Output '%s' does not meet the format requirements "
+                         "for destination type '%s'"), src, tokens[1]);
+        goto cleanup;
+    }
+
+    /* if running with setuid, only 'stderr' is allowed */
+    if (isSUID && dest != VIR_LOG_TO_STDERR) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Running with SUID permits only destination of type "
+                         "'stderr'"));
+        goto cleanup;
+    }
+
+    switch ((virLogDestination) dest) {
+    case VIR_LOG_TO_STDERR:
+        ret = virLogNewOutputToStderr(prio);
+        break;
+    case VIR_LOG_TO_SYSLOG:
+#if HAVE_SYSLOG_H
+        ret = virLogNewOutputToSyslog(prio, tokens[2]);
+#endif
+        break;
+    case VIR_LOG_TO_FILE:
+        if (virFileAbsPath(tokens[2], &abspath) < 0)
+            goto cleanup;
+        ret = virLogNewOutputToFile(prio, abspath);
+        VIR_FREE(abspath);
+        break;
+    case VIR_LOG_TO_JOURNALD:
+#if USE_JOURNALD
+        ret = virLogNewOutputToJournald(prio);
+#endif
+        break;
+    case VIR_LOG_TO_OUTPUT_LAST:
+        break;
+    }
+
+ cleanup:
+    virStringFreeList(tokens);
+    return ret;
+}
index d6d65bad875cd9fa655e71b7cd7520525372dc34..e1cf81e109caefc65de30cec8553ac37f084ad4f 100644 (file)
@@ -240,5 +240,6 @@ int virLogFindOutput(virLogOutputPtr *outputs, size_t noutputs,
 int virLogDefineOutputs(virLogOutputPtr *outputs,
                         size_t noutputs) ATTRIBUTE_NONNULL(1);
 int virLogDefineFilters(virLogFilterPtr *filters, size_t nfilters);
+virLogOutputPtr virLogParseOutput(const char *src) ATTRIBUTE_NONNULL(1);
 
 #endif