[PATCH] Fix performance problem of virStorageVolCreateXMLFrom()

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

 



virStorageVolCreateXMLFrom() is slow if destination Pool is LVM.
Because write block size is not appropriate.

On linux environment, block size of LVM Pool which is made by virStoragePoolCreateXML()
is 4096 bytes.
On the other hand, write block size of virStorageVolCreateXMLFrom() is 512 bytes.
This value are hard corded in virStorageBackendCopyToFD().

This patch fix this block size problem on linux.

[lvm block size]
  # virsh vol-dumpxml vol.img --pool lvm-pool |grep '<path>'
      <path>/dev/lvm-pool/vol.img</path>
  # blockdev --getbsz /dev/lvm-pool/vol.img
  4096

[before patch]
  # echo 1 > /proc/sys/vm/drop_caches
  # time virsh  vol-create-from lvm-pool vol.xml --inputpool dir-pool vol.img
  real    1m17.736s
  user    0m0.007s
  sys     0m0.021s

[after patch]
  # echo 1 > /proc/sys/vm/drop_caches
  # time virsh  vol-create-from lvm-pool vol.xml --inputpool dir-pool vol.img
  real    0m36.883s
  user    0m0.011s
  sys     0m0.031s

Signed-off-by: Minoru Usui <usui@xxxxxxxxxxxxxxxxx>
---
 src/storage/storage_backend.c |   23 +++++++++++++++++++----
 1 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 174155d..a1a930c 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -36,6 +36,10 @@
 #include <sys/stat.h>
 #include <sys/param.h>
 #include <dirent.h>
+#ifdef __linux__
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+#endif
 
 #if HAVE_SELINUX
 # include <selinux/selinux.h>
@@ -108,6 +112,9 @@ enum {
     TOOL_QCOW_CREATE,
 };
 
+#define READ_BLOCK_SIZE_DEFAULT  (1024 * 1024)
+#define WRITE_BLOCK_SIZE_DEFAULT (512)
+
 static int ATTRIBUTE_NONNULL (2)
 virStorageBackendCopyToFD(virStorageVolDefPtr vol,
                           virStorageVolDefPtr inputvol,
@@ -119,8 +126,10 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
     int amtread = -1;
     int ret = 0;
     unsigned long long remain;
-    size_t rbytes = 1024 * 1024; /* For Read */
-    char zerobuf[512];
+    size_t rbytes = READ_BLOCK_SIZE_DEFAULT;
+    size_t wbytes = WRITE_BLOCK_SIZE_DEFAULT;
+    int interval;
+    char zerobuf[WRITE_BLOCK_SIZE_DEFAULT];
     char *buf = NULL;
 
     if ((inputfd = open(inputvol->target.path, O_RDONLY)) < 0) {
@@ -131,6 +140,12 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
         goto cleanup;
     }
 
+#ifdef __linux__
+    if (ioctl(fd, BLKBSZGET, &wbytes) < 0) {
+        wbytes = WRITE_BLOCK_SIZE_DEFAULT;
+    }
+#endif
+
     bzero(&zerobuf, sizeof(zerobuf));
 
     if (VIR_ALLOC_N(buf, rbytes) < 0) {
@@ -160,7 +175,7 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
          * blocks */
         amtleft = amtread;
         do {
-            int interval = ((512 > amtleft) ? amtleft : 512);
+            interval = ((wbytes > amtleft) ? amtleft : wbytes);
             int offset = amtread - amtleft;
 
             if (is_dest_file && memcmp(buf+offset, zerobuf, interval) == 0) {
@@ -179,7 +194,7 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol,
                 goto cleanup;
 
             }
-        } while ((amtleft -= 512) > 0);
+        } while ((amtleft -= interval) > 0);
     }
 
     if (VIR_CLOSE(inputfd) < 0) {


-- 
Minoru Usui <usui@xxxxxxxxxxxxxxxxx>

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[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]