On Mon, Apr 09, 2012 at 21:52:18 -0600, Eric Blake wrote: > As mentioned several commits ago when the capability bits were added, > the new block copy storage migration sequence requires both the > 'drive-mirror' and 'drive-reopen' monitor commands. > > As of this[1] qemu email, both commands have been proposed but not yet > incorporated into the tree; in fact, the implementation I tested with > has changed to match this[2] email that suggested a mandatory > 'full':'bool' argument rather than 'mode':'no-backing-file'. So there > is a risk that qemu 1.1 will have yet another subtly different > implementation. > [1]https://lists.gnu.org/archive/html/qemu-devel/2012-03/msg01524.html > [2]https://lists.gnu.org/archive/html/qemu-devel/2012-04/msg00886.html > > * src/qemu/qemu_monitor_json.c (qemuMonitorJSONDriveMirror) > (qemuMonitorDriveReopen): New functions. > * src/qemu/qemu_monitor_json.h (qemuMonitorJSONDriveMirror) > (qemuMonitorDriveReopen): Declare them. > * src/qemu/qemu_monitor.c (qemuMonitorDriveMirror) > (qemuMonitorDriveReopen): New passthroughs. > * src/qemu/qemu_monitor.h (qemuMonitorDriveMirror) > (qemuMonitorDriveReopen): Declare them. > --- > src/qemu/qemu_monitor.c | 50 ++++++++++++++++++++++++++++++ > src/qemu/qemu_monitor.h | 13 ++++++++ > src/qemu/qemu_monitor_json.c | 70 ++++++++++++++++++++++++++++++++++++++++++ > src/qemu/qemu_monitor_json.h | 19 ++++++++++- > 4 files changed, 150 insertions(+), 2 deletions(-) > > diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c > index e1a8d4c..969e453 100644 > --- a/src/qemu/qemu_monitor.c > +++ b/src/qemu/qemu_monitor.c > @@ -2685,6 +2685,32 @@ qemuMonitorDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr actions, > return ret; > } > > +/* Add the drive-mirror action to a transaction. */ > +int > +qemuMonitorDriveMirror(qemuMonitorPtr mon, virJSONValuePtr actions, > + const char *device, const char *file, > + const char *format, unsigned int flags) > +{ > + int ret = -1; > + > + VIR_DEBUG("mon=%p, actions=%p, device=%s, file=%s, format=%s, flags=%x", > + mon, actions, device, file, format, flags); > + > + if (!mon) { > + qemuReportError(VIR_ERR_INVALID_ARG, "%s", > + _("monitor must not be NULL")); > + return -1; > + } > + > + if (mon->json) > + ret = qemuMonitorJSONDriveMirror(mon, actions, device, file, format, > + flags); > + else > + qemuReportError(VIR_ERR_INVALID_ARG, "%s", > + _("drive-mirror requires JSON monitor")); Why is this VIR_ERR_INVALID_ARG instead of VIR_ERR_CONFIG_UNSUPPORTED? > + return ret; > +} > + > /* Use the transaction QMP command to run atomic snapshot commands. */ > int > qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr actions) > @@ -2701,6 +2727,30 @@ qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr actions) > return ret; > } > > +/* Use the drive-reopen monitor command. */ > +int > +qemuMonitorDriveReopen(qemuMonitorPtr mon, const char *device, > + const char *file, const char *format) > +{ > + int ret = -1; > + > + VIR_DEBUG("mon=%p, device=%s, file=%s, format=%s", > + mon, device, file, format); > + > + if (!mon) { > + qemuReportError(VIR_ERR_INVALID_ARG, "%s", > + _("monitor must not be NULL")); > + return -1; > + } > + > + if (mon->json) > + ret = qemuMonitorJSONDriveReopen(mon, device, file, format); > + else > + qemuReportError(VIR_ERR_INVALID_ARG, "%s", > + _("drive-reopen requires JSON monitor")); Likewise. > + return ret; > +} > + > int qemuMonitorArbitraryCommand(qemuMonitorPtr mon, > const char *cmd, > char **reply, > diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h > index 2e6ac79..0534b4a 100644 > --- a/src/qemu/qemu_monitor.h > +++ b/src/qemu/qemu_monitor.h > @@ -508,8 +508,21 @@ int qemuMonitorDiskSnapshot(qemuMonitorPtr mon, > const char *file, > const char *format, > bool reuse); > + > +int qemuMonitorDriveMirror(qemuMonitorPtr mon, > + virJSONValuePtr actions, > + const char *device, > + const char *file, > + const char *format, > + unsigned int flags) > + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); > int qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr actions) > ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); > +int qemuMonitorDriveReopen(qemuMonitorPtr mon, > + const char *device, > + const char *file, > + const char *format) > + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); > > int qemuMonitorArbitraryCommand(qemuMonitorPtr mon, > const char *cmd, > diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c > index aea3765..89f0eb8 100644 > --- a/src/qemu/qemu_monitor_json.c > +++ b/src/qemu/qemu_monitor_json.c > @@ -3189,6 +3189,49 @@ cleanup: > } > > int > +qemuMonitorJSONDriveMirror(qemuMonitorPtr mon ATTRIBUTE_UNUSED, > + virJSONValuePtr actions, > + const char *device, const char *file, > + const char *format, unsigned int flags) > +{ > + int ret = -1; > + virJSONValuePtr cmd; > + virJSONValuePtr reply = NULL; > + bool shallow = (flags & VIR_DOMAIN_BLOCK_REBASE_SHALLOW) != 0; > + bool reuse = (flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT) != 0; > + > + cmd = qemuMonitorJSONMakeCommandRaw(actions != NULL, > + "drive-mirror", > + "s:device", device, > + "s:target", file, > + "b:full", !shallow, > + "s:mode", > + reuse ? "existing" : "absolute-paths", > + format ? "s:format" : NULL, format, > + NULL); > + if (!cmd) > + return -1; > + > + if (actions) { > + if (virJSONValueArrayAppend(actions, cmd) < 0) { > + virReportOOMError(); > + } else { > + cmd = NULL; > + ret = 0; > + } > + } else { > + if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) > + goto cleanup; > + ret = qemuMonitorJSONCheckError(cmd, reply); > + } > + > +cleanup: > + virJSONValueFree(cmd); > + virJSONValueFree(reply); > + return ret; > +} > + > +int > qemuMonitorJSONTransaction(qemuMonitorPtr mon, virJSONValuePtr actions) > { > int ret = -1; > @@ -3216,6 +3259,33 @@ cleanup: > return ret; > } > > +int > +qemuMonitorJSONDriveReopen(qemuMonitorPtr mon, const char *device, > + const char *file, const char *format) > +{ > + int ret; > + virJSONValuePtr cmd; > + virJSONValuePtr reply = NULL; > + > + cmd = qemuMonitorJSONMakeCommand("drive-reopen", > + "s:device", device, > + "s:new-image-file", file, > + format ? "s:format" : NULL, format, > + NULL); > + if (!cmd) > + return -1; > + > + if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0) > + goto cleanup; > + > + ret = qemuMonitorJSONCheckError(cmd, reply); > + > +cleanup: > + virJSONValueFree(cmd); > + virJSONValueFree(reply); > + return ret; > +} > + > int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon, > const char *cmd_str, > char **reply_str, > diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h > index a0f67aa..9cfae8d 100644 > --- a/src/qemu/qemu_monitor_json.h > +++ b/src/qemu/qemu_monitor_json.h > @@ -230,8 +230,23 @@ int qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon, > const char *device, > const char *file, > const char *format, > - bool reuse); > -int qemuMonitorJSONTransaction(qemuMonitorPtr mon, virJSONValuePtr actions); > + bool reuse) > + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) > + ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5); > +int qemuMonitorJSONDriveMirror(qemuMonitorPtr mon, > + virJSONValuePtr actions, > + const char *device, > + const char *file, > + const char *format, > + unsigned int flags) > + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); > +int qemuMonitorJSONTransaction(qemuMonitorPtr mon, virJSONValuePtr actions) > + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); > +int qemuMonitorJSONDriveReopen(qemuMonitorPtr mon, > + const char *device, > + const char *file, > + const char *format) > + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); > > int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon, > const char *cmd_str, OK Jirka -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list