Skip to content

Commit

Permalink
Add 0009-Backport-CA-350871-Add-lock-context-manager-for-LVM-.patch
Browse files Browse the repository at this point in the history
Improves performance when vdi_snapshot command is executed on LVM SR.
See: xapi-project/sm#550
  • Loading branch information
Wescoeur committed Apr 1, 2021
1 parent 0c16f24 commit 50f01ba
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From a950ac732d7beccdfc51c3a64b377b979a3686c9 Mon Sep 17 00:00:00 2001
From b0f4f09adfc48a0feaf4882f3f9547f063102cb6 Mon Sep 17 00:00:00 2001
From: Samuel Verschelde <stormi@laposte.net>
Date: Thu, 13 Aug 2020 15:22:17 +0200
Subject: [PATCH 1/7] Update xs-sm.service's description for XCP-ng
Subject: [PATCH 1/9] Update xs-sm.service's description for XCP-ng

This was a patch added to the sm RPM git repo before we had this
forked git repo for sm in the xcp-ng github organisation.
Expand All @@ -21,5 +21,5 @@ index 99cb313..609c6ef 100644
Conflicts=shutdown.target
RefuseManualStop=yes
--
2.28.0
2.30.1

6 changes: 3 additions & 3 deletions SOURCES/0002-Add-TrueNAS-multipath-config.patch
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From d178bfeea2ad6d575daba62062952fd5d9bb47f7 Mon Sep 17 00:00:00 2001
From 84cefd4329129dd401e7e4e97ed34d5debfa712f Mon Sep 17 00:00:00 2001
From: Samuel Verschelde <stormi@laposte.net>
Date: Thu, 13 Aug 2020 15:26:43 +0200
Subject: [PATCH 2/7] Add TrueNAS multipath config
Subject: [PATCH 2/9] Add TrueNAS multipath config

This was a patch added to the sm RPM git repo before we had this
forked git repo for sm in the xcp-ng github organisation.
Expand All @@ -26,5 +26,5 @@ index caa68e9..a414b70 100644
+ }
}
--
2.28.0
2.30.1

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From 98a0376a042eb9976302ce48a65ef23f12a7deff Mon Sep 17 00:00:00 2001
From 2309e81c0ee22e305d32f252cfeb03af575e14e7 Mon Sep 17 00:00:00 2001
From: Ronan Abhamon <ronan.abhamon@vates.fr>
Date: Mon, 20 Jul 2020 16:26:42 +0200
Subject: [PATCH 3/7] feat(drivers): add CephFS, GlusterFS and XFS drivers
Subject: [PATCH 3/9] feat(drivers): add CephFS, GlusterFS and XFS drivers

