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(a)redhat.com>
---
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