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@xxxxxxxxxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list