|
|
9119d9 |
From 5fe7a27d876a94c77d23b5e846f8af58756125c3 Mon Sep 17 00:00:00 2001
|
|
|
9119d9 |
Message-Id: <5fe7a27d876a94c77d23b5e846f8af58756125c3@dist-git>
|
|
|
9119d9 |
From: Laine Stump <laine@laine.org>
|
|
|
9119d9 |
Date: Mon, 3 Nov 2014 10:00:20 -0500
|
|
|
9119d9 |
Subject: [PATCH] qemu: setup infrastructure to handle NIC_RX_FILTER_CHANGED
|
|
|
9119d9 |
event
|
|
|
9119d9 |
|
|
|
9119d9 |
https://bugzilla.redhat.com/show_bug.cgi?id=848199
|
|
|
9119d9 |
|
|
|
9119d9 |
NIC_RX_FILTER_CHANGED is sent by qemu any time a NIC driver in the
|
|
|
9119d9 |
guest modified the NIC's RX Filter (for example, if the MAC address of
|
|
|
9119d9 |
the NIC is changed by the guest).
|
|
|
9119d9 |
|
|
|
9119d9 |
This patch doesn't do anything useful with that event; it just sets up
|
|
|
9119d9 |
all the plumbing to get news of the event into a worker thread with
|
|
|
9119d9 |
all proper locking/reference counting, and provide an easy place to
|
|
|
9119d9 |
add in desired functionality.
|
|
|
9119d9 |
|
|
|
9119d9 |
See src/qemu/EVENTHANDLERS.txt for information/instructions on adding
|
|
|
9119d9 |
a libvirt-internal handler for a qemu event (using
|
|
|
9119d9 |
NIC_RX_FILTER_CHANGED as an example).
|
|
|
9119d9 |
|
|
|
9119d9 |
(cherry picked from commit b6bdda458ab08353dc2b664d026de6322c7db680)
|
|
|
9119d9 |
|
|
|
9119d9 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
9119d9 |
---
|
|
|
9119d9 |
src/qemu/qemu_domain.h | 1 +
|
|
|
9119d9 |
src/qemu/qemu_driver.c | 55 ++++++++++++++++++++++++++++++++++++++++++++
|
|
|
9119d9 |
src/qemu/qemu_monitor.c | 13 +++++++++++
|
|
|
9119d9 |
src/qemu/qemu_monitor.h | 7 ++++++
|
|
|
9119d9 |
src/qemu/qemu_monitor_json.c | 17 ++++++++++++++
|
|
|
9119d9 |
src/qemu/qemu_process.c | 42 +++++++++++++++++++++++++++++++++
|
|
|
9119d9 |
6 files changed, 135 insertions(+)
|
|
|
9119d9 |
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
|
|
|
9119d9 |
index 845d3c7..ad45a66 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_domain.h
|
|
|
9119d9 |
+++ b/src/qemu/qemu_domain.h
|
|
|
9119d9 |
@@ -195,6 +195,7 @@ typedef enum {
|
|
|
9119d9 |
QEMU_PROCESS_EVENT_WATCHDOG = 0,
|
|
|
9119d9 |
QEMU_PROCESS_EVENT_GUESTPANIC,
|
|
|
9119d9 |
QEMU_PROCESS_EVENT_DEVICE_DELETED,
|
|
|
9119d9 |
+ QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED,
|
|
|
9119d9 |
|
|
|
9119d9 |
QEMU_PROCESS_EVENT_LAST
|
|
|
9119d9 |
} qemuProcessEventType;
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
9119d9 |
index c158f64..29deb76 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_driver.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_driver.c
|
|
|
9119d9 |
@@ -4147,6 +4147,58 @@ processDeviceDeletedEvent(virQEMUDriverPtr driver,
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
|
|
|
9119d9 |
+static void
|
|
|
9119d9 |
+processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
|
|
|
9119d9 |
+ virDomainObjPtr vm,
|
|
|
9119d9 |
+ char *devAlias)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
|
|
9119d9 |
+ virDomainDeviceDef dev;
|
|
|
9119d9 |
+ virDomainNetDefPtr def;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ VIR_DEBUG("Received NIC_RX_FILTER_CHANGED event for device %s "
|
|
|
9119d9 |
+ "from domain %p %s",
|
|
|
9119d9 |
+ devAlias, vm, vm->def->name);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!virDomainObjIsActive(vm)) {
|
|
|
9119d9 |
+ VIR_DEBUG("Domain is not running");
|
|
|
9119d9 |
+ goto endjob;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (virDomainDefFindDevice(vm->def, devAlias, &dev, true) < 0) {
|
|
|
9119d9 |
+ VIR_WARN("NIC_RX_FILTER_CHANGED event received for "
|
|
|
9119d9 |
+ "non-existent device %s in domain %s",
|
|
|
9119d9 |
+ devAlias, vm->def->name);
|
|
|
9119d9 |
+ goto endjob;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ if (dev.type != VIR_DOMAIN_DEVICE_NET) {
|
|
|
9119d9 |
+ VIR_WARN("NIC_RX_FILTER_CHANGED event received for "
|
|
|
9119d9 |
+ "non-network device %s in domain %s",
|
|
|
9119d9 |
+ devAlias, vm->def->name);
|
|
|
9119d9 |
+ goto endjob;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ def = dev.data.net;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ /* handle the event - send query-rx-filter and respond to it. */
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ VIR_DEBUG("process NIC_RX_FILTER_CHANGED event for network "
|
|
|
9119d9 |
+ "device %s in domain %s", def->info.alias, vm->def->name);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ endjob:
|
|
|
9119d9 |
+ /* We had an extra reference to vm before starting a new job so ending the
|
|
|
9119d9 |
+ * job is guaranteed not to remove the last reference.
|
|
|
9119d9 |
+ */
|
|
|
9119d9 |
+ ignore_value(qemuDomainObjEndJob(driver, vm));
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ cleanup:
|
|
|
9119d9 |
+ VIR_FREE(devAlias);
|
|
|
9119d9 |
+ virObjectUnref(cfg);
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+
|
|
|
9119d9 |
static void qemuProcessEventHandler(void *data, void *opaque)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
struct qemuProcessEvent *processEvent = data;
|
|
|
9119d9 |
@@ -4167,6 +4219,9 @@ static void qemuProcessEventHandler(void *data, void *opaque)
|
|
|
9119d9 |
case QEMU_PROCESS_EVENT_DEVICE_DELETED:
|
|
|
9119d9 |
processDeviceDeletedEvent(driver, vm, processEvent->data);
|
|
|
9119d9 |
break;
|
|
|
9119d9 |
+ case QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED:
|
|
|
9119d9 |
+ processNicRxFilterChangedEvent(driver, vm, processEvent->data);
|
|
|
9119d9 |
+ break;
|
|
|
9119d9 |
case QEMU_PROCESS_EVENT_LAST:
|
|
|
9119d9 |
break;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
|
|
|
9119d9 |
index be8d60b..b516880 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor.c
|
|
|
9119d9 |
@@ -1391,6 +1391,19 @@ qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon,
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
|
|
|
9119d9 |
+int
|
|
|
9119d9 |
+qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
|
|
|
9119d9 |
+ const char *devAlias)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ int ret = -1;
|
|
|
9119d9 |
+ VIR_DEBUG("mon=%p", mon);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ QEMU_MONITOR_CALLBACK(mon, ret, domainNicRxFilterChanged, mon->vm, devAlias);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ return ret;
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+
|
|
|
9119d9 |
int qemuMonitorSetCapabilities(qemuMonitorPtr mon)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
int ret;
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
|
|
|
9119d9 |
index cfcaf30..69f41bf 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor.h
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor.h
|
|
|
9119d9 |
@@ -171,6 +171,10 @@ typedef int (*qemuMonitorDomainDeviceDeletedCallback)(qemuMonitorPtr mon,
|
|
|
9119d9 |
virDomainObjPtr vm,
|
|
|
9119d9 |
const char *devAlias,
|
|
|
9119d9 |
void *opaque);
|
|
|
9119d9 |
+typedef int (*qemuMonitorDomainNicRxFilterChangedCallback)(qemuMonitorPtr mon,
|
|
|
9119d9 |
+ virDomainObjPtr vm,
|
|
|
9119d9 |
+ const char *devAlias,
|
|
|
9119d9 |
+ void *opaque);
|
|
|
9119d9 |
|
|
|
9119d9 |
typedef struct _qemuMonitorCallbacks qemuMonitorCallbacks;
|
|
|
9119d9 |
typedef qemuMonitorCallbacks *qemuMonitorCallbacksPtr;
|
|
|
9119d9 |
@@ -197,6 +201,7 @@ struct _qemuMonitorCallbacks {
|
|
|
9119d9 |
qemuMonitorDomainPMSuspendDiskCallback domainPMSuspendDisk;
|
|
|
9119d9 |
qemuMonitorDomainGuestPanicCallback domainGuestPanic;
|
|
|
9119d9 |
qemuMonitorDomainDeviceDeletedCallback domainDeviceDeleted;
|
|
|
9119d9 |
+ qemuMonitorDomainNicRxFilterChangedCallback domainNicRxFilterChanged;
|
|
|
9119d9 |
};
|
|
|
9119d9 |
|
|
|
9119d9 |
char *qemuMonitorEscapeArg(const char *in);
|
|
|
9119d9 |
@@ -285,6 +290,8 @@ int qemuMonitorEmitPMSuspendDisk(qemuMonitorPtr mon);
|
|
|
9119d9 |
int qemuMonitorEmitGuestPanic(qemuMonitorPtr mon);
|
|
|
9119d9 |
int qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon,
|
|
|
9119d9 |
const char *devAlias);
|
|
|
9119d9 |
+int qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
|
|
|
9119d9 |
+ const char *devAlias);
|
|
|
9119d9 |
|
|
|
9119d9 |
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
|
|
|
9119d9 |
virConnectPtr conn);
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
|
|
|
9119d9 |
index 7a6d1e1..4fb1d81 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_monitor_json.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_monitor_json.c
|
|
|
9119d9 |
@@ -81,6 +81,7 @@ static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValueP
|
|
|
9119d9 |
static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data);
|
|
|
9119d9 |
static void qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, virJSONValuePtr data);
|
|
|
9119d9 |
static void qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSONValuePtr data);
|
|
|
9119d9 |
+static void qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, virJSONValuePtr data);
|
|
|
9119d9 |
|
|
|
9119d9 |
typedef struct {
|
|
|
9119d9 |
const char *type;
|
|
|
9119d9 |
@@ -96,6 +97,7 @@ static qemuEventHandler eventHandlers[] = {
|
|
|
9119d9 |
{ "DEVICE_DELETED", qemuMonitorJSONHandleDeviceDeleted, },
|
|
|
9119d9 |
{ "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
|
|
|
9119d9 |
{ "GUEST_PANICKED", qemuMonitorJSONHandleGuestPanic, },
|
|
|
9119d9 |
+ { "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged, },
|
|
|
9119d9 |
{ "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
|
|
|
9119d9 |
{ "RESET", qemuMonitorJSONHandleReset, },
|
|
|
9119d9 |
{ "RESUME", qemuMonitorJSONHandleResume, },
|
|
|
9119d9 |
@@ -1021,6 +1023,21 @@ qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSONValuePtr data)
|
|
|
9119d9 |
qemuMonitorEmitDeviceDeleted(mon, device);
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+static void
|
|
|
9119d9 |
+qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, virJSONValuePtr data)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ const char *name;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!(name = virJSONValueObjectGetString(data, "name"))) {
|
|
|
9119d9 |
+ VIR_WARN("missing device in NIC_RX_FILTER_CHANGED event");
|
|
|
9119d9 |
+ return;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ qemuMonitorEmitNicRxFilterChanged(mon, name);
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+
|
|
|
9119d9 |
int
|
|
|
9119d9 |
qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
|
|
|
9119d9 |
const char *cmd_str,
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|
|
9119d9 |
index e711b5f..7101311 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_process.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_process.c
|
|
|
9119d9 |
@@ -1488,6 +1488,47 @@ qemuProcessHandleDeviceDeleted(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
|
|
|
9119d9 |
+static int
|
|
|
9119d9 |
+qemuProcessHandleNicRxFilterChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|
|
9119d9 |
+ virDomainObjPtr vm,
|
|
|
9119d9 |
+ const char *devAlias,
|
|
|
9119d9 |
+ void *opaque)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ virQEMUDriverPtr driver = opaque;
|
|
|
9119d9 |
+ struct qemuProcessEvent *processEvent = NULL;
|
|
|
9119d9 |
+ char *data;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ virObjectLock(vm);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ VIR_DEBUG("Device %s RX Filter changed in domain %p %s",
|
|
|
9119d9 |
+ devAlias, vm, vm->def->name);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (VIR_ALLOC(processEvent) < 0)
|
|
|
9119d9 |
+ goto error;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ processEvent->eventType = QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED;
|
|
|
9119d9 |
+ if (VIR_STRDUP(data, devAlias) < 0)
|
|
|
9119d9 |
+ goto error;
|
|
|
9119d9 |
+ processEvent->data = data;
|
|
|
9119d9 |
+ processEvent->vm = vm;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ virObjectRef(vm);
|
|
|
9119d9 |
+ if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
|
|
|
9119d9 |
+ ignore_value(virObjectUnref(vm));
|
|
|
9119d9 |
+ goto error;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ cleanup:
|
|
|
9119d9 |
+ virObjectUnlock(vm);
|
|
|
9119d9 |
+ return 0;
|
|
|
9119d9 |
+ error:
|
|
|
9119d9 |
+ if (processEvent)
|
|
|
9119d9 |
+ VIR_FREE(processEvent->data);
|
|
|
9119d9 |
+ VIR_FREE(processEvent);
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+
|
|
|
9119d9 |
static qemuMonitorCallbacks monitorCallbacks = {
|
|
|
9119d9 |
.eofNotify = qemuProcessHandleMonitorEOF,
|
|
|
9119d9 |
.errorNotify = qemuProcessHandleMonitorError,
|
|
|
9119d9 |
@@ -1509,6 +1550,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
|
|
|
9119d9 |
.domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
|
|
|
9119d9 |
.domainGuestPanic = qemuProcessHandleGuestPanic,
|
|
|
9119d9 |
.domainDeviceDeleted = qemuProcessHandleDeviceDeleted,
|
|
|
9119d9 |
+ .domainNicRxFilterChanged = qemuProcessHandleNicRxFilterChanged,
|
|
|
9119d9 |
};
|
|
|
9119d9 |
|
|
|
9119d9 |
static int
|
|
|
9119d9 |
--
|
|
|
9119d9 |
2.1.3
|
|
|
9119d9 |
|