Following callbacks have been implemented * domainRestore * domainRestoreFlags The path parameter to these callbacks has to be of the directory where libvirt has performed save. Additionally, call restore in `domainCreate` if the domain has managedsave. Signed-off-by: Purna Pavan Chandra Aekkaladevi <paekkaladevi@xxxxxxxxxxxxxxxxxxx> --- src/ch/ch_driver.c | 96 ++++++++++++++++++++++++++++++++++++++++++++- src/ch/ch_process.c | 53 +++++++++++++++++++++++++ src/ch/ch_process.h | 4 ++ 3 files changed, 152 insertions(+), 1 deletion(-) diff --git a/src/ch/ch_driver.c b/src/ch/ch_driver.c index 577544c941..218e2ec56f 100644 --- a/src/ch/ch_driver.c +++ b/src/ch/ch_driver.c @@ -252,6 +252,8 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) { virCHDriver *driver = dom->conn->privateData; virDomainObj *vm; + virCHDomainObjPrivate *priv; + g_autofree char *managed_save_path = NULL; int ret = -1; virCheckFlags(0, -1); @@ -265,8 +267,34 @@ chDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0) goto cleanup; - ret = virCHProcessStart(driver, vm, VIR_DOMAIN_RUNNING_BOOTED); + if (vm->hasManagedSave) { + priv = vm->privateData; + managed_save_path = chDomainManagedSavePath(driver, vm); + if (virCHProcessStartRestore(driver, vm, managed_save_path) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to restore domain from managed save")); + goto endjob; + } + if (virCHMonitorResumeVM(priv->monitor) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to resume domain after restore from managed save")); + goto endjob; + } + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_RESTORED); + /* cleanup the save dir after restore */ + if (virFileDeleteTree(managed_save_path) < 0) { + virReportSystemError(errno, + _("Failed to remove managed save path '%1$s'"), + managed_save_path); + goto endjob; + } + vm->hasManagedSave = false; + ret = 0; + } else { + ret = virCHProcessStart(driver, vm, VIR_DOMAIN_RUNNING_BOOTED); + } + endjob: virDomainObjEndJob(vm); cleanup: @@ -989,6 +1017,70 @@ chDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) return ret; } +static int +chDomainRestoreFlags(virConnectPtr conn, + const char *from, + const char *dxml, + unsigned int flags) +{ + virCHDriver *driver = conn->privateData; + virDomainObj *vm = NULL; + virCHDomainObjPrivate *priv; + g_autoptr(virDomainDef) def = NULL; + int ret = -1; + + virCheckFlags(0, -1); + + if (dxml) { + virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", + _("xml modification unsupported")); + return -1; + } + + if (chDomainSaveImageRead(driver, from, &def) < 0) + goto cleanup; + + if (virDomainRestoreFlagsEnsureACL(conn, def) < 0) + goto cleanup; + + if (!(vm = virDomainObjListAdd(driver->domains, &def, + driver->xmlopt, + VIR_DOMAIN_OBJ_LIST_ADD_LIVE | + VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, + NULL))) + goto cleanup; + + if (virDomainObjBeginJob(vm, VIR_JOB_MODIFY) < 0) + goto cleanup; + + if (virCHProcessStartRestore(driver, vm, from) < 0) + goto endjob; + + priv = vm->privateData; + if (virCHMonitorResumeVM(priv->monitor) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to resume domain after restore")); + goto endjob; + } + virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_RESTORED); + ret = 0; + + endjob: + virDomainObjEndJob(vm); + + cleanup: + if (vm && ret < 0) + virCHDomainRemoveInactive(driver, vm); + virDomainObjEndAPI(&vm); + return ret; +} + +static int +chDomainRestore(virConnectPtr conn, const char *from) +{ + return chDomainRestoreFlags(conn, from, NULL, 0); +} + static virDomainPtr chDomainLookupByID(virConnectPtr conn, int id) { @@ -2118,6 +2210,8 @@ static virHypervisorDriver chHypervisorDriver = { .domainManagedSaveRemove = chDomainManagedSaveRemove, /* 10.2.0 */ .domainManagedSaveGetXMLDesc = chDomainManagedSaveGetXMLDesc, /* 10.2.0 */ .domainHasManagedSaveImage = chDomainHasManagedSaveImage, /* 10.2.0 */ + .domainRestore = chDomainRestore, /* 10.2.0 */ + .domainRestoreFlags = chDomainRestoreFlags, /* 10.2.0 */ }; static virConnectDriver chConnectDriver = { diff --git a/src/ch/ch_process.c b/src/ch/ch_process.c index 02749adfb6..081fc5af52 100644 --- a/src/ch/ch_process.c +++ b/src/ch/ch_process.c @@ -852,3 +852,56 @@ virCHProcessStop(virCHDriver *driver G_GNUC_UNUSED, return 0; } + +/** + * virCHProcessStartRestore: + * @driver: pointer to driver structure + * @vm: pointer to virtual machine structure + * @from: directory path to restore the VM from + * + * Starts Cloud-Hypervisor process with the restored VM + * + * Returns 0 on success or -1 in case of error + */ +int +virCHProcessStartRestore(virCHDriver *driver, virDomainObj *vm, const char *from) +{ + virCHDomainObjPrivate *priv = vm->privateData; + g_autoptr(virCHDriverConfig) cfg = virCHDriverGetConfig(priv->driver); + + if (!priv->monitor) { + /* Get the first monitor connection if not already */ + if (!(priv->monitor = virCHProcessConnectMonitor(driver, vm))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to create connection to CH socket")); + return -1; + } + } + + vm->pid = priv->monitor->pid; + vm->def->id = vm->pid; + priv->machineName = virCHDomainGetMachineName(vm); + + if (virCHMonitorRestoreVM(priv->monitor, from) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to restore domain")); + return -1; + } + + /* Pass 0, NULL as restore only works without networking support */ + if (virDomainCgroupSetupCgroup("ch", vm, + 0, NULL, /* nnicindexes, nicindexes */ + &priv->cgroup, + cfg->cgroupControllers, + 0, /*maxThreadsPerProc*/ + priv->driver->privileged, + priv->machineName) < 0) + return -1; + + if (virCHProcessSetup(vm) < 0) + return -1; + + virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_FROM_SNAPSHOT); + + return 0; +} diff --git a/src/ch/ch_process.h b/src/ch/ch_process.h index 800e3f4e23..38bfce3b7f 100644 --- a/src/ch/ch_process.h +++ b/src/ch/ch_process.h @@ -32,3 +32,7 @@ int virCHProcessStop(virCHDriver *driver, int virCHProcessSetupVcpu(virDomainObj *vm, unsigned int vcpuid); + +int virCHProcessStartRestore(virCHDriver *driver, + virDomainObj *vm, + const char *from); -- 2.34.1 _______________________________________________ Devel mailing list -- devel@xxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxx