From: shotor <[email protected]> Libvirt reports Cloud Hypervisor domains as having unknown persistence.
Commit 85cf0e4f17ae added support for keeping a separate inactive definition for running domains, but it didn't persist domain definitions to disk or reload them when virtchd restarted. Meaning defined CH domains were still lost across daemon restarts and libvirt couldn't report them as persistent. Follow the approach used by the QEMU driver: save domain definitions to disk when they are defined, reload them during driver initialization, remove the stored configuration when they are undefined, and roll back the in-memory definition if saving fails. Also implement domainIsPersistent so libvirt reports the persistence state correctly. Signed-off-by: shotor <[email protected]> --- src/ch/ch_conf.c | 13 +++++++--- src/ch/ch_conf.h | 1 + src/ch/ch_driver.c | 63 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/src/ch/ch_conf.c b/src/ch/ch_conf.c index 6896683b7f..793ec33a10 100644 --- a/src/ch/ch_conf.c +++ b/src/ch/ch_conf.c @@ -178,22 +178,26 @@ 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->configDir = g_strdup(SYSCONFDIR "/libvirt"); + cfg->configBaseDir = g_strdup(SYSCONFDIR "/libvirt"); + cfg->configDir = g_strdup_printf("%s/ch/domains", + cfg->configBaseDir); } else { g_autofree char *rundir = NULL; g_autofree char *cachedir = NULL; - g_autofree char *configbasedir = NULL; + const char *configbasedir = NULL; cachedir = virGetUserCacheDirectory(); - cfg->logDir = g_strdup_printf("%s/ch/log", cachedir); rundir = virGetUserRuntimeDirectory(); cfg->stateDir = g_strdup_printf("%s/ch/run", rundir); configbasedir = virGetUserConfigDirectory(); + cfg->saveDir = g_strdup_printf("%s/ch/save", configbasedir); - cfg->configDir = g_strdup_printf("%s/ch", configbasedir); + cfg->configBaseDir = g_strdup_printf("%s/ch", configbasedir); + cfg->configDir = g_strdup_printf("%s/domains", + cfg->configBaseDir); } return cfg; @@ -211,6 +215,7 @@ virCHDriverConfigDispose(void *obj) virCHDriverConfig *cfg = obj; g_free(cfg->stateDir); + g_free(cfg->configBaseDir); g_free(cfg->configDir); g_free(cfg->logDir); g_free(cfg->saveDir); diff --git a/src/ch/ch_conf.h b/src/ch/ch_conf.h index 1660762f2b..c3b59bba0d 100644 --- a/src/ch/ch_conf.h +++ b/src/ch/ch_conf.h @@ -51,6 +51,7 @@ struct _virCHDriverConfig { GObject parent; char *stateDir; + char *configBaseDir; char *configDir; char *logDir; char *saveDir; diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c index f85f38eaf2..51c69b799a 100644 --- a/src/ch/ch_driver.c +++ b/src/ch/ch_driver.c @@ -336,11 +336,14 @@ chDomainCreate(virDomainPtr dom) } static virDomainPtr -chDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags) +chDomainDefineXMLFlags(virConnectPtr conn, + const char *xml, + unsigned int flags) { virCHDriver *driver = conn->privateData; g_autoptr(virDomainDef) vmdef = NULL; g_autoptr(virDomainDef) oldDef = NULL; + g_autoptr(virCHDriverConfig) cfg = virCHDriverGetConfig(driver); virDomainObj *vm = NULL; virDomainPtr dom = NULL; virObjectEvent *event = NULL; @@ -382,15 +385,34 @@ chDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags) goto cleanup; } + 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, !oldDef ? VIR_DOMAIN_EVENT_DEFINED_ADDED : VIR_DOMAIN_EVENT_DEFINED_UPDATED); + dom = virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id); cleanup: + if (!dom && !vmdef) { + if (oldDef) { + if (virDomainObjIsActive(vm)) + vm->newDef = oldDef; + else + vm->def = oldDef; + oldDef = NULL; + } else { + virCHDomainRemoveInactive(driver, vm); + } + } + virDomainObjEndAPI(&vm); virObjectEventStateQueue(driver->domainEventState, event); @@ -408,6 +430,7 @@ chDomainUndefineFlags(virDomainPtr dom, unsigned int flags) { virCHDriver *driver = dom->conn->privateData; + g_autoptr(virCHDriverConfig) cfg = virCHDriverGetConfig(driver); virDomainObj *vm; virObjectEvent *event = NULL; int ret = -1; @@ -425,14 +448,18 @@ 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); vm->persistent = 0; - if (!virDomainObjIsActive(vm)) { + + if (!virDomainObjIsActive(vm)) virCHDomainRemoveInactive(driver, vm); - } ret = 0; @@ -467,6 +494,24 @@ static int chDomainIsActive(virDomainPtr dom) return ret; } +static int chDomainIsPersistent(virDomainPtr dom) +{ + virDomainObj *vm; + int ret = -1; + + if (!(vm = virCHDomainObjFromDomain(dom))) + goto cleanup; + + if (virDomainIsPersistentEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + ret = vm->persistent; + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + static int chDomainShutdownFlags(virDomainPtr dom, unsigned int flags) @@ -1493,11 +1538,20 @@ chStateInitialize(bool privileged, if (!(ch_driver->config = virCHDriverConfigNew(privileged))) goto cleanup; - driverConf = g_strdup_printf("%s/ch.conf", ch_driver->config->configDir); + driverConf = g_strdup_printf("%s/ch.conf", ch_driver->config->configBaseDir); if (virCHDriverConfigLoadFile(ch_driver->config, driverConf) < 0) goto cleanup; + if (virDomainObjListLoadAllConfigs(ch_driver->domains, + ch_driver->config->configDir, + NULL, + false, + ch_driver->xmlopt, + NULL, + NULL) < 0) + goto cleanup; + if (!(ch_driver->hostdevMgr = virHostdevManagerGetDefault())) goto cleanup; @@ -2550,6 +2604,7 @@ static virHypervisorDriver chHypervisorDriver = { .domainGetXMLDesc = chDomainGetXMLDesc, /* 7.5.0 */ .domainGetInfo = chDomainGetInfo, /* 7.5.0 */ .domainIsActive = chDomainIsActive, /* 7.5.0 */ + .domainIsPersistent = chDomainIsPersistent, /* 12.7.0 */ .domainOpenConsole = chDomainOpenConsole, /* 7.8.0 */ .nodeGetInfo = chNodeGetInfo, /* 7.5.0 */ .domainGetVcpus = chDomainGetVcpus, /* 8.0.0 */ -- 2.55.0
