This code can be used by the nbdkit implementation for reading back
filtered log data for error reporting. Move it to qemuLogContext so that
it can be shared. Renamed to qemuLogContextReadFiltered().

Signed-off-by: Jonathon Jongsma <jjong...@redhat.com>
Reviewed-by: Peter Krempa <pkre...@redhat.com>
---
 src/qemu/qemu_logcontext.c | 65 ++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_logcontext.h |  3 ++
 src/qemu/qemu_process.c    | 67 +-------------------------------------
 3 files changed, 69 insertions(+), 66 deletions(-)

diff --git a/src/qemu/qemu_logcontext.c b/src/qemu/qemu_logcontext.c
index 0121ae5173..6e20f58bfa 100644
--- a/src/qemu/qemu_logcontext.c
+++ b/src/qemu/qemu_logcontext.c
@@ -21,6 +21,7 @@
 #include "qemu_logcontext.h"
 #include "viralloc.h"
 #include "virlog.h"
+#include "virstring.h"
 #include "virutil.h"
 
 #include <fcntl.h>
@@ -236,6 +237,70 @@ qemuLogContextRead(qemuLogContext *ctxt,
 }
 
 
+/**
+ * qemuLogContextFilter: Read and filter log for relevant messages
+ * @ctxt: the domain log context
+ * @msg: pointer to buffer to store the read messages in
+ * @max: maximum length of the message returned in @msg after filtering
+ *
+ * Reads log output from @ctxt and filters it. Skips messages not produced by
+ * the target executable or irrelevant messages. If @max is not zero, @buf will
+ * contain at most @max characters from the end of the log and @buf will start
+ * after a new line if possible.
+ */
+int
+qemuLogContextReadFiltered(qemuLogContext *ctxt,
+                           char **msg,
+                           size_t max)
+{
+    char *buf;
+    char *eol;
+    char *filter_next;
+    size_t skip;
+    ssize_t got;
+
+    if ((got = qemuLogContextRead(ctxt, &buf)) < 0)
+        return -1;
+
+    /* Filter out debug messages from intermediate libvirt process */
+    filter_next = buf;
+    while ((eol = strchr(filter_next, '\n'))) {
+        *eol = '\0';
+        if (virLogProbablyLogMessage(filter_next) ||
+            strstr(filter_next, "char device redirected to")) {
+            skip = (eol + 1) - filter_next;
+            memmove(filter_next, eol + 1, buf + got - eol);
+            got -= skip;
+        } else {
+            filter_next = eol + 1;
+            *eol = '\n';
+        }
+    }
+
+    if (got > 0 &&
+        buf[got - 1] == '\n') {
+        buf[got - 1] = '\0';
+        got--;
+    }
+
+    if (max > 0 && got > max) {
+        skip = got - max;
+
+        if (buf[skip - 1] != '\n' &&
+            (eol = strchr(buf + skip, '\n')) &&
+            !virStringIsEmpty(eol + 1))
+            skip = eol + 1 - buf;
+
+        memmove(buf, buf + skip, got - skip + 1);
+        got -= skip;
+    }
+
+    buf = g_renew(char, buf, got + 1);
+    *msg = buf;
+    return 0;
+}
+
+
 int
 qemuLogContextGetWriteFD(qemuLogContext *ctxt)
 {
diff --git a/src/qemu/qemu_logcontext.h b/src/qemu/qemu_logcontext.h
index 6ad60b7b4a..738e908bc3 100644
--- a/src/qemu/qemu_logcontext.h
+++ b/src/qemu/qemu_logcontext.h
@@ -32,6 +32,9 @@ int qemuLogContextWrite(qemuLogContext *ctxt,
                         const char *fmt, ...) G_GNUC_PRINTF(2, 3);
 ssize_t qemuLogContextRead(qemuLogContext *ctxt,
                            char **msg);
+int qemuLogContextReadFiltered(qemuLogContext *ctxt,
+                               char **msg,
+                               size_t max);
 int qemuLogContextGetWriteFD(qemuLogContext *ctxt);
 void qemuLogContextMarkPosition(qemuLogContext *ctxt);
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index e03d0d8b4d..a77d2ba7de 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1908,71 +1908,6 @@ qemuConnectMonitor(virQEMUDriver *driver,
 }
 
 
-/**
- * qemuProcessReadLog: Read log file of a qemu VM
- * @logCtxt: the domain log context
- * @msg: pointer to buffer to store the read messages in
- * @max: maximum length of the message returned in @msg
- *
- * Reads log of a qemu VM. Skips messages not produced by qemu or irrelevant
- * messages. If @max is not zero, @msg will contain at most @max characters
- * from the end of the log and @msg will start after a new line if possible.
- *
- * Returns 0 on success or -1 on error
- */
-static int
-qemuProcessReadLog(qemuLogContext *logCtxt,
-                   char **msg,
-                   size_t max)
-{
-    char *buf;
-    ssize_t got;
-    char *eol;
-    char *filter_next;
-    size_t skip;
-
-    if ((got = qemuLogContextRead(logCtxt, &buf)) < 0)
-        return -1;
-
-    /* Filter out debug messages from intermediate libvirt process */
-    filter_next = buf;
-    while ((eol = strchr(filter_next, '\n'))) {
-        *eol = '\0';
-        if (virLogProbablyLogMessage(filter_next) ||
-            strstr(filter_next, "char device redirected to")) {
-            skip = (eol + 1) - filter_next;
-            memmove(filter_next, eol + 1, buf + got - eol);
-            got -= skip;
-        } else {
-            filter_next = eol + 1;
-            *eol = '\n';
-        }
-    }
-
-    if (got > 0 &&
-        buf[got - 1] == '\n') {
-        buf[got - 1] = '\0';
-        got--;
-    }
-
-    if (max > 0 && got > max) {
-        skip = got - max;
-
-        if (buf[skip - 1] != '\n' &&
-            (eol = strchr(buf + skip, '\n')) &&
-            !virStringIsEmpty(eol + 1))
-            skip = eol + 1 - buf;
-
-        memmove(buf, buf + skip, got - skip + 1);
-        got -= skip;
-    }
-
-    buf = g_renew(char, buf, got + 1);
-    *msg = buf;
-    return 0;
-}
-
-
 static int
 qemuProcessReportLogError(qemuLogContext *logCtxt,
                           const char *msgprefix)
@@ -1980,7 +1915,7 @@ qemuProcessReportLogError(qemuLogContext *logCtxt,
     g_autofree char *logmsg = NULL;
 
     /* assume that 1024 chars of qemu log is the right balance */
-    if (qemuProcessReadLog(logCtxt, &logmsg, 1024) < 0)
+    if (qemuLogContextReadFiltered(logCtxt, &logmsg, 1024) < 0)
         return -1;
 
     virResetLastError();
-- 
2.41.0

Reply via email to