[libvirt] [PATCH] add compress stream support

Vasiliy Tolstov v.tolstov at selfip.ru
Tue Sep 22 14:10:41 UTC 2015


use libarchive for compressed stream support

Signed-off-by: Vasiliy Tolstov <v.tolstov at selfip.ru>
---
 configure.ac                     | 11 ++++++--
 include/libvirt/libvirt-stream.h |  6 +++++
 m4/virt-archive.m4               | 26 +++++++++++++++++++
 src/fdstream.c                   | 47 +++++++++++++++++++++++++++++++++
 src/libvirt-stream.c             | 56 +++++++++++++++++++++++++++++++++++++++-
 src/libvirt_public.syms          |  7 +++++
 6 files changed, 150 insertions(+), 3 deletions(-)
 create mode 100644 m4/virt-archive.m4

diff --git a/configure.ac b/configure.ac
index 03463b0..4018b49 100644
--- a/configure.ac
+++ b/configure.ac
@@ -250,6 +250,7 @@ LIBVIRT_CHECK_SANLOCK
 LIBVIRT_CHECK_SASL
 LIBVIRT_CHECK_SELINUX
 LIBVIRT_CHECK_SSH2
+LIBVIRT_CHECK_LIBARCHIVE
 LIBVIRT_CHECK_SYSTEMD_DAEMON
 LIBVIRT_CHECK_UDEV
 LIBVIRT_CHECK_WIRESHARK
@@ -1603,8 +1604,6 @@ fi
 AC_SUBST([LIBPCAP_CFLAGS])
 AC_SUBST([LIBPCAP_LIBS])
 
-
-
 dnl
 dnl Checks for the UML driver
 dnl
@@ -2097,6 +2096,13 @@ AM_CONDITIONAL([WITH_STORAGE_DISK], [test "$with_storage_disk" = "yes"])
 AC_SUBST([LIBPARTED_CFLAGS])
 AC_SUBST([LIBPARTED_LIBS])
 
+if test "$with_libarchive" = "yes" || test "$with_libarchive" = "check"; then
+   PKG_CHECK_MODULES([LIBARCHIVE], [libarchive >= 3.1.2], [], [LIBARCHIVE_FOUND=no])
+fi
+AC_SUBST([LIBARCHIVE_CFLAGS])
+AC_SUBST([LIBARCHIVE_LIBS])
+
+
 if test "$with_storage_mpath" = "yes" ||
    test "$with_storage_disk" = "yes"; then
    DEVMAPPER_CFLAGS=
@@ -2892,6 +2898,7 @@ LIBVIRT_RESULT_SANLOCK
 LIBVIRT_RESULT_SASL
 LIBVIRT_RESULT_SELINUX
 LIBVIRT_RESULT_SSH2
+LIBVIRT_RESULT_LIBARCHIVE
 LIBVIRT_RESULT_SYSTEMD_DAEMON
 LIBVIRT_RESULT_UDEV
 LIBVIRT_RESULT_WIRESHARK
diff --git a/include/libvirt/libvirt-stream.h b/include/libvirt/libvirt-stream.h
index 831640d..ac48fba 100644
--- a/include/libvirt/libvirt-stream.h
+++ b/include/libvirt/libvirt-stream.h
@@ -35,6 +35,12 @@ typedef enum {
 
 virStreamPtr virStreamNew(virConnectPtr conn,
                           unsigned int flags);
+virStreamPtr virStreamNewLz4(virConnectPtr conn,
+                          unsigned int flags);
+virStreamPtr virStreamNewGzip(virConnectPtr conn,
+                          unsigned int flags);
+virStreamPtr virStreamNewXz(virConnectPtr conn,
+                          unsigned int flags);
 int virStreamRef(virStreamPtr st);
 
 int virStreamSend(virStreamPtr st,
diff --git a/m4/virt-archive.m4 b/m4/virt-archive.m4
new file mode 100644
index 0000000..b550c41
--- /dev/null
+++ b/m4/virt-archive.m4
@@ -0,0 +1,26 @@
+dnl The libarchive.so library
+dnl
+dnl Copyright (C) 2012-2013 Red Hat, Inc.
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License, or (at your option) any later version.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library.  If not, see
+dnl <http://www.gnu.org/licenses/>.
+dnl
+
+AC_DEFUN([LIBVIRT_CHECK_LIBARCHIVE],[
+  LIBVIRT_CHECK_PKG([LIBARCHIVE], [libarchive], [3.1.2])
+])
+
+AC_DEFUN([LIBVIRT_RESULT_LIBARCHIVE],[
+  LIBVIRT_RESULT_LIB([LIBARCHIVE])
+])
diff --git a/src/fdstream.c b/src/fdstream.c
index b8ea86e..82f0e8c 100644
--- a/src/fdstream.c
+++ b/src/fdstream.c
@@ -33,6 +33,10 @@
 #include <netinet/in.h>
 #include <termios.h>
 
+#ifdef WITH_LIBARCHIVE
+# include <archive.h>
+#endif
+
 #include "fdstream.h"
 #include "virerror.h"
 #include "datatypes.h"
@@ -75,6 +79,9 @@ struct virFDStreamData {
     void *icbOpaque;
 
     virMutex lock;
+#ifdef WITH_LIBARCHIVE
+    void *archive;
+#endif
 };
 
 
@@ -319,6 +326,12 @@ virFDStreamCloseInt(virStreamPtr st, bool streamAbort)
     if (VIR_CLOSE(fdst->errfd) < 0)
         VIR_DEBUG("ignoring failed close on fd %d", fdst->errfd);
 
+#ifdef WITH_LIBARCHIVE
+    if (fdst->archive != NULL) {
+        archive_write_free(fdst->archive);
+        archive_read_free(fdst->archive);
+    }
+#endif
     st->privateData = NULL;
 
     /* call the internal stream closing callback */
@@ -385,7 +398,16 @@ static int virFDStreamWrite(virStreamPtr st, const char *bytes, size_t nbytes)
     }
 
  retry:
+#ifdef WITH_LIBARCHIVE
+    if (fdst->archive != NULL) {
+        archive_write_open_fd(fdst->archive, fdst->fd);
+        ret = archive_write_data(fdst->archive, bytes, nbytes);
+    } else {
+        ret = write(fdst->fd, bytes, nbytes);
+    }
+#else
     ret = write(fdst->fd, bytes, nbytes);
+#endif
     if (ret < 0) {
         if (errno == EAGAIN || errno == EWOULDBLOCK) {
             ret = -2;
@@ -397,7 +419,15 @@ static int virFDStreamWrite(virStreamPtr st, const char *bytes, size_t nbytes)
                                  _("cannot write to stream"));
         }
     } else if (fdst->length) {
+#ifdef WITH_LIBARCHIVE
+        if (fdst->archive != NULL) {
+            fdst->offset += nbytes;
+        } else {
+            fdst->offset += ret;
+        }
+#else
         fdst->offset += ret;
+#endif
     }
 
     virMutexUnlock(&fdst->lock);
