There's a common pattern for autostart of iterating over VMs, acquiring a lock and ref count, then checking the autostart & is-active flags. Wrap this all up into a helper method. Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> --- src/hypervisor/domain_driver.c | 40 ++++++++++++++++++++++++++++++++++ src/hypervisor/domain_driver.h | 17 +++++++++++++++ src/libvirt_private.syms | 1 + 3 files changed, 58 insertions(+) diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index 85d68b056c..c5b082fd00 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -29,9 +29,12 @@ #include "viraccessapicheck.h" #include "datatypes.h" #include "driver.h" +#include "virlog.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN +VIR_LOG_INIT("hypervisor.domain_driver"); + char * virDomainDriverGenerateRootHash(const char *drivername, const char *root) @@ -652,3 +655,40 @@ virDomainDriverGetIOThreadsConfig(virDomainDef *targetDef, return ret; } + +static int +virDomainDriverAutoStartOne(virDomainObj *vm, + void *opaque) +{ + virDomainDriverAutoStartConfig *cfg = opaque; + + virObjectLock(vm); + virObjectRef(vm); + + VIR_DEBUG("Autostart %s: autostart=%d", + vm->def->name, vm->autostart); + + if (vm->autostart && !virDomainObjIsActive(vm)) { + virResetLastError(); + cfg->callback(vm, cfg->opaque); + } + + virDomainObjEndAPI(&vm); + virResetLastError(); + + return 0; +} + +void virDomainDriverAutoStart(virDomainObjList *domains, + virDomainDriverAutoStartConfig *cfg) +{ + bool autostart; + VIR_DEBUG("Run autostart stateDir=%s", cfg->stateDir); + if (virDriverShouldAutostart(cfg->stateDir, &autostart) < 0 || + !autostart) { + VIR_DEBUG("Autostart already processed"); + return; + } + + virDomainObjListForEach(domains, false, virDomainDriverAutoStartOne, cfg); +} diff --git a/src/hypervisor/domain_driver.h b/src/hypervisor/domain_driver.h index 9942f58fda..c27ed9155e 100644 --- a/src/hypervisor/domain_driver.h +++ b/src/hypervisor/domain_driver.h @@ -23,6 +23,7 @@ #include "node_device_conf.h" #include "virhostdev.h" #include "virpci.h" +#include "virdomainobjlist.h" char * virDomainDriverGenerateRootHash(const char *drivername, @@ -71,3 +72,19 @@ int virDomainDriverDelIOThreadCheck(virDomainDef *def, int virDomainDriverGetIOThreadsConfig(virDomainDef *targetDef, virDomainIOThreadInfoPtr **info, unsigned int bitmap_size); + +/* + * Will be called with 'vm' locked and ref count held, + * which will be released when this returns. + */ +typedef void (*virDomainDriverAutoStartCallback)(virDomainObj *vm, + void *opaque); + +typedef struct _virDomainDriverAutoStartConfig { + char *stateDir; + virDomainDriverAutoStartCallback callback; + void *opaque; +} virDomainDriverAutoStartConfig; + +void virDomainDriverAutoStart(virDomainObjList *domains, + virDomainDriverAutoStartConfig *cfg); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d0c116b78c..d90b15e215 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1640,6 +1640,7 @@ virDomainCgroupSetupVcpuBW; # hypervisor/domain_driver.h virDomainDriverAddIOThreadCheck; +virDomainDriverAutoStart; virDomainDriverDelIOThreadCheck; virDomainDriverGenerateMachineName; virDomainDriverGenerateRootHash; -- 2.47.1