When the domain was defined, its persistent domain definition wasn't
saved on disk, leading to the loss of all defined domains after a CH
driver restart.

Now all defined persistent domains are saved on disk and loaded
from disk during CH driver initialization. Saved domains now also can
be removed with undefine.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/743

Signed-off-by: Kirill Shchetiniuk <kshch...@redhat.com>
---
 src/ch/ch_conf.c   | 10 +++++++---
 src/ch/ch_conf.h   |  2 ++
 src/ch/ch_driver.c | 24 +++++++++++++++++++++++-
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/ch/ch_conf.c b/src/ch/ch_conf.c
index cab97639c4..f0cb963656 100644
--- a/src/ch/ch_conf.c
+++ b/src/ch/ch_conf.c
@@ -149,11 +149,11 @@ virCHDriverConfigNew(bool privileged)
         cfg->logDir = g_strdup_printf("%s/log/libvirt/ch", LOCALSTATEDIR);
         cfg->stateDir = g_strdup_printf("%s/libvirt/ch", RUNSTATEDIR);
         cfg->saveDir = g_strdup_printf("%s/lib/libvirt/ch/save", 
LOCALSTATEDIR);
+        cfg->configBaseDir = g_strdup_printf("%s/libvirt", SYSCONFDIR);
 
     } else {
         g_autofree char *rundir = NULL;
         g_autofree char *cachedir = NULL;
-        g_autofree char *configbasedir = NULL;
 
         cachedir = virGetUserCacheDirectory();
 
@@ -162,10 +162,12 @@ virCHDriverConfigNew(bool privileged)
         rundir = virGetUserRuntimeDirectory();
         cfg->stateDir = g_strdup_printf("%s/ch/run", rundir);
 
-        configbasedir = virGetUserConfigDirectory();
-        cfg->saveDir = g_strdup_printf("%s/ch/save", configbasedir);
+        cfg->configBaseDir = virGetUserConfigDirectory();
+        cfg->saveDir = g_strdup_printf("%s/ch/save", cfg->configBaseDir);
     }
 
+    cfg->configDir = g_strdup_printf("%s/ch", cfg->configBaseDir);
+
     return cfg;
 }
 
@@ -183,6 +185,8 @@ virCHDriverConfigDispose(void *obj)
     g_free(cfg->saveDir);
     g_free(cfg->stateDir);
     g_free(cfg->logDir);
+    g_free(cfg->configBaseDir);
+    g_free(cfg->configDir);
 }
 
 #define MIN_VERSION ((15 * 1000000) + (0 * 1000) + (0))
diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h
index b08573476e..8beeb69b95 100644
--- a/src/ch/ch_conf.h
+++ b/src/ch/ch_conf.h
@@ -40,6 +40,8 @@ struct _virCHDriverConfig {
     char *stateDir;
     char *logDir;
     char *saveDir;
+    char *configBaseDir;
+    char *configDir;
 
     int cgroupControllers;
 
diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c
index 3bdcf66ebd..c7f357dac9 100644
--- a/src/ch/ch_driver.c
+++ b/src/ch/ch_driver.c
@@ -338,6 +338,7 @@ chDomainDefineXMLFlags(virConnectPtr conn, const char *xml, 
unsigned int flags)
     virDomainObj *vm = NULL;
     virDomainPtr dom = NULL;
     virObjectEvent *event = NULL;
+    g_autoptr(virCHDriverConfig) cfg = virCHDriverGetConfig(driver);
     g_autofree char *managed_save_path = NULL;
     unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
 
@@ -370,6 +371,11 @@ chDomainDefineXMLFlags(virConnectPtr conn, const char 
*xml, unsigned int flags)
         goto cleanup;
     }
 
+    /* Save new persistent domain definition */
+    if (virDomainDefSave(vm->newDef ? vm->newDef : vm->def,
+                         driver->xmlopt, cfg->configDir) < 0)
+        goto cleanup;
+
     vm->persistent = 1;
     event = virDomainEventLifecycleNewFromObj(vm,
                                               VIR_DOMAIN_EVENT_DEFINED,
@@ -398,6 +404,7 @@ chDomainUndefineFlags(virDomainPtr dom,
     virCHDriver *driver = dom->conn->privateData;
     virDomainObj *vm;
     virObjectEvent *event = NULL;
+    g_autoptr(virCHDriverConfig) cfg = NULL;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -405,6 +412,8 @@ chDomainUndefineFlags(virDomainPtr dom,
     if (!(vm = virCHDomainObjFromDomain(dom)))
         goto cleanup;
 
+    cfg = virCHDriverGetConfig(driver);
+
     if (virDomainUndefineFlagsEnsureACL(dom->conn, vm->def) < 0)
         goto cleanup;
 
@@ -413,6 +422,10 @@ chDomainUndefineFlags(virDomainPtr dom,
                        "%s", _("Cannot undefine transient domain"));
         goto cleanup;
     }
+
+    if (virDomainDeleteConfig(cfg->configDir, NULL, vm) < 0)
+        goto cleanup;
+
     event = virDomainEventLifecycleNewFromObj(vm,
                                               VIR_DOMAIN_EVENT_UNDEFINED,
                                               
VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
@@ -1413,6 +1426,7 @@ chStateInitialize(bool privileged,
 {
     int ret = VIR_DRV_STATE_INIT_ERROR;
     int rv;
+    virCHDriverConfig *cfg;
 
     if (root != NULL) {
         virReportError(VIR_ERR_INVALID_ARG, "%s",
@@ -1444,7 +1458,7 @@ chStateInitialize(bool privileged,
     if (!(ch_driver->xmlopt = chDomainXMLConfInit(ch_driver)))
         goto cleanup;
 
-    if (!(ch_driver->config = virCHDriverConfigNew(privileged)))
+    if (!(ch_driver->config = cfg = virCHDriverConfigNew(privileged)))
         goto cleanup;
 
     if (!(ch_driver->hostdevMgr = virHostdevManagerGetDefault()))
@@ -1459,6 +1473,14 @@ chStateInitialize(bool privileged,
         goto cleanup;
     }
 
+    /* Persistent domains load  */
+    if (virDomainObjListLoadAllConfigs(ch_driver->domains,
+                                       cfg->configDir,
+                                       NULL, false,
+                                       ch_driver->xmlopt,
+                                       NULL, NULL) < 0)
+        goto cleanup;
+
     ch_driver->chCaps = virCHCapsInitCHVersionCaps(ch_driver->version);
 
     ch_driver->privileged = privileged;
-- 
2.48.1

Reply via email to