Change in vdsm[master]: vm: allow live snapshot to any volume descendant

fsimonce at redhat.com fsimonce at redhat.com
Wed Nov 6 15:52:09 UTC 2013


Federico Simoncelli has uploaded a new change for review.

Change subject: vm: allow live snapshot to any volume descendant
......................................................................

vm: allow live snapshot to any volume descendant

When a live snapshot fails qemu might not be using the newly-created
leaf and the volume cleanup is at management discrection (sometime too
risky or even impossible).
In this particular situation (active layer not being the volume leaf)
a subsequent live snapshot would have failed as the baseVolumeID was
not the expected one.

This patch relaxes the volumes checks allowing a live snapshot on the
volume leaf even when it's not the direct descendant of the current
active layer.

Similarly also the check in hotunplugDisk has been relaxed so that
it's now possible to hotunplug a disk with a failed live snapshot.

Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1018867
Change-Id: Ib50243c93665b9ab47ae70c779b7a1eb37c5e473
Signed-off-by: Federico Simoncelli <fsimonce at redhat.com>
---
M vdsm/vm.py
1 file changed, 31 insertions(+), 13 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/86/20986/1

diff --git a/vdsm/vm.py b/vdsm/vm.py
index e716870..14e6a0c 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -3409,7 +3409,7 @@
         diskParams['path'] = self.cif.prepareVolumePath(diskParams)
 
         try:
-            drive = self._findDriveByUUIDs(diskParams)
+            drive = self._findDriveByImage(diskParams)
         except LookupError:
             self.log.error("Hotunplug disk failed - Disk not found: %s",
                            diskParams)
@@ -3535,19 +3535,25 @@
                 return device
         raise LookupError("No such drive: '%s'" % name)
 
+    def _findDriveByImage(self, drive):
+        """Find a drive given is domainID and imageID"""
+        tgetDrv = (drive["domainID"], drive["imageID"])
+
+        for device in self._devices[DISK_DEVICES][:]:
+            if not hasattr(device, "domainID"):
+                continue
+            if (device.domainID, device.imageID) == tgetDrv:
+                return device
+
+        raise LookupError("No such drive: '%s'" % drive)
+
     def _findDriveByUUIDs(self, drive):
         """Find a drive given its definition"""
 
         if "domainID" in drive:
-            tgetDrv = (drive["domainID"], drive["imageID"],
-                       drive["volumeID"])
-
-            for device in self._devices[DISK_DEVICES][:]:
-                if not hasattr(device, "domainID"):
-                    continue
-                if (device.domainID, device.imageID,
-                        device.volumeID) == tgetDrv:
-                    return device
+            device = self._findDriveByImage(drive)
+            if device.volumeID == drive.get("volumeID", None):
+                return device
 
         elif "GUID" in drive:
             for device in self._devices[DISK_DEVICES][:]:
@@ -3697,10 +3703,10 @@
                 continue  # Next drive
 
             try:
-                vmDrive = self._findDriveByUUIDs(baseDrv)
+                vmDrive = self._findDriveByImage(baseDrv)
             except LookupError:
-                # The volume we want to snapshot doesn't exist
-                self.log.error("The base volume doesn't exist: %s", baseDrv)
+                # The disk we want to snapshot doesn't exist
+                self.log.error("The disk doesn't exist: %s", baseDrv)
                 return errCode['snapshotErr']
 
             if vmDrive.hasVolumeLeases:
@@ -3711,6 +3717,18 @@
                 self.log.error("Disk %s is a transient disk", vmDrive.name)
                 return errCode['transientErr']
 
+            volumeInfo = self.cif.irs.getVolumeInfo(
+                tgetDrv['domainID'], vmDrive.poolID, tgetDrv['imageID'],
+                tgetDrv['volumeID'])
+
+            if volumeInfo.get("status", {}).get("code") != 0:
+                self.log.error("Unable to get volume info for: %s", tgetDrv)
+                return errCode["snapshotErr"]
+
+            if volumeInfo["info"]["voltype"] != "LEAF":
+                self.log.error("Volume %s is not a volume leaf", tgetDrv)
+                return errCode["snapshotErr"]
+
             vmDevName = vmDrive.name
 
             newDrives[vmDevName] = tgetDrv.copy()


-- 
To view, visit http://gerrit.ovirt.org/20986
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib50243c93665b9ab47ae70c779b7a1eb37c5e473
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce at redhat.com>


More information about the vdsm-patches mailing list