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