---
Makefile | 3 +
Expand Down Expand Up @@ -892,5 +892,5 @@ index 9d863f2..e0e411a 100755
if not type in SR.TYPES:
raise util.SMException("Unsupported SR type: %s" % type)
--
2.28.0
2.30.1

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From 8e576220cfc45888bf6b2f3d656dab78816c0438 Mon Sep 17 00:00:00 2001
From 2d584357ae0f3f3e1f1b3ef779cc735ecb0869fa Mon Sep 17 00:00:00 2001
From: Ronan Abhamon <ronan.abhamon@vates.fr>
Date: Wed, 12 Aug 2020 11:14:33 +0200
Subject: [PATCH 4/7] feat(drivers): add ZFS driver to avoid losing VDI
Subject: [PATCH 4/9] feat(drivers): add ZFS driver to avoid losing VDI
metadata (xcp-ng/xcp#401)

---
Expand Down Expand Up @@ -201,5 +201,5 @@ index e0e411a..461b979 100755
type = SR.TYPE_FILE
if not type in SR.TYPES:
--
2.28.0
2.30.1

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From a2470f6e8fab535c52c88b46854efbcd70b6d257 Mon Sep 17 00:00:00 2001
From ffc6e6717301fdc927c21c14991eb3d7b46290bd Mon Sep 17 00:00:00 2001
From: Samuel Verschelde <stormi@laposte.net>
Date: Thu, 13 Aug 2020 17:10:12 +0200
Subject: [PATCH 5/7] Re-add the ext4 driver for users who need to transition
Subject: [PATCH 5/9] Re-add the ext4 driver for users who need to transition

The driver is needed to transition to the ext driver.
Users who upgrade from XCP-ng <= 8.0 need a working driver so that they
Expand Down Expand Up @@ -291,5 +291,5 @@ index 461b979..0d06128 100755
type = SR.TYPE_FILE
if not type in SR.TYPES:
--
2.28.0
2.30.1

6 changes: 3 additions & 3 deletions SOURCES/0006-feat-drivers-add-LinstorSR-driver.patch
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From a8f86897162ce4babbcb8a1aaa254e208f02c643 Mon Sep 17 00:00:00 2001
From b73bae13fff9102fcf27f9e20277848aadc32956 Mon Sep 17 00:00:00 2001
From: Ronan Abhamon <ronan.abhamon@vates.fr>
Date: Mon, 16 Mar 2020 15:39:44 +0100
Subject: [PATCH 6/7] feat(drivers): add LinstorSR driver
Subject: [PATCH 6/9] feat(drivers): add LinstorSR driver

Some important points:

Expand Down Expand Up @@ -5675,5 +5675,5 @@ diff --git a/tests/mocks/linstor/__init__.py b/tests/mocks/linstor/__init__.py
new file mode 100644
index 0000000..e69de29
--
2.28.0
2.30.1

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From b63b44354e194e6d01d98ad25ed43b6a49019f08 Mon Sep 17 00:00:00 2001
From 327f349e87213fce8689195cb982fb475a417e91 Mon Sep 17 00:00:00 2001
From: Ronan Abhamon <ronan.abhamon@vates.fr>
Date: Tue, 27 Oct 2020 15:04:36 +0100
Subject: [PATCH 7/7] feat(tests): add unit tests concerning ZFS (close
Subject: [PATCH 7/9] feat(tests): add unit tests concerning ZFS (close
xcp-ng/xcp#425)

- Check if "create" doesn't succeed without zfs packages
Expand Down Expand Up @@ -208,5 +208,5 @@ index 0000000..c477fa3
+ failed = True
+ self.assertTrue(failed)
--
2.28.0
2.30.1

4 changes: 2 additions & 2 deletions SOURCES/0008-If-no-NFS-ACLs-provided-assume-everyone.patch
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From a6b5af89e8edbb5e88aff350e5e746b40f9cdec8 Mon Sep 17 00:00:00 2001
From: BenjiReis <benjamin.reis@vates.fr>
Date: Thu, 25 Feb 2021 09:54:52 +0100
Subject: [PATCH 8/8] If no NFS ACLs provided, assume everyone:
Subject: [PATCH 8/9] If no NFS ACLs provided, assume everyone:

Some QNAP devices do not provide ACL when fetching NFS mounts.
In this case the assumed ACL should be: "*".
Expand Down Expand Up @@ -71,5 +71,5 @@ index 248acb9..96eeba9 100644
+ self.assertEqual(len(pread2.mock_calls), 1)
+ pread2.assert_called_with(['/usr/sbin/showmount', '--no-headers', '-e', 'aServer'])
--
2.26.2
2.30.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
From cd8ff4c9e5e6b5805a7b02a4bab1ecf0cde9e28c Mon Sep 17 00:00:00 2001
From: Mark Syms <mark.syms@citrix.com>
Date: Fri, 15 Jan 2021 11:44:34 +0000
Subject: [PATCH 9/9] Backport: CA-350871: Add lock context manager for LVM
operations to allow for higher level control

Don't take locks for readonly operations

Signed-off-by: Mark Syms <mark.syms@citrix.com>
---
drivers/LVHDSR.py | 95 +++++++++++++++++++++++++----------------------
drivers/lvutil.py | 38 +++++++++++++------
2 files changed, 76 insertions(+), 57 deletions(-)

diff --git a/drivers/LVHDSR.py b/drivers/LVHDSR.py
index b84d5ec..ca9e5b4 100755
--- a/drivers/LVHDSR.py
+++ b/drivers/LVHDSR.py
@@ -1776,54 +1776,57 @@ class LVHDVDI(VDI.VDI):
if snapType == VDI.SNAPSHOT_DOUBLE:
clonUuid = util.gen_uuid()
jval = "%s_%s" % (baseUuid, clonUuid)
- self.sr.journaler.create(self.JRN_CLONE, origUuid, jval)
- util.fistpoint.activate("LVHDRT_clone_vdi_after_create_journal",self.sr.uuid)
+ with lvutil.LvmLockContext():
+ # This makes multiple LVM calls so take the lock early
+ self.sr.journaler.create(self.JRN_CLONE, origUuid, jval)
+ util.fistpoint.activate("LVHDRT_clone_vdi_after_create_journal", self.sr.uuid)

try:
- # self becomes the "base vdi"
- origOldLV = self.lvname
- baseLV = lvhdutil.LV_PREFIX[self.vdi_type] + baseUuid
- self.sr.lvmCache.rename(self.lvname, baseLV)
- self.sr.lvActivator.replace(self.uuid, baseUuid, baseLV, False)
- RefCounter.set(baseUuid, 1, 0, lvhdutil.NS_PREFIX_LVM + self.sr.uuid)
- self.uuid = baseUuid
- self.lvname = baseLV
- self.path = os.path.join(self.sr.path, baseLV)
- self.label = "base copy"
- self.read_only = True
- self.location = self.uuid
- self.managed = False
-
- # shrink the base copy to the minimum - we do it before creating
- # the snapshot volumes to avoid requiring double the space
- if self.vdi_type == vhdutil.VDI_TYPE_VHD:
- lvhdutil.deflate(self.sr.lvmCache, self.lvname, lvSizeBase)
- self.utilisation = lvSizeBase
- util.fistpoint.activate("LVHDRT_clone_vdi_after_shrink_parent", self.sr.uuid)
-
- snapVDI = self._createSnap(origUuid, lvSizeOrig, False)
- util.fistpoint.activate("LVHDRT_clone_vdi_after_first_snap", self.sr.uuid)
- snapVDI2 = None
- if snapType == VDI.SNAPSHOT_DOUBLE:
- snapVDI2 = self._createSnap(clonUuid, lvSizeClon, True)
- # If we have CBT enabled on the VDI,
- # set CBT status for the new snapshot disk
- if cbtlog:
- snapVDI2.cbt_enabled = True
- util.fistpoint.activate("LVHDRT_clone_vdi_after_second_snap", self.sr.uuid)
-
-
- # note: it is important to mark the parent hidden only AFTER the
- # new VHD children have been created, which are referencing it;
- # otherwise we would introduce a race with GC that could reclaim
- # the parent before we snapshot it
- if self.vdi_type == vhdutil.VDI_TYPE_RAW:
- self.sr.lvmCache.setHidden(self.lvname)
- else:
- vhdutil.setHidden(self.path)
- util.fistpoint.activate("LVHDRT_clone_vdi_after_parent_hidden", self.sr.uuid)
+ with lvutil.LvmLockContext():
+ # self becomes the "base vdi"
+ origOldLV = self.lvname
+ baseLV = lvhdutil.LV_PREFIX[self.vdi_type] + baseUuid
+ self.sr.lvmCache.rename(self.lvname, baseLV)
+ self.sr.lvActivator.replace(self.uuid, baseUuid, baseLV, False)
+ RefCounter.set(baseUuid, 1, 0, lvhdutil.NS_PREFIX_LVM + self.sr.uuid)
+ self.uuid = baseUuid
+ self.lvname = baseLV
+ self.path = os.path.join(self.sr.path, baseLV)
+ self.label = "base copy"
+ self.read_only = True
+ self.location = self.uuid
+ self.managed = False
+
+ # shrink the base copy to the minimum - we do it before creating
+ # the snapshot volumes to avoid requiring double the space
+ if self.vdi_type == vhdutil.VDI_TYPE_VHD:
+ lvhdutil.deflate(self.sr.lvmCache, self.lvname, lvSizeBase)
+ self.utilisation = lvSizeBase
+ util.fistpoint.activate("LVHDRT_clone_vdi_after_shrink_parent", self.sr.uuid)
+
+ snapVDI = self._createSnap(origUuid, lvSizeOrig, False)
+ util.fistpoint.activate("LVHDRT_clone_vdi_after_first_snap", self.sr.uuid)
+ snapVDI2 = None
+ if snapType == VDI.SNAPSHOT_DOUBLE:
+ snapVDI2 = self._createSnap(clonUuid, lvSizeClon, True)
+ # If we have CBT enabled on the VDI,
+ # set CBT status for the new snapshot disk
+ if cbtlog:
+ snapVDI2.cbt_enabled = True
+ util.fistpoint.activate("LVHDRT_clone_vdi_after_second_snap", self.sr.uuid)
+
+ # note: it is important to mark the parent hidden only AFTER the
+ # new VHD children have been created, which are referencing it;
+ # otherwise we would introduce a race with GC that could reclaim
+ # the parent before we snapshot it
+ if self.vdi_type == vhdutil.VDI_TYPE_RAW:
+ self.sr.lvmCache.setHidden(self.lvname)
+ else:
+ vhdutil.setHidden(self.path)
+ util.fistpoint.activate("LVHDRT_clone_vdi_after_parent_hidden", self.sr.uuid)

# set the base copy to ReadOnly
+ # Do this outside the LvmLockContext to avoid deadlock
self.sr.lvmCache.setReadonly(self.lvname, True)
util.fistpoint.activate("LVHDRT_clone_vdi_after_parent_ro", self.sr.uuid)

@@ -1850,7 +1853,9 @@ class LVHDVDI(VDI.VDI):
self._failClone(origUuid, jval, str(e))
util.fistpoint.activate("LVHDRT_clone_vdi_before_remove_journal",self.sr.uuid)

- self.sr.journaler.remove(self.JRN_CLONE, origUuid)
+ with lvutil.LvmLockContext():
+ # This makes multiple LVM calls so take the lock early
+ self.sr.journaler.remove(self.JRN_CLONE, origUuid)

return self._finishSnapshot(snapVDI, snapVDI2, hostRefs, cloneOp, snapType)

diff --git a/drivers/lvutil.py b/drivers/lvutil.py
index a5f6a62..2ba6945 100755
--- a/drivers/lvutil.py
+++ b/drivers/lvutil.py
@@ -74,6 +74,9 @@ DM_COMMANDS = frozenset({CMD_DMSETUP})

LVM_COMMANDS = VG_COMMANDS.union(PV_COMMANDS, LV_COMMANDS, DM_COMMANDS)

+LVM_LOCK = 'lvm'
+
+
def extract_vgname(str_in):
"""Search for and return a VG name

@@ -110,15 +113,30 @@ def extract_vgname(str_in):

return None

-
-def get_lvm_lock():
+class LvmLockContext(object):
"""
- Open and acquire a system wide lock to wrap LVM calls
- :return: the created lock
+ Context manager around the LVM lock.
+
+ To allow for higher level operations, e.g. VDI snapshot to pre-emptively
+ acquire the lock to encapsulte a set of calls and avoid having to reacquire
+ the locks for each LVM call.
"""
- new_lock = lock.Lock('lvm')
- new_lock.acquire()
- return new_lock
+
+ def __init__(self, cmd=None):
+ self.lock = lock.Lock(LVM_LOCK)
+ self.cmd = cmd
+ self.locked = False
+
+ def __enter__(self):
+ if self.cmd and '--readonly' in self.cmd:
+ return
+
+ self.lock.acquire()
+ self.locked = True
+
+ def __exit__(self, exc_type, value, traceback):
+ if self.locked:
+ self.lock.release()

def cmd_lvm(cmd, pread_func=util.pread2, *args):
""" Construct and run the appropriate lvm command.
@@ -162,14 +180,10 @@ def cmd_lvm(cmd, pread_func=util.pread2, *args):
util.SMlog("CMD_LVM: Not all lvm arguments are of type 'str'")
return None

- lvm_lock = get_lvm_lock()
-
- try:
+ with LvmLockContext(cmd):
start_time = time.time()
stdout = pread_func([os.path.join(LVM_BIN, lvm_cmd)] + lvm_args, *args)
end_time = time.time()
- finally:
- lvm_lock.release()

if (end_time - start_time > MAX_OPERATION_DURATION):
util.SMlog("***** Long LVM call of '%s' took %s" % (lvm_cmd, (end_time - start_time)))
--
2.30.1

7 changes: 6 additions & 1 deletion SPECS/sm.spec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Summary: sm - XCP storage managers
Name: sm
Version: 2.29.1
Release: 1.3%{?dist}
Release: 1.4%{?dist}
Group: System/Hypervisor
License: LGPL
URL: https://github.com/xapi-project/sm
Expand Down Expand Up @@ -41,6 +41,7 @@ Patch1005: 0005-Re-add-the-ext4-driver-for-users-who-need-to-transit.patch
Patch1006: 0006-feat-drivers-add-LinstorSR-driver.patch
Patch1007: 0007-feat-tests-add-unit-tests-concerning-ZFS-close-xcp-n.patch
Patch1008: 0008-If-no-NFS-ACLs-provided-assume-everyone.patch
Patch1009: 0009-Backport-CA-350871-Add-lock-context-manager-for-LVM-.patch

%description
This package contains storage backends used in XCP
Expand Down Expand Up @@ -414,6 +415,10 @@ cp -r htmlcov %{buildroot}/htmlcov
%{_unitdir}/linstor-monitor.service

%changelog
* Thu Apr 01 2021 Ronan Abhamon <ronan.abhamon@vates.fr> - 2.29.1-1.4
- Add: 0009-Backport-CA-350871-Add-lock-context-manager-for-LVM-.patch
- CA-350871: Add lock context manager for LVM operations to allow for higher level control

* Thu Feb 25 2021 Benjamin Reis <benjamin.reis@vates.fr> - 2.29.1-1.3
- Add: 0008-If-no-NFS-ACLs-provided-assume-everyone.patch
- Fix crash when attempting to access non existent ACL (happened on QNAP devices)
Expand Down

0 comments on commit 50f01ba

Please sign in to comment.