135 lines
4.9 KiB
Diff
135 lines
4.9 KiB
Diff
From ae80f9ec15b03d9d3ab6cfa2d48529b459a64fb2 Mon Sep 17 00:00:00 2001
|
|
From: Daniel P. Berrange <berrange@redhat.com>
|
|
Date: Mon, 6 Jul 2009 15:58:55 +0100
|
|
Subject: [PATCH] Fix PCI device hotplug/unplug with newer QEMU
|
|
|
|
* src/qemu_driver.c: Try new monitor syntax for hotplug first. If
|
|
that fails fallback to old KVM specific syntax
|
|
|
|
(cherry picked from commit 326ecb78145cfeb7706ef0dcd521b19d934950e7)
|
|
|
|
Fedora-patch: libvirt-0.6.2-hotplug-monitor-syntax.patch
|
|
---
|
|
src/qemu_driver.c | 56 +++++++++++++++++++++++++++++++++++++++-------------
|
|
1 files changed, 42 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
|
index f3661f8..8473616 100644
|
|
--- a/src/qemu_driver.c
|
|
+++ b/src/qemu_driver.c
|
|
@@ -3724,6 +3724,7 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
|
|
char *cmd, *reply, *s;
|
|
char *safe_path;
|
|
const char* type = virDomainDiskBusTypeToString(dev->data.disk->bus);
|
|
+ int tryOldSyntax = 0;
|
|
|
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
|
|
@@ -3738,14 +3739,15 @@ 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 0 storage file=%s,if=%s",
|
|
- safe_path, type);
|
|
+ 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);
|
|
@@ -3761,17 +3763,27 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn,
|
|
|
|
DEBUG ("%s: pci_add reply: %s", vm->def->name, reply);
|
|
/* If the command succeeds qemu prints:
|
|
- * OK bus 0... */
|
|
-#define PCI_ATTACH_OK_MSG "OK bus 0, slot "
|
|
- if ((s=strstr(reply, PCI_ATTACH_OK_MSG))) {
|
|
- char* dummy = s;
|
|
- s += strlen(PCI_ATTACH_OK_MSG);
|
|
+ * OK bus 0, slot XXX...
|
|
+ * or
|
|
+ * OK domain 0, bus 0, slot XXX
|
|
+ */
|
|
+ if ((s = strstr(reply, "OK ")) &&
|
|
+ (s = strstr(s, "slot "))) {
|
|
+ char *dummy = s;
|
|
+ s += strlen("slot ");
|
|
|
|
if (virStrToLong_i ((const char*)s, &dummy, 10, &dev->data.disk->slotnum) == -1)
|
|
VIR_WARN("%s", _("Unable to parse slot number\n"));
|
|
+ /* XXX not neccessarily always going to end up in domain 0 / bus 0 :-( */
|
|
+ /* XXX this slotnum is not persistant across restarts :-( */
|
|
+ } else if (!tryOldSyntax && strstr(reply, "invalid char in expression")) {
|
|
+ VIR_FREE(reply);
|
|
+ VIR_FREE(cmd);
|
|
+ tryOldSyntax = 1;
|
|
+ goto try_command;
|
|
} else {
|
|
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
|
|
- _("adding %s disk failed"), type);
|
|
+ _("adding %s disk failed: %s"), type, reply);
|
|
VIR_FREE(reply);
|
|
VIR_FREE(cmd);
|
|
return -1;
|
|
@@ -3990,6 +4002,7 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
|
|
char *cmd = NULL;
|
|
char *reply = NULL;
|
|
virDomainDiskDefPtr detach = NULL;
|
|
+ int tryOldSyntax = 0;
|
|
|
|
for (i = 0 ; i < vm->def->ndisks ; i++) {
|
|
if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
|
|
@@ -4011,9 +4024,17 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
|
|
goto cleanup;
|
|
}
|
|
|
|
- if (virAsprintf(&cmd, "pci_del 0 %d", detach->slotnum) < 0) {
|
|
- virReportOOMError(conn);
|
|
- goto cleanup;
|
|
+try_command:
|
|
+ if (tryOldSyntax) {
|
|
+ if (virAsprintf(&cmd, "pci_del 0 %d", detach->slotnum) < 0) {
|
|
+ virReportOOMError(conn);
|
|
+ goto cleanup;
|
|
+ }
|
|
+ } else {
|
|
+ if (virAsprintf(&cmd, "pci_del pci_addr=0:0:%d", detach->slotnum) < 0) {
|
|
+ virReportOOMError(conn);
|
|
+ goto cleanup;
|
|
+ }
|
|
}
|
|
|
|
if (qemudMonitorCommand(vm, cmd, &reply) < 0) {
|
|
@@ -4023,12 +4044,19 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn,
|
|
}
|
|
|
|
DEBUG ("%s: pci_del reply: %s",vm->def->name, reply);
|
|
+
|
|
+ if (!tryOldSyntax &&
|
|
+ strstr(reply, "extraneous characters")) {
|
|
+ tryOldSyntax = 1;
|
|
+ goto try_command;
|
|
+ }
|
|
/* If the command fails due to a wrong slot qemu prints: invalid slot,
|
|
* nothing is printed on success */
|
|
- if (strstr(reply, "invalid slot")) {
|
|
+ if (strstr(reply, "invalid slot") ||
|
|
+ strstr(reply, "Invalid pci address")) {
|
|
qemudReportError (conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
|
|
- _("failed to detach disk %s: invalid slot %d"),
|
|
- detach->dst, detach->slotnum);
|
|
+ _("failed to detach disk %s: invalid slot %d: %s"),
|
|
+ detach->dst, detach->slotnum, reply);
|
|
goto cleanup;
|
|
}
|
|
|
|
--
|
|
1.6.2.5
|
|
|