]> xenbits.xensource.com Git - libvirt.git/commitdiff
parallels: implement virDomainManagedSave
authorDmitry Guryanov <dguryanov@parallels.com>
Tue, 7 Apr 2015 20:35:02 +0000 (23:35 +0300)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 10 Apr 2015 07:50:29 +0000 (09:50 +0200)
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@parallels.com>
src/parallels/parallels_driver.c
src/parallels/parallels_sdk.c
src/parallels/parallels_sdk.h

index f5e58a8fefbf6c2c1854ad5f18c1e181fed2482f..3102007e5ef167c59edaa6c64a7fb78965e5fe15 100644 (file)
@@ -990,6 +990,8 @@ parallelsDomainHasManagedSaveImage(virDomainPtr domain, unsigned int flags)
 {
     parallelsConnPtr privconn = domain->conn->privateData;
     virDomainObjPtr dom = NULL;
+    int state, reason;
+    int ret = 0;
 
     virCheckFlags(0, -1);
 
@@ -999,9 +1001,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 = {
@@ -1046,6 +1111,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 = {
index d61e14ed6db46506c2c8ab047290de2af2c4207c..1b6751b146073a0ee70a1cae3a0ed93ef59a85eb 100644 (file)
@@ -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,
@@ -3210,3 +3218,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;
+}
index 780a226bf5c672d161ff03f04552190fad638e00..b084678e4747c2ad3b709ef6d54768af818b5768 100644 (file)
@@ -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);