Change in vdsm[master]: pool: live storage migration implementation
fsimonce at redhat.com
fsimonce at redhat.com
Fri Oct 19 10:43:05 UTC 2012
Federico Simoncelli has posted comments on this change.
Change subject: pool: live storage migration implementation
......................................................................
Patch Set 13: (31 inline comments)
....................................................
File vdsm/libvirtvm.py
Line 126: if vmDrive.device == 'disk' and vmDrive.isVdsmImage():
Line 127: volSize = self._vm.cif.irs.getVolumeSize(vmDrive.domainID,
Line 128: vmDrive.poolID, vmDrive.imageID, vmDrive.volumeID)
Line 129:
Line 130: if volSize['status']['code'] == 0:
Done
Line 131: continue
Line 132:
Line 133: vmDrive.truesize = int(volSize['truesize'])
Line 134: vmDrive.apparentsize = int(volSize['apparentsize'])
Line 1741:
Line 1742: def snapshot(self, snapDrives):
Line 1743: """Live snapshot command"""
Line 1744:
Line 1745: def _diskSnapshot(vmDev, newPath):
Done
Line 1746: """Libvirt snapshot XML"""
Line 1747:
Line 1748: disk = xml.dom.minidom.Element('disk')
Line 1749: disk.setAttribute('name', vmDev)
Line 1990:
Line 1991: self.saveState()
Line 1992:
Line 1993: def _setDiskReplica(self, srcDrive, dstDisk):
Line 1994: srcDrive.diskReplicate = dstDisk
Done
Line 1995:
Line 1996: for device in self.conf["devices"]:
Line 1997: if (device['type'] == vm.DISK_DEVICES
Line 1998: and device.get("name") == srcDrive.name):
Line 1995:
Line 1996: for device in self.conf["devices"]:
Line 1997: if (device['type'] == vm.DISK_DEVICES
Line 1998: and device.get("name") == srcDrive.name):
Line 1999: device['diskReplicate'] = dstDisk
Done
Line 2000:
Line 2001: self.saveState()
Line 2002:
Line 2003: def _hasDiskReplica(self, srcDrive):
Line 1999: device['diskReplicate'] = dstDisk
Line 2000:
Line 2001: self.saveState()
Line 2002:
Line 2003: def _hasDiskReplica(self, srcDrive):
Done
Line 2004: return hasattr(srcDrive, 'diskReplicate')
Line 2005:
Line 2006: def _delDiskReplica(self, srcDrive):
Line 2007: del srcDrive.diskReplicate
Line 2013:
Line 2014: self.saveState()
Line 2015:
Line 2016: def diskReplicateStart(self, srcDisk, dstDisk):
Line 2017: # Finding the source disk name and the destination path
Done
Line 2018: try:
Line 2019: srcDrive = self._findDriveByUUIDs(srcDisk)
Line 2020: except LookupError:
Line 2021: return errCode['imageErr']
Line 2019: srcDrive = self._findDriveByUUIDs(srcDisk)
Line 2020: except LookupError:
Line 2021: return errCode['imageErr']
Line 2022:
Line 2023: # Another replication is ongoing
Done
Line 2024: if self._hasDiskReplica(srcDrive):
Line 2025: return errCode['replicaErr']
Line 2026:
Line 2027: # Updating the destination disk device and name
Line 2023: # Another replication is ongoing
Line 2024: if self._hasDiskReplica(srcDrive):
Line 2025: return errCode['replicaErr']
Line 2026:
Line 2027: # Updating the destination disk device and name
Done
Line 2028: dstDisk.update({'device': srcDrive.device, 'name': srcDrive.name})
Line 2029:
Line 2030: self._setDiskReplica(srcDrive, dstDisk)
Line 2031: dstDrive = dstDisk.copy()
Line 2024: if self._hasDiskReplica(srcDrive):
Line 2025: return errCode['replicaErr']
Line 2026:
Line 2027: # Updating the destination disk device and name
Line 2028: dstDisk.update({'device': srcDrive.device, 'name': srcDrive.name})
The 'device' key is strictly required by prepareVolumePath.
Line 2029:
Line 2030: self._setDiskReplica(srcDrive, dstDisk)
Line 2031: dstDrive = dstDisk.copy()
Line 2032:
Line 2027: # Updating the destination disk device and name
Line 2028: dstDisk.update({'device': srcDrive.device, 'name': srcDrive.name})
Line 2029:
Line 2030: self._setDiskReplica(srcDrive, dstDisk)
Line 2031: dstDrive = dstDisk.copy()
Done
Line 2032:
Line 2033: try:
Line 2034: dstDrive['path'] = self.cif.prepareVolumePath(dstDrive)
Line 2035: self._dom.blockRebase(srcDrive.name, dstDrive['path'], 0, (
Line 2038: libvirt.VIR_DOMAIN_BLOCK_REBASE_SHALLOW
Line 2039: ))
Line 2040: except:
Line 2041: self.log.error("Unable to start the replication for %s to %s",
Line 2042: srcDisk.name, dstDrive['path'], exc_info=True)
srcDrive.name
Line 2043:
Line 2044: self._delDiskReplica(srcDrive)
Line 2045: return errCode['replicaErr']
Line 2046:
Line 2044: self._delDiskReplica(srcDrive)
Line 2045: return errCode['replicaErr']
Line 2046:
Line 2047: # Request an initial extension if the disk is on a block device
Line 2048: if srcDrive.blockDev:
Done
Line 2049: try:
Line 2050: self.extendDriveVolume(srcDrive)
Line 2051: except:
Line 2052: self.log.error("Initial extension request failed for %s",
Line 2053: srcDrive.name, exc_info=True)
Line 2054:
Line 2055: return {'status': doneCode}
Line 2056:
Line 2057: def diskReplicateStop(self, srcDisk, dstDisk):
Done
Line 2058: # Finding the source disk name and the destination path
Line 2059: try:
Line 2060: srcDrive = self._findDriveByUUIDs(srcDisk)
Line 2061: except LookupError:
Line 2067:
Line 2068: # Looking for the replication blockJob info (checking its presence)
Line 2069: blkJobInfo = self._dom.blockJobInfo(srcDrive.name, 0)
Line 2070:
Line 2071: if not isinstance(blkJobInfo, dict):
Done
Line 2072: self.log.error("Replication job not found for disk %s (%s)",
Line 2073: srcDrive.name, srcDisk)
Line 2074:
Line 2075: # Making sure that we don't have any stale information
Line 2075: # Making sure that we don't have any stale information
Line 2076: self._delDiskReplica(srcDrive)
Line 2077: return errCode['replicaErr']
Line 2078:
Line 2079: # Checking if we reached the mirroring mode
Done
Line 2080: if blkJobInfo['cur'] != blkJobInfo['end']:
Line 2081: return errCode['unavail']
Line 2082:
Line 2083: dstDrive = dstDisk.copy()
Line 2077: return errCode['replicaErr']
Line 2078:
Line 2079: # Checking if we reached the mirroring mode
Line 2080: if blkJobInfo['cur'] != blkJobInfo['end']:
Line 2081: return errCode['unavail']
I didn't find anything better, unavail is "Resource unavailable".
Line 2082:
Line 2083: dstDrive = dstDisk.copy()
Line 2084:
Line 2085: # Updating the destination disk device and name
Line 2079: # Checking if we reached the mirroring mode
Line 2080: if blkJobInfo['cur'] != blkJobInfo['end']:
Line 2081: return errCode['unavail']
Line 2082:
Line 2083: dstDrive = dstDisk.copy()
Done
Line 2084:
Line 2085: # Updating the destination disk device and name
Line 2086: dstDrive.update({'device': srcDrive.device, 'name': srcDrive.name})
Line 2087: dstDrive['path'] = self.cif.prepareVolumePath(dstDrive)
Line 2082:
Line 2083: dstDrive = dstDisk.copy()
Line 2084:
Line 2085: # Updating the destination disk device and name
Line 2086: dstDrive.update({'device': srcDrive.device, 'name': srcDrive.name})
Here the name is not redundant, it's the key used by _updateDrive, and 'device' is used by prepareVolumePath.
Line 2087: dstDrive['path'] = self.cif.prepareVolumePath(dstDrive)
Line 2088:
Line 2089: if srcDisk != dstDisk:
Line 2090: self.log.error("Stopping the disk replication switching to the "
Line 2087: dstDrive['path'] = self.cif.prepareVolumePath(dstDrive)
Line 2088:
Line 2089: if srcDisk != dstDisk:
Line 2090: self.log.error("Stopping the disk replication switching to the "
Line 2091: "destination drive: %s", dstDisk)
log.info
Line 2092: blockJobFlags = libvirt.VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT
Line 2093: else:
Line 2094: self.log.error("Stopping the disk replication remaining on the "
Line 2095: "source drive: %s", dstDisk)
Line 2091: "destination drive: %s", dstDisk)
Line 2092: blockJobFlags = libvirt.VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT
Line 2093: else:
Line 2094: self.log.error("Stopping the disk replication remaining on the "
Line 2095: "source drive: %s", dstDisk)
log.info
Line 2096: blockJobFlags = 0
Line 2097:
Line 2098: self._volumesPrepared = False
Line 2099:
Line 2094: self.log.error("Stopping the disk replication remaining on the "
Line 2095: "source drive: %s", dstDisk)
Line 2096: blockJobFlags = 0
Line 2097:
Line 2098: self._volumesPrepared = False
Done
Line 2099:
Line 2100: # Stopping the replication
Line 2101: try:
Line 2102: self._dom.blockJobAbort(srcDrive.name, blockJobFlags)
Line 2108: self.cif.teardownVolumePath(srcDrive.diskReplicate)
Line 2109:
Line 2110: return errCode['changeDisk']
Line 2111: finally:
Line 2112: self._volumesPrepared = True
Done
Line 2113:
Line 2114: # Tearing down the old drive only if we switched to the new one
Line 2115: try:
Line 2116: if blockJobFlags:
Line 2112: self._volumesPrepared = True
Line 2113:
Line 2114: # Tearing down the old drive only if we switched to the new one
Line 2115: try:
Line 2116: if blockJobFlags:
Done
Line 2117: self.cif.teardownVolumePath(srcDrive)
Line 2118: else:
Line 2119: self.cif.teardownVolumePath(srcDrive.diskReplicate)
Line 2120: except:
Line 2122: self.log.error("Unable to teardown the replication source ",
Line 2123: "disk", exc_info=True)
Line 2124:
Line 2125: # Updating the drive structure
Line 2126: self._updateDrive(dstDrive)
Done
Line 2127: self._delDiskReplica(srcDrive)
Line 2128:
Line 2129: return {'status': doneCode}
Line 2130:
....................................................
File vdsm/storage/hsm.py
Line 1345: misc.parseBool(force)
Line 1346: )
Line 1347:
Line 1348: @public
Line 1349: def syncImage(self, spUUID, sdUUID, imgUUID, dstSdUUID, operations):
Done
Line 1350: """
Line 1351: Synchronize images between storage domains within same storage pool
Line 1352: """
Line 1353: pool = self.getPool(spUUID)
Line 1347:
Line 1348: @public
Line 1349: def syncImage(self, spUUID, sdUUID, imgUUID, dstSdUUID, operations):
Line 1350: """
Line 1351: Synchronize images between storage domains within same storage pool
Done
Line 1352: """
Line 1353: pool = self.getPool(spUUID)
Line 1354:
Line 1355: srcDom = self.validateSdUUID(sdUUID)
Line 1353: pool = self.getPool(spUUID)
Line 1354:
Line 1355: srcDom = self.validateSdUUID(sdUUID)
Line 1356: dstDom = self.validateSdUUID(dstSdUUID)
Line 1357: self.validateImageMove(srcDom, dstDom, imgUUID)
Done
Line 1358:
Line 1359: for dom in sorted((sdUUID, dstSdUUID)):
Line 1360: vars.task.getSharedLock(STORAGE, dom)
Line 1361:
....................................................
File vdsm/storage/sp.py
Line 1750: srcImgResNs = sd.getNamespace(sdUUID, IMAGE_NAMESPACE)
Line 1751: dstImgResNs = sd.getNamespace(dstSdUUID, IMAGE_NAMESPACE)
Line 1752:
Line 1753: # Preparing the ordered resource list to be acquired
Line 1754: resList = (rmanager.acquireResource(*x) for x in sorted((
Yes indeed it acquires the resources, but it does that in the correct order. This is also what happens at line 1787. The nested( *resList) is basically used only to release the resources (__enter__ is a simple "return self", __exit__ is instead a real release of the resource). Ugly, but there's no time to fix infra issues.
Line 1755: (srcImgResNs, imgUUID, rm.LockType.shared),
Line 1756: (dstImgResNs, imgUUID, rm.LockType.exclusive),
Line 1757: )))
Line 1758:
....................................................
File vdsm/vm.py
Line 721: self.conf['timeOffset'] = timeOffset
Line 722:
Line 723: def extendDriveVolume(self, vmDrive, newSize=None):
Line 724: if not vmDrive.blockDev:
Line 725: self.log.error("The device %s is not a block device", vmDrive.name)
Done
Line 726: return
Line 727:
Line 728: if newSize is None:
Line 729: newSize = (config.getint('irs', 'volume_utilization_chunk_mb')
Line 735: 'imageID': vmDrive.diskReplicate['imageID'],
Line 736: 'volumeID': vmDrive.diskReplicate['volumeID'],
Line 737: 'name': vmDrive.name, 'newSize': newSize}
Line 738: self.log.debug("Requesting extension for the replica volume: %s",
Line 739: volInfo)
I can't, __extendDriveVolume takes a drive object, here we're building an extend request from a PDIV (diskReplicate).
Line 740: self.cif.irs.sendExtendMsg(vmDrive.poolID, volInfo,
Line 741: newSize, self.__afterReplicaExtend)
Line 742: else:
Line 743: self.__extendDriveVolume(vmDrive, newSize)
Line 758: self._guestCpuLock.release()
Line 759:
Line 760: def __afterReplicaExtend(self, volInfo):
Line 761: self.log.debug("Refreshing replica volume: %s", volInfo)
Line 762: self.__refreshDriveVolume(volInfo)
Done
Line 763:
Line 764: vmDrive = self._findDriveByName(volInfo['name'])
Line 765:
Line 766: self.log.debug("Requesting extension for the original drive: %s",
--
To view, visit http://gerrit.ovirt.org/5252
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: comment
Gerrit-Change-Id: I91e641cb1d25feb8a406aa7ad07415587a7ac290
Gerrit-PatchSet: 13
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce at redhat.com>
Gerrit-Reviewer: Ayal Baron <abaron at redhat.com>
Gerrit-Reviewer: Federico Simoncelli <fsimonce at redhat.com>
Gerrit-Reviewer: Maor Lipchuk <mlipchuk at redhat.com>
Gerrit-Reviewer: Royce Lv <lvroyce at linux.vnet.ibm.com>
Gerrit-Reviewer: Saggi Mizrahi <smizrahi at redhat.com>
Gerrit-Reviewer: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
Gerrit-Reviewer: Shu Ming <shuming at linux.vnet.ibm.com>
Gerrit-Reviewer: oVirt Jenkins CI Server
More information about the vdsm-patches
mailing list