]> xenbits.xensource.com Git - libvirt.git/commitdiff
virlog: Introduce virLogParseOutputs
authorErik Skultety <eskultet@redhat.com>
Wed, 5 Oct 2016 14:29:15 +0000 (16:29 +0200)
committerErik Skultety <eskultet@redhat.com>
Mon, 10 Oct 2016 06:27:25 +0000 (08:27 +0200)
Another abstraction added on the top of parsing a single logging output. This
method takes and parses the whole set of outputs, adding each single output
that has already been parsed into a caller-provided array. If the user-supplied
string contained duplicate outputs, only the last occurrence is taken into
account (all the others are removed from the list), so we silently avoid
duplicate logs.

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

index 24ac57041afa2e7cb685a67e39755221e3e1348a..f2e7965ba55891985bdea0ab612155b6c95d7920 100644 (file)
@@ -1892,6 +1892,7 @@ virLogParseAndDefineOutputs;
 virLogParseDefaultPriority;
 virLogParseFilter;
 virLogParseOutput;
+virLogParseOutputs;
 virLogPriorityFromSyslog;
 virLogProbablyLogMessage;
 virLogReset;
index 150deb3d4ed41aa3dc51bc0d374a28d5c09c1039..433405a170b159dd4b33b6df10043194949a13d7 100644 (file)
@@ -2039,3 +2039,63 @@ virLogParseFilter(const char *src)
     virStringFreeList(tokens);
     return ret;
 }
+
+/**
+ * virLogParseOutputs:
+ * @src: string defining a (set of) output(s)
+ * @outputs: user-supplied list where parsed outputs from @src shall be stored
+ *
+ * Parses a (set of) output(s) into a list of logging objects. Multiple outputs
+ * can be defined within @src string, they just need to be separated by spaces.
+ * If running in setuid mode, then only the 'stderr' output will be allowed.
+ *
+ * Returns the number of outputs parsed or -1 in case of error.
+ */
+int
+virLogParseOutputs(const char *src, virLogOutputPtr **outputs)
+{
+    int ret = -1;
+    int at = -1;
+    size_t noutputs = 0;
+    size_t i, count;
+    char **strings = NULL;
+    virLogOutputPtr output = NULL;
+    virLogOutputPtr *list = NULL;
+
+    VIR_DEBUG("outputs=%s", src);
+
+    if (!(strings = virStringSplitCount(src, " ", 0, &count)))
+        goto cleanup;
+
+    for (i = 0; i < count; i++) {
+        /* virStringSplit may return empty strings */
+        if (STREQ(strings[i], ""))
+            continue;
+
+        if (!(output = virLogParseOutput(strings[i])))
+            goto cleanup;
+
+        /* let's check if a duplicate output does not already exist in which
+         * case we need to replace it with its last occurrence, however, rather
+         * than first deleting the duplicate and then adding the new one, the
+         * new output object is added first so in case of an error we don't
+         * lose the old entry
+         */
+        at = virLogFindOutput(list, noutputs, output->dest, output->name);
+        if (VIR_APPEND_ELEMENT(list, noutputs, output) < 0) {
+            virLogOutputFree(output);
+            goto cleanup;
+        }
+        if (at >= 0) {
+            virLogOutputFree(list[at]);
+            VIR_DELETE_ELEMENT(list, at, noutputs);
+        }
+    }
+
+    ret = noutputs;
+    *outputs = list;
+    list = NULL;
+ cleanup:
+    virStringFreeList(strings);
+    return ret;
+}
index 568b8fa44abb798d223044eefd22750aee37d02e..3be2f558f860830ec1ca61342566e29fb2193e5a 100644 (file)
@@ -242,5 +242,7 @@ int virLogDefineOutputs(virLogOutputPtr *outputs,
 int virLogDefineFilters(virLogFilterPtr *filters, size_t nfilters);
 virLogOutputPtr virLogParseOutput(const char *src) ATTRIBUTE_NONNULL(1);
 virLogFilterPtr virLogParseFilter(const char *src) ATTRIBUTE_NONNULL(1);
+int virLogParseOutputs(const char *src,
+                       virLogOutputPtr **outputs) ATTRIBUTE_NONNULL(1);
 
 #endif