[libvirt] [PATCH 5/9] storage: Break out actual raw cloning to separate function.

Cole Robinson crobinso at redhat.com
Fri Jul 10 20:47:02 UTC 2009


The CreateRaw function has some 'file' only assumptions, so break the agnostic
cloning bits to a separate function.
---
 src/storage_backend.c |  160 ++++++++++++++++++++++++++++---------------------
 1 files changed, 92 insertions(+), 68 deletions(-)

diff --git a/src/storage_backend.c b/src/storage_backend.c
index aea6105..868c297 100644
--- a/src/storage_backend.c
+++ b/src/storage_backend.c
@@ -101,6 +101,95 @@ enum {
     TOOL_QCOW_CREATE,
 };
 
+static int
+virStorageBackendCopyToFD(virConnectPtr conn,
+                          virStorageVolDefPtr vol,
+                          virStorageVolDefPtr inputvol,
+                          int fd,
+                          unsigned long long *total)
+{
+    int inputfd = -1;
+    int amtread = -1;
+    int ret = -1;
+    unsigned long long remain;
+    size_t bytes = 1024 * 1024;
+    char zerobuf[512];
+    char *buf = NULL;
+
+    if (inputvol) {
+        if ((inputfd = open(inputvol->target.path, O_RDONLY)) < 0) {
+            virReportSystemError(conn, errno,
+                                 _("could not open input path '%s'"),
+                                 inputvol->target.path);
+            goto cleanup;
+        }
+    }
+
+    bzero(&zerobuf, sizeof(zerobuf));
+
+    if (VIR_ALLOC_N(buf, bytes) < 0) {
+        virReportOOMError(conn);
+        goto cleanup;
+    }
+
+    remain = *total;
+
+    while (amtread != 0) {
+        int amtleft;
+
+        if (remain < bytes)
+            bytes = remain;
+
+        if ((amtread = saferead(inputfd, buf, bytes)) < 0) {
+            virReportSystemError(conn, errno,
+                                 _("failed reading from file '%s'"),
+                                 inputvol->target.path);
+            goto cleanup;
+        }
+        remain -= amtread;
+
+        /* Loop over amt read in 512 byte increments, looking for sparse
+         * blocks */
+        amtleft = amtread;
+        do {
+            int interval = ((512 > amtleft) ? amtleft : 512);
+            int offset = amtread - amtleft;
+
+            if (memcmp(buf+offset, zerobuf, interval) == 0) {
+                if (lseek(fd, interval, SEEK_CUR) < 0) {
+                    virReportSystemError(conn, errno,
+                                         _("cannot extend file '%s'"),
+                                         vol->target.path);
+                    goto cleanup;
+                }
+            } else if (safewrite(fd, buf+offset, interval) < 0) {
+                virReportSystemError(conn, errno,
+                                     _("failed writing to file '%s'"),
+                                     vol->target.path);
+                goto cleanup;
+
+            }
+        } while ((amtleft -= 512) > 0);
+    }
+
+    if (inputfd != -1 && close(inputfd) < 0) {
+        virReportSystemError(conn, errno,
+                             _("cannot close file '%s'"),
+                             inputvol->target.path);
+        goto cleanup;
+    }
+    inputfd = -1;
+
+    *total -= remain;
+    ret = 0;
+
+cleanup:
+    if (inputfd != -1)
+        close(inputfd);
+
+    return ret;
+}
+
 int
 virStorageBackendCreateRaw(virConnectPtr conn,
                            virStorageVolDefPtr vol,
@@ -108,7 +197,6 @@ virStorageBackendCreateRaw(virConnectPtr conn,
                            unsigned int flags ATTRIBUTE_UNUSED)
 {
     int fd = -1;
-    int inputfd = -1;
     int ret = -1;
     unsigned long long remain;
     char *buf = NULL;
@@ -121,15 +209,6 @@ virStorageBackendCreateRaw(virConnectPtr conn,
         goto cleanup;
     }
 
-    if (inputvol) {
-        if ((inputfd = open(inputvol->target.path, O_RDONLY)) < 0) {
-            virReportSystemError(conn, errno,
-                                 _("could not open input path '%s'"),
-                                 inputvol->target.path);
-            goto cleanup;
-        }
-    }
-
     /* Seek to the final size, so the capacity is available upfront
      * for progress reporting */
     if (ftruncate(fd, vol->capacity) < 0) {
@@ -141,55 +220,10 @@ virStorageBackendCreateRaw(virConnectPtr conn,
 
     remain = vol->allocation;
 
-    if (inputfd != -1) {
-        int amtread = -1;
-        size_t bytes = 1024 * 1024;
-        char zerobuf[512];
-
-        bzero(&zerobuf, sizeof(zerobuf));
-
-        if (VIR_ALLOC_N(buf, bytes) < 0) {
-            virReportOOMError(conn);
+    if (inputvol) {
+        int res = virStorageBackendCopyToFD(conn, vol, inputvol, fd, &remain);
+        if (res < 0)
             goto cleanup;
-        }
-
-        while (amtread != 0) {
-            int amtleft;
-
-            if (remain < bytes)
-                bytes = remain;
-
-            if ((amtread = saferead(inputfd, buf, bytes)) < 0) {
-                virReportSystemError(conn, errno,
-                                     _("failed reading from file '%s'"),
-                                     inputvol->target.path);
-                goto cleanup;
-            }
-            remain -= amtread;
-
-            /* Loop over amt read in 512 byte increments, looking for sparse
-             * blocks */
-            amtleft = amtread;
-            do {
-                int interval = ((512 > amtleft) ? amtleft : 512);
-                int offset = amtread - amtleft;
-
-                if (memcmp(buf+offset, zerobuf, interval) == 0) {
-                    if (lseek(fd, interval, SEEK_CUR) < 0) {
-                        virReportSystemError(conn, errno,
-                                             _("cannot extend file '%s'"),
-                                             vol->target.path);
-                        goto cleanup;
-                    }
-                } else if (safewrite(fd, buf+offset, interval) < 0) {
-                    virReportSystemError(conn, errno,
-                                         _("failed writing to file '%s'"),
-                                         vol->target.path);
-                    goto cleanup;
-
-                }
-            } while ((amtleft -= 512) > 0);
-        }
     }
 
     /* Pre-allocate any data if requested */
@@ -220,20 +254,10 @@ virStorageBackendCreateRaw(virConnectPtr conn,
     }
     fd = -1;
 
-    if (inputfd != -1 && close(inputfd) < 0) {
-        virReportSystemError(conn, errno,
-                             _("cannot close file '%s'"),
-                             inputvol->target.path);
-        goto cleanup;
-    }
-    inputfd = -1;
-
     ret = 0;
 cleanup:
     if (fd != -1)
         close(fd);
-    if (inputfd != -1)
-        close(inputfd);
     VIR_FREE(buf);
 
     return ret;
-- 
1.6.0.6




More information about the libvir-list mailing list