From d2d5ca083145641a1ef906d18b2f736b7e812bc6 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Mon, 9 Sep 2024 13:50:00 +0200 Subject: [PATCH] Import 8.2 LINSTOR changes on 8.3 - Robustify HA: use a specific group with a replication count of 3 - Export helpers in linstor-manager regarding network interfaces - Improve health-check helper: more details and simple API - Fix pause/unpause: always load a valid VHD chain - Robustify remote "vhdutil check" command - Robustify SR destruction - Prevent diskless destruction on master host - Prevent tiebreaker destruction - Reduce LINSTOR vhdutil queries Last commit: 9207abe1f2e1ff1795cdba1a0aeb76574412a583 "fix(linstor): check if resource is tiebreaker (#62)" Signed-off-by: Ronan Abhamon --- ...-sm.service-s-description-for-XCP-ng.patch | 4 +- ...ers-add-CephFS-and-GlusterFS-drivers.patch | 10 +- .../0003-feat-drivers-add-XFS-driver.patch | 8 +- ...-ZFS-driver-to-avoid-losing-VDI-meta.patch | 10 +- ...05-feat-drivers-add-LinstorSR-driver.patch | 30 +- ...nit-tests-concerning-ZFS-close-xcp-n.patch | 6 +- .../0007-Added-SM-Driver-for-MooseFS.patch | 10 +- ...mount-in-ISOSR-when-legacy_mode-is-u.patch | 6 +- ...SR-uses-now-UUID-subdirs-for-each-SR.patch | 4 +- ...Fix-is_open-call-for-many-drivers-25.patch | 8 +- ...HING-capability-for-many-SR-types-24.patch | 8 +- ...age-regarding-MooseFSSR-and-ZFSSR-29.patch | 6 +- ...nges-from-futurize-on-XCP-ng-drivers.patch | 14 +- ...-of-xmlrpc-calls-for-CephFS-GlusterF.patch | 10 +- ...py3-use-of-integer-division-operator.patch | 4 +- ...low-to-work-with-SR-using-absolute-P.patch | 4 +- ...17-py3-switch-interpreter-to-python3.patch | 18 +- ...port-recent-version-of-coverage-tool.patch | 4 +- ...eat-LinstorSR-import-all-8.2-changes.patch | 44 +- ...orSR-is-now-compatible-with-python-3.patch | 20 +- ...ve-SR_PROBE-from-ZFS-capabilities-36.patch | 4 +- ...e-to-be-compatible-with-8.3-test-env.patch | 10 +- .../0023-Support-IPv6-in-Ceph-Driver.patch | 4 +- ...s-not-dd-to-clear-existing-signature.patch | 8 +- ...LargeBlock-introduce-largeblocksr-51.patch | 14 +- ...dd-a-way-to-modify-config-of-LVMs-60.patch | 8 +- ...eflect-upstream-changes-in-our-tests.patch | 6 +- ...tly-check-for-multiple-targets-in-iS.patch | 4 +- ...with-8.2-LINSTOR-before-a-stable-rel.patch | 1400 +++++++++++++++++ SPECS/sm.spec | 15 +- 30 files changed, 1557 insertions(+), 144 deletions(-) create mode 100644 SOURCES/0029-Synchronization-with-8.2-LINSTOR-before-a-stable-rel.patch diff --git a/SOURCES/0001-Update-xs-sm.service-s-description-for-XCP-ng.patch b/SOURCES/0001-Update-xs-sm.service-s-description-for-XCP-ng.patch index abfb0748..5ae76dbb 100644 --- a/SOURCES/0001-Update-xs-sm.service-s-description-for-XCP-ng.patch +++ b/SOURCES/0001-Update-xs-sm.service-s-description-for-XCP-ng.patch @@ -1,7 +1,7 @@ From de38d2672887c47a4e0600426d87137185243d38 Mon Sep 17 00:00:00 2001 From: Samuel Verschelde Date: Thu, 13 Aug 2020 15:22:17 +0200 -Subject: [PATCH 01/28] Update xs-sm.service's description for XCP-ng +Subject: [PATCH 01/29] 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. @@ -10,7 +10,7 @@ forked git repo for sm in the xcp-ng github organisation. 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/systemd/xs-sm.service b/systemd/xs-sm.service -index 99cb313..609c6ef 100644 +index 99cb313f..609c6ef5 100644 --- a/systemd/xs-sm.service +++ b/systemd/xs-sm.service @@ -1,5 +1,5 @@ diff --git a/SOURCES/0002-feat-drivers-add-CephFS-and-GlusterFS-drivers.patch b/SOURCES/0002-feat-drivers-add-CephFS-and-GlusterFS-drivers.patch index 58993e8e..a218701a 100644 --- a/SOURCES/0002-feat-drivers-add-CephFS-and-GlusterFS-drivers.patch +++ b/SOURCES/0002-feat-drivers-add-CephFS-and-GlusterFS-drivers.patch @@ -1,7 +1,7 @@ From 1809f021bf3af5fa18419e248469cd970bded9f3 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Mon, 20 Jul 2020 16:26:42 +0200 -Subject: [PATCH 02/28] feat(drivers): add CephFS and GlusterFS drivers +Subject: [PATCH 02/29] feat(drivers): add CephFS and GlusterFS drivers --- Makefile | 2 + @@ -13,7 +13,7 @@ Subject: [PATCH 02/28] feat(drivers): add CephFS and GlusterFS drivers create mode 100644 drivers/GlusterFSSR.py diff --git a/Makefile b/Makefile -index ad81be4..0750482 100755 +index ad81be40..07504828 100755 --- a/Makefile +++ b/Makefile @@ -14,6 +14,8 @@ SM_DRIVERS += LVHDoHBA @@ -27,7 +27,7 @@ index ad81be4..0750482 100755 SM_LIBS += SRCommand diff --git a/drivers/CephFSSR.py b/drivers/CephFSSR.py new file mode 100644 -index 0000000..415152f +index 00000000..415152f7 --- /dev/null +++ b/drivers/CephFSSR.py @@ -0,0 +1,296 @@ @@ -329,7 +329,7 @@ index 0000000..415152f + SR.registerSR(CephFSSR) diff --git a/drivers/GlusterFSSR.py b/drivers/GlusterFSSR.py new file mode 100644 -index 0000000..72c482a +index 00000000..72c482ae --- /dev/null +++ b/drivers/GlusterFSSR.py @@ -0,0 +1,287 @@ @@ -621,7 +621,7 @@ index 0000000..72c482a +else: + SR.registerSR(GlusterFSSR) diff --git a/drivers/cleanup.py b/drivers/cleanup.py -index 042fe99..d3dfc0e 100755 +index 042fe998..d3dfc0e4 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -2887,7 +2887,9 @@ def normalizeType(type): diff --git a/SOURCES/0003-feat-drivers-add-XFS-driver.patch b/SOURCES/0003-feat-drivers-add-XFS-driver.patch index 068aa87f..bc148dfa 100644 --- a/SOURCES/0003-feat-drivers-add-XFS-driver.patch +++ b/SOURCES/0003-feat-drivers-add-XFS-driver.patch @@ -1,7 +1,7 @@ From 4517b34462a3285630dc134de99eb84f6aa4fb58 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Mon, 20 Jul 2020 16:26:42 +0200 -Subject: [PATCH 03/28] feat(drivers): add XFS driver +Subject: [PATCH 03/29] feat(drivers): add XFS driver Originally-by: Ronan Abhamon @@ -21,7 +21,7 @@ Signed-off-by: Yann Dirson create mode 100755 drivers/XFSSR.py diff --git a/Makefile b/Makefile -index 0750482..7cb6ba4 100755 +index 07504828..7cb6ba49 100755 --- a/Makefile +++ b/Makefile @@ -16,6 +16,7 @@ SM_DRIVERS += SMB @@ -34,7 +34,7 @@ index 0750482..7cb6ba4 100755 SM_LIBS += SRCommand diff --git a/drivers/XFSSR.py b/drivers/XFSSR.py new file mode 100755 -index 0000000..1dfde09 +index 00000000..1dfde095 --- /dev/null +++ b/drivers/XFSSR.py @@ -0,0 +1,249 @@ @@ -288,7 +288,7 @@ index 0000000..1dfde09 +else: + SR.registerSR(XFSSR) diff --git a/drivers/cleanup.py b/drivers/cleanup.py -index d3dfc0e..57522b8 100755 +index d3dfc0e4..57522b8b 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -2889,6 +2889,7 @@ def normalizeType(type): diff --git a/SOURCES/0004-feat-drivers-add-ZFS-driver-to-avoid-losing-VDI-meta.patch b/SOURCES/0004-feat-drivers-add-ZFS-driver-to-avoid-losing-VDI-meta.patch index 86828e53..e4106e54 100644 --- a/SOURCES/0004-feat-drivers-add-ZFS-driver-to-avoid-losing-VDI-meta.patch +++ b/SOURCES/0004-feat-drivers-add-ZFS-driver-to-avoid-losing-VDI-meta.patch @@ -1,7 +1,7 @@ From cd3cd24251e847eb20ac5b32a374109718c8cca0 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Wed, 12 Aug 2020 11:14:33 +0200 -Subject: [PATCH 04/28] feat(drivers): add ZFS driver to avoid losing VDI +Subject: [PATCH 04/29] feat(drivers): add ZFS driver to avoid losing VDI metadata (xcp-ng/xcp#401) --- @@ -13,7 +13,7 @@ Subject: [PATCH 04/28] feat(drivers): add ZFS driver to avoid losing VDI create mode 100644 drivers/ZFSSR.py diff --git a/Makefile b/Makefile -index 7cb6ba4..2b2b980 100755 +index 7cb6ba49..2b2b980a 100755 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ SM_DRIVERS += LVHDoFCoE @@ -25,7 +25,7 @@ index 7cb6ba4..2b2b980 100755 SM_LIBS := SR SM_LIBS += SRCommand diff --git a/drivers/XE_SR_ERRORCODES.xml b/drivers/XE_SR_ERRORCODES.xml -index 725d14f..d4b7f29 100755 +index 725d14fe..d4b7f292 100755 --- a/drivers/XE_SR_ERRORCODES.xml +++ b/drivers/XE_SR_ERRORCODES.xml @@ -910,5 +910,15 @@ @@ -46,7 +46,7 @@ index 725d14f..d4b7f29 100755 diff --git a/drivers/ZFSSR.py b/drivers/ZFSSR.py new file mode 100644 -index 0000000..1b2f398 +index 00000000..1b2f398f --- /dev/null +++ b/drivers/ZFSSR.py @@ -0,0 +1,137 @@ @@ -188,7 +188,7 @@ index 0000000..1b2f398 +else: + SR.registerSR(ZFSSR) diff --git a/drivers/cleanup.py b/drivers/cleanup.py -index 57522b8..81cf032 100755 +index 57522b8b..81cf0324 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -2889,7 +2889,7 @@ def normalizeType(type): diff --git a/SOURCES/0005-feat-drivers-add-LinstorSR-driver.patch b/SOURCES/0005-feat-drivers-add-LinstorSR-driver.patch index 6ae263f8..88e50665 100644 --- a/SOURCES/0005-feat-drivers-add-LinstorSR-driver.patch +++ b/SOURCES/0005-feat-drivers-add-LinstorSR-driver.patch @@ -1,7 +1,7 @@ From ee88ac2658f10fe367a1a299f8b17b10209388ff Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Mon, 16 Mar 2020 15:39:44 +0100 -Subject: [PATCH 05/28] feat(drivers): add LinstorSR driver +Subject: [PATCH 05/29] feat(drivers): add LinstorSR driver Some important points: @@ -78,7 +78,7 @@ module imports are protected by try.. except... blocks. create mode 100644 tests/mocks/linstor/__init__.py diff --git a/Makefile b/Makefile -index 2b2b980..dc370cf 100755 +index 2b2b980a..dc370cfd 100755 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ SM_DRIVERS += Dummy @@ -141,7 +141,7 @@ index 2b2b980..dc370cf 100755 - diff --git a/drivers/LinstorSR.py b/drivers/LinstorSR.py new file mode 100755 -index 0000000..ffd70ab +index 00000000..ffd70abf --- /dev/null +++ b/drivers/LinstorSR.py @@ -0,0 +1,2100 @@ @@ -2246,7 +2246,7 @@ index 0000000..ffd70ab +else: + SR.registerSR(LinstorSR) diff --git a/drivers/XE_SR_ERRORCODES.xml b/drivers/XE_SR_ERRORCODES.xml -index d4b7f29..ae871c8 100755 +index d4b7f292..ae871c81 100755 --- a/drivers/XE_SR_ERRORCODES.xml +++ b/drivers/XE_SR_ERRORCODES.xml @@ -921,4 +921,40 @@ @@ -2291,7 +2291,7 @@ index d4b7f29..ae871c8 100755 + diff --git a/drivers/cleanup.py b/drivers/cleanup.py -index 81cf032..3bf84d5 100755 +index 81cf0324..3bf84d5e 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -46,10 +46,19 @@ import xs_errors @@ -2714,7 +2714,7 @@ index 81cf032..3bf84d5 100755 diff --git a/drivers/linstor-manager b/drivers/linstor-manager new file mode 100755 -index 0000000..f7ce180 +index 00000000..f7ce1809 --- /dev/null +++ b/drivers/linstor-manager @@ -0,0 +1,272 @@ @@ -2992,7 +2992,7 @@ index 0000000..f7ce180 + }) diff --git a/drivers/linstorjournaler.py b/drivers/linstorjournaler.py new file mode 100755 -index 0000000..7495330 +index 00000000..74953305 --- /dev/null +++ b/drivers/linstorjournaler.py @@ -0,0 +1,155 @@ @@ -3153,7 +3153,7 @@ index 0000000..7495330 + return '{}/{}'.format(type, identifier) diff --git a/drivers/linstorvhdutil.py b/drivers/linstorvhdutil.py new file mode 100644 -index 0000000..f31c752 +index 00000000..f31c7525 --- /dev/null +++ b/drivers/linstorvhdutil.py @@ -0,0 +1,186 @@ @@ -3345,7 +3345,7 @@ index 0000000..f31c752 + ) diff --git a/drivers/linstorvolumemanager.py b/drivers/linstorvolumemanager.py new file mode 100755 -index 0000000..d400421 +index 00000000..d4004217 --- /dev/null +++ b/drivers/linstorvolumemanager.py @@ -0,0 +1,1713 @@ @@ -5063,7 +5063,7 @@ index 0000000..d400421 + return True + return False diff --git a/drivers/tapdisk-pause b/drivers/tapdisk-pause -index 6b7fc09..932fc3c 100755 +index 6b7fc09f..932fc3ca 100755 --- a/drivers/tapdisk-pause +++ b/drivers/tapdisk-pause @@ -29,6 +29,12 @@ import lvhdutil @@ -5133,7 +5133,7 @@ index 6b7fc09..932fc3c 100755 def Pause(self): util.SMlog("Pause for %s" % self.vdi_uuid) diff --git a/drivers/util.py b/drivers/util.py -index 8fa80da..a64512f 100755 +index 8fa80da4..a64512f4 100755 --- a/drivers/util.py +++ b/drivers/util.py @@ -694,10 +694,35 @@ def get_this_host(): @@ -5201,7 +5201,7 @@ index 8fa80da..a64512f 100755 if retries >= maxretry: diff --git a/linstor/Makefile b/linstor/Makefile new file mode 100644 -index 0000000..c329ca3 +index 00000000..c329ca30 --- /dev/null +++ b/linstor/Makefile @@ -0,0 +1,22 @@ @@ -5229,7 +5229,7 @@ index 0000000..c329ca3 + rm -f linstor-monitord diff --git a/linstor/linstor-monitord.c b/linstor/linstor-monitord.c new file mode 100644 -index 0000000..8161813 +index 00000000..8161813d --- /dev/null +++ b/linstor/linstor-monitord.c @@ -0,0 +1,402 @@ @@ -5637,7 +5637,7 @@ index 0000000..8161813 +} diff --git a/systemd/linstor-monitor.service b/systemd/linstor-monitor.service new file mode 100644 -index 0000000..5f8f0a7 +index 00000000..5f8f0a76 --- /dev/null +++ b/systemd/linstor-monitor.service @@ -0,0 +1,13 @@ @@ -5656,4 +5656,4 @@ index 0000000..5f8f0a7 +WantedBy=multi-user.target diff --git a/tests/mocks/linstor/__init__.py b/tests/mocks/linstor/__init__.py new file mode 100644 -index 0000000..e69de29 +index 00000000..e69de29b diff --git a/SOURCES/0006-feat-tests-add-unit-tests-concerning-ZFS-close-xcp-n.patch b/SOURCES/0006-feat-tests-add-unit-tests-concerning-ZFS-close-xcp-n.patch index cc14911e..b2a7b5ae 100644 --- a/SOURCES/0006-feat-tests-add-unit-tests-concerning-ZFS-close-xcp-n.patch +++ b/SOURCES/0006-feat-tests-add-unit-tests-concerning-ZFS-close-xcp-n.patch @@ -1,7 +1,7 @@ From 52c6e98da6238b6a624f7e59b4e0d896ca0728bc Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Tue, 27 Oct 2020 15:04:36 +0100 -Subject: [PATCH 06/28] feat(tests): add unit tests concerning ZFS (close +Subject: [PATCH 06/29] feat(tests): add unit tests concerning ZFS (close xcp-ng/xcp#425) - Check if "create" doesn't succeed without zfs packages @@ -13,7 +13,7 @@ Subject: [PATCH 06/28] feat(tests): add unit tests concerning ZFS (close create mode 100644 tests/test_ZFSSR.py diff --git a/drivers/ZFSSR.py b/drivers/ZFSSR.py -index 1b2f398..d375210 100644 +index 1b2f398f..d3752101 100644 --- a/drivers/ZFSSR.py +++ b/drivers/ZFSSR.py @@ -58,6 +58,18 @@ DRIVER_INFO = { @@ -85,7 +85,7 @@ index 1b2f398..d375210 100644 class ZFSFileVDI(FileSR.FileVDI): diff --git a/tests/test_ZFSSR.py b/tests/test_ZFSSR.py new file mode 100644 -index 0000000..879ea37 +index 00000000..879ea372 --- /dev/null +++ b/tests/test_ZFSSR.py @@ -0,0 +1,121 @@ diff --git a/SOURCES/0007-Added-SM-Driver-for-MooseFS.patch b/SOURCES/0007-Added-SM-Driver-for-MooseFS.patch index 186f0945..cfae0487 100644 --- a/SOURCES/0007-Added-SM-Driver-for-MooseFS.patch +++ b/SOURCES/0007-Added-SM-Driver-for-MooseFS.patch @@ -1,7 +1,7 @@ From 1dc43ae24403979db03fb7bbf90aeffe81d6c28b Mon Sep 17 00:00:00 2001 From: Aleksander Wieliczko Date: Fri, 29 Jan 2021 15:21:23 +0100 -Subject: [PATCH 07/28] Added SM Driver for MooseFS +Subject: [PATCH 07/29] Added SM Driver for MooseFS Co-authored-by: Piotr Robert Konopelko Signed-off-by: Aleksander Wieliczko @@ -16,7 +16,7 @@ Signed-off-by: Ronan Abhamon create mode 100644 tests/test_MooseFSSR.py diff --git a/Makefile b/Makefile -index dc370cf..c2f6f46 100755 +index dc370cfd..c2f6f463 100755 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ SM_DRIVERS += CephFS @@ -29,7 +29,7 @@ index dc370cf..c2f6f46 100755 SM_LIBS += SRCommand diff --git a/drivers/MooseFSSR.py b/drivers/MooseFSSR.py new file mode 100755 -index 0000000..53485a0 +index 00000000..53485a0c --- /dev/null +++ b/drivers/MooseFSSR.py @@ -0,0 +1,271 @@ @@ -305,7 +305,7 @@ index 0000000..53485a0 +else: + SR.registerSR(MooseFSSR) diff --git a/drivers/cleanup.py b/drivers/cleanup.py -index 3bf84d5..9fa6f27 100755 +index 3bf84d5e..9fa6f27b 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -3245,7 +3245,7 @@ def normalizeType(type): @@ -319,7 +319,7 @@ index 3bf84d5..9fa6f27 100755 if type in ["linstor"]: diff --git a/tests/test_MooseFSSR.py b/tests/test_MooseFSSR.py new file mode 100644 -index 0000000..3349a44 +index 00000000..3349a449 --- /dev/null +++ b/tests/test_MooseFSSR.py @@ -0,0 +1,64 @@ diff --git a/SOURCES/0008-Avoid-usage-of-umount-in-ISOSR-when-legacy_mode-is-u.patch b/SOURCES/0008-Avoid-usage-of-umount-in-ISOSR-when-legacy_mode-is-u.patch index fd708cd8..cb209132 100644 --- a/SOURCES/0008-Avoid-usage-of-umount-in-ISOSR-when-legacy_mode-is-u.patch +++ b/SOURCES/0008-Avoid-usage-of-umount-in-ISOSR-when-legacy_mode-is-u.patch @@ -1,7 +1,7 @@ From 0f993508af755b52d46b216b503e81914eb570ef Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 2 Dec 2021 09:28:37 +0100 -Subject: [PATCH 08/28] Avoid usage of `umount` in `ISOSR` when `legacy_mode` +Subject: [PATCH 08/29] Avoid usage of `umount` in `ISOSR` when `legacy_mode` is used `umount` should not be called when `legacy_mode` is enabled, otherwise a mounted dir @@ -15,7 +15,7 @@ Signed-off-by: Ronan Abhamon 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/drivers/ISOSR.py b/drivers/ISOSR.py -index f591d23..9ca4450 100755 +index f591d237..9ca44506 100755 --- a/drivers/ISOSR.py +++ b/drivers/ISOSR.py @@ -569,8 +569,7 @@ class ISOSR(SR.SR): @@ -29,7 +29,7 @@ index f591d23..9ca4450 100755 try: diff --git a/tests/test_ISOSR.py b/tests/test_ISOSR.py -index 3aea796..760c566 100644 +index 3aea7963..760c566a 100644 --- a/tests/test_ISOSR.py +++ b/tests/test_ISOSR.py @@ -24,6 +24,65 @@ class FakeISOSR(ISOSR.ISOSR): diff --git a/SOURCES/0009-MooseFS-SR-uses-now-UUID-subdirs-for-each-SR.patch b/SOURCES/0009-MooseFS-SR-uses-now-UUID-subdirs-for-each-SR.patch index 4bf9dc94..94b856c1 100644 --- a/SOURCES/0009-MooseFS-SR-uses-now-UUID-subdirs-for-each-SR.patch +++ b/SOURCES/0009-MooseFS-SR-uses-now-UUID-subdirs-for-each-SR.patch @@ -1,7 +1,7 @@ From 1f67bfaffbd431c166a5e61322ea7d179ee4d687 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Wed, 18 May 2022 17:28:09 +0200 -Subject: [PATCH 09/28] MooseFS SR uses now UUID subdirs for each SR +Subject: [PATCH 09/29] MooseFS SR uses now UUID subdirs for each SR A sm-config boolean param `subdir` is available to configure where to store the VHDs: - In a subdir with the SR UUID, the new behavior @@ -17,7 +17,7 @@ Signed-off-by: Ronan Abhamon 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/drivers/MooseFSSR.py b/drivers/MooseFSSR.py -index 53485a0..b2e056a 100755 +index 53485a0c..b2e056af 100755 --- a/drivers/MooseFSSR.py +++ b/drivers/MooseFSSR.py @@ -18,6 +18,7 @@ diff --git a/SOURCES/0010-Fix-is_open-call-for-many-drivers-25.patch b/SOURCES/0010-Fix-is_open-call-for-many-drivers-25.patch index 3aebfb15..a3e27dde 100644 --- a/SOURCES/0010-Fix-is_open-call-for-many-drivers-25.patch +++ b/SOURCES/0010-Fix-is_open-call-for-many-drivers-25.patch @@ -1,7 +1,7 @@ From d32bf0ccfe58c67ba87e9bab5b76f9eead92735d Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 23 Jun 2022 10:36:36 +0200 -Subject: [PATCH 10/28] Fix is_open call for many drivers (#25) +Subject: [PATCH 10/29] Fix is_open call for many drivers (#25) Ensure all shared drivers are imported in `_is_open` definition to register them in the driver list. Otherwise this function always fails with a SRUnknownType exception. @@ -20,7 +20,7 @@ Signed-off-by: Ronan Abhamon 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/GlusterFSSR.py b/drivers/GlusterFSSR.py -index 72c482a..750eb23 100644 +index 72c482ae..750eb233 100644 --- a/drivers/GlusterFSSR.py +++ b/drivers/GlusterFSSR.py @@ -96,7 +96,8 @@ class GlusterFSSR(FileSR.FileSR): @@ -34,7 +34,7 @@ index 72c482a..750eb23 100644 self.sm_config = self.session.xenapi.SR.get_sm_config(self.sr_ref) else: diff --git a/drivers/NFSSR.py b/drivers/NFSSR.py -index b499cc9..ef73e1b 100755 +index b499cc90..ef73e1b4 100755 --- a/drivers/NFSSR.py +++ b/drivers/NFSSR.py @@ -88,9 +88,12 @@ class NFSSR(FileSR.SharedFileSR): @@ -64,7 +64,7 @@ index b499cc9..ef73e1b 100755 try: self.scan_exports(self.dconf['server']) diff --git a/drivers/on_slave.py b/drivers/on_slave.py -index b4f33de..bb3f5db 100755 +index b4f33de2..bb3f5db6 100755 --- a/drivers/on_slave.py +++ b/drivers/on_slave.py @@ -76,9 +76,14 @@ def _is_open(session, args): diff --git a/SOURCES/0011-Remove-SR_CACHING-capability-for-many-SR-types-24.patch b/SOURCES/0011-Remove-SR_CACHING-capability-for-many-SR-types-24.patch index a8f5139f..6c3d40e3 100644 --- a/SOURCES/0011-Remove-SR_CACHING-capability-for-many-SR-types-24.patch +++ b/SOURCES/0011-Remove-SR_CACHING-capability-for-many-SR-types-24.patch @@ -1,7 +1,7 @@ From 3c420bca8372e1441f977562b61439ff2235003f Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 23 Jun 2022 10:37:07 +0200 -Subject: [PATCH 11/28] Remove SR_CACHING capability for many SR types (#24) +Subject: [PATCH 11/29] Remove SR_CACHING capability for many SR types (#24) SR_CACHING offers the capacity to use IntelliCache, but this feature is only available using NFS SR. @@ -17,7 +17,7 @@ Signed-off-by: Ronan Abhamon 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/CephFSSR.py b/drivers/CephFSSR.py -index 415152f..f334bb3 100644 +index 415152f7..f334bb30 100644 --- a/drivers/CephFSSR.py +++ b/drivers/CephFSSR.py @@ -38,7 +38,7 @@ import vhdutil @@ -30,7 +30,7 @@ index 415152f..f334bb3 100644 "VDI_UPDATE", "VDI_CLONE", "VDI_SNAPSHOT", "VDI_RESIZE", "VDI_MIRROR", "VDI_GENERATE_CONFIG", diff --git a/drivers/GlusterFSSR.py b/drivers/GlusterFSSR.py -index 750eb23..290a331 100644 +index 750eb233..290a3312 100644 --- a/drivers/GlusterFSSR.py +++ b/drivers/GlusterFSSR.py @@ -35,7 +35,7 @@ import vhdutil @@ -43,7 +43,7 @@ index 750eb23..290a331 100644 "VDI_UPDATE", "VDI_CLONE", "VDI_SNAPSHOT", "VDI_RESIZE", "VDI_MIRROR", "VDI_GENERATE_CONFIG", diff --git a/drivers/MooseFSSR.py b/drivers/MooseFSSR.py -index b2e056a..504e850 100755 +index b2e056af..504e8503 100755 --- a/drivers/MooseFSSR.py +++ b/drivers/MooseFSSR.py @@ -39,7 +39,7 @@ import vhdutil diff --git a/SOURCES/0012-Fix-code-coverage-regarding-MooseFSSR-and-ZFSSR-29.patch b/SOURCES/0012-Fix-code-coverage-regarding-MooseFSSR-and-ZFSSR-29.patch index a79025bf..67849502 100644 --- a/SOURCES/0012-Fix-code-coverage-regarding-MooseFSSR-and-ZFSSR-29.patch +++ b/SOURCES/0012-Fix-code-coverage-regarding-MooseFSSR-and-ZFSSR-29.patch @@ -1,7 +1,7 @@ From 471b7b2742da807aca012c6609c8917cbe786507 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Mon, 19 Sep 2022 10:31:00 +0200 -Subject: [PATCH 12/28] Fix code coverage regarding MooseFSSR and ZFSSR (#29) +Subject: [PATCH 12/29] Fix code coverage regarding MooseFSSR and ZFSSR (#29) Signed-off-by: Ronan Abhamon --- @@ -10,7 +10,7 @@ Signed-off-by: Ronan Abhamon 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/tests/test_MooseFSSR.py b/tests/test_MooseFSSR.py -index 3349a44..feaac62 100644 +index 3349a449..feaac626 100644 --- a/tests/test_MooseFSSR.py +++ b/tests/test_MooseFSSR.py @@ -23,8 +23,6 @@ class TestMooseFSSR(unittest.TestCase): @@ -23,7 +23,7 @@ index 3349a44..feaac62 100644 'command': 'some_command', 'device_config': {} diff --git a/tests/test_ZFSSR.py b/tests/test_ZFSSR.py -index 879ea37..d0cca93 100644 +index 879ea372..d0cca935 100644 --- a/tests/test_ZFSSR.py +++ b/tests/test_ZFSSR.py @@ -53,9 +53,7 @@ class TestZFSSR(unittest.TestCase): diff --git a/SOURCES/0013-py3-simple-changes-from-futurize-on-XCP-ng-drivers.patch b/SOURCES/0013-py3-simple-changes-from-futurize-on-XCP-ng-drivers.patch index ef121aa8..fd858cee 100644 --- a/SOURCES/0013-py3-simple-changes-from-futurize-on-XCP-ng-drivers.patch +++ b/SOURCES/0013-py3-simple-changes-from-futurize-on-XCP-ng-drivers.patch @@ -1,7 +1,7 @@ From 395daa86f0b4dcbc4eeabb42fed4f818d46afc36 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 8 Mar 2023 10:13:18 +0100 -Subject: [PATCH 13/28] py3: simple changes from futurize on XCP-ng drivers +Subject: [PATCH 13/29] py3: simple changes from futurize on XCP-ng drivers * `except` syntax fixes * drop `has_key()` usage @@ -21,7 +21,7 @@ Signed-off-by: Yann Dirson 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/drivers/CephFSSR.py b/drivers/CephFSSR.py -index f334bb3..f83beb3 100644 +index f334bb30..f83beb3d 100644 --- a/drivers/CephFSSR.py +++ b/drivers/CephFSSR.py @@ -132,18 +132,18 @@ class CephFSSR(FileSR.FileSR): @@ -89,7 +89,7 @@ index f334bb3..f83beb3 100644 if inst.code != errno.ENOENT: raise xs_errors.SROSError(114, "Failed to remove CephFS mount point") diff --git a/drivers/GlusterFSSR.py b/drivers/GlusterFSSR.py -index 290a331..6d5e061 100644 +index 290a3312..6d5e0614 100644 --- a/drivers/GlusterFSSR.py +++ b/drivers/GlusterFSSR.py @@ -122,7 +122,7 @@ class GlusterFSSR(FileSR.FileSR): @@ -153,7 +153,7 @@ index 290a331..6d5e061 100644 if inst.code != errno.ENOENT: raise xs_errors.SROSError(114, "Failed to remove GlusterFS mount point") diff --git a/drivers/LinstorSR.py b/drivers/LinstorSR.py -index ffd70ab..4e8888e 100755 +index ffd70abf..4e8888e2 100755 --- a/drivers/LinstorSR.py +++ b/drivers/LinstorSR.py @@ -460,7 +460,7 @@ class LinstorSR(SR.SR): @@ -196,7 +196,7 @@ index ffd70ab..4e8888e 100755 # 7. Verify parent locator field of both children and diff --git a/drivers/MooseFSSR.py b/drivers/MooseFSSR.py -index 504e850..05a4264 100755 +index 504e8503..05a42640 100755 --- a/drivers/MooseFSSR.py +++ b/drivers/MooseFSSR.py @@ -139,12 +139,12 @@ class MooseFSSR(FileSR.FileSR): @@ -257,7 +257,7 @@ index 504e850..05a4264 100755 if inst.code != errno.ENOENT: raise xs_errors.SROSError(114, "Failed to remove MooseFS mount point") diff --git a/drivers/cleanup.py b/drivers/cleanup.py -index 9fa6f27..90611b3 100755 +index 9fa6f27b..90611b3d 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -3004,7 +3004,7 @@ class LinstorSR(SR): @@ -288,7 +288,7 @@ index 9fa6f27..90611b3 100755 self._hasValidDevicePath(self.TMP_RENAME_PREFIX + uuid): self._undoInterruptedCoalesceLeaf(uuid, parentUuid) diff --git a/drivers/linstorvolumemanager.py b/drivers/linstorvolumemanager.py -index d400421..dca9645 100755 +index d4004217..dca96456 100755 --- a/drivers/linstorvolumemanager.py +++ b/drivers/linstorvolumemanager.py @@ -1053,7 +1053,7 @@ class LinstorVolumeManager(object): diff --git a/SOURCES/0014-py3-futurize-fix-of-xmlrpc-calls-for-CephFS-GlusterF.patch b/SOURCES/0014-py3-futurize-fix-of-xmlrpc-calls-for-CephFS-GlusterF.patch index 144fce45..3a378a64 100644 --- a/SOURCES/0014-py3-futurize-fix-of-xmlrpc-calls-for-CephFS-GlusterF.patch +++ b/SOURCES/0014-py3-futurize-fix-of-xmlrpc-calls-for-CephFS-GlusterF.patch @@ -1,7 +1,7 @@ From af592f003d7fb8bc2572455271bf143e97a10c81 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 8 Mar 2023 10:28:10 +0100 -Subject: [PATCH 14/28] py3: futurize fix of xmlrpc calls for CephFS, +Subject: [PATCH 14/29] py3: futurize fix of xmlrpc calls for CephFS, GlusterFS, MooseFS, Linstore Signed-off-by: Yann Dirson @@ -13,7 +13,7 @@ Signed-off-by: Yann Dirson 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/CephFSSR.py b/drivers/CephFSSR.py -index f83beb3..be2521f 100644 +index f83beb3d..be2521fd 100644 --- a/drivers/CephFSSR.py +++ b/drivers/CephFSSR.py @@ -21,7 +21,7 @@ @@ -37,7 +37,7 @@ index f83beb3..be2521f 100644 def attach_from_config(self, sr_uuid, vdi_uuid): try: diff --git a/drivers/GlusterFSSR.py b/drivers/GlusterFSSR.py -index 6d5e061..48471f9 100644 +index 6d5e0614..48471f96 100644 --- a/drivers/GlusterFSSR.py +++ b/drivers/GlusterFSSR.py @@ -19,7 +19,7 @@ @@ -61,7 +61,7 @@ index 6d5e061..48471f9 100644 def attach_from_config(self, sr_uuid, vdi_uuid): try: diff --git a/drivers/LinstorSR.py b/drivers/LinstorSR.py -index 4e8888e..f6badab 100755 +index 4e8888e2..f6badabb 100755 --- a/drivers/LinstorSR.py +++ b/drivers/LinstorSR.py @@ -38,7 +38,7 @@ import traceback @@ -94,7 +94,7 @@ index 4e8888e..f6badab 100755 def attach_from_config(self, sr_uuid, vdi_uuid): """ diff --git a/drivers/MooseFSSR.py b/drivers/MooseFSSR.py -index 05a4264..c29c758 100755 +index 05a42640..c29c7583 100755 --- a/drivers/MooseFSSR.py +++ b/drivers/MooseFSSR.py @@ -22,7 +22,7 @@ import distutils.util diff --git a/SOURCES/0015-py3-use-of-integer-division-operator.patch b/SOURCES/0015-py3-use-of-integer-division-operator.patch index bb97da2d..4ac71e52 100644 --- a/SOURCES/0015-py3-use-of-integer-division-operator.patch +++ b/SOURCES/0015-py3-use-of-integer-division-operator.patch @@ -1,7 +1,7 @@ From e1335b1ca83771142e6a6f831b5b4aa888e2ff18 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 8 Mar 2023 10:32:37 +0100 -Subject: [PATCH 15/28] py3: use of integer division operator +Subject: [PATCH 15/29] py3: use of integer division operator Guided by futurize's "old_div" use @@ -11,7 +11,7 @@ Signed-off-by: Yann Dirson 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/linstorvolumemanager.py b/drivers/linstorvolumemanager.py -index dca9645..1b86a43 100755 +index dca96456..1b86a439 100755 --- a/drivers/linstorvolumemanager.py +++ b/drivers/linstorvolumemanager.py @@ -28,7 +28,7 @@ import util diff --git a/SOURCES/0016-test_on_slave-allow-to-work-with-SR-using-absolute-P.patch b/SOURCES/0016-test_on_slave-allow-to-work-with-SR-using-absolute-P.patch index 01a91100..de94cf93 100644 --- a/SOURCES/0016-test_on_slave-allow-to-work-with-SR-using-absolute-P.patch +++ b/SOURCES/0016-test_on_slave-allow-to-work-with-SR-using-absolute-P.patch @@ -1,7 +1,7 @@ From 2e7fa79a4d7d4ebbee00959326b8f8151a816889 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 8 Mar 2023 13:53:21 +0100 -Subject: [PATCH 16/28] test_on_slave: allow to work with SR using absolute +Subject: [PATCH 16/29] test_on_slave: allow to work with SR using absolute PROBE_MOUNTPOINT PROBE_MOUNTPOINT in a some drivers is a relative path, which is resolved @@ -36,7 +36,7 @@ Signed-off-by: Yann Dirson 1 file changed, 1 insertion(+) diff --git a/tests/test_on_slave.py b/tests/test_on_slave.py -index 9034747..679d442 100644 +index 90347477..679d4421 100644 --- a/tests/test_on_slave.py +++ b/tests/test_on_slave.py @@ -30,6 +30,7 @@ class Test_on_slave_is_open(unittest.TestCase): diff --git a/SOURCES/0017-py3-switch-interpreter-to-python3.patch b/SOURCES/0017-py3-switch-interpreter-to-python3.patch index 449cfd7f..26666100 100644 --- a/SOURCES/0017-py3-switch-interpreter-to-python3.patch +++ b/SOURCES/0017-py3-switch-interpreter-to-python3.patch @@ -1,7 +1,7 @@ From 2df6ea2d37f2a117f70f844105db2771d9c88517 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Mon, 27 Mar 2023 15:30:46 +0200 -Subject: [PATCH 17/28] py3: switch interpreter to python3 +Subject: [PATCH 17/29] py3: switch interpreter to python3 --- drivers/CephFSSR.py | 2 +- @@ -15,7 +15,7 @@ Subject: [PATCH 17/28] py3: switch interpreter to python3 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/CephFSSR.py b/drivers/CephFSSR.py -index be2521f..bd6a4b1 100644 +index be2521fd..bd6a4b14 100644 --- a/drivers/CephFSSR.py +++ b/drivers/CephFSSR.py @@ -1,4 +1,4 @@ @@ -25,7 +25,7 @@ index be2521f..bd6a4b1 100644 # Original work copyright (C) Citrix systems # Modified work copyright (C) Vates SAS and XCP-ng community diff --git a/drivers/GlusterFSSR.py b/drivers/GlusterFSSR.py -index 48471f9..42e5ab5 100644 +index 48471f96..42e5ab52 100644 --- a/drivers/GlusterFSSR.py +++ b/drivers/GlusterFSSR.py @@ -1,4 +1,4 @@ @@ -35,7 +35,7 @@ index 48471f9..42e5ab5 100644 # Original work copyright (C) Citrix systems # Modified work copyright (C) Vates SAS and XCP-ng community diff --git a/drivers/LinstorSR.py b/drivers/LinstorSR.py -index f6badab..e7022ca 100755 +index f6badabb..e7022ca9 100755 --- a/drivers/LinstorSR.py +++ b/drivers/LinstorSR.py @@ -1,4 +1,4 @@ @@ -45,7 +45,7 @@ index f6badab..e7022ca 100755 # Copyright (C) 2020 Vates SAS - ronan.abhamon@vates.fr # diff --git a/drivers/MooseFSSR.py b/drivers/MooseFSSR.py -index c29c758..3911b09 100755 +index c29c7583..3911b096 100755 --- a/drivers/MooseFSSR.py +++ b/drivers/MooseFSSR.py @@ -1,4 +1,4 @@ @@ -55,7 +55,7 @@ index c29c758..3911b09 100755 # Original work copyright (C) Citrix systems # Modified work copyright (C) Tappest sp. z o.o., Vates SAS and XCP-ng community diff --git a/drivers/ZFSSR.py b/drivers/ZFSSR.py -index d375210..354ca90 100644 +index d3752101..354ca90e 100644 --- a/drivers/ZFSSR.py +++ b/drivers/ZFSSR.py @@ -1,4 +1,4 @@ @@ -65,7 +65,7 @@ index d375210..354ca90 100644 # Copyright (C) 2020 Vates SAS # diff --git a/drivers/linstorjournaler.py b/drivers/linstorjournaler.py -index 7495330..bc7cff7 100755 +index 74953305..bc7cff7c 100755 --- a/drivers/linstorjournaler.py +++ b/drivers/linstorjournaler.py @@ -1,4 +1,4 @@ @@ -75,7 +75,7 @@ index 7495330..bc7cff7 100755 # Copyright (C) 2020 Vates SAS - ronan.abhamon@vates.fr # diff --git a/drivers/linstorvhdutil.py b/drivers/linstorvhdutil.py -index f31c752..7a13566 100644 +index f31c7525..7a135662 100644 --- a/drivers/linstorvhdutil.py +++ b/drivers/linstorvhdutil.py @@ -1,4 +1,4 @@ @@ -85,7 +85,7 @@ index f31c752..7a13566 100644 # Copyright (C) 2020 Vates SAS - ronan.abhamon@vates.fr # diff --git a/drivers/linstorvolumemanager.py b/drivers/linstorvolumemanager.py -index 1b86a43..182b889 100755 +index 1b86a439..182b8899 100755 --- a/drivers/linstorvolumemanager.py +++ b/drivers/linstorvolumemanager.py @@ -1,4 +1,4 @@ diff --git a/SOURCES/0018-Support-recent-version-of-coverage-tool.patch b/SOURCES/0018-Support-recent-version-of-coverage-tool.patch index 2f28b270..df368c8e 100644 --- a/SOURCES/0018-Support-recent-version-of-coverage-tool.patch +++ b/SOURCES/0018-Support-recent-version-of-coverage-tool.patch @@ -1,7 +1,7 @@ From 09aa72c4d2655ba1027dc831b1580bde87643447 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 4 May 2023 10:24:22 +0200 -Subject: [PATCH 18/28] Support recent version of coverage tool (coverage +Subject: [PATCH 18/29] Support recent version of coverage tool (coverage 7.2.5) Without these changes many warns/errors are emitted: @@ -16,7 +16,7 @@ Signed-off-by: Ronan Abhamon 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_ISOSR.py b/tests/test_ISOSR.py -index 760c566..9dec459 100644 +index 760c566a..9dec459c 100644 --- a/tests/test_ISOSR.py +++ b/tests/test_ISOSR.py @@ -80,7 +80,7 @@ class TestISOSR_overLocal(unittest.TestCase): diff --git a/SOURCES/0019-feat-LinstorSR-import-all-8.2-changes.patch b/SOURCES/0019-feat-LinstorSR-import-all-8.2-changes.patch index ffee6899..86da2c3b 100644 --- a/SOURCES/0019-feat-LinstorSR-import-all-8.2-changes.patch +++ b/SOURCES/0019-feat-LinstorSR-import-all-8.2-changes.patch @@ -1,7 +1,7 @@ From 98d8c31104c3eae9ea62ea106d09fb801a784f4e Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Fri, 20 Nov 2020 16:42:52 +0100 -Subject: [PATCH 19/28] feat(LinstorSR): import all 8.2 changes +Subject: [PATCH 19/29] feat(LinstorSR): import all 8.2 changes Signed-off-by: Ronan Abhamon --- @@ -35,7 +35,7 @@ Signed-off-by: Ronan Abhamon create mode 100755 scripts/safe-umount diff --git a/Makefile b/Makefile -index c2f6f46..075f460 100755 +index c2f6f463..075f4603 100755 --- a/Makefile +++ b/Makefile @@ -86,6 +86,7 @@ PLUGIN_SCRIPT_DEST := /etc/xapi.d/plugins/ @@ -80,7 +80,7 @@ index c2f6f46..075f460 100755 install -m 755 scripts/check-device-sharing $(SM_STAGING)$(LIBEXEC) install -m 755 scripts/usb_change $(SM_STAGING)$(LIBEXEC) diff --git a/drivers/LinstorSR.py b/drivers/LinstorSR.py -index e7022ca..52d5c26 100755 +index e7022ca9..52d5c26e 100755 --- a/drivers/LinstorSR.py +++ b/drivers/LinstorSR.py @@ -19,25 +19,39 @@ from constants import CBTLOG_TAG @@ -2200,7 +2200,7 @@ index e7022ca..52d5c26 100755 else: SR.registerSR(LinstorSR) diff --git a/drivers/blktap2.py b/drivers/blktap2.py -index 5712d8f..669b9f6 100755 +index 5712d8f2..669b9f65 100755 --- a/drivers/blktap2.py +++ b/drivers/blktap2.py @@ -50,6 +50,12 @@ import VDI as sm @@ -2242,7 +2242,7 @@ index 5712d8f..669b9f6 100755 tapdisk = cls.__from_blktap(blktap) node = '/sys/dev/block/%d:%d' % (tapdisk.major(), tapdisk.minor) diff --git a/drivers/cleanup.py b/drivers/cleanup.py -index 90611b3..03bdc94 100755 +index 90611b3d..03bdc94d 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -53,8 +53,11 @@ from time import monotonic as _time @@ -2831,7 +2831,7 @@ index 90611b3..03bdc94 100755 1. If we are already GC'ing in this SR, return 2. If we are already coalescing a VDI pair: diff --git a/drivers/linstor-manager b/drivers/linstor-manager -index f7ce180..8a30834 100755 +index f7ce1809..8a308344 100755 --- a/drivers/linstor-manager +++ b/drivers/linstor-manager @@ -14,32 +14,53 @@ @@ -3910,7 +3910,7 @@ index f7ce180..8a30834 100755 + 'setNodePreferredInterface': set_node_preferred_interface }) diff --git a/drivers/linstorjournaler.py b/drivers/linstorjournaler.py -index bc7cff7..a61d9f1 100755 +index bc7cff7c..a61d9f11 100755 --- a/drivers/linstorjournaler.py +++ b/drivers/linstorjournaler.py @@ -16,7 +16,8 @@ @@ -3991,7 +3991,7 @@ index bc7cff7..a61d9f1 100755 def _get_key(type, identifier): return '{}/{}'.format(type, identifier) diff --git a/drivers/linstorvhdutil.py b/drivers/linstorvhdutil.py -index 7a13566..836f4ce 100644 +index 7a135662..836f4ceb 100644 --- a/drivers/linstorvhdutil.py +++ b/drivers/linstorvhdutil.py @@ -14,6 +14,8 @@ @@ -4557,7 +4557,7 @@ index 7a13566..836f4ce 100644 + opterr='Failed to zero out VHD footer {}'.format(path) + ) diff --git a/drivers/linstorvolumemanager.py b/drivers/linstorvolumemanager.py -index 182b889..5e5bcd5 100755 +index 182b8899..5e5bcd51 100755 --- a/drivers/linstorvolumemanager.py +++ b/drivers/linstorvolumemanager.py @@ -16,14 +16,104 @@ @@ -7501,7 +7501,7 @@ index 182b889..5e5bcd5 100755 + '`{}` is open: {}'.format(path, e) + ) diff --git a/drivers/on_slave.py b/drivers/on_slave.py -index bb3f5db..524424f 100755 +index bb3f5db6..524424f6 100755 --- a/drivers/on_slave.py +++ b/drivers/on_slave.py @@ -79,6 +79,7 @@ def _is_open(session, args): @@ -7543,7 +7543,7 @@ index bb3f5db..524424f 100755 tapdisk = blktap2.Tapdisk.find_by_path(vdi.path) util.SMlog("Tapdisk for %s: %s" % (vdi.path, tapdisk)) diff --git a/drivers/tapdisk-pause b/drivers/tapdisk-pause -index 932fc3c..7532875 100755 +index 932fc3ca..75328757 100755 --- a/drivers/tapdisk-pause +++ b/drivers/tapdisk-pause @@ -30,7 +30,7 @@ import vhdutil @@ -7576,7 +7576,7 @@ index 932fc3c..7532875 100755 logger=util.SMlog ).get_device_path(self.vdi_uuid) diff --git a/drivers/util.py b/drivers/util.py -index a64512f..9db6994 100755 +index a64512f4..9db6994b 100755 --- a/drivers/util.py +++ b/drivers/util.py @@ -699,32 +699,10 @@ def get_master_ref(session): @@ -7727,7 +7727,7 @@ index a64512f..9db6994 100755 + finally: + SMlog('* End profiling of {} ({}) *'.format(name, filename)) diff --git a/drivers/vhdutil.py b/drivers/vhdutil.py -index 40807e8..723f3af 100755 +index 40807e84..723f3af2 100755 --- a/drivers/vhdutil.py +++ b/drivers/vhdutil.py @@ -94,13 +94,16 @@ def ioretry(cmd, text=True): @@ -7750,7 +7750,7 @@ index 40807e8..723f3af 100755 fields = ret.strip().split('\n') diff --git a/etc/systemd/system/drbd-reactor.service.d/override.conf b/etc/systemd/system/drbd-reactor.service.d/override.conf new file mode 100644 -index 0000000..2f99a46 +index 00000000..2f99a46a --- /dev/null +++ b/etc/systemd/system/drbd-reactor.service.d/override.conf @@ -0,0 +1,6 @@ @@ -7762,7 +7762,7 @@ index 0000000..2f99a46 +RestartSec=2 diff --git a/etc/systemd/system/linstor-satellite.service.d/override.conf b/etc/systemd/system/linstor-satellite.service.d/override.conf new file mode 100644 -index 0000000..b1686b4 +index 00000000..b1686b4f --- /dev/null +++ b/etc/systemd/system/linstor-satellite.service.d/override.conf @@ -0,0 +1,5 @@ @@ -7773,7 +7773,7 @@ index 0000000..b1686b4 +After=drbd.service diff --git a/etc/systemd/system/var-lib-linstor.service b/etc/systemd/system/var-lib-linstor.service new file mode 100644 -index 0000000..e9deb90 +index 00000000..e9deb904 --- /dev/null +++ b/etc/systemd/system/var-lib-linstor.service @@ -0,0 +1,21 @@ @@ -7799,7 +7799,7 @@ index 0000000..e9deb90 +ExecStop=/opt/xensource/libexec/safe-umount /var/lib/linstor +RemainAfterExit=true diff --git a/linstor/linstor-monitord.c b/linstor/linstor-monitord.c -index 8161813..4774059 100644 +index 8161813d..47740598 100644 --- a/linstor/linstor-monitord.c +++ b/linstor/linstor-monitord.c @@ -14,8 +14,10 @@ @@ -8118,7 +8118,7 @@ index 8161813..4774059 100644 const int inotifyFd = createInotifyInstance(); diff --git a/multipath/multipath.conf b/multipath/multipath.conf -index 744b646..00a8f48 100644 +index 744b6461..00a8f488 100644 --- a/multipath/multipath.conf +++ b/multipath/multipath.conf @@ -23,6 +23,7 @@ blacklist { @@ -8131,7 +8131,7 @@ index 744b646..00a8f48 100644 blacklist_exceptions { diff --git a/scripts/fork-log-daemon b/scripts/fork-log-daemon new file mode 100755 -index 0000000..665a60b +index 00000000..665a60ba --- /dev/null +++ b/scripts/fork-log-daemon @@ -0,0 +1,36 @@ @@ -8173,7 +8173,7 @@ index 0000000..665a60b + syslog.syslog(sys.argv[1] + ' is now terminated!') diff --git a/scripts/linstor-kv-tool b/scripts/linstor-kv-tool new file mode 100755 -index 0000000..b845ec2 +index 00000000..b845ec2b --- /dev/null +++ b/scripts/linstor-kv-tool @@ -0,0 +1,84 @@ @@ -8263,7 +8263,7 @@ index 0000000..b845ec2 + main() diff --git a/scripts/safe-umount b/scripts/safe-umount new file mode 100755 -index 0000000..9c1dcc4 +index 00000000..9c1dcc40 --- /dev/null +++ b/scripts/safe-umount @@ -0,0 +1,39 @@ @@ -8307,7 +8307,7 @@ index 0000000..9c1dcc4 + args = parser.parse_args() + sys.exit(safe_umount(args.path)) diff --git a/tests/test_on_slave.py b/tests/test_on_slave.py -index 679d442..4b59f63 100644 +index 679d4421..4b59f632 100644 --- a/tests/test_on_slave.py +++ b/tests/test_on_slave.py @@ -13,7 +13,15 @@ import on_slave diff --git a/SOURCES/0020-feat-LinstorSR-is-now-compatible-with-python-3.patch b/SOURCES/0020-feat-LinstorSR-is-now-compatible-with-python-3.patch index 75a07d24..fe997469 100644 --- a/SOURCES/0020-feat-LinstorSR-is-now-compatible-with-python-3.patch +++ b/SOURCES/0020-feat-LinstorSR-is-now-compatible-with-python-3.patch @@ -1,7 +1,7 @@ From 1354e78a5409805f08f118910db32b89bfc6c780 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Fri, 30 Jun 2023 12:41:43 +0200 -Subject: [PATCH 20/28] feat(LinstorSR): is now compatible with python 3 +Subject: [PATCH 20/29] feat(LinstorSR): is now compatible with python 3 Signed-off-by: Ronan Abhamon --- @@ -17,7 +17,7 @@ Signed-off-by: Ronan Abhamon 9 files changed, 36 insertions(+), 40 deletions(-) diff --git a/drivers/LinstorSR.py b/drivers/LinstorSR.py -index 52d5c26..1c9bd54 100755 +index 52d5c26e..1c9bd54a 100755 --- a/drivers/LinstorSR.py +++ b/drivers/LinstorSR.py @@ -758,7 +758,7 @@ class LinstorSR(SR.SR): @@ -88,7 +88,7 @@ index 52d5c26..1c9bd54 100755 str(device_size) ] diff --git a/drivers/cleanup.py b/drivers/cleanup.py -index 03bdc94..02435db 100755 +index 03bdc94d..02435db8 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -3381,7 +3381,7 @@ class LinstorSR(SR): @@ -101,7 +101,7 @@ index 03bdc94..02435db 100755 if opener['process-name'] != 'tapdisk': raise util.SMException( diff --git a/drivers/linstor-manager b/drivers/linstor-manager -index 8a30834..8d313ec 100755 +index 8a308344..8d313ec7 100755 --- a/drivers/linstor-manager +++ b/drivers/linstor-manager @@ -1,4 +1,4 @@ @@ -120,7 +120,7 @@ index 8a30834..8d313ec 100755 util.SMlog('linstor-manager:get_block_bitmap error: {}'.format(e)) raise diff --git a/drivers/linstorvhdutil.py b/drivers/linstorvhdutil.py -index 836f4ce..13e1bb0 100644 +index 836f4ceb..13e1bb08 100644 --- a/drivers/linstorvhdutil.py +++ b/drivers/linstorvhdutil.py @@ -27,9 +27,6 @@ import xs_errors @@ -176,7 +176,7 @@ index 836f4ce..13e1bb0 100644 continue diff --git a/drivers/linstorvolumemanager.py b/drivers/linstorvolumemanager.py -index 5e5bcd5..dbca3b4 100755 +index 5e5bcd51..dbca3b41 100755 --- a/drivers/linstorvolumemanager.py +++ b/drivers/linstorvolumemanager.py @@ -529,8 +529,8 @@ class LinstorVolumeManager(object): @@ -286,7 +286,7 @@ index 5e5bcd5..dbca3b4 100755 try: if not force: diff --git a/drivers/util.py b/drivers/util.py -index 9db6994..0564b29 100755 +index 9db6994b..0564b29b 100755 --- a/drivers/util.py +++ b/drivers/util.py @@ -751,7 +751,7 @@ def get_this_host_address(session): @@ -299,7 +299,7 @@ index 9db6994..0564b29 100755 return addresses diff --git a/scripts/fork-log-daemon b/scripts/fork-log-daemon -index 665a60b..986de63 100755 +index 665a60ba..986de63f 100755 --- a/scripts/fork-log-daemon +++ b/scripts/fork-log-daemon @@ -1,4 +1,4 @@ @@ -309,7 +309,7 @@ index 665a60b..986de63 100755 import select import signal diff --git a/scripts/linstor-kv-tool b/scripts/linstor-kv-tool -index b845ec2..de14e73 100755 +index b845ec2b..de14e731 100755 --- a/scripts/linstor-kv-tool +++ b/scripts/linstor-kv-tool @@ -1,4 +1,4 @@ @@ -319,7 +319,7 @@ index b845ec2..de14e73 100755 # Copyright (C) 2022 Vates SAS # diff --git a/scripts/safe-umount b/scripts/safe-umount -index 9c1dcc4..3c64a3f 100755 +index 9c1dcc40..3c64a3f3 100755 --- a/scripts/safe-umount +++ b/scripts/safe-umount @@ -1,4 +1,4 @@ diff --git a/SOURCES/0021-Remove-SR_PROBE-from-ZFS-capabilities-36.patch b/SOURCES/0021-Remove-SR_PROBE-from-ZFS-capabilities-36.patch index e61240ad..ecffdf99 100644 --- a/SOURCES/0021-Remove-SR_PROBE-from-ZFS-capabilities-36.patch +++ b/SOURCES/0021-Remove-SR_PROBE-from-ZFS-capabilities-36.patch @@ -1,7 +1,7 @@ From d778817b78c72a04d419073ee8e98099e2a960a0 Mon Sep 17 00:00:00 2001 From: BenjiReis Date: Fri, 4 Aug 2023 12:10:37 +0200 -Subject: [PATCH 21/28] Remove `SR_PROBE` from ZFS capabilities (#36) +Subject: [PATCH 21/29] Remove `SR_PROBE` from ZFS capabilities (#36) The probe method is not implemented so we shouldn't advertise it. @@ -12,7 +12,7 @@ Signed-off-by: BenjiReis 1 file changed, 1 deletion(-) diff --git a/drivers/ZFSSR.py b/drivers/ZFSSR.py -index 354ca90..5301d5e 100644 +index 354ca90e..5301d5ec 100644 --- a/drivers/ZFSSR.py +++ b/drivers/ZFSSR.py @@ -23,7 +23,6 @@ import util diff --git a/SOURCES/0022-Repair-coverage-to-be-compatible-with-8.3-test-env.patch b/SOURCES/0022-Repair-coverage-to-be-compatible-with-8.3-test-env.patch index 93a58528..5f2fd77b 100644 --- a/SOURCES/0022-Repair-coverage-to-be-compatible-with-8.3-test-env.patch +++ b/SOURCES/0022-Repair-coverage-to-be-compatible-with-8.3-test-env.patch @@ -1,7 +1,7 @@ From 18fe0f0b6c645b314d49b377602cc681167422e6 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Fri, 22 Sep 2023 11:11:27 +0200 -Subject: [PATCH 22/28] Repair coverage to be compatible with 8.3 test env +Subject: [PATCH 22/29] Repair coverage to be compatible with 8.3 test env Impacted drivers: LINSTOR, MooseFS and ZFS. - Ignore all linstor.* members during coverage, @@ -18,7 +18,7 @@ Signed-off-by: Ronan Abhamon 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/LinstorSR.py b/drivers/LinstorSR.py -index 1c9bd54..fe6d01d 100755 +index 1c9bd54a..fe6d01d4 100755 --- a/drivers/LinstorSR.py +++ b/drivers/LinstorSR.py @@ -779,9 +779,8 @@ class LinstorSR(SR.SR): @@ -33,7 +33,7 @@ index 1c9bd54..fe6d01d 100755 @_locked_load def vdi(self, uuid): diff --git a/tests/pylintrc b/tests/pylintrc -index a982913..4588675 100644 +index a982913b..4588675b 100644 --- a/tests/pylintrc +++ b/tests/pylintrc @@ -84,7 +84,7 @@ ignored-classes=SQLObject @@ -46,7 +46,7 @@ index a982913..4588675 100644 # List of module names for which member attributes should not be checked # # (useful for modules/projects where namespaces are manipulated during runtime diff --git a/tests/test_MooseFSSR.py b/tests/test_MooseFSSR.py -index feaac62..f4e0a85 100644 +index feaac626..f4e0a852 100644 --- a/tests/test_MooseFSSR.py +++ b/tests/test_MooseFSSR.py @@ -1,4 +1,6 @@ @@ -58,7 +58,7 @@ index feaac62..f4e0a85 100644 import unittest diff --git a/tests/test_ZFSSR.py b/tests/test_ZFSSR.py -index d0cca93..544ea39 100644 +index d0cca935..544ea39a 100644 --- a/tests/test_ZFSSR.py +++ b/tests/test_ZFSSR.py @@ -1,10 +1,10 @@ diff --git a/SOURCES/0023-Support-IPv6-in-Ceph-Driver.patch b/SOURCES/0023-Support-IPv6-in-Ceph-Driver.patch index f5cf0474..d44a0a66 100644 --- a/SOURCES/0023-Support-IPv6-in-Ceph-Driver.patch +++ b/SOURCES/0023-Support-IPv6-in-Ceph-Driver.patch @@ -1,7 +1,7 @@ From e46f99246bd1c9d1e06e6dbc49b1d95dbaaf8eac Mon Sep 17 00:00:00 2001 From: BenjiReis Date: Mon, 25 Sep 2023 16:13:13 +0200 -Subject: [PATCH 23/28] Support IPv6 in Ceph Driver +Subject: [PATCH 23/29] Support IPv6 in Ceph Driver Signed-off-by: BenjiReis --- @@ -9,7 +9,7 @@ Signed-off-by: BenjiReis 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/CephFSSR.py b/drivers/CephFSSR.py -index bd6a4b1..f7c2633 100644 +index bd6a4b14..f7c26336 100644 --- a/drivers/CephFSSR.py +++ b/drivers/CephFSSR.py @@ -20,6 +20,7 @@ diff --git a/SOURCES/0024-lvutil-use-wipefs-not-dd-to-clear-existing-signature.patch b/SOURCES/0024-lvutil-use-wipefs-not-dd-to-clear-existing-signature.patch index 52e87e98..adf86c81 100644 --- a/SOURCES/0024-lvutil-use-wipefs-not-dd-to-clear-existing-signature.patch +++ b/SOURCES/0024-lvutil-use-wipefs-not-dd-to-clear-existing-signature.patch @@ -1,7 +1,7 @@ From 709b30f2d5d8c85c87da2f375a032a0d004b4298 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Wed, 5 Jul 2023 16:57:26 +0200 -Subject: [PATCH 24/28] lvutil: use wipefs not dd to clear existing signatures +Subject: [PATCH 24/29] lvutil: use wipefs not dd to clear existing signatures (xapi-project#624) Signed-off-by: Yann Dirson @@ -12,7 +12,7 @@ Signed-off-by: Yann Dirson 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/XE_SR_ERRORCODES.xml b/drivers/XE_SR_ERRORCODES.xml -index ae871c8..f1497ca 100755 +index ae871c81..f1497ca3 100755 --- a/drivers/XE_SR_ERRORCODES.xml +++ b/drivers/XE_SR_ERRORCODES.xml @@ -904,6 +904,12 @@ @@ -29,7 +29,7 @@ index ae871c8..f1497ca 100755 GenericException SM has thrown a generic python exception diff --git a/drivers/lvutil.py b/drivers/lvutil.py -index 2f2a68e..54d30d6 100755 +index 2f2a68e0..54d30d6d 100755 --- a/drivers/lvutil.py +++ b/drivers/lvutil.py @@ -478,24 +478,12 @@ def createVG(root, vgname): @@ -62,7 +62,7 @@ index 2f2a68e..54d30d6 100755 if not (dev == rootdev): try: diff --git a/drivers/util.py b/drivers/util.py -index 0564b29..5d7b320 100755 +index 0564b29b..5d7b320b 100755 --- a/drivers/util.py +++ b/drivers/util.py @@ -638,6 +638,11 @@ def zeroOut(path, fromByte, bytes): diff --git a/SOURCES/0025-feat-LargeBlock-introduce-largeblocksr-51.patch b/SOURCES/0025-feat-LargeBlock-introduce-largeblocksr-51.patch index d412e9c9..fe1c0475 100644 --- a/SOURCES/0025-feat-LargeBlock-introduce-largeblocksr-51.patch +++ b/SOURCES/0025-feat-LargeBlock-introduce-largeblocksr-51.patch @@ -1,7 +1,7 @@ From 47d5d8691b40f9c4bd8a77c00d851443e68ac887 Mon Sep 17 00:00:00 2001 From: Damien Thenot Date: Fri, 12 Apr 2024 15:08:59 +0200 -Subject: [PATCH 25/28] feat(LargeBlock): introduce largeblocksr (#51) +Subject: [PATCH 25/29] feat(LargeBlock): introduce largeblocksr (#51) A SR inheriting from a EXTSR allowing to use a 4KiB blocksize device as SR. @@ -47,7 +47,7 @@ Signed-off-by: Damien Thenot create mode 100644 drivers/LargeBlockSR.py diff --git a/Makefile b/Makefile -index 075f460..472413e 100755 +index 075f4603..472413e5 100755 --- a/Makefile +++ b/Makefile @@ -20,6 +20,7 @@ SM_DRIVERS += GlusterFS @@ -60,7 +60,7 @@ index 075f460..472413e 100755 SM_LIBS += SRCommand diff --git a/drivers/LargeBlockSR.py b/drivers/LargeBlockSR.py new file mode 100644 -index 0000000..ba0ac1d +index 00000000..ba0ac1d1 --- /dev/null +++ b/drivers/LargeBlockSR.py @@ -0,0 +1,249 @@ @@ -314,7 +314,7 @@ index 0000000..ba0ac1d +else: + SR.registerSR(LargeBlockSR) diff --git a/drivers/XE_SR_ERRORCODES.xml b/drivers/XE_SR_ERRORCODES.xml -index f1497ca..0ec1fa1 100755 +index f1497ca3..0ec1fa1b 100755 --- a/drivers/XE_SR_ERRORCODES.xml +++ b/drivers/XE_SR_ERRORCODES.xml @@ -963,4 +963,26 @@ @@ -345,7 +345,7 @@ index f1497ca..0ec1fa1 100755 + diff --git a/drivers/cleanup.py b/drivers/cleanup.py -index 02435db..99d7387 100755 +index 02435db8..99d73872 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -3430,7 +3430,7 @@ def normalizeType(type): @@ -358,7 +358,7 @@ index 02435db..99d7387 100755 type = SR.TYPE_FILE if type in ["linstor"]: diff --git a/drivers/lvutil.py b/drivers/lvutil.py -index 54d30d6..9bf9d1e 100755 +index 54d30d6d..9bf9d1e9 100755 --- a/drivers/lvutil.py +++ b/drivers/lvutil.py @@ -569,12 +569,16 @@ def resizePV(dev): @@ -381,7 +381,7 @@ index 54d30d6..9bf9d1e 100755 @lvmretry diff --git a/drivers/on_slave.py b/drivers/on_slave.py -index 524424f..2f58281 100755 +index 524424f6..2f58281a 100755 --- a/drivers/on_slave.py +++ b/drivers/on_slave.py @@ -78,6 +78,7 @@ def _is_open(session, args): diff --git a/SOURCES/0026-feat-LVHDSR-add-a-way-to-modify-config-of-LVMs-60.patch b/SOURCES/0026-feat-LVHDSR-add-a-way-to-modify-config-of-LVMs-60.patch index 60a7f184..7b91ca84 100644 --- a/SOURCES/0026-feat-LVHDSR-add-a-way-to-modify-config-of-LVMs-60.patch +++ b/SOURCES/0026-feat-LVHDSR-add-a-way-to-modify-config-of-LVMs-60.patch @@ -1,7 +1,7 @@ From db0a6cb684e3a24ef1c47094154d19c03a6f0a5c Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Tue, 30 Jul 2024 15:31:23 +0200 -Subject: [PATCH 26/28] feat(LVHDSR): add a way to modify config of LVMs (#60) +Subject: [PATCH 26/29] feat(LVHDSR): add a way to modify config of LVMs (#60) With this change the driver supports a "lvm-conf" param on "other-config". For now The configuration is only used by "remove" calls from LVMCache. @@ -22,7 +22,7 @@ Signed-off-by: Ronan Abhamon 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/LVHDSR.py b/drivers/LVHDSR.py -index dedaef9..66a50fa 100755 +index dedaef95..66a50fa2 100755 --- a/drivers/LVHDSR.py +++ b/drivers/LVHDSR.py @@ -161,14 +161,24 @@ class LVHDSR(SR.SR): @@ -61,7 +61,7 @@ index dedaef9..66a50fa 100755 self.testMode = self.other_conf[self.TEST_MODE_KEY] self._prepareTestMode() diff --git a/drivers/cleanup.py b/drivers/cleanup.py -index 99d7387..6454199 100755 +index 99d73872..64541999 100755 --- a/drivers/cleanup.py +++ b/drivers/cleanup.py @@ -2834,7 +2834,12 @@ class LVHDSR(SR): @@ -79,7 +79,7 @@ index 99d7387..6454199 100755 self.journaler = journaler.Journaler(self.lvmCache) diff --git a/drivers/lvmcache.py b/drivers/lvmcache.py -index 8c63d45..6e21568 100644 +index 8c63d45a..6e21568e 100644 --- a/drivers/lvmcache.py +++ b/drivers/lvmcache.py @@ -59,10 +59,11 @@ class LVMCache: diff --git a/SOURCES/0027-reflect-upstream-changes-in-our-tests.patch b/SOURCES/0027-reflect-upstream-changes-in-our-tests.patch index 42daab25..bdbaeae4 100644 --- a/SOURCES/0027-reflect-upstream-changes-in-our-tests.patch +++ b/SOURCES/0027-reflect-upstream-changes-in-our-tests.patch @@ -1,7 +1,7 @@ From df0d4cd2dcafb2d866ee121d8d7903711ffa4456 Mon Sep 17 00:00:00 2001 From: Benjamin Reis Date: Tue, 13 Aug 2024 11:11:39 +0200 -Subject: [PATCH 27/28] reflect upstream changes in our tests +Subject: [PATCH 27/29] reflect upstream changes in our tests Signed-off-by: Benjamin Reis --- @@ -10,7 +10,7 @@ Signed-off-by: Benjamin Reis 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/test_ISOSR.py b/tests/test_ISOSR.py -index 9dec459..ad5d99d 100644 +index 9dec459c..ad5d99dc 100644 --- a/tests/test_ISOSR.py +++ b/tests/test_ISOSR.py @@ -68,17 +68,14 @@ class TestISOSR_overLocal(unittest.TestCase): @@ -34,7 +34,7 @@ index 9dec459..ad5d99d 100644 self.assertEqual(ose.exception.errno, 226) self.assertFalse(pread.called) diff --git a/tests/test_ZFSSR.py b/tests/test_ZFSSR.py -index 544ea39..47d72b8 100644 +index 544ea39a..47d72b89 100644 --- a/tests/test_ZFSSR.py +++ b/tests/test_ZFSSR.py @@ -6,6 +6,7 @@ import FileSR diff --git a/SOURCES/0028-CA-398425-correctly-check-for-multiple-targets-in-iS.patch b/SOURCES/0028-CA-398425-correctly-check-for-multiple-targets-in-iS.patch index ffd2324d..54fd976d 100644 --- a/SOURCES/0028-CA-398425-correctly-check-for-multiple-targets-in-iS.patch +++ b/SOURCES/0028-CA-398425-correctly-check-for-multiple-targets-in-iS.patch @@ -1,7 +1,7 @@ From 006a3727a18eed16a581251553b829667efceefd Mon Sep 17 00:00:00 2001 From: Mark Syms Date: Fri, 30 Aug 2024 10:13:27 +0100 -Subject: [PATCH 28/28] CA-398425: correctly check for multiple targets in +Subject: [PATCH 28/29] CA-398425: correctly check for multiple targets in iSCSI Signed-off-by: Mark Syms @@ -10,7 +10,7 @@ Signed-off-by: Mark Syms 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/LVHDoISCSISR.py b/drivers/LVHDoISCSISR.py -index cbde1b9..442ec30 100755 +index cbde1b92..442ec30f 100755 --- a/drivers/LVHDoISCSISR.py +++ b/drivers/LVHDoISCSISR.py @@ -103,7 +103,8 @@ class LVHDoISCSISR(LVHDSR.LVHDSR): diff --git a/SOURCES/0029-Synchronization-with-8.2-LINSTOR-before-a-stable-rel.patch b/SOURCES/0029-Synchronization-with-8.2-LINSTOR-before-a-stable-rel.patch new file mode 100644 index 00000000..31c3b4c6 --- /dev/null +++ b/SOURCES/0029-Synchronization-with-8.2-LINSTOR-before-a-stable-rel.patch @@ -0,0 +1,1400 @@ +From 93a8128e234613c4973d83bbb37c84d2a9cf5d87 Mon Sep 17 00:00:00 2001 +From: Ronan Abhamon +Date: Mon, 5 Feb 2024 23:16:16 +0100 +Subject: [PATCH 29/29] Synchronization with 8.2 LINSTOR before a stable + release + +Last commit: 9207abe1f2e1ff1795cdba1a0aeb76574412a583 +"fix(linstor): check if resource is tiebreaker (#62)" + +Signed-off-by: Ronan Abhamon +--- + dev_requirements.txt | 1 + + drivers/LinstorSR.py | 100 +++--- + drivers/linstor-manager | 183 ++++++++--- + drivers/linstorvhdutil.py | 60 +++- + drivers/linstorvolumemanager.py | 349 +++++++++++++++------ + drivers/tapdisk-pause | 6 +- + {tests/mocks => mocks}/linstor/__init__.py | 0 + 7 files changed, 497 insertions(+), 202 deletions(-) + rename {tests/mocks => mocks}/linstor/__init__.py (100%) + +diff --git a/dev_requirements.txt b/dev_requirements.txt +index 104316ba..f25f7686 100644 +--- a/dev_requirements.txt ++++ b/dev_requirements.txt +@@ -2,3 +2,4 @@ coverage + astroid==2.3.3 + pylint==2.4.4 + bitarray ++python-linstor +diff --git a/drivers/LinstorSR.py b/drivers/LinstorSR.py +index fe6d01d4..8b8be6c9 100755 +--- a/drivers/LinstorSR.py ++++ b/drivers/LinstorSR.py +@@ -362,9 +362,6 @@ class LinstorSR(SR.SR): + self._linstor = None # Ensure that LINSTOR attribute exists. + self._journaler = None + +- self._is_master = False +- if 'SRmaster' in self.dconf and self.dconf['SRmaster'] == 'true': +- self._is_master = True + self._group_name = self.dconf['group-name'] + + self._vdi_shared_time = 0 +@@ -437,7 +434,7 @@ class LinstorSR(SR.SR): + + return wrapped_method(self, *args, **kwargs) + +- if not self._is_master: ++ if not self.is_master(): + if self.cmd in [ + 'sr_create', 'sr_delete', 'sr_update', 'sr_probe', + 'sr_scan', 'vdi_create', 'vdi_delete', 'vdi_resize', +@@ -472,7 +469,7 @@ class LinstorSR(SR.SR): + + # Ensure we use a non-locked volume when vhdutil is called. + if ( +- self._is_master and self.cmd.startswith('vdi_') and ++ self.is_master() and self.cmd.startswith('vdi_') and + self.cmd != 'vdi_create' + ): + self._linstor.ensure_volume_is_not_locked( +@@ -487,7 +484,7 @@ class LinstorSR(SR.SR): + # + # If the command is a SR command we want at least to remove + # resourceless volumes. +- if self._is_master and self.cmd not in [ ++ if self.is_master() and self.cmd not in [ + 'vdi_attach', 'vdi_detach', + 'vdi_activate', 'vdi_deactivate', + 'vdi_epoch_begin', 'vdi_epoch_end', +@@ -650,17 +647,17 @@ class LinstorSR(SR.SR): + opterr='Cannot get controller node name' + ) + +- host = None ++ host_ref = None + if node_name == 'localhost': +- host = util.get_this_host_ref(self.session) ++ host_ref = util.get_this_host_ref(self.session) + else: + for slave in util.get_all_slaves(self.session): + r_name = self.session.xenapi.host.get_record(slave)['hostname'] + if r_name == node_name: +- host = slave ++ host_ref = slave + break + +- if not host: ++ if not host_ref: + raise xs_errors.XenError( + 'LinstorSRDelete', + opterr='Failed to find host with hostname: {}'.format( +@@ -677,7 +674,7 @@ class LinstorSR(SR.SR): + 'groupName': self._group_name, + } + self._exec_manager_command( +- host, 'destroy', args, 'LinstorSRDelete' ++ host_ref, 'destroy', args, 'LinstorSRDelete' + ) + except Exception as e: + try: +@@ -766,7 +763,7 @@ class LinstorSR(SR.SR): + # is started without a shared and mounted /var/lib/linstor path. + try: + self._linstor.get_database_path() +- except Exception: ++ except Exception as e: + # Failed to get database path, ensure we don't have + # VDIs in the XAPI database... + if self.session.xenapi.SR.get_VDIs( +@@ -774,7 +771,7 @@ class LinstorSR(SR.SR): + ): + raise xs_errors.XenError( + 'SRUnavailable', +- opterr='Database is not mounted' ++ opterr='Database is not mounted or node name is invalid ({})'.format(e) + ) + + # Update the database before the restart of the GC to avoid +@@ -782,6 +779,15 @@ class LinstorSR(SR.SR): + super(LinstorSR, self).scan(self.uuid) + self._kick_gc() + ++ def is_master(self): ++ if not hasattr(self, '_is_master'): ++ if 'SRmaster' not in self.dconf: ++ self._is_master = self.session is not None and util.is_master(self.session) ++ else: ++ self._is_master = self.dconf['SRmaster'] == 'true' ++ ++ return self._is_master ++ + @_locked_load + def vdi(self, uuid): + return LinstorVDI(self, uuid) +@@ -967,7 +973,7 @@ class LinstorSR(SR.SR): + ) + + def _synchronize_metadata(self): +- if not self._is_master: ++ if not self.is_master(): + return + + util.SMlog('Synchronize metadata...') +@@ -1014,7 +1020,7 @@ class LinstorSR(SR.SR): + if self._vdis_loaded: + return + +- assert self._is_master ++ assert self.is_master() + + # We use a cache to avoid repeated JSON parsing. + # The performance gain is not big but we can still +@@ -1492,7 +1498,7 @@ class LinstorSR(SR.SR): + controller_uri, + self._group_name, + repair=( +- self._is_master and ++ self.is_master() and + self.srcmd.cmd in self.ops_exclusive + ), + logger=util.SMlog +@@ -1660,8 +1666,11 @@ class LinstorVDI(VDI.VDI): + volume_name = REDO_LOG_VOLUME_NAME + + self._linstor.create_volume( +- self.uuid, volume_size, persistent=False, +- volume_name=volume_name ++ self.uuid, ++ volume_size, ++ persistent=False, ++ volume_name=volume_name, ++ high_availability=volume_name is not None + ) + volume_info = self._linstor.get_volume_info(self.uuid) + +@@ -1788,10 +1797,10 @@ class LinstorVDI(VDI.VDI): + 'scan SR first to trigger auto-repair' + ) + +- if not attach_from_config or self.sr._is_master: +- writable = 'args' not in self.sr.srcmd.params or \ +- self.sr.srcmd.params['args'][0] == 'true' ++ writable = 'args' not in self.sr.srcmd.params or \ ++ self.sr.srcmd.params['args'][0] == 'true' + ++ if not attach_from_config or self.sr.is_master(): + # We need to inflate the volume if we don't have enough place + # to mount the VHD image. I.e. the volume capacity must be greater + # than the VHD size + bitmap size. +@@ -1825,7 +1834,7 @@ class LinstorVDI(VDI.VDI): + return self._attach_using_http_nbd() + + # Ensure we have a path... +- self._create_chain_paths(self.uuid) ++ self.sr._vhdutil.create_chain_paths(self.uuid, readonly=not writable) + + self.attached = True + return VDI.VDI.attach(self, self.sr.uuid, self.uuid) +@@ -1873,7 +1882,7 @@ class LinstorVDI(VDI.VDI): + ) + + # We remove only on slaves because the volume can be used by the GC. +- if self.sr._is_master: ++ if self.sr.is_master(): + return + + while vdi_uuid: +@@ -1894,7 +1903,7 @@ class LinstorVDI(VDI.VDI): + + def resize(self, sr_uuid, vdi_uuid, size): + util.SMlog('LinstorVDI.resize for {}'.format(self.uuid)) +- if not self.sr._is_master: ++ if not self.sr.is_master(): + raise xs_errors.XenError( + 'VDISize', + opterr='resize on slave not allowed' +@@ -2153,7 +2162,7 @@ class LinstorVDI(VDI.VDI): + # -------------------------------------------------------------------------- + + def _prepare_thin(self, attach): +- if self.sr._is_master: ++ if self.sr.is_master(): + if attach: + attach_thin( + self.session, self.sr._journaler, self._linstor, +@@ -2352,7 +2361,7 @@ class LinstorVDI(VDI.VDI): + raise xs_errors.XenError('SnapshotChainTooLong') + + # Ensure we have a valid path if we don't have a local diskful. +- self._create_chain_paths(self.uuid) ++ self.sr._vhdutil.create_chain_paths(self.uuid, readonly=True) + + volume_path = self.path + if not util.pathexists(volume_path): +@@ -2499,10 +2508,10 @@ class LinstorVDI(VDI.VDI): + active_uuid, clone_info, force_undo=True + ) + self.sr._journaler.remove(LinstorJournaler.CLONE, active_uuid) +- except Exception as e: ++ except Exception as clean_error: + util.SMlog( + 'WARNING: Failed to clean up failed snapshot: {}' +- .format(e) ++ .format(clean_error) + ) + raise xs_errors.XenError('VDIClone', opterr=str(e)) + +@@ -2739,7 +2748,7 @@ class LinstorVDI(VDI.VDI): + + # 0. Fetch drbd path. + must_get_device_path = True +- if not self.sr._is_master: ++ if not self.sr.is_master(): + # We are on a slave, we must try to find a diskful locally. + try: + volume_info = self._linstor.get_volume_info(self.uuid) +@@ -2754,7 +2763,7 @@ class LinstorVDI(VDI.VDI): + must_get_device_path = hostname in volume_info.diskful + + drbd_path = None +- if must_get_device_path or self.sr._is_master: ++ if must_get_device_path or self.sr.is_master(): + # If we are master, we must ensure we have a diskless + # or diskful available to init HA. + # It also avoid this error in xensource.log +@@ -2812,37 +2821,6 @@ class LinstorVDI(VDI.VDI): + self._kill_persistent_nbd_server(volume_name) + self._kill_persistent_http_server(volume_name) + +- def _create_chain_paths(self, vdi_uuid): +- # OPTIMIZE: Add a limit_to_first_allocated_block param to limit vhdutil calls. +- # Useful for the snapshot code algorithm. +- +- while vdi_uuid: +- path = self._linstor.get_device_path(vdi_uuid) +- if not util.pathexists(path): +- raise xs_errors.XenError( +- 'VDIUnavailable', opterr='Could not find: {}'.format(path) +- ) +- +- # Diskless path can be created on the fly, ensure we can open it. +- def check_volume_usable(): +- while True: +- try: +- with open(path, 'r+'): +- pass +- except IOError as e: +- if e.errno == errno.ENODATA: +- time.sleep(2) +- continue +- if e.errno == errno.EROFS: +- util.SMlog('Volume not attachable because RO. Openers: {}'.format( +- self.sr._linstor.get_volume_openers(vdi_uuid) +- )) +- raise +- break +- util.retry(check_volume_usable, 15, 2) +- +- vdi_uuid = self.sr._vhdutil.get_vhd_info(vdi_uuid).parentUuid +- + # ------------------------------------------------------------------------------ + + +diff --git a/drivers/linstor-manager b/drivers/linstor-manager +index 8d313ec7..47c434a3 100755 +--- a/drivers/linstor-manager ++++ b/drivers/linstor-manager +@@ -27,8 +27,9 @@ import socket + import XenAPI + import XenAPIPlugin + ++from json import JSONEncoder + from linstorjournaler import LinstorJournaler +-from linstorvhdutil import LinstorVhdUtil ++from linstorvhdutil import LinstorVhdUtil, check_ex + from linstorvolumemanager import get_controller_uri, get_local_volume_openers, LinstorVolumeManager + from lock import Lock + import json +@@ -240,7 +241,10 @@ def get_drbd_volumes(volume_group=None): + config = json.loads(stdout) + for resource in config: + for volume in resource['_this_host']['volumes']: +- backing_disk = volume['backing-disk'] ++ backing_disk = volume.get('backing-disk') ++ if not backing_disk: ++ continue ++ + match = BACKING_DISK_RE.match(backing_disk) + if not match: + continue +@@ -389,7 +393,8 @@ def check(session, args): + args['ignoreMissingFooter'] + ) + fast = distutils.util.strtobool(args['fast']) +- return str(vhdutil.check(device_path, ignore_missing_footer, fast)) ++ check_ex(device_path, ignore_missing_footer, fast) ++ return str(True) + except Exception as e: + util.SMlog('linstor-manager:check error: {}'.format(e)) + raise +@@ -534,7 +539,8 @@ def set_parent(session, args): + def coalesce(session, args): + try: + device_path = args['devicePath'] +- return str(vhdutil.coalesce(device_path)) ++ vhdutil.coalesce(device_path) ++ return '' + except Exception as e: + util.SMlog('linstor-manager:coalesce error: {}'.format(e)) + raise +@@ -885,6 +891,64 @@ def get_drbd_openers(session, args): + raise + + ++class HealthCheckError(object): ++ __slots__ = ('data') ++ ++ MASK_REPORT_LEVEL = 0x7000000 ++ MASK_TYPE = 0xFF0000 ++ MASK_VALUE = 0XFFFF ++ ++ # 24-26 bits ++ REPORT_LEVEL_WARN = 0x1000000 ++ REPORT_LEVEL_ERR = 0x2000000 ++ ++ # 16-23 bits ++ TYPE_GENERIC = 0x10000 ++ TYPE_NODE = 0x20000 ++ TYPE_STORAGE_POOL = 0x30000 ++ TYPE_VOLUME = 0x40000 ++ TYPE_RESOURCE = 0x50000 ++ ++ # 1-15 bits ++ GENERIC_UNEXPECTED = REPORT_LEVEL_ERR | TYPE_GENERIC | 0 ++ GENERIC_LINSTOR_UNREACHABLE = REPORT_LEVEL_ERR | TYPE_GENERIC | 1 ++ ++ NODE_NOT_ONLINE = REPORT_LEVEL_WARN | TYPE_NODE | 0 ++ ++ STORAGE_POOL_UNKNOWN_FREE_SIZE = REPORT_LEVEL_ERR | TYPE_STORAGE_POOL | 0 ++ STORAGE_POOL_UNKNOWN_CAPACITY = REPORT_LEVEL_ERR | TYPE_STORAGE_POOL | 1 ++ STORAGE_POOL_LOW_FREE_SIZE = REPORT_LEVEL_WARN | TYPE_STORAGE_POOL | 2 ++ ++ VOLUME_UNKNOWN_STATE = REPORT_LEVEL_WARN | TYPE_VOLUME | 0 ++ VOLUME_INVALID_STATE = REPORT_LEVEL_ERR | TYPE_VOLUME | 1 ++ VOLUME_WRONG_DISKLESS_STATE = REPORT_LEVEL_WARN | TYPE_VOLUME | 2 ++ VOLUME_INTERNAL_UNVERIFIED_STATE = REPORT_LEVEL_WARN | TYPE_VOLUME | 3 ++ ++ MAP_CODE_TO_PARAMS = { ++ GENERIC_UNEXPECTED: { 'message' }, ++ GENERIC_LINSTOR_UNREACHABLE: { 'message' }, ++ NODE_NOT_ONLINE: { 'name', 'status' }, ++ STORAGE_POOL_UNKNOWN_FREE_SIZE: { 'name' }, ++ STORAGE_POOL_UNKNOWN_CAPACITY: { 'name' }, ++ STORAGE_POOL_LOW_FREE_SIZE: { 'name', 'threshold' }, ++ VOLUME_UNKNOWN_STATE: { 'node', 'resource', 'number' }, ++ VOLUME_INVALID_STATE: { 'node', 'resource', 'number', 'state' }, ++ VOLUME_WRONG_DISKLESS_STATE: { 'node', 'resource', 'number', 'state' }, ++ VOLUME_INTERNAL_UNVERIFIED_STATE: { 'node', 'resource', 'number', 'state' } ++ } ++ ++ def __init__(self, code, **kwargs): ++ attributes = self.MAP_CODE_TO_PARAMS[code] ++ data = { 'code': code } ++ for attr_name, attr_value in kwargs.items(): ++ assert attr_name in attributes ++ data[attr_name] = attr_value ++ self.data = data ++ ++ def to_json(self): ++ return self.data ++ ++ + def health_check(session, args): + group_name = args['groupName'] + +@@ -892,11 +956,16 @@ def health_check(session, args): + 'controller-uri': '', + 'nodes': {}, + 'storage-pools': {}, +- 'warnings': [], ++ 'resources': {}, + 'errors': [] + } + + def format_result(): ++ # See: https://stackoverflow.com/questions/18478287/making-object-json-serializable-with-regular-encoder/18561055#18561055 ++ def _default(self, obj): ++ return getattr(obj.__class__, 'to_json', _default.default)(obj) ++ _default.default = JSONEncoder().default ++ JSONEncoder.default = _default + return json.dumps(result) + + # 1. Get controller. +@@ -919,7 +988,10 @@ def health_check(session, args): + ) + except Exception as e: + # Probably a network issue, or offline controller. +- result['errors'].append('Cannot join SR: `{}`.'.format(e)) ++ result['errors'].append(HealthCheckError( ++ code=HealthCheckError.GENERIC_LINSTOR_UNREACHABLE, ++ message=str(e) ++ )) + return format_result() + + try: +@@ -928,7 +1000,11 @@ def health_check(session, args): + result['nodes'] = nodes + for node_name, status in nodes.items(): + if status != 'ONLINE': +- result['warnings'].append('Node `{}` is {}.'.format(node_name, status)) ++ result['errors'].append(HealthCheckError( ++ code=HealthCheckError.NODE_NOT_ONLINE, ++ name=node_name, ++ status=status ++ )) + + # 3. Check storage pool statuses. + storage_pools_per_node = linstor.get_storage_pools_info() +@@ -938,23 +1014,25 @@ def health_check(session, args): + free_size = storage_pool['free-size'] + capacity = storage_pool['capacity'] + if free_size < 0 or capacity <= 0: +- result['errors'].append( +- 'Cannot get free size and/or capacity of storage pool `{}`.' +- .format(storage_pool['uuid']) +- ) +- elif free_size > capacity: +- result['errors'].append( +- 'Free size of storage pool `{}` is greater than capacity.' +- .format(storage_pool['uuid']) +- ) ++ if free_size < 0: ++ result['errors'].append(HealthCheckError( ++ code=HealthCheckError.STORAGE_POOL_UNKNOWN_FREE_SIZE, ++ name=storage_pool['name'] ++ )) ++ elif capacity < 0: ++ result['errors'].append(HealthCheckError( ++ code=HealthCheckError.STORAGE_POOL_UNKNOWN_CAPACITY, ++ name=storage_pool['name'] ++ )) + else: + remaining_percent = free_size / float(capacity) * 100.0 + threshold = 10.0 + if remaining_percent < threshold: +- result['warnings'].append( +- 'Remaining size of storage pool `{}` is below {}% of its capacity.' +- .format(storage_pool['uuid'], threshold) +- ) ++ result['errors'].append(HealthCheckError( ++ code=HealthCheckError.STORAGE_POOL_LOW_FREE_SIZE, ++ name=storage_pool['name'], ++ threshold=threshold ++ )) + + # 4. Check resource statuses. + all_resources = linstor.get_resources_info() +@@ -967,33 +1045,46 @@ def health_check(session, args): + if disk_state in ['UpToDate', 'Created', 'Attached']: + continue + if disk_state == 'DUnknown': +- result['warnings'].append( +- 'Unknown state for volume `{}` at index {} for resource `{}` on node `{}`' +- .format(volume['device-path'], volume_index, resource_name, node_name) +- ) ++ result['errors'].append(HealthCheckError( ++ code=HealthCheckError.VOLUME_UNKNOWN_STATE, ++ node=node_name, ++ resource=resource_name, ++ number=volume_index ++ )) + continue + if disk_state in ['Inconsistent', 'Failed', 'To: Creating', 'To: Attachable', 'To: Attaching']: +- result['errors'].append( +- 'Invalid state `{}` for volume `{}` at index {} for resource `{}` on node `{}`' +- .format(disk_state, volume['device-path'], volume_index, resource_name, node_name) +- ) ++ result['errors'].append(HealthCheckError( ++ code=HealthCheckError.VOLUME_INVALID_STATE, ++ node=node_name, ++ resource=resource_name, ++ number=volume_index, ++ state=disk_state ++ )) + continue + if disk_state == 'Diskless': + if resource['diskful']: +- result['errors'].append( +- 'Unintentional diskless state detected for volume `{}` at index {} for resource `{}` on node `{}`' +- .format(volume['device-path'], volume_index, resource_name, node_name) +- ) ++ result['errors'].append(HealthCheckError( ++ code=HealthCheckError.VOLUME_WRONG_DISKLESS_STATE, ++ node=node_name, ++ resource=resource_name, ++ number=volume_index, ++ state=disk_state ++ )) + elif resource['tie-breaker']: + volume['disk-state'] = 'TieBreaker' + continue +- result['warnings'].append( +- 'Unhandled state `{}` for volume `{}` at index {} for resource `{}` on node `{}`' +- .format(disk_state, volume['device-path'], volume_index, resource_name, node_name) +- ) +- ++ result['errors'].append(HealthCheckError( ++ code=HealthCheckError.VOLUME_INTERNAL_UNVERIFIED_STATE, ++ node=node_name, ++ resource=resource_name, ++ number=volume_index, ++ state=disk_state ++ )) + except Exception as e: +- result['errors'].append('Unexpected error: `{}`'.format(e)) ++ result['errors'].append(HealthCheckError( ++ code=HealthCheckError.GENERIC_UNEXPECTED, ++ message=str(e) ++ )) + + return format_result() + +@@ -1070,6 +1161,21 @@ def list_node_interfaces(session, args): + raise XenAPIPlugin.Failure('-1', [str(e)]) + + ++def get_node_preferred_interface(session, args): ++ group_name = args['groupName'] ++ hostname = args['hostname'] ++ ++ linstor = LinstorVolumeManager( ++ get_controller_uri(), ++ group_name, ++ logger=util.SMlog ++ ) ++ try: ++ return linstor.get_node_preferred_interface(hostname) ++ except Exception as e: ++ raise XenAPIPlugin.Failure('-1', [str(e)]) ++ ++ + def set_node_preferred_interface(session, args): + group_name = args['groupName'] + hostname = args['hostname'] +@@ -1141,5 +1247,6 @@ if __name__ == '__main__': + 'destroyNodeInterface': destroy_node_interface, + 'modifyNodeInterface': modify_node_interface, + 'listNodeInterfaces': list_node_interfaces, ++ 'getNodePreferredInterface': get_node_preferred_interface, + 'setNodePreferredInterface': set_node_preferred_interface + }) +diff --git a/drivers/linstorvhdutil.py b/drivers/linstorvhdutil.py +index 13e1bb08..046c9695 100644 +--- a/drivers/linstorvhdutil.py ++++ b/drivers/linstorvhdutil.py +@@ -21,6 +21,7 @@ import distutils.util + import errno + import json + import socket ++import time + import util + import vhdutil + import xs_errors +@@ -46,6 +47,16 @@ def call_remote_method(session, host_ref, method, device_path, args): + return response + + ++def check_ex(path, ignoreMissingFooter = False, fast = False): ++ cmd = [vhdutil.VHD_UTIL, "check", vhdutil.OPT_LOG_ERR, "-n", path] ++ if ignoreMissingFooter: ++ cmd.append("-i") ++ if fast: ++ cmd.append("-B") ++ ++ vhdutil.ioretry(cmd) ++ ++ + class LinstorCallException(util.SMException): + def __init__(self, cmd_err): + self.cmd_err = cmd_err +@@ -138,6 +149,44 @@ class LinstorVhdUtil: + self._session = session + self._linstor = linstor + ++ def create_chain_paths(self, vdi_uuid, readonly=False): ++ # OPTIMIZE: Add a limit_to_first_allocated_block param to limit vhdutil calls. ++ # Useful for the snapshot code algorithm. ++ ++ leaf_vdi_path = self._linstor.get_device_path(vdi_uuid) ++ path = leaf_vdi_path ++ while True: ++ if not util.pathexists(path): ++ raise xs_errors.XenError( ++ 'VDIUnavailable', opterr='Could not find: {}'.format(path) ++ ) ++ ++ # Diskless path can be created on the fly, ensure we can open it. ++ def check_volume_usable(): ++ while True: ++ try: ++ with open(path, 'r' if readonly else 'r+'): ++ pass ++ except IOError as e: ++ if e.errno == errno.ENODATA: ++ time.sleep(2) ++ continue ++ if e.errno == errno.EROFS: ++ util.SMlog('Volume not attachable because RO. Openers: {}'.format( ++ self._linstor.get_volume_openers(vdi_uuid) ++ )) ++ raise ++ break ++ util.retry(check_volume_usable, 15, 2) ++ ++ vdi_uuid = self.get_vhd_info(vdi_uuid).parentUuid ++ if not vdi_uuid: ++ break ++ path = self._linstor.get_device_path(vdi_uuid) ++ readonly = True # Non-leaf is always readonly. ++ ++ return leaf_vdi_path ++ + # -------------------------------------------------------------------------- + # Getters: read locally and try on another host in case of failure. + # -------------------------------------------------------------------------- +@@ -147,9 +196,14 @@ class LinstorVhdUtil: + 'ignoreMissingFooter': ignore_missing_footer, + 'fast': fast + } +- return self._check(vdi_uuid, **kwargs) # pylint: disable = E1123 ++ try: ++ self._check(vdi_uuid, **kwargs) # pylint: disable = E1123 ++ return True ++ except Exception as e: ++ util.SMlog('Call to `check` failed: {}'.format(e)) ++ return False + +- @linstorhostcall(vhdutil.check, 'check') ++ @linstorhostcall(check_ex, 'check') + def _check(self, vdi_uuid, response): + return distutils.util.strtobool(response) + +@@ -322,7 +376,7 @@ class LinstorVhdUtil: + + @linstormodifier() + def force_coalesce(self, path): +- return int(self._call_method(vhdutil.coalesce, 'coalesce', path, use_parent=True)) ++ return self._call_method(vhdutil.coalesce, 'coalesce', path, use_parent=True) + + @linstormodifier() + def force_repair(self, path): +diff --git a/drivers/linstorvolumemanager.py b/drivers/linstorvolumemanager.py +index dbca3b41..a470dfec 100755 +--- a/drivers/linstorvolumemanager.py ++++ b/drivers/linstorvolumemanager.py +@@ -18,7 +18,6 @@ + + import distutils.util + import errno +-import glob + import json + import linstor + import os.path +@@ -273,7 +272,8 @@ class LinstorVolumeManagerError(Exception): + ERR_GENERIC = 0, + ERR_VOLUME_EXISTS = 1, + ERR_VOLUME_NOT_EXISTS = 2, +- ERR_VOLUME_DESTROY = 3 ++ ERR_VOLUME_DESTROY = 3, ++ ERR_GROUP_NOT_EXISTS = 4 + + def __init__(self, message, code=ERR_GENERIC): + super(LinstorVolumeManagerError, self).__init__(message) +@@ -298,11 +298,9 @@ class LinstorVolumeManager(object): + """ + + __slots__ = ( +- '_linstor', '_logger', +- '_uri', '_base_group_name', +- '_redundancy', '_group_name', +- '_volumes', '_storage_pools', +- '_storage_pools_time', ++ '_linstor', '_logger', '_redundancy', ++ '_base_group_name', '_group_name', '_ha_group_name', ++ '_volumes', '_storage_pools', '_storage_pools_time', + '_kv_cache', '_resource_cache', '_volume_info_cache', + '_kv_cache_dirty', '_resource_cache_dirty', '_volume_info_cache_dirty' + ) +@@ -348,6 +346,7 @@ class LinstorVolumeManager(object): + # A LINSTOR (resource, group, ...) name cannot start with a number. + # So we add a prefix behind our SR/VOLUME uuids. + PREFIX_SR = 'xcp-sr-' ++ PREFIX_HA = 'xcp-ha-' + PREFIX_VOLUME = 'xcp-volume-' + + # Limit request number when storage pool info is asked, we fetch +@@ -406,8 +405,7 @@ class LinstorVolumeManager(object): + + # Ensure group exists. + group_name = self._build_group_name(group_name) +- groups = self._linstor.resource_group_list_raise([group_name]) +- groups = groups.resource_groups ++ groups = self._linstor.resource_group_list_raise([group_name]).resource_groups + if not groups: + raise LinstorVolumeManagerError( + 'Unable to find `{}` Linstor SR'.format(group_name) +@@ -417,6 +415,7 @@ class LinstorVolumeManager(object): + self._logger = logger + self._redundancy = groups[0].select_filter.place_count + self._group_name = group_name ++ self._ha_group_name = self._build_ha_group_name(self._base_group_name) + self._volumes = set() + self._storage_pools_time = 0 + +@@ -617,7 +616,12 @@ class LinstorVolumeManager(object): + return volume_uuid in self._volumes + + def create_volume( +- self, volume_uuid, size, persistent=True, volume_name=None ++ self, ++ volume_uuid, ++ size, ++ persistent=True, ++ volume_name=None, ++ high_availability=False + ): + """ + Create a new volume on the SR. +@@ -627,6 +631,8 @@ class LinstorVolumeManager(object): + on the next constructor call LinstorSR(...). + :param str volume_name: If set, this name is used in the LINSTOR + database instead of a generated name. ++ :param bool high_availability: If set, the volume is created in ++ the HA group. + :return: The current device path of the volume. + :rtype: str + """ +@@ -635,7 +641,11 @@ class LinstorVolumeManager(object): + if not volume_name: + volume_name = self.build_volume_name(util.gen_uuid()) + volume_properties = self._create_volume_with_properties( +- volume_uuid, volume_name, size, place_resources=True ++ volume_uuid, ++ volume_name, ++ size, ++ True, # place_resources ++ high_availability + ) + + # Volume created! Now try to find the device path. +@@ -651,7 +661,7 @@ class LinstorVolumeManager(object): + 'LINSTOR volume {} created!'.format(volume_uuid) + ) + return device_path +- except Exception as e: ++ except Exception: + # There is an issue to find the path. + # At this point the volume has just been created, so force flag can be used. + self._destroy_volume(volume_uuid, force=True) +@@ -802,6 +812,13 @@ class LinstorVolumeManager(object): + volume_name = volume_properties.get(self.PROP_VOLUME_NAME) + + node_name = socket.gethostname() ++ ++ for resource in self._get_resource_cache().resources: ++ if resource.name == volume_name and resource.node_name == node_name: ++ if linstor.consts.FLAG_TIE_BREAKER in resource.flags: ++ return ++ break ++ + result = self._linstor.resource_delete_if_diskless( + node_name=node_name, rsc_name=volume_name + ) +@@ -1351,14 +1368,29 @@ class LinstorVolumeManager(object): + + # 4.4. Refresh linstor connection. + # Without we get this error: +- # "Cannot delete resource group 'xcp-sr-linstor_group_thin_device' because it has existing resource definitions.." ++ # "Cannot delete resource group 'xcp-sr-linstor_group_thin_device' because it has existing resource definitions.." + # Because the deletion of the databse was not seen by Linstor for some reason. + # It seems a simple refresh of the Linstor connection make it aware of the deletion. + self._linstor.disconnect() + self._linstor.connect() + +- # 4.5. Destroy group and storage pools. ++ # 4.5. Destroy remaining drbd nodes on hosts. ++ # We check if there is a DRBD node on hosts that could mean blocking when destroying resource groups. ++ # It needs to be done locally by each host so we go through the linstor-manager plugin. ++ # If we don't do this sometimes, the destroy will fail when trying to destroy the resource groups with: ++ # "linstor-manager:destroy error: Failed to destroy SP `xcp-sr-linstor_group_thin_device` on node `r620-s2`: The specified storage pool 'xcp-sr-linstor_group_thin_device' on node 'r620-s2' can not be deleted as volumes / snapshot-volumes are still using it." ++ session = util.timeout_call(5, util.get_localAPI_session) ++ for host_ref in session.xenapi.host.get_all(): ++ try: ++ response = session.xenapi.host.call_plugin( ++ host_ref, 'linstor-manager', 'destroyDrbdVolumes', {'volume_group': self._group_name} ++ ) ++ except Exception as e: ++ util.SMlog('Calling destroyDrbdVolumes on host {} failed with error {}'.format(host_ref, e)) ++ ++ # 4.6. Destroy group and storage pools. + self._destroy_resource_group(self._linstor, self._group_name) ++ self._destroy_resource_group(self._linstor, self._ha_group_name) + for pool in self._get_storage_pools(force=True): + self._destroy_storage_pool( + self._linstor, pool.name, pool.node_name +@@ -1369,8 +1401,9 @@ class LinstorVolumeManager(object): + + try: + self._start_controller(start=False) +- for file in glob.glob(DATABASE_PATH + '/'): +- os.remove(file) ++ for file in os.listdir(DATABASE_PATH): ++ if file != 'lost+found': ++ os.remove(DATABASE_PATH + '/' + file) + except Exception as e: + util.SMlog( + 'Ignoring failure after LINSTOR SR destruction: {}' +@@ -1479,6 +1512,12 @@ class LinstorVolumeManager(object): + :param str node_name: Node name of the interface to remove. + :param str name: Interface to remove. + """ ++ ++ if name == 'default': ++ raise LinstorVolumeManagerError( ++ 'Unable to delete the default interface of a node!' ++ ) ++ + result = self._linstor.netinterface_delete(node_name, name) + errors = self._filter_errors(result) + if errors: +@@ -1532,6 +1571,23 @@ class LinstorVolumeManager(object): + } + return interfaces + ++ def get_node_preferred_interface(self, node_name): ++ """ ++ Get the preferred interface used by a node. ++ :param str node_name: Node name of the interface to get. ++ :rtype: str ++ """ ++ try: ++ nodes = self._linstor.node_list_raise([node_name]).nodes ++ if nodes: ++ properties = nodes[0].props ++ return properties.get('PrefNic', 'default') ++ return nodes ++ except Exception as e: ++ raise LinstorVolumeManagerError( ++ 'Failed to get preferred interface: `{}`'.format(e) ++ ) ++ + def set_node_preferred_interface(self, node_name, name): + """ + Set the preferred interface to use on a node. +@@ -1588,8 +1644,8 @@ class LinstorVolumeManager(object): + capacity *= 1024 + + storage_pools[pool.node_name].append({ +- 'storage-pool-name': pool.name, +- 'uuid': pool.uuid, ++ 'name': pool.name, ++ 'linstor-uuid': pool.uuid, + 'free-size': size, + 'capacity': capacity + }) +@@ -1602,16 +1658,19 @@ class LinstorVolumeManager(object): + :rtype: dict(str, list) + """ + resources = {} +- resource_list = self._linstor.resource_list_raise() ++ resource_list = self._get_resource_cache() ++ volume_names = self.get_volumes_with_name() + for resource in resource_list.resources: + if resource.name not in resources: +- resources[resource.name] = {} ++ resources[resource.name] = { 'nodes': {}, 'uuid': '' } ++ resource_nodes = resources[resource.name]['nodes'] + +- resources[resource.name][resource.node_name] = { ++ resource_nodes[resource.node_name] = { + 'volumes': [], + 'diskful': linstor.consts.FLAG_DISKLESS not in resource.flags, + 'tie-breaker': linstor.consts.FLAG_TIE_BREAKER in resource.flags + } ++ resource_volumes = resource_nodes[resource.node_name]['volumes'] + + for volume in resource.volumes: + # We ignore diskless pools of the form "DfltDisklessStorPool". +@@ -1630,17 +1689,17 @@ class LinstorVolumeManager(object): + else: + allocated_size *= 1024 + +- resources[resource.name][resource.node_name]['volumes'].append({ +- 'storage-pool-name': volume.storage_pool_name, +- 'uuid': volume.uuid, +- 'number': volume.number, +- 'device-path': volume.device_path, +- 'usable-size': usable_size, +- 'allocated-size': allocated_size +- }) ++ resource_volumes.append({ ++ 'storage-pool-name': volume.storage_pool_name, ++ 'linstor-uuid': volume.uuid, ++ 'number': volume.number, ++ 'device-path': volume.device_path, ++ 'usable-size': usable_size, ++ 'allocated-size': allocated_size ++ }) + + for resource_state in resource_list.resource_states: +- resource = resources[resource_state.rsc_name][resource_state.node_name] ++ resource = resources[resource_state.rsc_name]['nodes'][resource_state.node_name] + resource['in-use'] = resource_state.in_use + + volumes = resource['volumes'] +@@ -1649,6 +1708,11 @@ class LinstorVolumeManager(object): + if volume: + volume['disk-state'] = volume_state.disk_state + ++ for volume_uuid, volume_name in volume_names.items(): ++ resource = resources.get(volume_name) ++ if resource: ++ resource['uuid'] = volume_uuid ++ + return resources + + def get_database_path(self): +@@ -1659,6 +1723,16 @@ class LinstorVolumeManager(object): + """ + return self._request_database_path(self._linstor) + ++ @classmethod ++ def get_all_group_names(cls, base_name): ++ """ ++ Get all group names. I.e. list of current group + HA. ++ :param str base_name: The SR group_name to use. ++ :return: List of group names. ++ :rtype: list ++ """ ++ return [cls._build_group_name(base_name), cls._build_ha_group_name(base_name)] ++ + @classmethod + def create_sr( + cls, group_name, ips, redundancy, +@@ -1744,8 +1818,8 @@ class LinstorVolumeManager(object): + driver_pool_name = group_name + base_group_name = group_name + group_name = cls._build_group_name(group_name) +- pools = lin.storage_pool_list_raise(filter_by_stor_pools=[group_name]) +- pools = pools.storage_pools ++ storage_pool_name = group_name ++ pools = lin.storage_pool_list_raise(filter_by_stor_pools=[storage_pool_name]).storage_pools + if pools: + existing_node_names = [pool.node_name for pool in pools] + raise LinstorVolumeManagerError( +@@ -1754,7 +1828,7 @@ class LinstorVolumeManager(object): + ) + + if lin.resource_group_list_raise( +- [group_name] ++ cls.get_all_group_names(base_group_name) + ).resource_groups: + if not lin.resource_dfn_list_raise().resource_definitions: + backup_path = cls._create_database_backup_path() +@@ -1791,7 +1865,7 @@ class LinstorVolumeManager(object): + + result = lin.storage_pool_create( + node_name=node_name, +- storage_pool_name=group_name, ++ storage_pool_name=storage_pool_name, + storage_driver='LVM_THIN' if thin_provisioning else 'LVM', + driver_pool_name=driver_pool_name + ) +@@ -1807,7 +1881,7 @@ class LinstorVolumeManager(object): + 'Volume group `{}` not found on `{}`. Ignoring...' + .format(group_name, node_name) + ) +- cls._destroy_storage_pool(lin, group_name, node_name) ++ cls._destroy_storage_pool(lin, storage_pool_name, node_name) + else: + error_str = cls._get_error_str(result) + raise LinstorVolumeManagerError( +@@ -1825,49 +1899,28 @@ class LinstorVolumeManager(object): + ) + ) + +- # 2.b. Create resource group. +- rg_creation_attempt = 0 +- while True: +- result = lin.resource_group_create( +- name=group_name, +- place_count=redundancy, +- storage_pool=group_name, +- diskless_on_remaining=False +- ) +- error_str = cls._get_error_str(result) +- if not error_str: +- break +- +- errors = cls._filter_errors(result) +- if cls._check_errors(errors, [linstor.consts.FAIL_EXISTS_RSC_GRP]): +- rg_creation_attempt += 1 +- if rg_creation_attempt < 2: +- try: +- cls._destroy_resource_group(lin, group_name) +- except Exception as e: +- error_str = 'Failed to destroy old and empty RG: {}'.format(e) +- else: +- continue +- +- raise LinstorVolumeManagerError( +- 'Could not create RG `{}`: {}'.format(group_name, error_str) +- ) +- +- # 2.c. Create volume group. +- result = lin.volume_group_create(group_name) +- error_str = cls._get_error_str(result) +- if error_str: +- raise LinstorVolumeManagerError( +- 'Could not create VG `{}`: {}'.format( +- group_name, error_str +- ) +- ) ++ # 2.b. Create resource groups. ++ ha_group_name = cls._build_ha_group_name(base_group_name) ++ cls._create_resource_group( ++ lin, ++ group_name, ++ storage_pool_name, ++ redundancy, ++ True ++ ) ++ cls._create_resource_group( ++ lin, ++ ha_group_name, ++ storage_pool_name, ++ 3, ++ True ++ ) + + # 3. Create the LINSTOR database volume and mount it. + try: + logger('Creating database volume...') + volume_path = cls._create_database_volume( +- lin, group_name, node_names, redundancy, auto_quorum ++ lin, ha_group_name, storage_pool_name, node_names, redundancy, auto_quorum + ) + except LinstorVolumeManagerError as e: + if e.code != LinstorVolumeManagerError.ERR_VOLUME_EXISTS: +@@ -1907,6 +1960,7 @@ class LinstorVolumeManager(object): + logger('Destroying resource group and storage pools after fail...') + try: + cls._destroy_resource_group(lin, group_name) ++ cls._destroy_resource_group(lin, ha_group_name) + except Exception as e2: + logger('Failed to destroy resource group: {}'.format(e2)) + pass +@@ -1914,7 +1968,7 @@ class LinstorVolumeManager(object): + i = min(i, len(node_names) - 1) + while j <= i: + try: +- cls._destroy_storage_pool(lin, group_name, node_names[j]) ++ cls._destroy_storage_pool(lin, storage_pool_name, node_names[j]) + except Exception as e2: + logger('Failed to destroy resource group: {}'.format(e2)) + pass +@@ -1952,7 +2006,7 @@ class LinstorVolumeManager(object): + def build_volume_name(cls, base_name): + """ + Build a volume name given a base name (i.e. a UUID). +- :param str volume_name: The volume name to use. ++ :param str base_name: The volume name to use. + :return: A valid or not device path. + :rtype: str + """ +@@ -2031,7 +2085,7 @@ class LinstorVolumeManager(object): + resource_names = set() + dfns = self._linstor.resource_dfn_list_raise().resource_definitions + for dfn in dfns: +- if dfn.resource_group_name == self._group_name and ( ++ if dfn.resource_group_name in self.get_all_group_names(self._base_group_name) and ( + ignore_deleted or + linstor.consts.FLAG_DELETE not in dfn.flags + ): +@@ -2149,27 +2203,54 @@ class LinstorVolumeManager(object): + return self._storage_pools + + def _create_volume( +- self, volume_uuid, volume_name, size, place_resources ++ self, ++ volume_uuid, ++ volume_name, ++ size, ++ place_resources, ++ high_availability + ): + size = self.round_up_volume_size(size) + self._mark_resource_cache_as_dirty() + ++ group_name = self._ha_group_name if high_availability else self._group_name + def create_definition(): +- self._check_volume_creation_errors( +- self._linstor.resource_group_spawn( +- rsc_grp_name=self._group_name, +- rsc_dfn_name=volume_name, +- vlm_sizes=['{}B'.format(size)], +- definitions_only=True +- ), +- volume_uuid, +- self._group_name +- ) ++ first_attempt = True ++ while True: ++ try: ++ self._check_volume_creation_errors( ++ self._linstor.resource_group_spawn( ++ rsc_grp_name=group_name, ++ rsc_dfn_name=volume_name, ++ vlm_sizes=['{}B'.format(size)], ++ definitions_only=True ++ ), ++ volume_uuid, ++ self._group_name ++ ) ++ break ++ except LinstorVolumeManagerError as e: ++ if ( ++ not first_attempt or ++ not high_availability or ++ e.code != LinstorVolumeManagerError.ERR_GROUP_NOT_EXISTS ++ ): ++ raise ++ ++ first_attempt = False ++ self._create_resource_group( ++ self._linstor, ++ group_name, ++ self._group_name, ++ 3, ++ True ++ ) ++ + self._configure_volume_peer_slots(self._linstor, volume_name) + + def clean(): + try: +- self._destroy_volume(volume_uuid, force=True) ++ self._destroy_volume(volume_uuid, force=True, preserve_properties=True) + except Exception as e: + self._logger( + 'Unable to destroy volume {} after creation fail: {}' +@@ -2201,7 +2282,12 @@ class LinstorVolumeManager(object): + util.retry(create, maxretry=5) + + def _create_volume_with_properties( +- self, volume_uuid, volume_name, size, place_resources ++ self, ++ volume_uuid, ++ volume_name, ++ size, ++ place_resources, ++ high_availability + ): + if self.check_volume_exists(volume_uuid): + raise LinstorVolumeManagerError( +@@ -2230,7 +2316,11 @@ class LinstorVolumeManager(object): + volume_properties[self.PROP_VOLUME_NAME] = volume_name + + self._create_volume( +- volume_uuid, volume_name, size, place_resources ++ volume_uuid, ++ volume_name, ++ size, ++ place_resources, ++ high_availability + ) + + assert volume_properties.namespace == \ +@@ -2331,7 +2421,7 @@ class LinstorVolumeManager(object): + break + self._destroy_resource(resource_name) + +- def _destroy_volume(self, volume_uuid, force=False): ++ def _destroy_volume(self, volume_uuid, force=False, preserve_properties=False): + volume_properties = self._get_volume_properties(volume_uuid) + try: + volume_name = volume_properties.get(self.PROP_VOLUME_NAME) +@@ -2339,7 +2429,8 @@ class LinstorVolumeManager(object): + self._destroy_resource(volume_name, force) + + # Assume this call is atomic. +- volume_properties.clear() ++ if not preserve_properties: ++ volume_properties.clear() + except Exception as e: + raise LinstorVolumeManagerError( + 'Cannot destroy volume `{}`: {}'.format(volume_uuid, e) +@@ -2578,7 +2669,7 @@ class LinstorVolumeManager(object): + ), None) + except Exception as e: + raise LinstorVolumeManagerError( +- 'Unable to get resources during database creation: {}' ++ 'Unable to fetch database resource: {}' + .format(e) + ) + +@@ -2599,7 +2690,7 @@ class LinstorVolumeManager(object): + + @classmethod + def _create_database_volume( +- cls, lin, group_name, node_names, redundancy, auto_quorum ++ cls, lin, group_name, storage_pool_name, node_names, redundancy, auto_quorum + ): + try: + dfns = lin.resource_dfn_list_raise().resource_definitions +@@ -2621,7 +2712,7 @@ class LinstorVolumeManager(object): + # I don't understand why but this command protect against this bug. + try: + pools = lin.storage_pool_list_raise( +- filter_by_stor_pools=[group_name] ++ filter_by_stor_pools=[storage_pool_name] + ) + except Exception as e: + raise LinstorVolumeManagerError( +@@ -2630,8 +2721,8 @@ class LinstorVolumeManager(object): + ) + + # Ensure we have a correct list of storage pools. +- nodes_with_pool = [pool.node_name for pool in pools.storage_pools] +- assert nodes_with_pool # We must have at least one storage pool! ++ assert pools.storage_pools # We must have at least one storage pool! ++ nodes_with_pool = list(map(lambda pool: pool.node_name, pools.storage_pools)) + for node_name in nodes_with_pool: + assert node_name in node_names + util.SMlog('Nodes with storage pool: {}'.format(nodes_with_pool)) +@@ -2663,7 +2754,7 @@ class LinstorVolumeManager(object): + resources.append(linstor.ResourceData( + node_name=node_name, + rsc_name=DATABASE_VOLUME_NAME, +- storage_pool=group_name ++ storage_pool=storage_pool_name + )) + # Create diskless resources on the remaining set. + for node_name in diskful_nodes[redundancy:] + diskless_nodes: +@@ -2825,6 +2916,55 @@ class LinstorVolumeManager(object): + # after LINSTOR database volume destruction. + return util.retry(destroy, maxretry=10) + ++ @classmethod ++ def _create_resource_group( ++ cls, ++ lin, ++ group_name, ++ storage_pool_name, ++ redundancy, ++ destroy_old_group ++ ): ++ rg_creation_attempt = 0 ++ while True: ++ result = lin.resource_group_create( ++ name=group_name, ++ place_count=redundancy, ++ storage_pool=storage_pool_name, ++ diskless_on_remaining=False ++ ) ++ error_str = cls._get_error_str(result) ++ if not error_str: ++ break ++ ++ errors = cls._filter_errors(result) ++ if destroy_old_group and cls._check_errors(errors, [ ++ linstor.consts.FAIL_EXISTS_RSC_GRP ++ ]): ++ rg_creation_attempt += 1 ++ if rg_creation_attempt < 2: ++ try: ++ cls._destroy_resource_group(lin, group_name) ++ except Exception as e: ++ error_str = 'Failed to destroy old and empty RG: {}'.format(e) ++ else: ++ continue ++ ++ raise LinstorVolumeManagerError( ++ 'Could not create RG `{}`: {}'.format( ++ group_name, error_str ++ ) ++ ) ++ ++ result = lin.volume_group_create(group_name) ++ error_str = cls._get_error_str(result) ++ if error_str: ++ raise LinstorVolumeManagerError( ++ 'Could not create VG `{}`: {}'.format( ++ group_name, error_str ++ ) ++ ) ++ + @classmethod + def _destroy_resource_group(cls, lin, group_name): + def destroy(): +@@ -2849,6 +2989,12 @@ class LinstorVolumeManager(object): + # `VG/LV`. "/" is not accepted by LINSTOR. + return '{}{}'.format(cls.PREFIX_SR, base_name.replace('/', '_')) + ++ # Used to store important data in a HA context, ++ # i.e. a replication count of 3. ++ @classmethod ++ def _build_ha_group_name(cls, base_name): ++ return '{}{}'.format(cls.PREFIX_HA, base_name.replace('/', '_')) ++ + @classmethod + def _check_volume_creation_errors(cls, result, volume_uuid, group_name): + errors = cls._filter_errors(result) +@@ -2861,6 +3007,13 @@ class LinstorVolumeManager(object): + LinstorVolumeManagerError.ERR_VOLUME_EXISTS + ) + ++ if cls._check_errors(errors, [linstor.consts.FAIL_NOT_FOUND_RSC_GRP]): ++ raise LinstorVolumeManagerError( ++ 'Failed to create volume `{}` from SR `{}`, resource group doesn\'t exist' ++ .format(volume_uuid, group_name), ++ LinstorVolumeManagerError.ERR_GROUP_NOT_EXISTS ++ ) ++ + if errors: + raise LinstorVolumeManagerError( + 'Failed to create volume `{}` from SR `{}`: {}'.format( +diff --git a/drivers/tapdisk-pause b/drivers/tapdisk-pause +index 75328757..f98257a2 100755 +--- a/drivers/tapdisk-pause ++++ b/drivers/tapdisk-pause +@@ -30,6 +30,7 @@ import vhdutil + import lvmcache + + try: ++ from linstorvhdutil import LinstorVhdUtil + from linstorvolumemanager import get_controller_uri, LinstorVolumeManager + LINSTOR_AVAILABLE = True + except ImportError: +@@ -162,11 +163,12 @@ class Tapdisk: + dconf = session.xenapi.PBD.get_device_config(pbd) + group_name = dconf['group-name'] + +- device_path = LinstorVolumeManager( ++ linstor = LinstorVolumeManager( + get_controller_uri(), + group_name, + logger=util.SMlog +- ).get_device_path(self.vdi_uuid) ++ ) ++ device_path = LinstorVhdUtil(session, linstor).create_chain_paths(self.vdi_uuid) + + if realpath != device_path: + util.SMlog( +diff --git a/tests/mocks/linstor/__init__.py b/mocks/linstor/__init__.py +similarity index 100% +rename from tests/mocks/linstor/__init__.py +rename to mocks/linstor/__init__.py diff --git a/SPECS/sm.spec b/SPECS/sm.spec index bf01fd3f..49ee1dd9 100644 --- a/SPECS/sm.spec +++ b/SPECS/sm.spec @@ -6,7 +6,7 @@ Summary: sm - XCP storage managers Name: sm Version: 3.2.3 -Release: 1.4%{?xsrel}%{?dist} +Release: 1.7%{?xsrel}%{?dist} License: LGPL URL: https://github.com/xapi-project/sm Source0: sm-3.2.3.tar.gz @@ -73,6 +73,7 @@ Patch1025: 0025-feat-LargeBlock-introduce-largeblocksr-51.patch Patch1026: 0026-feat-LVHDSR-add-a-way-to-modify-config-of-LVMs-60.patch Patch1027: 0027-reflect-upstream-changes-in-our-tests.patch Patch1028: 0028-CA-398425-correctly-check-for-multiple-targets-in-iS.patch +Patch1029: 0029-Synchronization-with-8.2-LINSTOR-before-a-stable-rel.patch %description This package contains storage backends used in XCP @@ -384,6 +385,18 @@ Manager and some other packages %changelog +* Mon Sep 09 2024 Ronan Abhamon - 3.2.3-1.7 +- Import 8.2 LINSTOR changes on 8.3: +- Robustify HA: use a specific group with a replication count of 3 +- Export helpers in linstor-manager regarding network interfaces +- Improve health-check helper: more details and simple API +- Fix pause/unpause: always load a valid VHD chain +- Robustify remote "vhdutil check" command +- Robustify SR destruction +- Prevent diskless destruction on master host +- Prevent tiebreaker destruction +- Reduce LINSTOR vhdutil queries + * Tue Sep 03 2024 Samuel Verschelde - 3.2.3-1.4 - Add 0028-CA-398425-correctly-check-for-multiple-targets-in-iS.patch - Restore the sr_health_check service and the code which goes with it.