mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-27 16:15:23 +00:00
4445723811
The current API for domain events has a number of problems - Only allows for domain lifecycle change events - Does not allow the same callback to be registered multiple times - Does not allow filtering of events to a specific domain This introduces a new more general purpose domain events API typedef enum { VIR_DOMAIN_EVENT_ID_LIFECYCLE = 0, /* virConnectDomainEventCallback */ ...more events later.. } int virConnectDomainEventRegisterAny(virConnectPtr conn, virDomainPtr dom, /* Optional, to filter */ int eventID, virConnectDomainEventGenericCallback cb, void *opaque, virFreeCallback freecb); int virConnectDomainEventDeregisterAny(virConnectPtr conn, int callbackID); Since different event types can received different data in the callback, the API is defined with a generic callback. Specific events will each have a custom signature for their callback. Thus when registering an event it is neccessary to cast the callback to the generic signature eg int myDomainEventCallback(virConnectPtr conn, virDomainPtr dom, int event, int detail, void *opaque) { ... } virConnectDomainEventRegisterAny(conn, NULL, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_DOMAIN_EVENT_CALLBACK(myDomainEventCallback) NULL, NULL); The VIR_DOMAIN_EVENT_CALLBACK() macro simply does a "bad" cast to the generic signature * include/libvirt/libvirt.h.in: Define new APIs for registering domain events * src/driver.h: Internal driver entry points for new events APIs * src/libvirt.c: Wire up public API to driver API for events APIs * src/libvirt_public.syms: Export new APIs * src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/opennebula/one_driver.c, src/openvz/openvz_driver.c, src/phyp/phyp_driver.c, src/qemu/qemu_driver.c, src/remote/remote_driver.c, src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c, src/xen/xen_driver.c, src/xenapi/xenapi_driver.c: Stub out new API entries |
||
---|---|---|
.. | ||
esx_device_monitor.c | ||
esx_device_monitor.h | ||
esx_driver.c | ||
esx_driver.h | ||
esx_interface_driver.c | ||
esx_interface_driver.h | ||
esx_network_driver.c | ||
esx_network_driver.h | ||
esx_private.h | ||
esx_secret_driver.c | ||
esx_secret_driver.h | ||
esx_storage_driver.c | ||
esx_storage_driver.h | ||
esx_util.c | ||
esx_util.h | ||
esx_vi_methods.c | ||
esx_vi_methods.h | ||
esx_vi_types.c | ||
esx_vi_types.h | ||
esx_vi.c | ||
esx_vi.h | ||
esx_vmx.c | ||
esx_vmx.h | ||
README |
Some links to relevant documentation ==================================== VI/vSphere API: http://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/ http://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/ VMX config: http://www.sanbarrow.com/vmx.html CPUID: http://www.sandpile.org/ia32/cpuid.htm Memory model: http://www.vmware.com/pdf/esx3_memory.pdf http://www.vmware.com/pdf/usenix_resource_mgmt.pdf Automatic question handling =========================== What is a question in the ESX context? -------------------------------------- The VI API contains methods that start tasks, for example PowerOnVM_Task(). Such tasks may be blocked by questions if the ESX host detects an issue with the virtual machine that requires user interaction. An example: If a virtual machine has a serial port that is realized via a file, the ESX host will ask a question on power-on of this virtual machine whether new content should be appended to this file or the file should be replaced. Until this question is answered the power-on task is blocked and the virtual machine won't get powered on. The ESX driver cannot prompt the user to answer a question, libvirt doesn't have an API for something like this. The VI API provides the AnswerVM() method to programmatically answer such questions. A question comes together with a list of possible answers. One of this answers is marked as the default one. For all questions I've seen so far the default answer is always a non-destructive one. There are two options how to handle a question that is blocking a task: either answer it automatically or report it as error and try to cancel the blocked task. The auto_answer query parameter defines how the driver should handle questions. Possible values are 0 for the report-error-and-try-to-cancel option and 1 for the automatic-answer option. How is automatic question handling implemented? ----------------------------------------------- Before any new task is started the driver checks if there is a pending task blocked by a question. If automatic question handling is disabled the driver reports an error that includes the question and returns from the driver function. If automatic question handling is enabled the driver answers the question with the default answer and returns from the driver function. In both cases the actual desired task is not started. If the question was not answered the blocked task is still blocked and because task can't be executed in parallel in general it's of no use to start yet another task. If the question was answered the blocked task may already perform the desired action and one must wait for its completion, so it's of no use to start yet another task. If there is no question blocking a task or another pending task that had not finished yet the driver starts the desired task and waits for its completion. While polling for status updates of the task it also checks for question that may have been triggered by the current task and handles them according to the value of the auto_answer query parameter. If automatic question handling is enabled the driver answers the question with the default answer and continues polling for status updates. If automatic question handling is disabled the driver reports an error that includes the question, tries to cancel the blocked task and returns from the driver function. It tries to cancel the blocked task, but this may not be possible, because there are task like the power-on task that is marked as non-cancelable. So the driver may leave blocked tasks behind if automatic question handling is disabled.