[libvirt] [PATCH v2 3/6] parallels: implement virDomainManagedSave

Dmitry Guryanov dguryanov at parallels.com
Thu Mar 19 12:37:44 UTC 2015


Implement virDomainManagedSave api function. In PCS
this feature called "suspend". You can suspend VM or
CT while it is in running or paused state. And after
resuming (or starting) it will have the same state, as
before suspend.

Signed-off-by: Dmitry Guryanov <dguryanov at parallels.com>
---
 src/parallels/parallels_driver.c | 69 +++++++++++++++++++++++++++++++++++++++-
 src/parallels/parallels_sdk.c    | 21 ++++++++++++
 src/parallels/parallels_sdk.h    |  3 ++
 3 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index 2a6a7c9..9bbb970 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -986,6 +986,8 @@ parallelsDomainHasManagedSaveImage(virDomainPtr domain, unsigned int flags)
 {
     parallelsConnPtr privconn = domain->conn->privateData;
     virDomainObjPtr dom = NULL;
+    int state, reason;
+    int ret = 0;
 
     virCheckFlags(0, -1);
 
@@ -995,9 +997,72 @@ parallelsDomainHasManagedSaveImage(virDomainPtr domain, unsigned int flags)
         return -1;
     }
 
+    state = virDomainObjGetState(dom, &reason);
+    if (state == VIR_DOMAIN_SHUTOFF && reason == VIR_DOMAIN_SHUTOFF_SAVED)
+        ret = 1;
     virObjectUnlock(dom);
 
-    return 0;
+    return ret;
+}
+
+static int
+parallelsDomainManagedSave(virDomainPtr domain, unsigned int flags)
+{
+    parallelsConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr dom = NULL;
+    int state, reason;
+    int ret = -1;
+
+    virCheckFlags(VIR_DOMAIN_SAVE_RUNNING |
+                  VIR_DOMAIN_SAVE_PAUSED, -1);
+
+    dom = virDomainObjListFindByUUID(privconn->domains, domain->uuid);
+    if (dom == NULL) {
+        parallelsDomNotFoundError(domain);
+        return -1;
+    }
+
+    state = virDomainObjGetState(dom, &reason);
+
+    if (state == VIR_DOMAIN_RUNNING && (flags & VIR_DOMAIN_SAVE_PAUSED)) {
+        ret = prlsdkDomainChangeStateLocked(privconn, dom, prlsdkPause);
+        if (ret)
+            goto cleanup;
+    }
+
+    ret = prlsdkDomainChangeStateLocked(privconn, dom, prlsdkSuspend);
+
+ cleanup:
+    virObjectUnlock(dom);
+    return ret;
+}
+
+static int
+parallelsDomainManagedSaveRemove(virDomainPtr domain, unsigned int flags)
+{
+    parallelsConnPtr privconn = domain->conn->privateData;
+    virDomainObjPtr dom = NULL;
+    int state, reason;
+    int ret = -1;
+
+    virCheckFlags(0, -1);
+
+    dom = virDomainObjListFindByUUID(privconn->domains, domain->uuid);
+    if (dom == NULL) {
+        parallelsDomNotFoundError(domain);
+        return -1;
+    }
+
+    state = virDomainObjGetState(dom, &reason);
+
+    if (!(state == VIR_DOMAIN_SHUTOFF && reason == VIR_DOMAIN_SHUTOFF_SAVED))
+        goto cleanup;
+
+    ret = prlsdkDomainManagedSaveRemove(privconn, dom);
+
+ cleanup:
+    virObjectUnlock(dom);
+    return ret;
 }
 
 static virHypervisorDriver parallelsDriver = {
@@ -1042,6 +1107,8 @@ static virHypervisorDriver parallelsDriver = {
     .connectIsSecure = parallelsConnectIsSecure, /* 1.2.5 */
     .connectIsAlive = parallelsConnectIsAlive, /* 1.2.5 */
     .domainHasManagedSaveImage = parallelsDomainHasManagedSaveImage, /* 1.2.13 */
+    .domainManagedSave = parallelsDomainManagedSave, /* 1.2.14 */
+    .domainManagedSaveRemove = parallelsDomainManagedSaveRemove, /* 1.2.14 */
 };
 
 static virConnectDriver parallelsConnectDriver = {
diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c
index d985a93..7a90eec 100644
--- a/src/parallels/parallels_sdk.c
+++ b/src/parallels/parallels_sdk.c
@@ -1720,6 +1720,14 @@ PRL_RESULT prlsdkResume(parallelsConnPtr privconn, PRL_HANDLE sdkdom)
     return waitJob(job, privconn->jobTimeout);
 }
 
+PRL_RESULT prlsdkSuspend(parallelsConnPtr privconn, PRL_HANDLE sdkdom)
+{
+    PRL_HANDLE job = PRL_INVALID_HANDLE;
+
+    job = PrlVm_Suspend(sdkdom);
+    return waitJob(job, privconn->jobTimeout);
+}
+
 int
 prlsdkDomainChangeStateLocked(parallelsConnPtr privconn,
                               virDomainObjPtr dom,
@@ -3204,3 +3212,16 @@ prlsdkUnregisterDomain(parallelsConnPtr privconn, virDomainObjPtr dom)
     virDomainObjListRemove(privconn->domains, dom);
     return 0;
 }
+
+int
+prlsdkDomainManagedSaveRemove(parallelsConnPtr privconn, virDomainObjPtr dom)
+{
+    parallelsDomObjPtr privdom = dom->privateData;
+    PRL_HANDLE job;
+
+    job = PrlVm_DropSuspendedState(privdom->sdkdom);
+    if (PRL_FAILED(waitJob(job, privconn->jobTimeout)))
+        return -1;
+
+    return 0;
+}
diff --git a/src/parallels/parallels_sdk.h b/src/parallels/parallels_sdk.h
index 780a226..b084678 100644
--- a/src/parallels/parallels_sdk.h
+++ b/src/parallels/parallels_sdk.h
@@ -40,6 +40,7 @@ PRL_RESULT prlsdkKill(parallelsConnPtr privconn, PRL_HANDLE sdkdom);
 PRL_RESULT prlsdkStop(parallelsConnPtr privconn, PRL_HANDLE sdkdom);
 PRL_RESULT prlsdkPause(parallelsConnPtr privconn, PRL_HANDLE sdkdom);
 PRL_RESULT prlsdkResume(parallelsConnPtr privconn, PRL_HANDLE sdkdom);
+PRL_RESULT prlsdkSuspend(parallelsConnPtr privconn, PRL_HANDLE sdkdom);
 
 typedef PRL_RESULT (*prlsdkChangeStateFunc)(parallelsConnPtr privconn, PRL_HANDLE sdkdom);
 int
@@ -57,3 +58,5 @@ int prlsdkCreateVm(virConnectPtr conn, virDomainDefPtr def);
 int prlsdkCreateCt(virConnectPtr conn, virDomainDefPtr def);
 int
 prlsdkUnregisterDomain(parallelsConnPtr privconn, virDomainObjPtr dom);
+int
+prlsdkDomainManagedSaveRemove(parallelsConnPtr privconn, virDomainObjPtr dom);
-- 
2.1.0




More information about the libvir-list mailing list