diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5f17bfb8194843d7bb0f7797a0ecb673eb55aedf..5a061a4652548c86f84e6052c62c0daec925f1cb 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); - 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); + 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; - } - - 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 030faf84ea930735822f0ec94061c1ffb1d01dad..7dd9ac37d89ec71d1c78f436d7e495eb7f44b849 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 41f57b08e042db3384b4cf8f5f8090171d73b8de..188d3cb9eed12b94be2c6d152d3332bad65fc653 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,