Skip to content

Commit

Permalink
LVM COW in progress
Browse files Browse the repository at this point in the history
Signed-off-by: Ronan Abhamon <ronan.abhamon@vates.fr>
  • Loading branch information
Wescoeur committed Jan 23, 2025
1 parent 7a992dc commit a9c8f12
Show file tree
Hide file tree
Showing 28 changed files with 789 additions and 732 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ SM_LIBS += vhdutil
SM_LIBS += linstorjournaler
SM_LIBS += linstorvhdutil
SM_LIBS += linstorvolumemanager
SM_LIBS += lvhdutil # TODO: Split
SM_LIBS += lvmcowutil
SM_LIBS += cifutils
SM_LIBS += xs_errors
SM_LIBS += nfs
Expand Down
4 changes: 2 additions & 2 deletions drivers/02-vhdcleanup
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
. /etc/init.d/functions

CLEANUP_SCRIPT="/opt/xensource/sm/cleanup.py"
LVHD_UTIL_SCRIPT="/opt/xensource/sm/lvhdutil.py"
LVM_COW_UTIL_SCRIPT="/opt/xensource/sm/lvmcowutil.py"

start() {
echo -n $"Fixing refcounts on new master: "
Expand All @@ -31,7 +31,7 @@ start() {
srUuids=`xe sr-list type=$type params=uuid --minimal | sed "s/,/ /g"`
for uuid in $srUuids; do
echo -n "Fixing $type"
python $LVHD_UTIL_SCRIPT fixrefcounts $uuid
python $LVM_COW_UTIL_SCRIPT fixrefcounts $uuid
done
done
echo -n $"OK"
Expand Down
377 changes: 193 additions & 184 deletions drivers/LVMSR.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion drivers/LVMoHBASR.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@

DRIVER_INFO = {
'name': 'LVM over FC',
'description': 'SR plugin which represents disks as VHDs on Logical Volumes within a Volume Group created on an HBA LUN, e.g. hardware-based iSCSI or FC support',
'description': 'SR plugin which represents disks as VHDs and QCOW2s on Logical Volumes within a Volume Group created on an HBA LUN, e.g. hardware-based iSCSI or FC support',
'vendor': 'Citrix Systems Inc',
'copyright': '(C) 2008 Citrix Systems Inc',
'driver_version': '1.0',
Expand Down
2 changes: 1 addition & 1 deletion drivers/LinstorSR.py
Original file line number Diff line number Diff line change
Expand Up @@ -2293,7 +2293,7 @@ def _create_snapshot(self, snap_uuid, snap_of_uuid=None):
# 2. Write the snapshot content.
is_raw = (self.vdi_type == VdiType.RAW)
self._cowutil.snapshot(
snap_path, self.path, is_raw, self.MAX_METADATA_VIRT_SIZE
snap_path, self.path, is_raw, max(self.size, cowutil.getDefaultPreallocationSizeVirt())
)

# 3. Get snapshot parent.
Expand Down
1 change: 0 additions & 1 deletion drivers/VDI.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import xmlrpc.client
import xs_errors
import util
import vhdutil
import cbtutil
import os
import base64
Expand Down
8 changes: 4 additions & 4 deletions drivers/blktap2.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@
import scsiutil
from syslog import openlog, syslog
from stat import * # S_ISBLK(), ...
from lvmcowutil import NS_PREFIX_LVM
from vditype import VdiType
import nfs

import resetvdis
import lvhdutil

import VDI as sm

Expand Down Expand Up @@ -1117,7 +1117,7 @@ def __str__(self) -> str:

VDI_PLUG_TYPE = {'phy': 'phy', # for NETAPP
'raw': 'phy',
'aio': 'tap', # for LVHD raw nodes
'aio': 'tap', # for LVM raw nodes
'iso': 'tap', # for ISOSR
'file': 'tap',
'vhd': 'tap',
Expand Down Expand Up @@ -1672,7 +1672,7 @@ def _activate_locked(self, sr_uuid, vdi_uuid, options):
if hasattr(self.target.vdi.sr, 'DRIVER_TYPE') and \
self.target.vdi.sr.DRIVER_TYPE == 'lvhd' and \
VdiType.isCowImage(vdi_type):
lock = Lock("lvchange-p", lvhdutil.NS_PREFIX_LVM + sr_uuid)
lock = Lock("lvchange-p", NS_PREFIX_LVM + sr_uuid)
lock.acquire()

# When we attach a static VDI for HA, we cannot communicate with
Expand Down Expand Up @@ -1975,7 +1975,7 @@ def _setup_cache(self, session, sr_uuid, vdi_uuid, local_sr_uuid,
os.unlink(local_leaf_path)
try:
self._cowutil.snapshot(local_leaf_path, read_cache_path, False,
msize=leaf_size // 1024 // 1024, checkEmpty=False)
msize=leaf_size, checkEmpty=False)
except util.CommandException as e:
util.SMlog("Error creating leaf cache: %s" % e)
self.alert_no_cache(session, vdi_uuid, local_sr_uuid, e.code)
Expand Down
2 changes: 1 addition & 1 deletion drivers/cbtutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# along with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Helper functions pertaining to VHD operations
# Helper functions pertaining to COW image operations
#

import util
Expand Down
79 changes: 39 additions & 40 deletions drivers/cleanup.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import XenAPI # pylint: disable=import-error
import util
import lvutil
import lvhdutil
import lvmcowutil
import lvmcache
import journaler
import fjournaler
Expand All @@ -52,6 +52,7 @@
from time import monotonic as _time

from cowutil import CowUtil, getCowUtil
from lvmcowutil import LV_PREFIX, NS_PREFIX_LVM, VG_LOCATION, VG_PREFIX
from vditype import VdiType, VdiTypeExtension, VDI_COW_TYPES, VDI_TYPE_TO_EXTENSION

try:
Expand Down Expand Up @@ -767,7 +768,7 @@ def rename(self, uuid) -> None:

def delete(self) -> None:
"Physically delete the VDI"
lock.Lock.cleanup(self.uuid, lvhdutil.NS_PREFIX_LVM + self.sr.uuid)
lock.Lock.cleanup(self.uuid, NS_PREFIX_LVM + self.sr.uuid)
lock.Lock.cleanupAll(self.uuid)
self._clear()

Expand Down Expand Up @@ -896,8 +897,7 @@ def _reportCoalesceError(vdi, ce):
xapi.message.create(msg_name, "3", "SR", vdi.sr.uuid, msg_body)

def coalesce(self) -> int:
# size is returned in sectors
return self.cowutil.coalesce(self.path) * 512
return self.cowutil.coalesce(self.path)

@staticmethod
def _doCoalesceCowImage(vdi):
Expand Down Expand Up @@ -981,7 +981,7 @@ def _reloadChildren(self, vdiSkip):
child._reload()

def _reload(self):
"""Pause & unpause to cause blktap to reload the VHD metadata"""
"""Pause & unpause to cause blktap to reload the image metadata"""
for child in self.children:
child._reload()

Expand Down Expand Up @@ -1023,7 +1023,7 @@ def _tagChildrenForRelink(self):
child._tagChildrenForRelink()

def _loadInfoParent(self):
ret = self.cowutil.getParent(self.path, lvhdutil.extractUuid)
ret = self.cowutil.getParent(self.path, LvmCowUtil.extractUuid)
if ret:
self.parentUuid = ret

Expand Down Expand Up @@ -1091,9 +1091,9 @@ def _queryVHDBlocks(self) -> bytes:
return self.cowutil.getBlockBitmap(self.path)

def _getCoalescedSizeData(self):
"""Get the data size of the resulting VHD if we coalesce self onto
parent. We calculate the actual size by using the VHD block allocation
information (as opposed to just adding up the two VHD sizes to get an
"""Get the data size of the resulting image if we coalesce self onto
parent. We calculate the actual size by using the image block allocation
information (as opposed to just adding up the two image sizes to get an
upper bound)"""
# make sure we don't use stale BAT info from vdi_rec since the child
# was writable all this time
Expand Down Expand Up @@ -1225,7 +1225,7 @@ def load(self, info=None) -> None:

@staticmethod
def extractUuid(path):
return lvhdutil.extractUuid(path)
return LvmCowUtil.extractUuid(path)

def inflate(self, size):
"""inflate the LV containing the VHD to 'size'"""
Expand All @@ -1234,7 +1234,7 @@ def inflate(self, size):
self._activate()
self.sr.lock()
try:
lvhdutil.inflate(self.sr.journaler, self.sr.uuid, self.uuid, size)
self.lvmcowutil.inflate(self.sr.journaler, self.sr.uuid, self.uuid, self.vdi_type, size)
util.fistpoint.activate("LVHDRT_inflating_the_parent", self.sr.uuid)
finally:
self.sr.unlock()
Expand All @@ -1243,21 +1243,21 @@ def inflate(self, size):
self._sizeAllocated = -1

def deflate(self):
"""deflate the LV containing the VHD to minimum"""
"""deflate the LV containing the image to minimum"""
if not VdiType.isCowImage(self.vdi_type):
return
self._activate()
self.sr.lock()
try:
lvhdutil.deflate(self.sr.lvmCache, self.fileName, self.getSizePhys())
self.lvmcowutil.deflate(self.sr.lvmCache, self.fileName, self.getSizePhys())
finally:
self.sr.unlock()
self.sizeLV = self.sr.lvmCache.getSize(self.fileName)
self._sizePhys = -1
self._sizeAllocated = -1

def inflateFully(self):
self.inflate(lvhdutil.calcSizeVHDLV(self.sizeVirt))
self.inflate(self.lvmcowutil.calcVolumeSize(self.sizeVirt))

def inflateParentForCoalesce(self):
"""Inflate the parent only as much as needed for the purposes of
Expand All @@ -1280,15 +1280,15 @@ def rename(self, uuid) -> None:
oldUuid = self.uuid
oldLVName = self.fileName
VDI.rename(self, uuid)
self.fileName = lvhdutil.LV_PREFIX[self.vdi_type] + self.uuid
self.fileName = LV_PREFIX[self.vdi_type] + self.uuid
self.path = os.path.join(self.sr.path, self.fileName)
assert(not self.sr.lvmCache.checkLV(self.fileName))

self.sr.lvmCache.rename(oldLVName, self.fileName)
if self.sr.lvActivator.get(oldUuid, False):
self.sr.lvActivator.replace(oldUuid, self.uuid, self.fileName, False)

ns = lvhdutil.NS_PREFIX_LVM + self.sr.uuid
ns = NS_PREFIX_LVM + self.sr.uuid
(cnt, bcnt) = RefCounter.check(oldUuid, ns)
RefCounter.set(self.uuid, cnt, bcnt, ns)
RefCounter.reset(oldUuid, ns)
Expand All @@ -1304,7 +1304,7 @@ def delete(self) -> None:
self.sr.forgetVDI(self.uuid)
finally:
self.sr.unlock()
RefCounter.reset(self.uuid, lvhdutil.NS_PREFIX_LVM + self.sr.uuid)
RefCounter.reset(self.uuid, NS_PREFIX_LVM + self.sr.uuid)
VDI.delete(self)

@override
Expand Down Expand Up @@ -1476,12 +1476,11 @@ def _setSizeVirt(self, size) -> None:
subtree are guaranteed to be unplugged (and remain so for the duration
of the operation): this operation is only safe for offline VHDs"""
self._activate()
jFile = lvhdutil.createVHDJournalLV(self.sr.lvmCache, self.uuid, self.cowutil.getResizeJournalSize())
jFile = self.lvmcowutil.createResizeJournal(self.sr.lvmCache, self.uuid)
try:
lvhdutil.setSizeVirt(self.sr.journaler, self.sr.uuid, self.uuid,
size, jFile)
self.lvmcowutil.setSizeVirt(self.sr.journaler, self.sr.uuid, self.uuid, self.vdi_type, size, jFile)
finally:
lvhdutil.deleteVHDJournalLV(self.sr.lvmCache, self.uuid)
self.lvmcowutil.destroyResizeJournal(self.sr.lvmCache, self.uuid)

@override
def _queryVHDBlocks(self) -> bytes:
Expand All @@ -1492,7 +1491,7 @@ def _queryVHDBlocks(self) -> bytes:
def _calcExtraSpaceForCoalescing(self) -> int:
if not VdiType.isCowImage(self.parent.vdi_type):
return 0 # raw parents are never deflated in the first place
sizeCoalesced = lvhdutil.calcSizeVHDLV(self._getCoalescedSizeData())
sizeCoalesced = self.lvmcowutil.calcVolumeSize(self._getCoalescedSizeData())
Util.log("Coalesced size = %s" % Util.num2str(sizeCoalesced))
return sizeCoalesced - self.parent.sizeLV

Expand All @@ -1501,13 +1500,13 @@ def _calcExtraSpaceForLeafCoalescing(self) -> int:
"""How much extra space in the SR will be required to
[live-]leaf-coalesce this VDI"""
# we can deflate the leaf to minimize the space requirements
deflateDiff = self.sizeLV - lvhdutil.calcSizeLV(self.getSizePhys())
deflateDiff = self.sizeLV - lvutil.calcSizeLV(self.getSizePhys())
return self._calcExtraSpaceForCoalescing() - deflateDiff

@override
def _calcExtraSpaceForSnapshotCoalescing(self) -> int:
return self._calcExtraSpaceForCoalescing() + \
lvhdutil.calcSizeLV(self.getSizePhys())
lvutil.calcSizeLV(self.getSizePhys())


class LinstorVDI(VDI):
Expand Down Expand Up @@ -1634,7 +1633,7 @@ def pause(self, failfast=False) -> None:
def coalesce(self) -> int:
# Note: We raise `SMException` here to skip the current coalesce in case of failure.
# Using another exception we can't execute the next coalesce calls.
return self.sr._vhdutil.force_coalesce(self.path) * 512
return self.sr._vhdutil.force_coalesce(self.path)

@override
def getParent(self) -> str:
Expand Down Expand Up @@ -2880,8 +2879,8 @@ class LVMSR(SR):

def __init__(self, uuid, xapi, createLock, force):
SR.__init__(self, uuid, xapi, createLock, force)
self.vgName = "%s%s" % (lvhdutil.VG_PREFIX, self.uuid)
self.path = os.path.join(lvhdutil.VG_LOCATION, self.vgName)
self.vgName = "%s%s" % (VG_PREFIX, self.uuid)
self.path = os.path.join(VG_LOCATION, self.vgName)

sr_ref = self.xapi.session.xenapi.SR.get_by_uuid(self.uuid)
other_conf = self.xapi.session.xenapi.SR.get_other_config(sr_ref)
Expand Down Expand Up @@ -2958,7 +2957,7 @@ def _scan(self, force):
for i in range(SR.SCAN_RETRY_ATTEMPTS):
error = False
self.lvmCache.refresh()
vdis = lvhdutil.getVDIInfo(self.lvmCache)
vdis = LvmCowUtil.getVDIInfo(self.lvmCache)
for uuid, vdiInfo in vdis.items():
if vdiInfo.scanError:
error = True
Expand Down Expand Up @@ -3007,7 +3006,7 @@ def _updateNode(self, vdi) -> None:
# this node is really the parent node) - minus 1 if it is online (since
# non-leaf nodes increment their normal counts when they are online and
# we are now a leaf, storing that 1 in the binary refcount).
ns = lvhdutil.NS_PREFIX_LVM + self.uuid
ns = NS_PREFIX_LVM + self.uuid
cCnt, cBcnt = RefCounter.check(vdi.uuid, ns)
pCnt, pBcnt = RefCounter.check(vdi.parent.uuid, ns)
pCnt = pCnt - cBcnt
Expand All @@ -3023,17 +3022,17 @@ def _finishCoalesceLeaf(self, parent) -> None:

@override
def _calcExtraSpaceNeeded(self, child, parent) -> int:
return lvhdutil.calcSizeVHDLV(parent.sizeVirt) - parent.sizeLV
return parent.lvmcowutil.calcVolumeSize(parent.sizeVirt) - parent.sizeLV

@override
def _handleInterruptedCoalesceLeaf(self) -> None:
entries = self.journaler.getAll(VDI.JRN_LEAF)
for uuid, parentUuid in entries.items():
childLV = lvhdutil.LV_PREFIX[VdiType.VHD] + uuid
tmpChildLV = lvhdutil.LV_PREFIX[VdiType.VHD] + \
childLV = LV_PREFIX[VdiType.VHD] + uuid
tmpChildLV = LV_PREFIX[VdiType.VHD] + \
self.TMP_RENAME_PREFIX + uuid
parentLV1 = lvhdutil.LV_PREFIX[VdiType.VHD] + parentUuid
parentLV2 = lvhdutil.LV_PREFIX[VdiType.RAW] + parentUuid
parentLV1 = LV_PREFIX[VdiType.VHD] + parentUuid
parentLV2 = LV_PREFIX[VdiType.RAW] + parentUuid
parentPresent = (self.lvmCache.checkLV(parentLV1) or \
self.lvmCache.checkLV(parentLV2))
if parentPresent or self.lvmCache.checkLV(tmpChildLV):
Expand Down Expand Up @@ -3073,7 +3072,7 @@ def _undoInterruptedCoalesceLeaf(self, childUuid, parentUuid):
# refcount (best effort - assume that it had succeeded if the
# second rename succeeded; if not, this adjustment will be wrong,
# leading to a non-deactivation of the LV)
ns = lvhdutil.NS_PREFIX_LVM + self.uuid
ns = NS_PREFIX_LVM + self.uuid
cCnt, cBcnt = RefCounter.check(child.uuid, ns)
pCnt, pBcnt = RefCounter.check(parent.uuid, ns)
pCnt = pCnt + cBcnt
Expand Down Expand Up @@ -3120,7 +3119,7 @@ def _checkSlaves(self, vdi):
"lvName1": vdi.fileName,
"action2": "cleanupLockAndRefcount",
"uuid2": vdi.uuid,
"ns2": lvhdutil.NS_PREFIX_LVM + self.uuid}
"ns2": NS_PREFIX_LVM + self.uuid}
onlineHosts = self.xapi.getOnlineHosts()
abortFlag = IPCFlag(self.uuid)
for pbdRecord in self.xapi.getAttachedPBDs():
Expand All @@ -3145,7 +3144,7 @@ def _updateSlavesOnUndoLeafCoalesce(self, parent, child) -> None:
child)
return

tmpName = lvhdutil.LV_PREFIX[VdiType.VHD] + \
tmpName = LV_PREFIX[VdiType.VHD] + \
self.TMP_RENAME_PREFIX + child.uuid
args = {"vgName": self.vgName,
"action1": "deactivateNoRefcount",
Expand Down Expand Up @@ -3178,7 +3177,7 @@ def _updateSlavesOnRename(self, vdi, oldNameLV, origParentUuid) -> None:
"lvName2": vdi.fileName,
"action3": "cleanupLockAndRefcount",
"uuid3": origParentUuid,
"ns3": lvhdutil.NS_PREFIX_LVM + self.uuid}
"ns3": NS_PREFIX_LVM + self.uuid}
for slave in slaves:
Util.log("Updating %s to %s on slave %s" % \
(oldNameLV, vdi.fileName,
Expand All @@ -3194,7 +3193,7 @@ def _updateSlavesOnResize(self, vdi) -> None:
if not slaves:
util.SMlog("Update-on-resize: %s not attached on any slave" % vdi)
return
lvhdutil.lvRefreshOnSlaves(self.xapi.session, self.uuid, self.vgName,
LvmCowUtil.refreshVolumeOnSlaves(self.xapi.session, self.uuid, self.vgName,
vdi.fileName, vdi.uuid, slaves)


Expand Down Expand Up @@ -3973,7 +3972,7 @@ def debug(sr_uuid, cmd, vdi_uuid):
vdi._activate()
print("VDI file: %s" % vdi.path)
if cmd == "deactivate":
ns = lvhdutil.NS_PREFIX_LVM + sr.uuid
ns = NS_PREFIX_LVM + sr.uuid
sr.lvmCache.deactivate(ns, vdi.uuid, vdi.fileName, False)
if cmd == "inflate":
vdi.inflateFully()
Expand Down
Loading

0 comments on commit a9c8f12

Please sign in to comment.