Hi! I use QEMU via QMP and I've discovered that for some tasks there
is no proper way to do them via QMP. I've written few patches:
* One of them modifies pci_add command to return pci address of the
added device, when user hasn't specified it (to be able to delete it
via pci_del in the future).
* The second one adds INCOMING_FINISHED QMP event which is emitted
when QEMU finished incoming migration (when started with -incoming
command line option). It is needed because now there is no way to
determine, whether it finished or not, and QMP cont command just
returns error.
It will be awesome if you include this patches to the upstream (I've
attached them to this message).
--
Dmitry Konishchev
mailto:konishc...@gmail.com
From f7e7119fecbce280e7ee45364260fb6e4d58d49a Mon Sep 17 00:00:00 2001
From: Dmitry Konishchev konishc...@gmail.com
Date: Wed, 16 Mar 2011 12:26:09 +0300
Subject: [PATCH 1/2] QMP: Return pci address in pci_add command
---
hw/pci-hotplug.c | 17 +++--
qemu-monitor.hx |4 +++-
sysemu.h |2 +-
3 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index 6b2de85..23c105f 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -32,6 +32,7 @@
#include virtio-blk.h
#include qemu-config.h
#include device-assignment.h
+#include qjson.h
#if defined(TARGET_I386)
static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
@@ -247,7 +248,7 @@ static PCIDevice *qemu_pci_hot_assign_device(Monitor *mon,
}
#endif /* CONFIG_KVM_DEVICE_ASSIGNMENT */
-void pci_device_hot_add(Monitor *mon, const QDict *qdict)
+int pci_device_hot_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
PCIDevice *dev = NULL;
const char *pci_addr = qdict_get_str(qdict, pci_addr);
@@ -283,8 +284,20 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict)
pci_find_domain(dev-bus),
pci_bus_num(dev-bus), PCI_SLOT(dev-devfn),
PCI_FUNC(dev-devfn));
-} else
+
+char format[] = { 'domain': '%x', 'bus': '%x', 'slot': '%x' };
+char buf[sizeof format + 3 * sizeof(int) * 2];
+snprintf(buf, sizeof buf, format,
+pci_find_domain(dev-bus), pci_bus_num(dev-bus), PCI_SLOT(dev-devfn));
+
+*ret_data = qobject_from_json(buf);
+assert(*ret_data != NULL);
+} else {
monitor_printf(mon, failed to add %s\n, opts);
+qerror_report(QERR_UNDEFINED_ERROR);
+}
+
+return !dev;
}
#endif
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 595d362..8b1415d 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -1149,7 +1149,8 @@ ETEXI
.args_type = pci_addr:s,type:s,opts:s?,
.params = auto|[[domain:]bus:]slot nic|storage|host [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]... [host=02:00.0[,name=string][,dma=none],
.help = hot-add PCI device,
-.mhandler.cmd = pci_device_hot_add,
+.user_print = monitor_user_noop,
+.mhandler.cmd_new = pci_device_hot_add,
},
#endif
@@ -1165,6 +1166,7 @@ ETEXI
.args_type = pci_addr:s,
.params = [[domain:]bus:]slot,
.help = hot remove PCI device,
+.user_print = monitor_user_noop,
.mhandler.cmd = do_pci_device_hot_remove,
},
#endif
diff --git a/sysemu.h b/sysemu.h
index 98bd47d..99f890c 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -153,7 +153,7 @@ extern unsigned int nb_prom_envs;
void qemu_system_cpu_hot_add(int cpu, int state);
/* pci-hotplug */
-void pci_device_hot_add(Monitor *mon, const QDict *qdict);
+int pci_device_hot_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
void drive_hot_add(Monitor *mon, const QDict *qdict);
void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict);
--
1.7.1
From 97250c2a7eeb1506e0a1517b416046dd02720025 Mon Sep 17 00:00:00 2001
From: Dmitry Konishchev konishc...@gmail.com
Date: Wed, 16 Mar 2011 12:31:52 +0300
Subject: [PATCH 2/2] Added a way for user to determine, whether incoming migration is finished or not
---
migration.c |1 +
monitor.c | 24
monitor.h |1 +
qemu-monitor.hx | 19 +++
4 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/migration.c b/migration.c
index 468d517..1898bcc 100644
--- a/migration.c
+++ b/migration.c
@@ -68,6 +68,7 @@ void process_incoming_migration(QEMUFile *f)
DPRINTF(successfully loaded vm state\n);
incoming_expected = false;
+monitor_protocol_event(QEVENT_INCOMING_FINISHED, NULL);
if (autostart)
vm_start();
diff --git a/monitor.c b/monitor.c
index dd5469f..6338827 100644
--- a/monitor.c
+++ b/monitor.c
@@ -454,6 +454,9 @@ void monitor_protocol_event(MonitorEvent event, QObject *data)
case QEVENT_WATCHDOG:
event_name = WATCHDOG;
break;
+case QEVENT_INCOMING_FINISHED:
+event_name