[PATCH v2 13/17] virfdstream: Allow sparse stream vol-download

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When handling sparse stream, a thread is executed. This thread
runs a read() or write() loop (depending what API is called; in
this case it's virStorageVolDownload() and  this the thread run
read() loop). The read() is handled in virFDStreamThreadDoRead()
which is then data/hole section aware, meaning it uses
virFileInData() to detect data and hole sections and sends
TYPE_DATA or TYPE_HOLE virStream messages accordingly.

However, virFileInData() does not work with block devices. Simply
because block devices don't have data and hole sections. But we
can use new virFileInDataDetectZeroes() which is block device
friendly for that.

Partially resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1852528

Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx>
---
 src/util/virfdstream.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/util/virfdstream.c b/src/util/virfdstream.c
index 50209a8bd4..44b4855549 100644
--- a/src/util/virfdstream.c
+++ b/src/util/virfdstream.c
@@ -398,6 +398,7 @@ struct _virFDStreamThreadData {
     size_t length;
     bool doRead;
     bool sparse;
+    bool isBlock;
     int fdin;
     char *fdinname;
     int fdout;
@@ -421,6 +422,7 @@ virFDStreamThreadDataFree(virFDStreamThreadDataPtr data)
 static ssize_t
 virFDStreamThreadDoRead(virFDStreamDataPtr fdst,
                         bool sparse,
+                        bool isBlock,
                         const int fdin,
                         const int fdout,
                         const char *fdinname,
@@ -437,8 +439,13 @@ virFDStreamThreadDoRead(virFDStreamDataPtr fdst,
     ssize_t got;
 
     if (sparse && *dataLen == 0) {
-        if (virFileInData(fdin, &inData, &sectionLen) < 0)
-            return -1;
+        if (isBlock) {
+            if (virFileInDataDetectZeroes(fdin, &inData, &sectionLen) < 0)
+                return -1;
+        } else {
+            if (virFileInData(fdin, &inData, &sectionLen) < 0)
+                return -1;
+        }
 
         if (length &&
             sectionLen > length - total)
@@ -568,6 +575,7 @@ virFDStreamThread(void *opaque)
     virStreamPtr st = data->st;
     size_t length = data->length;
     bool sparse = data->sparse;
+    bool isBlock = data->isBlock;
     VIR_AUTOCLOSE fdin = data->fdin;
     char *fdinname = data->fdinname;
     VIR_AUTOCLOSE fdout = data->fdout;
@@ -604,7 +612,7 @@ virFDStreamThread(void *opaque)
         }
 
         if (doRead)
-            got = virFDStreamThreadDoRead(fdst, sparse,
+            got = virFDStreamThreadDoRead(fdst, sparse, isBlock,
                                           fdin, fdout,
                                           fdinname, fdoutname,
                                           length, total,
@@ -1271,6 +1279,7 @@ virFDStreamOpenFileInternal(virStreamPtr st,
         threadData->st = virObjectRef(st);
         threadData->length = length;
         threadData->sparse = sparse;
+        threadData->isBlock = !!S_ISBLK(sb.st_mode);
 
         if ((oflags & O_ACCMODE) == O_RDONLY) {
             threadData->fdin = fd;
-- 
2.26.2




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux