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).