]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: reduce file padding requirements
authorEric Blake <eblake@redhat.com>
Thu, 10 Jun 2010 02:23:51 +0000 (20:23 -0600)
committerEric Blake <eblake@redhat.com>
Thu, 17 Jun 2010 19:29:16 +0000 (13:29 -0600)
Followup to https://bugzilla.redhat.com/show_bug.cgi?id=599091,
commit 20206a4b, to reduce disk waste in padding.

* src/qemu/qemu_monitor.h (QEMU_MONITOR_MIGRATE_TO_FILE_BS): Drop
back to 4k.
(QEMU_MONITOR_MIGRATE_TO_FILE_TRANSFER_SIZE): New macro.
* src/qemu/qemu_driver.c (qemudDomainSaveFlag): Update comment.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextMigrateToFile): Use
two invocations of dd to output non-aligned large blocks.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONMigrateToFile):
Likewise.

src/qemu/qemu_driver.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_text.c

index df04ea11cfccbc7c2dac30c967a78cb404bb530d..c7923bc6947cf5e85dcf7fdcfb7f4ff1477f1ffe 100644 (file)
@@ -5001,13 +5001,6 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
      * we need to ensure there's a 512 byte boundary. Unfortunately
      * we don't have an explicit offset in the header, so we fake
      * it by padding the XML string with NULLs.
-     *
-     * XXX: This means there will be (QEMU_MONITOR_MIGRATE_TO_FILE_BS
-     *      - strlen(xml)) bytes of wastage in each file.
-     *      Unfortunately, a large BS is needed for reasonable
-     *      performance. It would be nice to find a replacement for dd
-     *      that could specify the start offset in bytes rather than
-     *      blocks, to eliminate this waste.
      */
     if (offset % QEMU_MONITOR_MIGRATE_TO_FILE_BS) {
         unsigned long long pad =
index e03b4dff19f4d94863384caac6d570fc7c35072e..6c104f1bc9d69c4ed51737f245bc9e1a0bb9e3e9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * qemu_monitor.h: interaction with QEMU monitor console
  *
- * Copyright (C) 2006-2009 Red Hat, Inc.
+ * Copyright (C) 2006-2010 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -261,10 +261,16 @@ int qemuMonitorMigrateToCommand(qemuMonitorPtr mon,
                                 unsigned int background,
                                 const char * const *argv);
 
-/* In general, a larger BS means better domain save performance,
- * at the expense of a larger resulting file - see qemu_driver.c
+/* In general, BS is the smallest fundamental block size we can use to
+ * access a block device; everything must be aligned to a multiple of
+ * this.  Linux generally supports a BS as small as 512, but with
+ * newer disks with 4k sectors, performance is better if we guarantee
+ * alignment to the sector size.  However, operating on BS-sized
+ * blocks is painfully slow, so we also have a transfer size that is
+ * larger but only aligned to the smaller block size.
  */
-# define QEMU_MONITOR_MIGRATE_TO_FILE_BS (1024llu * 1024)
+# define QEMU_MONITOR_MIGRATE_TO_FILE_BS (1024llu * 4)
+# define QEMU_MONITOR_MIGRATE_TO_FILE_TRANSFER_SIZE (1024llu * 1024)
 
 int qemuMonitorMigrateToFile(qemuMonitorPtr mon,
                              unsigned int background,
index e89ad43000549df0c1dd6d8b73066494361bcc9a..40218aaf4ee6607aa9ff96e6558526a72db6d3a8 100644 (file)
@@ -1695,10 +1695,16 @@ int qemuMonitorJSONMigrateToFile(qemuMonitorPtr mon,
         goto cleanup;
     }
 
-    if (virAsprintf(&dest, "exec:%s | dd of=%s bs=%llu seek=%llu",
-                    argstr, safe_target,
-                    QEMU_MONITOR_MIGRATE_TO_FILE_BS,
-                    offset / QEMU_MONITOR_MIGRATE_TO_FILE_BS) < 0) {
+    /* Two dd processes, sharing the same stdout, are necessary to
+     * allow starting at an alignment of 512, but without wasting
+     * padding to get to the larger alignment useful for speed.  Use
+     * <> redirection to avoid truncating a regular file.  */
+    if (virAsprintf(&dest, "exec:%s | { dd bs=%llu seek=%llu if=/dev/null && "
+                    "dd bs=%llu; } 1<>%s",
+                    argstr, QEMU_MONITOR_MIGRATE_TO_FILE_BS,
+                    offset / QEMU_MONITOR_MIGRATE_TO_FILE_BS,
+                    QEMU_MONITOR_MIGRATE_TO_FILE_TRANSFER_SIZE,
+                    safe_target) < 0) {
         virReportOOMError();
         goto cleanup;
     }
index c0ebe5f369ccd8c11b30c8bc962934b1760970ac..c08696244f951be88108c346d74d50555e00f81e 100644 (file)
@@ -1273,10 +1273,16 @@ int qemuMonitorTextMigrateToFile(qemuMonitorPtr mon,
         goto cleanup;
     }
 
-    if (virAsprintf(&dest, "exec:%s | dd of=%s bs=%llu seek=%llu",
-                    argstr, safe_target,
-                    QEMU_MONITOR_MIGRATE_TO_FILE_BS,
-                    offset / QEMU_MONITOR_MIGRATE_TO_FILE_BS) < 0) {
+    /* Two dd processes, sharing the same stdout, are necessary to
+     * allow starting at an alignment of 512, but without wasting
+     * padding to get to the larger alignment useful for speed.  Use
+     * <> redirection to avoid truncating a regular file.  */
+    if (virAsprintf(&dest, "exec:%s | { dd bs=%llu seek=%llu if=/dev/null && "
+                    "dd bs=%llu; } 1<>%s",
+                    argstr, QEMU_MONITOR_MIGRATE_TO_FILE_BS,
+                    offset / QEMU_MONITOR_MIGRATE_TO_FILE_BS,
+                    QEMU_MONITOR_MIGRATE_TO_FILE_TRANSFER_SIZE,
+                    safe_target) < 0) {
         virReportOOMError();
         goto cleanup;
     }