libvirt/libvirt-0.6.2-hotplug-monit...

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