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(a)pandorasboxen.com>
---
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