This implements a two-tier driver loading system into libvirt. The two classes of drivers are "Libvirt" drivers and "Hypervisor" drivers. Hypervisor drivers are fairly self-explanatory, they provide domain services. Libvirt drivers are sort of the backend drivers for those, like the secret and storage drivers. In the two-tier loading system here, the "Libvirt" drivers are all loaded and auto-started. Once those have finished, the "Hypervisor" drivers are loaded and auto-started. By doing things in this manner, we do not have to hard-code a driver loading order or roll our own dynamic dependency-based loading algorithm, while still gaining the benefits of a more orderly driver loading approach, which should help minimize the possibility of a race condition during startup. If another race condition is found, the code can be extended to provide any number of extra tiers without much trouble. Signed-off-by: Adam Walters <adam@xxxxxxxxxxxxxxxxx> --- src/libvirt.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index 77f481e..9c00491 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -837,31 +837,72 @@ int virStateInitialize(bool privileged, void *opaque) { size_t i; + virStateDriverPtr virLibvirtStateDriverTab[MAX_DRIVERS]; + int virLibvirtStateDriverTabCount = 0; + virStateDriverPtr virHypervisorStateDriverTab[MAX_DRIVERS]; + int virHypervisorStateDriverTabCount = 0; if (virInitialize() < 0) return -1; for (i = 0; i < virStateDriverTabCount; i++) { - if (virStateDriverTab[i]->stateInitialize) { + switch (virStateDriverTab[i]->stateType) { + case VIR_DRV_STATE_DRV_LIBVIRT: + virLibvirtStateDriverTab[virLibvirtStateDriverTabCount++] = + virStateDriverTab[i]; + break; + case VIR_DRV_STATE_DRV_HYPERVISOR: + virHypervisorStateDriverTab[virHypervisorStateDriverTabCount++] = + virStateDriverTab[i]; + break; + } + } + + for (i = 0; i < virLibvirtStateDriverTabCount; i++) { + if (virLibvirtStateDriverTab[i]->stateInitialize) { VIR_DEBUG("Running global init for %s state driver", - virStateDriverTab[i]->name); - if (virStateDriverTab[i]->stateInitialize(privileged, + virLibvirtStateDriverTab[i]->name); + if (virLibvirtStateDriverTab[i]->stateInitialize(privileged, callback, opaque) < 0) { virErrorPtr err = virGetLastError(); VIR_ERROR(_("Initialization of %s state driver failed: %s"), - virStateDriverTab[i]->name, + virLibvirtStateDriverTab[i]->name, err && err->message ? err->message : _("Unknown problem")); return -1; } } } - for (i = 0; i < virStateDriverTabCount; i++) { - if (virStateDriverTab[i]->stateAutoStart) { + for (i = 0; i < virLibvirtStateDriverTabCount; i++) { + if (virLibvirtStateDriverTab[i]->stateAutoStart) { + VIR_DEBUG("Running global auto start for %s state driver", + virLibvirtStateDriverTab[i]->name); + virLibvirtStateDriverTab[i]->stateAutoStart(); + } + } + + for (i = 0; i < virHypervisorStateDriverTabCount; i++) { + if (virHypervisorStateDriverTab[i]->stateInitialize) { + VIR_DEBUG("Running global init for %s state driver", + virHypervisorStateDriverTab[i]->name); + if (virHypervisorStateDriverTab[i]->stateInitialize(privileged, + callback, + opaque) < 0) { + virErrorPtr err = virGetLastError(); + VIR_ERROR(_("Initialization of %s state driver failed: %s"), + virHypervisorStateDriverTab[i]->name, + err && err->message ? err->message : _("Unknown problem")); + return -1; + } + } + } + + for (i = 0; i < virHypervisorStateDriverTabCount; i++) { + if (virHypervisorStateDriverTab[i]->stateAutoStart) { VIR_DEBUG("Running global auto start for %s state driver", - virStateDriverTab[i]->name); - virStateDriverTab[i]->stateAutoStart(); + virHypervisorStateDriverTab[i]->name); + virHypervisorStateDriverTab[i]->stateAutoStart(); } } return 0; -- 1.8.5.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list