]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: implement support for autostart once feature
authorDaniel P. Berrangé <berrange@redhat.com>
Fri, 20 Dec 2024 11:26:55 +0000 (11:26 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Thu, 20 Mar 2025 14:55:17 +0000 (14:55 +0000)
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 <pkrempa@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/virdomainobjlist.c
src/hypervisor/domain_driver.c

index bf466e7a3275b5e3eb342780d0d14f6cc9340dfa..d27378f76c64f6583a70e78238acb3561ee92a41 100644 (file)
@@ -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) {
index 2babcd253146a3ac965d90812d3a7410575f2f91..523c61eff46778370e6182ae6c2da5b1171759f3 100644 (file)
@@ -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 */
index 72207450c5e7b3f313b2190c974b0bd6053bd6d4..90efb3465c61740fecb1e4ea5198b0210e227d73 100644 (file)
@@ -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);
index 9cad2e5da1a4ae42da2cad761a96c29912f9747c..f9fead5a468f1d05e4e9d61bb5693eed2515e026 100644 (file)
@@ -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);