From 85df93399c9ec4252a15649bbbee5c7d1badb8b8 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Wed, 23 Sep 2009 16:38:44 +0100 Subject: [PATCH] Add API for issuing 'pci_add storage' monitor command * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new API qemuMonitorAddPCIDisk() * src/qemu/qemu_driver.c: Convert over to using the new qemuMonitorAddPCIDisk() method, and remove now obsolete qemudEscape() method --- src/qemu/qemu_driver.c | 130 ++--------------------------------- src/qemu/qemu_monitor_text.c | 56 +++++++++++++++ src/qemu/qemu_monitor_text.h | 13 ++++ 3 files changed, 76 insertions(+), 123 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5f17bfb819..5a061a4652 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3093,83 +3093,6 @@ cleanup: } -static char *qemudEscape(const char *in, int shell) -{ - int len = 0; - int i, j; - char *out; - - /* To pass through the QEMU monitor, we need to use escape - sequences: \r, \n, \", \\ - - To pass through both QEMU + the shell, we need to escape - the single character ' as the five characters '\\'' - */ - - for (i = 0; in[i] != '\0'; i++) { - switch(in[i]) { - case '\r': - case '\n': - case '"': - case '\\': - len += 2; - break; - case '\'': - if (shell) - len += 5; - else - len += 1; - break; - default: - len += 1; - break; - } - } - - if (VIR_ALLOC_N(out, len + 1) < 0) - return NULL; - - for (i = j = 0; in[i] != '\0'; i++) { - switch(in[i]) { - case '\r': - out[j++] = '\\'; - out[j++] = 'r'; - break; - case '\n': - out[j++] = '\\'; - out[j++] = 'n'; - break; - case '"': - case '\\': - out[j++] = '\\'; - out[j++] = in[i]; - break; - case '\'': - if (shell) { - out[j++] = '\''; - out[j++] = '\\'; - out[j++] = '\\'; - out[j++] = '\''; - out[j++] = '\''; - } else { - out[j++] = in[i]; - } - break; - default: - out[j++] = in[i]; - break; - } - } - out[j] = '\0'; - - return out; -} - -static char *qemudEscapeMonitorArg(const char *in) -{ - return qemudEscape(in, 0); -} - #define QEMUD_SAVE_MAGIC "LibvirtQemudSave" #define QEMUD_SAVE_VERSION 2 @@ -4626,12 +4549,8 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn, virDomainObjPtr vm, virDomainDeviceDefPtr dev) { - int ret, i; - char *cmd, *reply; - char *safe_path; + int i; const char* type = virDomainDiskBusTypeToString(dev->data.disk->bus); - int tryOldSyntax = 0; - unsigned domain, bus, slot; for (i = 0 ; i < vm->def->ndisks ; i++) { if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) { @@ -4646,48 +4565,13 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn, return -1; } -try_command: - safe_path = qemudEscapeMonitorArg(dev->data.disk->src); - if (!safe_path) { - virReportOOMError(conn); + if (qemuMonitorAddPCIDisk(vm, + dev->data.disk->src, + type, + &dev->data.disk->pci_addr.domain, + &dev->data.disk->pci_addr.bus, + &dev->data.disk->pci_addr.slot) < 0) return -1; - } - - ret = virAsprintf(&cmd, "pci_add %s storage file=%s,if=%s", - (tryOldSyntax ? "0": "pci_addr=auto"), safe_path, type); - VIR_FREE(safe_path); - if (ret == -1) { - virReportOOMError(conn); - return ret; - } - - if (qemudMonitorCommand(vm, cmd, &reply) < 0) { - qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - _("cannot attach %s disk"), type); - VIR_FREE(cmd); - return -1; - } - - VIR_FREE(cmd); - - if (qemudParsePciAddReply(vm, reply, &domain, &bus, &slot) < 0) { - if (!tryOldSyntax && strstr(reply, "invalid char in expression")) { - VIR_FREE(reply); - tryOldSyntax = 1; - goto try_command; - } - - qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - _("adding %s disk failed: %s"), type, reply); - VIR_FREE(reply); - return -1; - } - - VIR_FREE(reply); - - dev->data.disk->pci_addr.domain = domain; - dev->data.disk->pci_addr.bus = bus; - dev->data.disk->pci_addr.slot = slot; virDomainDiskInsertPreAlloced(vm->def, dev->data.disk); diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 030faf84ea..7dd9ac37d8 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1437,6 +1437,62 @@ cleanup: } +int qemuMonitorAddPCIDisk(const virDomainObjPtr vm, + const char *path, + const char *bus, + unsigned *guestDomain, + unsigned *guestBus, + unsigned *guestSlot) { + char *cmd = NULL; + char *reply = NULL; + char *safe_path = NULL; + int tryOldSyntax = 0; + int ret = -1; + + safe_path = qemudEscapeMonitorArg(path); + if (!safe_path) { + virReportOOMError(NULL); + return -1; + } + +try_command: + if (virAsprintf(&cmd, "pci_add %s storage file=%s,if=%s", + (tryOldSyntax ? "0": "pci_addr=auto"), safe_path, bus) < 0) { + virReportOOMError(NULL); + goto cleanup; + } + + if (qemudMonitorCommand(vm, cmd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("cannot attach %s disk %s"), bus, path); + goto cleanup; + } + + if (qemuMonitorParsePciAddReply(vm, reply, + guestDomain, guestBus, guestSlot) < 0) { + if (!tryOldSyntax && strstr(reply, "invalid char in expression")) { + VIR_FREE(reply); + VIR_FREE(cmd); + tryOldSyntax = 1; + goto try_command; + } + + qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("adding %s disk failed %s: %s"), bus, path, reply); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(safe_path); + VIR_FREE(cmd); + VIR_FREE(reply); + return ret; +} + + + int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm, unsigned guestDomain, unsigned guestBus, diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index 41f57b08e0..188d3cb9ee 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -137,6 +137,9 @@ int qemuMonitorMigrateToCommand(const virDomainObjPtr vm, const char *target); +/* XXX disk driver type eg, qcow/etc. + * XXX cache mode + */ int qemuMonitorAddUSBDisk(const virDomainObjPtr vm, const char *path); @@ -157,6 +160,16 @@ int qemuMonitorAddPCIHostDevice(const virDomainObjPtr vm, unsigned *guestBus, unsigned *guestSlot); +/* XXX disk driver type eg, qcow/etc. + * XXX cache mode + */ +int qemuMonitorAddPCIDisk(const virDomainObjPtr vm, + const char *path, + const char *bus, + unsigned *guestDomain, + unsigned *guestBus, + unsigned *guestSlot); + int qemuMonitorRemovePCIDevice(const virDomainObjPtr vm, unsigned guestDomain, unsigned guestBus,