This is maintained in the same way as the autostart flag, using a symlink. The difference is that instead of '.xml', the symlink suffix is '.xml.once'. The link is also deleted immediately after it has been read. Signed-off-by: Daniel P. Berrangé <berrange@xxxxxxxxxx> --- src/conf/domain_conf.c | 7 ++++++- src/conf/domain_conf.h | 2 ++ src/conf/virdomainobjlist.c | 8 ++++++++ src/hypervisor/domain_driver.c | 14 +++++++++++--- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b94cf99236..cf8374ab18 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4166,6 +4166,7 @@ static void virDomainObjDispose(void *obj) virDomainCheckpointObjListFree(dom->checkpoints); virDomainJobObjFree(dom->job); virObjectUnref(dom->closecallbacks); + g_free(dom->autostartOnceLink); } virDomainObj * @@ -29135,13 +29136,17 @@ virDomainDeleteConfig(const char *configDir, { g_autofree char *configFile = NULL; g_autofree char *autostartLink = NULL; + g_autofree char *autostartOnceLink = NULL; configFile = virDomainConfigFile(configDir, dom->def->name); autostartLink = virDomainConfigFile(autostartDir, dom->def->name); + autostartOnceLink = g_strdup_printf("%s.once", autostartLink); - /* Not fatal if this doesn't work */ + /* Not fatal if these don't work */ unlink(autostartLink); + unlink(autostartOnceLink); dom->autostart = 0; + dom->autostartOnce = 0; if (unlink(configFile) < 0 && errno != ENOENT) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3a97fd866c..c648864083 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3324,9 +3324,11 @@ struct _virDomainObj { virDomainStateReason state; unsigned int autostart : 1; + unsigned int autostartOnce : 1; unsigned int persistent : 1; unsigned int updated : 1; unsigned int removing : 1; + char *autostartOnceLink; virDomainDef *def; /* The current definition */ virDomainDef *newDef; /* New definition to activate at shutdown */ diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c index 72207450c5..90efb3465c 100644 --- a/src/conf/virdomainobjlist.c +++ b/src/conf/virdomainobjlist.c @@ -487,9 +487,11 @@ virDomainObjListLoadConfig(virDomainObjList *doms, { g_autofree char *configFile = NULL; g_autofree char *autostartLink = NULL; + g_autofree char *autostartOnceLink = NULL; g_autoptr(virDomainDef) def = NULL; virDomainObj *dom; int autostart; + int autostartOnce; g_autoptr(virDomainDef) oldDef = NULL; configFile = virDomainConfigFile(configDir, name); @@ -500,13 +502,19 @@ virDomainObjListLoadConfig(virDomainObjList *doms, return NULL; autostartLink = virDomainConfigFile(autostartDir, name); + autostartOnceLink = g_strdup_printf("%s.once", autostartLink); autostart = virFileLinkPointsTo(autostartLink, configFile); + autostartOnce = virFileLinkPointsTo(autostartOnceLink, configFile); if (!(dom = virDomainObjListAddLocked(doms, &def, xmlopt, 0, &oldDef))) return NULL; dom->autostart = autostart; + dom->autostartOnce = autostartOnce; + + if (autostartOnce) + dom->autostartOnceLink = g_steal_pointer(&autostartOnceLink); if (notify) (*notify)(dom, oldDef == NULL, opaque); diff --git a/src/hypervisor/domain_driver.c b/src/hypervisor/domain_driver.c index d4cf09174b..bfba435ee0 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -682,10 +682,12 @@ virDomainDriverAutoStartOne(virDomainObj *vm, virObjectLock(vm); virObjectRef(vm); - VIR_DEBUG("Autostart %s: autostart=%d", - vm->def->name, vm->autostart); + VIR_DEBUG("Autostart %s: autostart=%d autostartOnce=%d autostartOnceLink=%s", + vm->def->name, vm->autostart, vm->autostartOnce, + NULLSTR(vm->autostartOnceLink)); - if (vm->autostart && !virDomainObjIsActive(vm)) { + if ((vm->autostart || vm->autostartOnce) && + !virDomainObjIsActive(vm)) { virResetLastError(); if (state->cfg->delayMS) { if (!state->first) { @@ -696,6 +698,12 @@ virDomainDriverAutoStartOne(virDomainObj *vm, } state->cfg->callback(vm, state->cfg->opaque); + vm->autostartOnce = 0; + } + + if (vm->autostartOnceLink) { + unlink(vm->autostartOnceLink); + g_clear_pointer(&vm->autostartOnceLink, g_free); } virDomainObjEndAPI(&vm); -- 2.48.1