Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
1d58bcd
Update xs-sm.service's description for XCP-ng
stormi Aug 13, 2020
e0ce6f7
feat(drivers): add CephFS and GlusterFS drivers
Wescoeur Jul 20, 2020
c3bc204
feat(drivers): add XFS driver
Wescoeur Jul 20, 2020
293a234
feat(drivers): add ZFS driver to avoid losing VDI metadata (xcp-ng/xc…
Wescoeur Aug 12, 2020
615a18a
feat(drivers): add LinstorSR driver
Wescoeur Mar 16, 2020
7f888a1
feat(tests): add unit tests concerning ZFS (close xcp-ng/xcp#425)
Wescoeur Oct 27, 2020
74a37d4
Added SM Driver for MooseFS
xandrus Jan 29, 2021
e4e9ad5
Avoid usage of `umount` in `ISOSR` when `legacy_mode` is used
Wescoeur Dec 2, 2021
a832e8f
MooseFS SR uses now UUID subdirs for each SR
Wescoeur May 18, 2022
45b0f38
Fix is_open call for many drivers (#25)
Wescoeur Jun 23, 2022
5a88219
Remove SR_CACHING capability for many SR types (#24)
Wescoeur Jun 23, 2022
93dcae8
Fix code coverage regarding MooseFSSR and ZFSSR (#29)
Wescoeur Sep 19, 2022
247e2f5
py3: simple changes from futurize on XCP-ng drivers
ydirson Mar 8, 2023
5b9bf26
py3: futurize fix of xmlrpc calls for CephFS, GlusterFS, MooseFS, Lin…
ydirson Mar 8, 2023
6e2b833
py3: use of integer division operator
ydirson Mar 8, 2023
27901c3
test_on_slave: allow to work with SR using absolute PROBE_MOUNTPOINT
ydirson Mar 8, 2023
7a9d771
py3: switch interpreter to python3
ydirson Mar 27, 2023
ce9e62b
Support recent version of coverage tool
Wescoeur May 4, 2023
f3df781
feat(LinstorSR): import all 8.2 changes
Wescoeur Nov 20, 2020
69d2892
feat(LinstorSR): is now compatible with python 3
Wescoeur Jun 30, 2023
18466cc
Remove `SR_PROBE` from ZFS capabilities (#36)
benjamreis Aug 4, 2023
1ca799b
Repair coverage to be compatible with 8.3 test env
Wescoeur Sep 22, 2023
9e3cce7
Support IPv6 in Ceph Driver
benjamreis Sep 25, 2023
ed49d18
lvutil: use wipefs not dd to clear existing signatures (xapi-project#…
ydirson Jul 5, 2023
5de21ca
feat(LargeBlock): introduce largeblocksr (#51)
Nambrok Apr 12, 2024
c41e021
feat(LVHDSR): add a way to modify config of LVMs (#60)
Wescoeur Jul 30, 2024
a68dcc4
reflect upstream changes in our tests
benjamreis Aug 13, 2024
1309f7c
Synchronization with 8.2 LINSTOR before a stable release (#68)
Wescoeur Sep 26, 2024
ad442b0
fix(LinstorSR): sync fork-load-daemon with http-nbd-transfer (v1.5.0)…
Wescoeur Nov 28, 2024
261733a
fix(LinstorSR): simplify _kick_gc code using systemd service
Wescoeur Apr 10, 2025
cad401f
fix(LinstorSR): imitate the CA-400106 change
Wescoeur Apr 10, 2025
263a17f
fix(linstorvhdutil): coalesce helper returns the sector count now
Wescoeur Dec 11, 2024
d2337fe
Prevent wrong mypy error regarding `_linstor` member not set
Wescoeur Oct 16, 2024
6e3b3c5
Fix many invalid escape sequences
Wescoeur Oct 11, 2024
132f8c9
Fix many invalid escape sequences on regexes
Wescoeur Oct 11, 2024
a660830
Fix override of FileSR.attach
Wescoeur Oct 14, 2024
aa419c4
Fix override of BaseISCSISR.detach
Wescoeur Oct 15, 2024
d7a1b57
Fix override of VDI.delete in many subclasses
Wescoeur Oct 15, 2024
68a4cf8
Fix override of `VDI._do_snapshot`
Wescoeur Oct 16, 2024
9a5320f
Fix override of VDI.load in LVHDVDI cleanup.py
Wescoeur Oct 22, 2024
3e029a5
Use a specific var for NFS options in ISOSR.attach
Wescoeur Oct 16, 2024
f7f58b9
Modernize Lock class using `staticmethod` decorator
Wescoeur Oct 15, 2024
8830bb8
Modernize GC using `staticmethod` decorator
Wescoeur Oct 15, 2024
47e0a27
Modernize RefCounter using `staticmethod` decorator
Wescoeur Oct 15, 2024
07167d8
Simplify FakeSMBSR implementation (remove member vars in class)
Wescoeur Oct 21, 2024
e4eb10c
Use `for session` instead of `for e`
Wescoeur Oct 21, 2024
e3aa564
Fix util.SRtoXML calls in many drivers
Wescoeur Oct 16, 2024
e489d39
Replace `Dict` variable with `info` in `LVHDSR`
Wescoeur Oct 16, 2024
740076a
Prevent mypy errors when a variable type is changed in `BaseISCSISR`
Wescoeur Oct 16, 2024
114c7ab
Prevent bad mypy error in TestMultiLUNISCSISR using formatted-string
Wescoeur Oct 16, 2024
e6d0d7e
Count correctly IQN sessions during ISCSISR attach
Wescoeur Oct 21, 2024
cc37e7f
Use importlib instead of imp which is deprecated in python 3.4
Wescoeur Oct 10, 2024
2a7e2b3
Replace deprecated calls to distutils.spawn.find_executable
Wescoeur Oct 11, 2024
d6a7039
Replace deprecated calls to distutils.util.strtobool
Wescoeur Oct 11, 2024
f787ebb
Fix _locked_load calls compatibility with python 3.10
Wescoeur Oct 11, 2024
de0611f
Use static analysis tool (mypy)
Wescoeur Oct 11, 2024
4404225
Add mypy stubs
Nambrok Oct 9, 2024
0221694
Use `override` everywhere!
Wescoeur Nov 8, 2024
5658b6c
Makefile fix: don't execute precheck during installation
Wescoeur Nov 7, 2024
44d8cf5
Fix LVHDSR.load: set other_conf in cond-branch to prevent mypy error
Wescoeur Jan 8, 2025
31c760e
fix(cleanup.py): protect LinstorSR init against race condition (#79)
Wescoeur Jan 9, 2025
97ef3f8
Fix filter to reject other device types (#77)
Nambrok Jan 9, 2025
1921c52
fix(cleanup.py): resize on a primary host (#82)
Wescoeur Feb 17, 2025
4706f33
chore(.github/workflows): use ubuntu-24.04
Wescoeur Apr 22, 2025
ae3a4c1
Fix warns reported by new github workflow
Wescoeur Apr 22, 2025
7a631e6
Improve LinstorSR.py to handle `thick` SR creation (#85)
rushikeshjadhav Jun 25, 2025
09caac2
Fix LINSTOR satellite LS_KEEP_RES regex
Wescoeur Jul 14, 2025
654ffc1
fix(LinstorSR): Correctly reference a variable exception (#91)
Nambrok Aug 19, 2025
a57ddcd
Fix GC hidden attribute in case of SIGTERM signal (#87)
Wescoeur Aug 19, 2025
6dbec46
fix(LinstorSR): robustify DB umount call
Wescoeur Jul 8, 2025
d4b46be
feat(Linstor): rewrite linstorhostcall logic
Nambrok Apr 19, 2024
4cfae54
feat(linstor): Add new debug log in linstorhostcall (#67)
Nambrok Aug 9, 2024
ca5b52d
fix(linstor): subsequent fixes for linstorhostcall
Millefeuille42 Aug 11, 2025
921f385
Fix tests of "CP-51843: add unit tests for setup_cache"
Wescoeur Aug 28, 2025
3579d92
feat: add caching functions for controller_uri
Millefeuille42 Mar 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,34 @@ name: Test SM
on: [push, pull_request]

jobs:
static-analysis:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Python 3
uses: actions/setup-python@v4
with:
python-version: '3.x'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r dev_requirements_static_analysis.txt

- name: mypy
run: |
mypy .

build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v3
- name: Set up Python 3
uses: actions/setup-python@v4
with:
python-version: '3.6'
python-version: '3.x'

- name: Install dependencies
run: |
Expand Down
3 changes: 3 additions & 0 deletions .mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[mypy]
enable_error_code = explicit-override

34 changes: 31 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ SM_DRIVERS += Dummy
SM_DRIVERS += udev
SM_DRIVERS += ISO
SM_DRIVERS += HBA
SM_DRIVERS += Linstor
SM_DRIVERS += LVHD
SM_DRIVERS += LVHDoISCSI
SM_DRIVERS += LVHDoHBA
SM_DRIVERS += SHM
SM_DRIVERS += SMB
SM_DRIVERS += LVHDoFCoE
SM_DRIVERS += CephFS
SM_DRIVERS += GlusterFS
SM_DRIVERS += XFS
SM_DRIVERS += ZFS
SM_DRIVERS += MooseFS
SM_DRIVERS += LargeBlock

SM_LIBS := SR
SM_LIBS += SRCommand
Expand All @@ -27,6 +34,9 @@ SM_LIBS += verifyVHDsOnSR
SM_LIBS += scsiutil
SM_LIBS += scsi_host_rescan
SM_LIBS += vhdutil
SM_LIBS += linstorjournaler
SM_LIBS += linstorvhdutil
SM_LIBS += linstorvolumemanager
SM_LIBS += lvhdutil
SM_LIBS += cifutils
SM_LIBS += xs_errors
Expand Down Expand Up @@ -77,6 +87,7 @@ PLUGIN_SCRIPT_DEST := /etc/xapi.d/plugins/
LIBEXEC := /opt/xensource/libexec/
UDEV_RULES_DIR := /etc/udev/rules.d/
UDEV_SCRIPTS_DIR := /etc/udev/scripts/
SYSTEMD_CONF_DIR := /etc/systemd/system/
SYSTEMD_SERVICE_DIR := /usr/lib/systemd/system/
INIT_DIR := /etc/rc.d/init.d/
MPATH_CONF_DIR := /etc/multipath.xenserver/
Expand All @@ -92,7 +103,8 @@ SM_PY_FILES = $(foreach LIB, $(SM_LIBS), drivers/$(LIB).py) $(foreach DRIVER, $(

.PHONY: build
build:
make -C dcopy
make -C dcopy
make -C linstor

.PHONY: precommit
precommit: build
Expand All @@ -115,14 +127,17 @@ precheck: build
echo "Precheck succeeded with no outstanding issues found."

.PHONY: install
install: precheck
install: build
mkdir -p $(SM_STAGING)
$(call mkdir_clean,$(SM_STAGING))
mkdir -p $(SM_STAGING)$(SM_DEST)
mkdir -p $(SM_STAGING)$(SM_DEST)/plugins
mkdir -p $(SM_STAGING)$(UDEV_RULES_DIR)
mkdir -p $(SM_STAGING)$(UDEV_SCRIPTS_DIR)
mkdir -p $(SM_STAGING)$(INIT_DIR)
mkdir -p $(SM_STAGING)$(SYSTEMD_CONF_DIR)
mkdir -p $(SM_STAGING)$(SYSTEMD_CONF_DIR)/drbd-reactor.service.d
mkdir -p $(SM_STAGING)$(SYSTEMD_CONF_DIR)/linstor-satellite.service.d
mkdir -p $(SM_STAGING)$(SYSTEMD_SERVICE_DIR)
mkdir -p $(SM_STAGING)$(MPATH_CONF_DIR)
mkdir -p $(SM_STAGING)$(MPATH_CUSTOM_CONF_DIR)
Expand Down Expand Up @@ -151,6 +166,12 @@ install: precheck
$(SM_STAGING)/$(SM_DEST)
install -m 644 etc/logrotate.d/$(SMLOG_CONF) \
$(SM_STAGING)/$(LOGROTATE_DIR)
install -m 644 etc/systemd/system/drbd-reactor.service.d/override.conf \
$(SM_STAGING)/$(SYSTEMD_CONF_DIR)/drbd-reactor.service.d/
install -m 644 etc/systemd/system/linstor-satellite.service.d/override.conf \
$(SM_STAGING)/$(SYSTEMD_CONF_DIR)/linstor-satellite.service.d/
install -m 644 etc/systemd/system/var-lib-linstor.service \
$(SM_STAGING)/$(SYSTEMD_CONF_DIR)
install -m 644 etc/make-dummy-sr.service \
$(SM_STAGING)/$(SYSTEMD_SERVICE_DIR)
install -m 644 systemd/xs-sm.service \
Expand All @@ -169,6 +190,8 @@ install: precheck
$(SM_STAGING)/$(SYSTEMD_SERVICE_DIR)
install -m 644 systemd/[email protected] \
$(SM_STAGING)/$(SYSTEMD_SERVICE_DIR)
install -m 644 systemd/linstor-monitor.service \
$(SM_STAGING)/$(SYSTEMD_SERVICE_DIR)
for i in $(UDEV_RULES); do \
install -m 644 udev/$$i.rules \
$(SM_STAGING)$(UDEV_RULES_DIR); done
Expand All @@ -186,6 +209,7 @@ install: precheck
cd $(SM_STAGING)$(SM_DEST) && rm -f LVHDoFCoESR && ln -sf LVHDoFCoESR.py LVMoFCoESR
ln -sf $(SM_DEST)mpathutil.py $(SM_STAGING)/sbin/mpathutil
install -m 755 drivers/02-vhdcleanup $(SM_STAGING)$(MASTER_SCRIPT_DEST)
install -m 755 drivers/linstor-manager $(SM_STAGING)$(PLUGIN_SCRIPT_DEST)
install -m 755 drivers/lvhd-thin $(SM_STAGING)$(PLUGIN_SCRIPT_DEST)
install -m 755 drivers/on_slave.py $(SM_STAGING)$(PLUGIN_SCRIPT_DEST)/on-slave
install -m 755 drivers/testing-hooks $(SM_STAGING)$(PLUGIN_SCRIPT_DEST)
Expand All @@ -197,6 +221,9 @@ install: precheck
install -m 755 drivers/iscsilib.py $(SM_STAGING)$(SM_DEST)
install -m 755 drivers/fcoelib.py $(SM_STAGING)$(SM_DEST)
mkdir -p $(SM_STAGING)$(LIBEXEC)
install -m 755 scripts/fork-log-daemon $(SM_STAGING)$(LIBEXEC)
install -m 755 scripts/linstor-kv-tool $(SM_STAGING)$(BIN_DEST)
install -m 755 scripts/safe-umount $(SM_STAGING)$(LIBEXEC)
install -m 755 scripts/local-device-change $(SM_STAGING)$(LIBEXEC)
install -m 755 scripts/check-device-sharing $(SM_STAGING)$(LIBEXEC)
install -m 755 scripts/usb_change $(SM_STAGING)$(LIBEXEC)
Expand All @@ -205,6 +232,8 @@ install: precheck
mkdir -p $(SM_STAGING)/etc/xapi.d/xapi-pre-shutdown/
install -m 755 scripts/stop_all_gc $(SM_STAGING)/etc/xapi.d/xapi-pre-shutdown/
$(MAKE) -C dcopy install DESTDIR=$(SM_STAGING)
$(MAKE) -C linstor install DESTDIR=$(SM_STAGING)
$(MAKE) -C sm_typing install DESTDIR=$(SM_STAGING)
ln -sf $(SM_DEST)blktap2.py $(SM_STAGING)$(BIN_DEST)/blktap2
ln -sf $(SM_DEST)lcache.py $(SM_STAGING)$(BIN_DEST)tapdisk-cache-stats
ln -sf /dev/null $(SM_STAGING)$(UDEV_RULES_DIR)/69-dm-lvm-metad.rules
Expand All @@ -215,4 +244,3 @@ install: precheck
.PHONY: clean
clean:
rm -rf $(SM_STAGING)

5 changes: 3 additions & 2 deletions dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
coverage
astroid==2.3.3
pylint==2.4.4
astroid
pylint
bitarray
python-linstor
3 changes: 3 additions & 0 deletions dev_requirements_static_analysis.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bitarray
mypy
python-linstor
58 changes: 36 additions & 22 deletions drivers/BaseISCSI.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
# ISCSISR: ISCSI software initiator SR driver
#

from sm_typing import override

import SR
import VDI
import util
import time
import LUNperVDI
Expand Down Expand Up @@ -100,11 +103,12 @@ def address(self):
self._initPaths()
return self._address

def handles(type):
@override
@staticmethod
def handles(type) -> bool:
return False
handles = staticmethod(handles)

def _synchroniseAddrList(self, addrlist):
def _synchroniseAddrList(self, addrlist) -> None:
if not self.multihomed:
return
change = False
Expand Down Expand Up @@ -133,7 +137,8 @@ def _synchroniseAddrList(self, addrlist):
except:
pass

def load(self, sr_uuid):
@override
def load(self, sr_uuid) -> None:
if self.force_tapdisk:
self.sr_vditype = 'aio'
else:
Expand Down Expand Up @@ -175,23 +180,23 @@ def load(self, sr_uuid):
and ('chappassword' in self.dconf or 'chappassword_secret' in self.dconf):
self.chapuser = self.dconf['chapuser'].encode('utf-8')
if 'chappassword_secret' in self.dconf:
self.chappassword = util.get_secret(self.session, self.dconf['chappassword_secret'])
chappassword = util.get_secret(self.session, self.dconf['chappassword_secret'])
else:
self.chappassword = self.dconf['chappassword']
chappassword = self.dconf['chappassword']

self.chappassword = self.chappassword.encode('utf-8')
self.chappassword = chappassword.encode('utf-8')

self.incoming_chapuser = ""
self.incoming_chappassword = ""
if 'incoming_chapuser' in self.dconf \
and ('incoming_chappassword' in self.dconf or 'incoming_chappassword_secret' in self.dconf):
self.incoming_chapuser = self.dconf['incoming_chapuser'].encode('utf-8')
if 'incoming_chappassword_secret' in self.dconf:
self.incoming_chappassword = util.get_secret(self.session, self.dconf['incoming_chappassword_secret'])
incoming_chappassword = util.get_secret(self.session, self.dconf['incoming_chappassword_secret'])
else:
self.incoming_chappassword = self.dconf['incoming_chappassword']
incoming_chappassword = self.dconf['incoming_chappassword']

self.incoming_chappassword = self.incoming_chappassword.encode('utf-8')
self.incoming_chappassword = incoming_chappassword.encode('utf-8')

self.port = DEFAULT_PORT
if 'port' in self.dconf and self.dconf['port']:
Expand Down Expand Up @@ -276,7 +281,7 @@ def _initPaths(self):
self._address = self.tgtidx
self._synchroniseAddrList(addrlist)

def _init_adapters(self):
def _init_adapters(self) -> None:
# Generate a list of active adapters
ids = scsiutil._genHostList(ISCSI_PROCNAME)
util.SMlog(ids)
Expand All @@ -293,7 +298,8 @@ def _init_adapters(self):
pass
self._devs = scsiutil.cacheSCSIidentifiers()

def attach(self, sr_uuid):
@override
def attach(self, sr_uuid) -> None:
self._mpathHandle()

multiTargets = False
Expand Down Expand Up @@ -391,10 +397,9 @@ def attach(self, sr_uuid):
util._incr_iscsiSR_refcount(self.targetIQN, sr_uuid)
IQNs = []
if "multiSession" in self.dconf:
IQNs = ""
for iqn in self.dconf['multiSession'].split("|"):
if len(iqn):
IQNs += iqn.split(',')[2]
IQNs.append(iqn.split(',')[2])
else:
IQNs.append(self.targetIQN)

Expand Down Expand Up @@ -433,7 +438,11 @@ def attach(self, sr_uuid):
realdev = os.path.realpath(os.path.join(dev_path, dev))
util.set_scheduler(os.path.basename(realdev))

def detach(self, sr_uuid, delete=False):
@override
def detach(self, sr_uuid) -> None:
self.detach_and_delete(sr_uuid, delete=False)

def detach_and_delete(self, sr_uuid, delete=True) -> None:
keys = []
pbdref = None
try:
Expand Down Expand Up @@ -474,7 +483,8 @@ def detach(self, sr_uuid, delete=False):

self.attached = False

def create(self, sr_uuid, size):
@override
def create(self, sr_uuid, size) -> None:
# Check whether an SR already exists
SRs = self.session.xenapi.SR.get_all_records()
for sr in SRs:
Expand Down Expand Up @@ -503,11 +513,13 @@ def create(self, sr_uuid, size):
self.session.xenapi.SR.set_sm_config(self.sr_ref, self.sm_config)
return

def delete(self, sr_uuid):
@override
def delete(self, sr_uuid) -> None:
self.detach(sr_uuid)
return

def probe(self):
@override
def probe(self) -> str:
SRs = self.session.xenapi.SR.get_all_records()
Recs = {}
for sr in SRs:
Expand All @@ -517,8 +529,9 @@ def probe(self):
sm_config['targetIQN'] == self.targetIQN:
Recs[record["uuid"]] = sm_config
return self.srlist_toxml(Recs)

def scan(self, sr_uuid):

@override
def scan(self, sr_uuid) -> None:
if not self.passthrough:
if not self.attached:
raise xs_errors.XenError('SRUnavailable')
Expand All @@ -530,9 +543,10 @@ def scan(self, sr_uuid):
if vdi.managed:
self.physical_utilisation += vdi.size
self.virtual_allocation = self.physical_utilisation
return super(BaseISCSISR, self).scan(sr_uuid)
super(BaseISCSISR, self).scan(sr_uuid)

def vdi(self, uuid):
@override
def vdi(self, uuid) -> VDI.VDI:
return LUNperVDI.RAWVDI(self, uuid)

def _scan_IQNs(self):
Expand Down
Loading