QEMU_PROCESS_EVENT_WATCHDOG = 0,
QEMU_PROCESS_EVENT_GUESTPANIC,
QEMU_PROCESS_EVENT_DEVICE_DELETED,
+ QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED,
QEMU_PROCESS_EVENT_LAST
} qemuProcessEventType;
}
+static void
+processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ char *devAlias)
+{
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ virDomainDeviceDef dev;
+ virDomainNetDefPtr def;
+
+ VIR_DEBUG("Received NIC_RX_FILTER_CHANGED event for device %s "
+ "from domain %p %s",
+ devAlias, vm, vm->def->name);
+
+ if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ VIR_DEBUG("Domain is not running");
+ goto endjob;
+ }
+
+ if (virDomainDefFindDevice(vm->def, devAlias, &dev, true) < 0) {
+ VIR_WARN("NIC_RX_FILTER_CHANGED event received for "
+ "non-existent device %s in domain %s",
+ devAlias, vm->def->name);
+ goto endjob;
+ }
+ if (dev.type != VIR_DOMAIN_DEVICE_NET) {
+ VIR_WARN("NIC_RX_FILTER_CHANGED event received for "
+ "non-network device %s in domain %s",
+ devAlias, vm->def->name);
+ goto endjob;
+ }
+ def = dev.data.net;
+
+ /* handle the event - send query-rx-filter and respond to it. */
+
+ VIR_DEBUG("process NIC_RX_FILTER_CHANGED event for network "
+ "device %s in domain %s", def->info.alias, vm->def->name);
+
+ endjob:
+ /* We had an extra reference to vm before starting a new job so ending the
+ * job is guaranteed not to remove the last reference.
+ */
+ ignore_value(qemuDomainObjEndJob(driver, vm));
+
+ cleanup:
+ VIR_FREE(devAlias);
+ virObjectUnref(cfg);
+}
+
+
static void qemuProcessEventHandler(void *data, void *opaque)
{
struct qemuProcessEvent *processEvent = data;
case QEMU_PROCESS_EVENT_DEVICE_DELETED:
processDeviceDeletedEvent(driver, vm, processEvent->data);
break;
+ case QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED:
+ processNicRxFilterChangedEvent(driver, vm, processEvent->data);
+ break;
case QEMU_PROCESS_EVENT_LAST:
break;
}
}
+int
+qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
+ const char *devAlias)
+{
+ int ret = -1;
+ VIR_DEBUG("mon=%p", mon);
+
+ QEMU_MONITOR_CALLBACK(mon, ret, domainNicRxFilterChanged, mon->vm, devAlias);
+
+ return ret;
+}
+
+
int qemuMonitorSetCapabilities(qemuMonitorPtr mon)
{
int ret;
virDomainObjPtr vm,
const char *devAlias,
void *opaque);
+typedef int (*qemuMonitorDomainNicRxFilterChangedCallback)(qemuMonitorPtr mon,
+ virDomainObjPtr vm,
+ const char *devAlias,
+ void *opaque);
typedef struct _qemuMonitorCallbacks qemuMonitorCallbacks;
typedef qemuMonitorCallbacks *qemuMonitorCallbacksPtr;
qemuMonitorDomainPMSuspendDiskCallback domainPMSuspendDisk;
qemuMonitorDomainGuestPanicCallback domainGuestPanic;
qemuMonitorDomainDeviceDeletedCallback domainDeviceDeleted;
+ qemuMonitorDomainNicRxFilterChangedCallback domainNicRxFilterChanged;
};
char *qemuMonitorEscapeArg(const char *in);
int qemuMonitorEmitGuestPanic(qemuMonitorPtr mon);
int qemuMonitorEmitDeviceDeleted(qemuMonitorPtr mon,
const char *devAlias);
+int qemuMonitorEmitNicRxFilterChanged(qemuMonitorPtr mon,
+ const char *devAlias);
int qemuMonitorStartCPUs(qemuMonitorPtr mon,
virConnectPtr conn);
static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleGuestPanic(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleDeviceDeleted(qemuMonitorPtr mon, virJSONValuePtr data);
+static void qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, virJSONValuePtr data);
typedef struct {
const char *type;
{ "DEVICE_DELETED", qemuMonitorJSONHandleDeviceDeleted, },
{ "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
{ "GUEST_PANICKED", qemuMonitorJSONHandleGuestPanic, },
+ { "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged, },
{ "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
{ "RESET", qemuMonitorJSONHandleReset, },
{ "RESUME", qemuMonitorJSONHandleResume, },
qemuMonitorEmitDeviceDeleted(mon, device);
}
+
+static void
+qemuMonitorJSONHandleNicRxFilterChanged(qemuMonitorPtr mon, virJSONValuePtr data)
+{
+ const char *name;
+
+ if (!(name = virJSONValueObjectGetString(data, "name"))) {
+ VIR_WARN("missing device in NIC_RX_FILTER_CHANGED event");
+ return;
+ }
+
+ qemuMonitorEmitNicRxFilterChanged(mon, name);
+}
+
+
int
qemuMonitorJSONHumanCommandWithFd(qemuMonitorPtr mon,
const char *cmd_str,
}
+static int
+qemuProcessHandleNicRxFilterChanged(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm,
+ const char *devAlias,
+ void *opaque)
+{
+ virQEMUDriverPtr driver = opaque;
+ struct qemuProcessEvent *processEvent = NULL;
+ char *data;
+
+ virObjectLock(vm);
+
+ VIR_DEBUG("Device %s RX Filter changed in domain %p %s",
+ devAlias, vm, vm->def->name);
+
+ if (VIR_ALLOC(processEvent) < 0)
+ goto error;
+
+ processEvent->eventType = QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED;
+ if (VIR_STRDUP(data, devAlias) < 0)
+ goto error;
+ processEvent->data = data;
+ processEvent->vm = vm;
+
+ virObjectRef(vm);
+ if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
+ ignore_value(virObjectUnref(vm));
+ goto error;
+ }
+
+ cleanup:
+ virObjectUnlock(vm);
+ return 0;
+ error:
+ if (processEvent)
+ VIR_FREE(processEvent->data);
+ VIR_FREE(processEvent);
+ goto cleanup;
+}
+
+
static qemuMonitorCallbacks monitorCallbacks = {
.eofNotify = qemuProcessHandleMonitorEOF,
.errorNotify = qemuProcessHandleMonitorError,
.domainPMSuspendDisk = qemuProcessHandlePMSuspendDisk,
.domainGuestPanic = qemuProcessHandleGuestPanic,
.domainDeviceDeleted = qemuProcessHandleDeviceDeleted,
+ .domainNicRxFilterChanged = qemuProcessHandleNicRxFilterChanged,
};
static int