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 20, 2025
1 parent 5540c2c commit e34e2ee
Show file tree
Hide file tree
Showing 24 changed files with 631 additions and 574 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
159 changes: 83 additions & 76 deletions drivers/LVMSR.py

Large diffs are not rendered by default.

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, cowutil.getPreallocationSizeVirt()
)

# 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
64 changes: 32 additions & 32 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 @@ -1023,7 +1024,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 @@ -1225,7 +1226,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 +1235,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 @@ -1249,15 +1250,15 @@ def deflate(self):
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 +1281,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 +1305,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 +1477,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 +1492,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 +1501,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 @@ -2880,8 +2880,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 +2958,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 +3007,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 +3023,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 +3073,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 +3120,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 +3145,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 +3178,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 +3194,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 +3973,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
8 changes: 6 additions & 2 deletions drivers/cowutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ImageFormat(IntEnum):
ImageFormat.QCOW2: "qcow2"
}

STR_TO_IMAGE_FORMAT = {v: k for k, v in IMAGE_FORMAT_TO_STR.items()}
STR_TO_IMAGE_FORMAT: Final = {v: k for k, v in IMAGE_FORMAT_TO_STR.items()}

# ------------------------------------------------------------------------------

Expand Down Expand Up @@ -99,7 +99,11 @@ def getBlockSize(self, path: str) -> int:
pass

@abstractmethod
def getFooterSize(self, path: str) -> int:
def getFooterSize(self) -> int:
pass

@abstractmethod
def getDefaultPreallocationSizeVirt(self) -> int:
pass

@abstractmethod
Expand Down
10 changes: 5 additions & 5 deletions drivers/lvhd-thin
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import sys
import XenAPIPlugin
sys.path.append("/opt/xensource/sm/")
import lvmcowutil
import util
import lvhdutil
from lvmcache import LVMCache
from journaler import Journaler
import lvutil
Expand All @@ -33,11 +33,11 @@ def attach(session, args):
os.environ['LVM_SYSTEM_DIR'] = lvutil.MASTER_LVM_CONF
srUuid = args["srUuid"]
vdiUuid = args["vdiUuid"]
vgName = "%s%s" % (lvhdutil.VG_PREFIX, srUuid)
vgName = "%s%s" % (lvmcowutil.VG_PREFIX, srUuid)
lvmCache = LVMCache(vgName)
journaler = Journaler(lvmCache)
try:
lvhdutil.attachThin(journaler, srUuid, vdiUuid)
lvcowutil.attachThin(journaler, srUuid, vdiUuid, vdiType)
return str(True)
except Exception as e:
util.logException("lvhd-thin:attach %s" % e)
Expand All @@ -48,10 +48,10 @@ def detach(session, args):
os.environ['LVM_SYSTEM_DIR'] = lvutil.MASTER_LVM_CONF
srUuid = args["srUuid"]
vdiUuid = args["vdiUuid"]
vgName = "%s%s" % (lvhdutil.VG_PREFIX, srUuid)
vgName = "%s%s" % (lvmcowutil.VG_PREFIX, srUuid)
lvmCache = LVMCache(vgName)
try:
lvhdutil.detachThin(session, lvmCache, args["srUuid"], args["vdiUuid"])
lvcowutil.detachThin(session, lvmCache, srUuid, vdiUuid, vdiType)
return str(True)
except Exception as e:
util.logException("lvhd-thin:detach %s" % e)
Expand Down
Loading

0 comments on commit e34e2ee

Please sign in to comment.