From ff87b8626006538a4f681cfe68ef336d861e2d4d Mon Sep 17 00:00:00 2001 Message-Id: From: Laine Stump Date: Mon, 3 Nov 2014 10:00:19 -0500 Subject: [PATCH] qemu: add short document on qemu event handlers https://bugzilla.redhat.com/show_bug.cgi?id=848199 This text was in the commit log for the patch that added the event handler for NIC_RX_FILTER_CHANGED, and John Ferlan expressed a desire that the information not be "lost", so I've put it into a file in the qemu directory, hoping that it might catch the attention of future writers of handlers for qemu events. (cherry picked from commit ac4f8be422521875b64f51bcea953a6d1c6bfb09) Signed-off-by: Jiri Denemark --- src/qemu/EVENTHANDLERS.txt | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/qemu/EVENTHANDLERS.txt diff --git a/src/qemu/EVENTHANDLERS.txt b/src/qemu/EVENTHANDLERS.txt new file mode 100644 index 0000000..79c1505 --- /dev/null +++ b/src/qemu/EVENTHANDLERS.txt @@ -0,0 +1,76 @@ +This is a short description of how an example qemu event can be used +to trigger handler code that is called from the context of a worker +thread, rather than directly from the event thread (which should +itself never block, and can't do things like send qemu monitor +commands, etc). + +In this case (the NIC_RX_FILTER_CHANGED event) the event is handled by +calling a qemu monitor command to get the current RX filter state, +then executing ioctls/sending netlink messages on the host in response +to changes in that filter state. This event is *not* propagated to the +libvirt API (but if someone wants to add details of how to handle that +to the end of this document, please do!). + +Hopefully this narration will be helpful when adding handlers for +other qemu events in the future. + +---------------------------------------------------- + +Any event emitted by qemu is received by +qemu_monitor_json.c:qemuMonitorJSONProcessEvent(). It looks up the +event by name in the table eventHandlers (in the same file), which +should have an entry like this for each event that libvirt +understands: + + { "NIC_RX_FILTER_CHANGED", qemuMonitorJSONHandleNicRxFilterChanged, }, + + NB: This table is searched with bsearch, so it *must* be + alphabetically sorted. + +qemuMonitorJSONProcessEvent calls the function listed in +eventHandlers, e.g.: + + qemu_monitor_json.c:qemuMonitorJSONHandleNicRxFilterChanged() + +which extracts any required data from the JSON ("name" in this case), +and calls: + + qemu_monitor.c:qemuMonitorEmitNicRxFilterChanged() + +which uses QEMU_MONITOR_CALLBACK() to call +mon->cb->domainNicRxFilterChanged(). domainNicRxFilterChanged is one +in a list of function pointers in qemu_process.c:monitorCallbacks. For +our example, it has been set to: + + qemuProcessHandleNicRxFilterChanged() + +This function allocates a qemuProcessEvent object, and queues an event +named QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED (you'll want to add an +enum to qemu_domain.h:qemuProcessEventType for your event) for a +worker thread to handle. + +(Everything up to this point has happened in the context of the thread +that is reading events from qemu, so it should do as little as +possible, never block, and never call back into the qemu +monitor. Everything after this is handled in the context of a worker +thread, so it has more freedom to make qemu monitor calls and blocking +system calls on the host.) + +When the worker thread gets the event, it calls + + qemuProcessEventHandler() + +which switches on the eventType (in our example, +QEMU_PROCESS_EVENT_NIC_RX_FILTER_CHANGED) and decides to call: + + processNicRxFilterChangedEvent() + +and *that* is where the actual work will be done (and any +event-specific memory allocated during qemuProcessHandleXXX() will be +freed). Note that this function must do proper refcounting of the +domain object, and assure that the domain is still active prior to +performing any operations - it is possible that the domain could have +been destroyed between the time the event was received and the time +that it is processed, and it is also possible that the domain could be +destroyed *during* the event processing if it doesn't get properly +referenced by the handler. -- 2.1.3