@@ -435,7 +465,16 @@ static int virFDStreamRead(virStreamPtr st, char *bytes, size_t nbytes)
     }
 
  retry:
+#ifdef WITH_LIBARCHIVE
+    if (fdst->archive != NULL) {
+        archive_read_open_fd(fdst->archive, fdst->fd, 4096);
+        ret = archive_read_data(fdst->archive, bytes, nbytes);
+    } else {
+        ret = read(fdst->fd, bytes, nbytes);
+    }
+#else
     ret = read(fdst->fd, bytes, nbytes);
+#endif
     if (ret < 0) {
         if (errno == EAGAIN || errno == EWOULDBLOCK) {
             ret = -2;
@@ -447,7 +486,15 @@ static int virFDStreamRead(virStreamPtr st, char *bytes, size_t nbytes)
                                  _("cannot read from stream"));
         }
     } else if (fdst->length) {
+#ifdef WITH_LIBARCHIVE
+        if (fdst->archive != NULL) {
+            fdst->offset += nbytes;
+        } else {
+            fdst->offset += ret;
+        }
+#else
         fdst->offset += ret;
+#endif
     }
 
     virMutexUnlock(&fdst->lock);
diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c
index c16f586..40702dc 100644
--- a/src/libvirt-stream.c
+++ b/src/libvirt-stream.c
@@ -23,12 +23,16 @@
 #include "datatypes.h"
 #include "viralloc.h"
 #include "virlog.h"
+#include "fdstream.h"
+
+#include <archive.h>
+
+struct virFDStreamData;
 
 VIR_LOG_INIT("libvirt.stream");
 
 #define VIR_FROM_THIS VIR_FROM_STREAMS
 
-
 /**
  * virStreamNew:
  * @conn: pointer to the connection
@@ -69,6 +73,56 @@ virStreamNew(virConnectPtr conn,
     return st;
 }
 
+virStreamPtr
+virStreamNewLz4(virConnectPtr conn,
+                unsigned int flags)
+{
+    virStreamPtr st;
+
+    st = virStreamNew(conn, flags);
+    if (st != NULL) {
+        struct virFDStreamData *fdst = st->privateData;
+        fdst->archive = archive_write_new();
+        archive_write_add_filter(fdst->archive, ARCHIVE_FILTER_LZ4);
+    }
+
+    return st;
+}
+
+virStreamPtr
+virStreamNewGzip(virConnectPtr conn,
+                unsigned int flags)
+{
+    virStreamPtr st;
+
+    st = virStreamNew(conn, flags);
+    if (st != NULL) {
+        struct virFDStreamData *fdst = st->privateData;
+        fdst->archive = archive_write_new();
+        archive_write_add_filter(fdst->archive, ARCHIVE_FILTER_GZIP);
+    }
+
+    return st;
+}
+
+
+virStreamPtr
+virStreamNewXz(virConnectPtr conn,
+                unsigned int flags)
+{
+    virStreamPtr st;
+
+    st = virStreamNew(conn, flags);
+    if (st != NULL) {
+        struct virFDStreamData *fdst = st->privateData;
+        fdst->archive = archive_write_new();
+        archive_write_add_filter(fdst->archive, ARCHIVE_FILTER_XZ);
+    }
+
+    return st;
+}
+
+
 
 /**
  * virStreamRef:
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index dd94191..46519ce 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -725,4 +725,11 @@ LIBVIRT_1.2.19 {
         virDomainRename;
 } LIBVIRT_1.2.17;
 
+LIBVIRT_1.2.20 {
+    global:
+        virStreamNewLz4;
+        virStreamNewGzip;
+        virStreamNewXz;
+} LIBVIRT_1.2.19;
+
 # .... define new API here using predicted next version number ....
-- 
2.5.0




More information about the libvir-list mailing list