Support shared_targets tristate value

Cinder microversion 3.69 adds an additional value to shared_targets
beyond true and false.  Now null/None is also a valid value that can be
used to force locking.

So we now have 3 possible values:

- True ==> Lock if iSCSI initiator doesn't support manual scans
- False ==> Never lock.
- None ==> Always lock.

This patch updates the guard_connection context manager to support the
3 possible values.

With this Cinder can now force locking for NVMe-oF drivers that share
subsystems.

Closes-Bug: #1961102
Depends-On: I8cda6d9830f39e27ac700b1d8796fe0489fd7c0a
Change-Id: Id872543ce08c934cefbbbdaff6ddc61e3828b1f1
This commit is contained in:
Gorka Eguileor 2022-05-11 12:15:27 +02:00
parent 05a4c05c14
commit 1cb6d3e1f1
3 changed files with 30 additions and 3 deletions

View File

@ -36,8 +36,17 @@ ISCSI_SUPPORTS_MANUAL_SCAN = check_manual_scan()
@contextlib.contextmanager
def guard_connection(device):
"""Context Manager handling locks for attach/detach operations."""
if ISCSI_SUPPORTS_MANUAL_SCAN or not device.get('shared_targets'):
"""Context Manager handling locks for attach/detach operations.
In Cinder microversion 3.69 the shared_targets field for volumes are
tristate:
- True ==> Lock if iSCSI initiator doesn't support manual scans
- False ==> Never lock.
- None ==> Always lock.
"""
shared = device.get('shared_targets', False)
if (shared is not None and ISCSI_SUPPORTS_MANUAL_SCAN) or shared is False:
yield
else:
# Cinder passes an OVO, but Nova passes a dictionary, so we use dict

View File

@ -47,6 +47,16 @@ class InitiatorUtilsTestCase(base.TestCase):
with utils.guard_connection({'shared_targets': True}):
mock_lock.assert_not_called()
@mock.patch('oslo_concurrency.lockutils.lock')
def test_guard_connection_manual_scan_support_forced(self, mock_lock):
"""Guard locks when cinder forces locking."""
utils.ISCSI_SUPPORTS_MANUAL_SCAN = True
# We confirm that shared_targets is ignored
with utils.guard_connection({'service_uuid': mock.sentinel.uuid,
'shared_targets': None}):
mock_lock.assert_called_once_with(mock.sentinel.uuid, 'os-brick-',
external=True)
@mock.patch('oslo_concurrency.lockutils.lock')
def test_guard_connection_manual_scan_unsupported_not_shared(self,
mock_lock):
@ -55,7 +65,7 @@ class InitiatorUtilsTestCase(base.TestCase):
mock_lock.assert_not_called()
@mock.patch('oslo_concurrency.lockutils.lock')
def test_guard_connection_manual_scan_unsupported_hared(self, mock_lock):
def test_guard_connection_manual_scan_unsupported_shared(self, mock_lock):
utils.ISCSI_SUPPORTS_MANUAL_SCAN = False
with utils.guard_connection({'service_uuid': mock.sentinel.uuid,
'shared_targets': True}):

View File

@ -0,0 +1,8 @@
---
fixes:
- |
NVMe-oF connector `bug #1961102
<https://bugs.launchpad.net/os-brick/+bug/1961102>`_: Fixed leaving
controller devices (i.e., /dev/nvme0) behind on hosts. Now NVMe-oF
subsytems are disconnected when disconnecting volumes if the subsytem
doesn't have additional volumes present in the host.