[libvirt] [PATCH RFC 48/48] iohelper: Wire up formatted messages

Michal Privoznik mprivozn at redhat.com
Wed Jun 22 14:44:05 UTC 2016


Finally, now that everything is prepared, we can wire up
formatted messages for iohelper too.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/Makefile.am         |   2 +
 src/iohelper/iohelper.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 115 insertions(+)

diff --git a/src/Makefile.am b/src/Makefile.am
index 1cce603..f5bc5b6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2867,6 +2867,8 @@ libvirt_iohelper_LDFLAGS = \
 		$(NULL)
 libvirt_iohelper_LDADD =		\
 		libvirt_util.la		\
+		libvirt-iohelper.la	\
+		libvirt-net-rpc.la	\
 		../gnulib/lib/libgnu.la
 if WITH_DTRACE_PROBES
 libvirt_iohelper_LDADD += libvirt_probes.lo
diff --git a/src/iohelper/iohelper.c b/src/iohelper/iohelper.c
index 65fbc63..4b431af 100644
--- a/src/iohelper/iohelper.c
+++ b/src/iohelper/iohelper.c
@@ -32,6 +32,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "iohelper_message.h"
 #include "virutil.h"
 #include "virthread.h"
 #include "virfile.h"
@@ -40,6 +41,7 @@
 #include "virrandom.h"
 #include "virstring.h"
 #include "virgettext.h"
+#include "virobject.h"
 
 #define VIR_FROM_THIS VIR_FROM_STORAGE
 
@@ -228,6 +230,114 @@ runIOBasic(const char *path, int fd, int oflags, unsigned long long length)
 
 
 static int
+runIOFormatted(const char *path,
+               int fd,
+               int oflags,
+               unsigned long long length)
+{
+    int ret = -1;
+    int fdin, fdout;
+    const char *fdinname, *fdoutname;
+    unsigned long long total = 0;
+    iohelperCtlPtr ioCtl = NULL;
+    char *buf = NULL;
+    size_t bufLen = 1024 * 1024;
+    bool formattedIN, formattedOUT;
+
+    if (VIR_ALLOC_N(buf, bufLen) < 0)
+        goto cleanup;
+
+    if (setupFDs(path, fd, oflags,
+                 &fdin, &fdinname,
+                 &fdout, &fdoutname) < 0)
+        goto cleanup;
+
+    /* Maybe this looks a bit silly. But it's simple. Either we
+     * are reading from @fd and writing to stdout, or we're
+     * reading from stdin and writing to @fd. But the formatted
+     * messages occurs just on std* not @fd. */
+    formattedIN = fdout == fd;
+    formattedOUT = fdin == fd;
+
+    if (!(ioCtl = iohelperCtlNew(formattedIN ? fdin : fdout, true)))
+        goto cleanup;
+
+    while (true) {
+        ssize_t nread, nwritten, want = bufLen;
+        int inData = 1;
+        unsigned long long sectionLength;
+
+        if (formattedOUT) {
+            if (virFileInData(fdin, &inData, &sectionLength) < 0)
+                goto cleanup;
+
+            if (!inData) {
+                if (iohelperSkip(ioCtl, sectionLength) < 0)
+                    goto cleanup;
+                if (!sectionLength)
+                    break;
+                if (lseek(fdin, sectionLength, SEEK_CUR) == (off_t) -1) {
+                    virReportSystemError(errno,
+                                         _("Unable to seek in %s"), fdoutname);
+                    goto cleanup;
+                }
+                continue;
+            } else {
+                want = MIN(sectionLength, bufLen);
+            }
+        } else {
+            if (iohelperInData(ioCtl, &inData, &sectionLength) < 0)
+                goto cleanup;
+
+            if (!inData) {
+                if (!sectionLength)
+                    break;
+
+                if (lseek(fdout, sectionLength, SEEK_CUR) == (off_t) -1) {
+                    virReportSystemError(errno,
+                                         _("Unable to seek in %s"), fdoutname);
+                    goto cleanup;
+                }
+                continue;
+            } else {
+                want = MIN(sectionLength, bufLen);
+            }
+        }
+
+        if (length &&
+            (length - total) < want)
+            want = length - total;
+
+        if (want == 0)
+            break; /* End of requested data from client */
+
+        if ((formattedIN && (nread = iohelperRead(ioCtl, buf, want)) < 0) ||
+            (!formattedIN && (nread = saferead(fdin, buf, want)) < 0)) {
+            virReportSystemError(errno, _("Unable to read %s"), fdinname);
+            goto cleanup;
+        }
+
+        if (!nread)
+            break;
+
+        total += nread;
+
+        if ((formattedOUT && (nwritten = iohelperWrite(ioCtl, buf, nread)) < 0) ||
+            (!formattedOUT && (nwritten = safewrite(fdout, buf, nread)) < 0)) {
+            virReportSystemError(errno, _("Unable to write %s"), fdoutname);
+            goto cleanup;
+        }
+    }
+
+    ret = 0;
+ cleanup:
+    virObjectUnref(ioCtl);
+    VIR_FREE(buf);
+    return ret;
+}
+
+
+static int
 runIO(const char *path, int fd, int oflags,
       unsigned long long length, bool sparse)
 {
@@ -240,6 +350,9 @@ runIO(const char *path, int fd, int oflags,
         return -1;
     }
 
+    if (sparse)
+        return runIOFormatted(path, fd, oflags, length);
+
     return runIOBasic(path, fd, oflags, length);
 }
 
-- 
2.8.4




More information about the libvir-list mailing list