This utilizes the new state driver field to implement a tiered driver
loading system. The two currently defined classes of driver are
"libvirt" and "hypervisor" drivers. Hypervisor drivers are fairly
self-explanatory, they provide domain services. Libvirt drivers are more
like backend drivers, like the secret and storage drivers.
The way the tiered loading is implemented makes it simple to add
additional tiers as needed. The tiers are loaded in numeric order,
starting with the lowered numbered tier. These tiers are defined in
driver.h. Each tier's drivers are all initialized, then all auto-started
before moving on to the next tier. This allows some interdependency
between drivers within a tier, similar to the current free-for-all
loading, while ensuring that auto-start is complete for a tier before
moving on.
By loading drivers in this manner, there is little-to-no need to
hard-code driver load ordering or create a fully dynamic
dependency-based loading algorithm. We still gain the benefits of a more
orderly driver load order, which helps minimize the possibility of a
race condition during startup. If a race condition is discovered in the
future, the number of tiers can be changed to mitigate it without
requiring too much effort.
Signed-off-by: Adam Walters <adam(a)pandorasboxen.com>
---
src/libvirt.c | 45 +++++++++++++++++++++++++++------------------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index c15e29a..d8d1723 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -729,31 +729,40 @@ virStateInitialize(bool privileged,
void *opaque)
{
size_t i;
+ size_t stateDriverTier;
if (virInitialize() < 0)
return -1;
- for (i = 0; i < virStateDriverTabCount; i++) {
- if (virStateDriverTab[i]->stateInitialize) {
- VIR_DEBUG("Running global init for %s state driver",
- virStateDriverTab[i]->name);
- if (virStateDriverTab[i]->stateInitialize(privileged,
- callback,
- opaque) < 0) {
- virErrorPtr err = virGetLastError();
- VIR_ERROR(_("Initialization of %s state driver failed: %s"),
- virStateDriverTab[i]->name,
- err && err->message ? err->message :
_("Unknown problem"));
- return -1;
+ for (stateDriverTier = 0; stateDriverTier < VIR_DRV_STATE_DRV_LAST;
stateDriverTier++) {
+ for (i = 0; i < virStateDriverTabCount; i++) {
+ if (virStateDriverTab[i]->stateDrvType != stateDriverTier)
+ continue;
+
+ if (virStateDriverTab[i]->stateInitialize) {
+ VIR_DEBUG("Running global init for %s state driver",
+ virStateDriverTab[i]->name);
+ if (virStateDriverTab[i]->stateInitialize(privileged,
+ callback,
+ opaque) < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Initialization of %s state driver failed:
%s"),
+ virStateDriverTab[i]->name,
+ err && err->message ? err->message :
_("Unknown problem"));
+ return -1;
+ }
}
}
- }
- for (i = 0; i < virStateDriverTabCount; i++) {
- if (virStateDriverTab[i]->stateAutoStart) {
- VIR_DEBUG("Running global auto start for %s state driver",
- virStateDriverTab[i]->name);
- virStateDriverTab[i]->stateAutoStart();
+ for (i = 0; i < virStateDriverTabCount; i++) {
+ if (virStateDriverTab[i]->stateDrvType != stateDriverTier)
+ continue;
+
+ if (virStateDriverTab[i]->stateAutoStart) {
+ VIR_DEBUG("Running global auto start for %s state driver",
+ virStateDriverTab[i]->name);
+ virStateDriverTab[i]->stateAutoStart();
+ }
}
}
return 0;
--
1.8.5.2