Change in vdsm[master]: vm: destroy: retry to gracefully destroy

fromani at redhat.com fromani at redhat.com
Thu Mar 24 16:41:50 UTC 2016


Francesco Romani has uploaded a new change for review.

Change subject: vm: destroy: retry to gracefully destroy
......................................................................

vm: destroy: retry to gracefully destroy

Add support to retry gracefully to destroy a VM
before to go forcefully.
Clients (Engine) could use a new optional parameter
to tell Vdsm how many times it should retry
gracefully. This is meant to reduce the risk
of data corruption in the case the first graceful
destroy fails (e.g. EBUSY, or system-level timeout).

The default number of graceful attempt is one for
backward compatibility.

Change-Id: I513b16c5091cb22313dc18e2587ed6db386e982a
Related-To: https://bugzilla.redhat.com/1309884
Backport-To: 3.6
Signed-off-by: Francesco Romani <fromani at redhat.com>
---
M lib/api/vdsmapi-schema.json
M vdsm/API.py
M vdsm/virt/vm.py
3 files changed, 23 insertions(+), 12 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/24/55224/1

diff --git a/lib/api/vdsmapi-schema.json b/lib/api/vdsmapi-schema.json
index 0ab6136..d182dd8 100644
--- a/lib/api/vdsmapi-schema.json
+++ b/lib/api/vdsmapi-schema.json
@@ -6866,12 +6866,18 @@
 #
 # Forcibly stop a running VM.
 #
-# @vmID:  The UUID of the VM
+# @vmID:               The UUID of the VM
+#
+# @gracefulAttempts:   #optional number of times Vdsm should try to
+#                      gracefully destroy the VM before to switch to
+#                      forceful. Default is 1.
+#                      (new in version 4.18.0)
+#
 #
 # Since: 4.10.0
 ##
 {'command': {'class': 'VM', 'name': 'destroy'},
- 'data': {'vmID': 'UUID'}}
+ 'data': {'vmID': 'UUID', '*gracefulAttempts': 'uint'}}
 
 ##
 # @VM.getInfo:
diff --git a/vdsm/API.py b/vdsm/API.py
index 13c5ee4..6d0cc85 100644
--- a/vdsm/API.py
+++ b/vdsm/API.py
@@ -319,7 +319,7 @@
         else:
             return errCode['nonresp']
 
-    def destroy(self):
+    def destroy(self, gracefulAttempts=1):
         """
         Destroy the specified VM.
         """
@@ -329,7 +329,7 @@
             v = self._cif.vmContainer.get(self._UUID)
             if not v:
                 return errCode['noVM']
-            res = v.destroy()
+            res = v.destroy(gracefulAttempts)
             status = utils.picklecopy(res)
             if status['status']['code'] == 0:
                 status['status']['message'] = "Machine destroyed"
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index d7d0933..a1594a0 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -3780,7 +3780,7 @@
             utils.rmFile(self.conf['floppy'])
         self._changeBlockDev('floppy', 'fda', '')
 
-    def releaseVm(self):
+    def releaseVm(self, gracefulAttempts=1):
         """
         Stop VM and release all resources
         """
@@ -3810,7 +3810,7 @@
             self._incomingMigrationFinished.set()
             self.guestAgent.stop()
             if self._dom.connected:
-                result = self._destroyVm()
+                result = self._destroyVm(gracefulAttempts)
                 if response.is_error(result):
                     return result
 
@@ -3834,8 +3834,13 @@
 
         return response.success()
 
-    def _destroyVm(self):
-        res, safe_to_force = self._destroyVmGraceful()
+    def _destroyVm(self, gracefulAttempts=1):
+        for idx in range(gracefulAttempts):
+            self.log.info("_destroyVmGraceful attempt #%i", idx)
+            res, safe_to_force = self._destroyVmGraceful()
+            if not response.is_error(res):
+                return res
+
         if safe_to_force:
             res = self._destroyVmForceful()
         return res
@@ -3883,10 +3888,10 @@
             self.log.debug("Total desktops after destroy of %s is %d",
                            self.conf['vmId'], len(self.cif.vmContainer))
 
-    def destroy(self):
+    def destroy(self, gracefulAttempts=1):
         self.log.debug('destroy Called')
 
-        result = self.doDestroy()
+        result = self.doDestroy(gracefulAttempts)
         if response.is_error(result):
             return result
         # Clean VM from the system
@@ -3894,7 +3899,7 @@
 
         return response.success()
 
-    def doDestroy(self):
+    def doDestroy(self, gracefulAttempts):
         for dev in self._customDevices():
             hooks.before_device_destroy(dev._deviceXML, self.conf,
                                         dev.custom)
@@ -3904,7 +3909,7 @@
             self._shutdownReason = vmexitreason.ADMIN_SHUTDOWN
         self._destroyed = True
 
-        return self.releaseVm()
+        return self.releaseVm(gracefulAttempts)
 
     def acpiShutdown(self):
         with self._shutdownLock:


-- 
To view, visit https://gerrit.ovirt.org/55224
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I513b16c5091cb22313dc18e2587ed6db386e982a
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Francesco Romani <fromani at redhat.com>


More information about the vdsm-patches mailing list