
On Thu, 2009-09-24 at 16:00 +0100, Daniel P. Berrange wrote:
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new APis qemuMonitorChangeMedia and qemuMonitorEjectMedia. Pull in code for qemudEscape * src/qemu/qemu_driver.c: Remove code that directly issues 'eject' and 'change' commands in favour of API calls. --- src/qemu/qemu_driver.c | 52 +++----------- src/qemu/qemu_monitor_text.c | 159 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_text.h | 10 +++ 3 files changed, 178 insertions(+), 43 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index a0b5e49..b15dc03 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4573,9 +4573,9 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn, unsigned int qemuCmdFlags) { virDomainDiskDefPtr origdisk = NULL, newdisk; - char *cmd, *reply, *safe_path; char *devname = NULL; int i; + int ret;
origdisk = NULL; newdisk = dev->data.disk; @@ -4621,52 +4621,18 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn, }
if (newdisk->src) { - safe_path = qemudEscapeMonitorArg(newdisk->src); - if (!safe_path) { - virReportOOMError(conn); - VIR_FREE(devname); - return -1; - } - if (virAsprintf(&cmd, "change %s \"%s\"", devname, safe_path) == -1) { - virReportOOMError(conn); - VIR_FREE(safe_path); - VIR_FREE(devname); - return -1; - } - VIR_FREE(safe_path); - - } else if (virAsprintf(&cmd, "eject %s", devname) == -1) { - virReportOOMError(conn); - VIR_FREE(devname); - return -1; - } - VIR_FREE(devname); - - if (qemudMonitorCommand(vm, cmd, &reply) < 0) { - qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("could not change cdrom media")); - VIR_FREE(cmd); - return -1; + ret = qemuMonitorChangeMedia(vm, devname, newdisk->src); + } else { + ret = qemuMonitorEjectMedia(vm, devname); }
- /* If the command failed qemu prints: - * device not found, device is locked ... - * No message is printed on success it seems */ - DEBUG ("%s: ejectable media change reply: %s", vm->def->name, reply); - if (strstr(reply, "\ndevice ")) { - qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - _("changing cdrom media failed: %s"), reply); - VIR_FREE(reply); - VIR_FREE(cmd); - return -1; + if (ret == 0) { + VIR_FREE(origdisk->src); + origdisk->src = newdisk->src; + newdisk->src = NULL; + origdisk->type = newdisk->type; } - VIR_FREE(reply); - VIR_FREE(cmd);
- VIR_FREE(origdisk->src); - origdisk->src = newdisk->src; - newdisk->src = NULL; - origdisk->type = newdisk->type; return 0;
Should return ret here
}
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index be13dce..8be8047 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -40,6 +40,84 @@
#define VIR_FROM_THIS VIR_FROM_QEMU
+static char *qemudEscape(const char *in, int shell) +{
Personally, rather than creating a copy of the code, I'd have moved it and exported it back to qemu_driver.c - end result is the same, but the way you've done it, I couldn't just look at the patch to confirm that the copy of the code was the same as the original ...
@@ -651,3 +729,84 @@ int qemuMonitorSetBalloon(const virDomainObjPtr vm, return ret; }
+int qemuMonitorEjectMedia(const virDomainObjPtr vm, + const char *devname) +{ + char *cmd = NULL; + char *reply = NULL; + int ret = -1; + + if (virAsprintf(&cmd, "eject %s", devname) < 0) { + virReportOOMError(NULL); + goto cleanup; + } + + if (qemudMonitorCommand(vm, cmd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("could not eject media on %s"), devname); + goto cleanup; + } + + /* If the command failed qemu prints: + * device not found, device is locked ... + * No message is printed on success it seems */ + DEBUG ("%s: ejectable media change reply: %s", vm->def->name, reply); + if (strstr(reply, "\ndevice ")) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("could not eject media on %s: %s"), devname, reply); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(reply); + VIR_FREE(cmd); + return ret; +} + + +int qemuMonitorChangeMedia(const virDomainObjPtr vm, + const char *devname, + const char *newmedia) +{ + char *cmd = NULL; + char *reply = NULL; + char *safepath = NULL; + int ret = -1; + + if (!(safepath = qemudEscapeMonitorArg(newmedia))) { + virReportOOMError(NULL); + goto cleanup; + } + + if (virAsprintf(&cmd, "change %s \"%s\"", devname, safepath) < 0) { + virReportOOMError(NULL); + goto cleanup; + } + + if (qemudMonitorCommand(vm, cmd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("could not eject media on %s"), devname); + goto cleanup; + } + + /* If the command failed qemu prints: + * device not found, device is locked ... + * No message is printed on success it seems */ + DEBUG ("%s: ejectable media change reply: %s", vm->def->name, reply); + if (strstr(reply, "\ndevice ")) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("could not eject media on %s: %s"), devname, reply); + goto cleanup; + }
Pity this code is duplicated Should be 'could not eject' here Otherwise, ACK Cheers, Mark.