[PATCH 07/11] ch_driver: Implement domain restore callbacks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux