From: Daniel P. Berrangé Date: Fri, 20 Dec 2024 11:26:55 +0000 (+0000) Subject: conf: implement support for autostart once feature X-Git-Tag: v11.2.0-rc1~77 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c6018e5f87449f52edeedf195bddbec9d273e065;p=thirdparty%2Flibvirt.git conf: implement support for autostart once feature 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'. Reviewed-by: Peter Krempa Signed-off-by: Daniel P. Berrangé --- diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index bf466e7a32..d27378f76c 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4170,6 +4170,7 @@ static void virDomainObjDispose(void *obj) virDomainCheckpointObjListFree(dom->checkpoints); virDomainJobObjFree(dom->job); virObjectUnref(dom->closecallbacks); + g_free(dom->autostartOnceLink); } virDomainObj * @@ -29159,13 +29160,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 2babcd2531..523c61eff4 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3328,9 +3328,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 9cad2e5da1..f9fead5a46 100644 --- a/src/hypervisor/domain_driver.c +++ b/src/hypervisor/domain_driver.c @@ -683,10 +683,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) { @@ -697,6 +699,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);