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

Re: [libvirt] [PATCH 3/4] Fix QEMU save/restore with block devices



On 04/22/2010 07:43 AM, Daniel P. Berrange wrote:
The save process was relying on use of the shell>>  append
operator to ensure the save data was placed after the libvirt
header + XML. This doesn't work for block devices though.
Replace this code with use of 'dd' and its 'seek' parameter.
This means that we need to pad the header + XML out to a
multiple of dd block size (in this case we choose 512).

The qemuMonitorMigateToCommand() monitor API is used for both
save/coredump, and migration via UNIX socket. We can't simply
switch this to use 'dd' since this causes problems with the
migration usage. Thus, create a dedicated qemuMonitorMigateToFile
which can accept an filename + offset, and remove the filename
from the current qemuMonitorMigateToCommand() API

* src/qemu/qemu_driver.c: Switch to qemuMonitorMigateToFile
   for save and core dump
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
   src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h,
   src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Create
   a new qemuMonitorMigateToFile, separate from the existing
   qemuMonitorMigateToCommand to allow handling file offsets
---
  src/qemu/qemu_driver.c       |  190 +++++++++++++++++++++++++-----------------
  src/qemu/qemu_monitor.c      |   35 +++++++--
  src/qemu/qemu_monitor.h      |   11 ++-
  src/qemu/qemu_monitor_json.c |   37 ++++++++-
  src/qemu/qemu_monitor_json.h |    9 ++-
  src/qemu/qemu_monitor_text.c |   37 ++++++++-
  src/qemu/qemu_monitor_text.h |    9 ++-
  7 files changed, 232 insertions(+), 96 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 41a516c..09b6493 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4789,6 +4789,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
      qemuDomainObjPrivatePtr priv;
      struct stat sb;
      int is_reg = 0;
+    unsigned long long offset;

      memset(&header, 0, sizeof(header));
      memcpy(header.magic, QEMUD_SAVE_MAGIC, sizeof(header.magic));
@@ -4862,104 +4863,137 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
      hdata.path = path;
      hdata.xml = xml;
      hdata.header =&header;
+    offset = sizeof(header) + header.xml_len;
+
+    /* Due to way we append QEMU state on our header with dd,
+     * 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 */
+    if (offset % QEMU_MONITOR_MIGRATE_TO_FILE_BS) {
+        unsigned long long pad =
+            QEMU_MONITOR_MIGRATE_TO_FILE_BS -
+            (offset % QEMU_MONITOR_MIGRATE_TO_FILE_BS);
+
+        if (VIR_REALLOC_N(xml, header.xml_len + pad)<  0) {
+            virReportOOMError();
+            goto endjob;
+        }
+        memset(xml + header.xml_len, 0, pad);
+        offset += pad;
+        header.xml_len += pad;
+    }

Is it really necessary to add this padding even when we *aren't* using dd? (ie, when is_reg == 1).


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