mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-28 16:45:26 +00:00
ac4f8be422
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.
77 lines
3.1 KiB
Plaintext
77 lines
3.1 KiB
Plaintext
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.
|