diff --git a/Auto-detect-readonly-state-for-iblock-devices.patch b/Auto-detect-readonly-state-for-iblock-devices.patch new file mode 100644 index 0000000..cb06d49 --- /dev/null +++ b/Auto-detect-readonly-state-for-iblock-devices.patch @@ -0,0 +1,78 @@ +From 5d1abab36be9375f46210dd19d5293cf73433681 Mon Sep 17 00:00:00 2001 +From: David Disseldorp +Date: Thu, 7 Dec 2017 15:25:35 +0100 +Subject: [PATCH 1/4] Auto-detect readonly state for iblock devices + +Configuring a read-only block device as read-write currently results in +a backstore->enable configfs I/O error, as documented in: +http://www.spinics.net/lists/target-devel/msg16310.html + +This change sees targetcli check the read-only status of the underlying +block device via ioctl(BLKROGET). If a readonly= parameter isn't +provided, then the backstore will use the ioctl(BLKROGET) value as the +default. + +Signed-off-by: David Disseldorp +(cherry picked from commit 1a0886ecbcba6d5b2d9756ecadb3e2eaab99d29e) +--- + targetcli/ui_backstore.py | 30 +++++++++++++++++++++++++++++- + 1 file changed, 29 insertions(+), 1 deletion(-) + +diff --git a/targetcli/ui_backstore.py b/targetcli/ui_backstore.py +index 83673a0..66a21c5 100644 +--- a/targetcli/ui_backstore.py ++++ b/targetcli/ui_backstore.py +@@ -19,6 +19,9 @@ under the License. + + import glob + import os ++import fcntl ++import array ++import struct + import re + import stat + import dbus +@@ -516,6 +519,25 @@ class UIBlockBackstore(UIBackstore): + self.so_cls = UIBlockStorageObject + UIBackstore.__init__(self, 'block', parent) + ++ def _ui_block_ro_check(self, dev): ++ BLKROGET=0x0000125E ++ try: ++ f = os.open(dev, os.O_RDONLY) ++ except (OSError, IOError): ++ raise ExecutionError("Could not open %s" % dev) ++ # ioctl returns an int. Provision a buffer for it ++ buf = array.array('c', [chr(0)] * 4) ++ try: ++ fcntl.ioctl(f, BLKROGET, buf) ++ except (OSError, IOError): ++ os.close(f) ++ return False ++ ++ os.close(f) ++ if struct.unpack('I', buf)[0] == 0: ++ return False ++ return True ++ + def ui_command_create(self, name, dev, readonly=None, wwn=None): + ''' + Creates an Block Storage object. I{dev} is the path to the TYPE_DISK +@@ -523,7 +545,13 @@ class UIBlockBackstore(UIBackstore): + ''' + self.assert_root() + +- readonly = self.ui_eval_param(readonly, 'bool', False) ++ ro_string = self.ui_eval_param(readonly, 'string', None) ++ if ro_string == None: ++ # attempt to detect block device readonly state via ioctl ++ readonly = self._ui_block_ro_check(dev) ++ else: ++ readonly = self.ui_eval_param(readonly, 'bool', False) ++ + wwn = self.ui_eval_param(wwn, 'string', None) + + so = BlockStorageObject(name, dev, readonly=readonly, wwn=wwn) +-- +2.13.6 + diff --git a/Split-out-blockdev-readonly-state-detection-helper.patch b/Split-out-blockdev-readonly-state-detection-helper.patch new file mode 100644 index 0000000..e2ff45c --- /dev/null +++ b/Split-out-blockdev-readonly-state-detection-helper.patch @@ -0,0 +1,80 @@ +From 7374ba0e53d8e6af4abbb02bd60f35ed541b94f5 Mon Sep 17 00:00:00 2001 +From: David Disseldorp +Date: Tue, 10 Apr 2018 16:22:54 +0200 +Subject: [PATCH 3/4] Split out blockdev readonly state detection helper + +So that it can be reused for RBD backstores. + +Signed-off-by: David Disseldorp +--- + targetcli/ui_backstore.py | 40 ++++++++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 20 deletions(-) + +diff --git a/targetcli/ui_backstore.py b/targetcli/ui_backstore.py +index 546d9d2..57dedb1 100644 +--- a/targetcli/ui_backstore.py ++++ b/targetcli/ui_backstore.py +@@ -117,6 +117,25 @@ def complete_path(path, stat_fn): + return sorted(filtered, + key=lambda s: '~'+s if s.endswith('/') else s) + ++def blk_dev_ro_check(dev): ++ BLKROGET=0x0000125E ++ try: ++ f = os.open(dev, os.O_RDONLY) ++ except (OSError, IOError): ++ raise ExecutionError("Could not open %s" % dev) ++ # ioctl returns an int. Provision a buffer for it ++ buf = array.array('b', [0] * 4) ++ try: ++ fcntl.ioctl(f, BLKROGET, buf) ++ except (OSError, IOError): ++ os.close(f) ++ return False ++ ++ os.close(f) ++ if struct.unpack('I', buf)[0] == 0: ++ return False ++ return True ++ + + class UIALUATargetPortGroup(UIRTSLibNode): + ''' +@@ -519,25 +538,6 @@ class UIBlockBackstore(UIBackstore): + self.so_cls = UIBlockStorageObject + UIBackstore.__init__(self, 'block', parent) + +- def _ui_block_ro_check(self, dev): +- BLKROGET=0x0000125E +- try: +- f = os.open(dev, os.O_RDONLY) +- except (OSError, IOError): +- raise ExecutionError("Could not open %s" % dev) +- # ioctl returns an int. Provision a buffer for it +- buf = array.array('b', [0] * 4) +- try: +- fcntl.ioctl(f, BLKROGET, buf) +- except (OSError, IOError): +- os.close(f) +- return False +- +- os.close(f) +- if struct.unpack('I', buf)[0] == 0: +- return False +- return True +- + def ui_command_create(self, name, dev, readonly=None, wwn=None): + ''' + Creates an Block Storage object. I{dev} is the path to the TYPE_DISK +@@ -548,7 +548,7 @@ class UIBlockBackstore(UIBackstore): + ro_string = self.ui_eval_param(readonly, 'string', None) + if ro_string == None: + # attempt to detect block device readonly state via ioctl +- readonly = self._ui_block_ro_check(dev) ++ readonly = blk_dev_ro_check(dev) + else: + readonly = self.ui_eval_param(readonly, 'bool', False) + +-- +2.13.6 + diff --git a/Use-signed-char-instead-of-char.patch b/Use-signed-char-instead-of-char.patch new file mode 100644 index 0000000..c8b04f1 --- /dev/null +++ b/Use-signed-char-instead-of-char.patch @@ -0,0 +1,29 @@ +From 5bfd75f66225fb4127faa2dd14d3c43af9a575a4 Mon Sep 17 00:00:00 2001 +From: Taylor Jakobson +Date: Thu, 1 Feb 2018 14:44:32 -0600 +Subject: [PATCH 2/4] Use signed char instead of char + +Python3 does not have the "character" type, use signed char instead. + +(cherry picked from commit ed5ff9b9505e50b545e86dfbdd32077f0ddda0cb) +Reviewed-by: David Disseldorp +--- + targetcli/ui_backstore.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/targetcli/ui_backstore.py b/targetcli/ui_backstore.py +index 66a21c5..546d9d2 100644 +--- a/targetcli/ui_backstore.py ++++ b/targetcli/ui_backstore.py +@@ -526,7 +526,7 @@ class UIBlockBackstore(UIBackstore): + except (OSError, IOError): + raise ExecutionError("Could not open %s" % dev) + # ioctl returns an int. Provision a buffer for it +- buf = array.array('c', [chr(0)] * 4) ++ buf = array.array('b', [0] * 4) + try: + fcntl.ioctl(f, BLKROGET, buf) + except (OSError, IOError): +-- +2.13.6 + diff --git a/_service b/_service index a560ba9..be5878c 100644 --- a/_service +++ b/_service @@ -4,7 +4,9 @@ https://github.com/open-iscsi/targetcli-fb.git targetcli-fb - 2.1.fb47 + @PARENT_TAG@ + v(\d*\.\d*\.)fb(\d*) + \1\2 v2.1.fb47 enable diff --git a/rbd-support.patch b/rbd-support.patch new file mode 100644 index 0000000..a21a9fa --- /dev/null +++ b/rbd-support.patch @@ -0,0 +1,108 @@ +From dc250fa879939702bdf69e561cb9041a57f997ea Mon Sep 17 00:00:00 2001 +From: Mike Christie +Date: Tue, 10 Apr 2018 17:31:32 +0200 +Subject: [PATCH 4/4] rbd support + +targetcli-fb-rbd.patch obtained from: +https://marc.info/?l=ceph-devel&m=143816209010058 + +[ddiss@suse.de: accept and propagate wwn parameter] +Reviewed-by: David Disseldorp +--- + targetcli/ui_backstore.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +diff --git a/targetcli/ui_backstore.py b/targetcli/ui_backstore.py +index 57dedb1..d576122 100644 +--- a/targetcli/ui_backstore.py ++++ b/targetcli/ui_backstore.py +@@ -29,6 +29,7 @@ import dbus + from configshell_fb import ExecutionError + from rtslib_fb import BlockStorageObject, FileIOStorageObject + from rtslib_fb import PSCSIStorageObject, RDMCPStorageObject, UserBackedStorageObject ++from rtslib_fb import RBDStorageObject + from rtslib_fb import ALUATargetPortGroup + from rtslib_fb import RTSLibError + from rtslib_fb import RTSRoot +@@ -269,6 +270,7 @@ class UIBackstores(UINode): + UIRDMCPBackstore(self) + UIFileIOBackstore(self) + UIBlockBackstore(self) ++ UIRBDBackstore(self) + + for name, iface, prop_dict in self._user_backstores(): + UIUserBackedBackstore(self, name, iface, prop_dict) +@@ -572,6 +574,48 @@ class UIBlockBackstore(UIBackstore): + completions = [completions[0] + ' '] + return completions + ++class UIRBDBackstore(UIBackstore): ++ ''' ++ RBD backstore UI. ++ ''' ++ def __init__(self, parent): ++ self.so_cls = UIRBDStorageObject ++ UIBackstore.__init__(self, 'rbd', parent) ++ ++ def ui_command_create(self, name, dev, readonly=None, wwn=None): ++ ''' ++ Creates an RBD Storage object. I{dev} is the path to the RBD ++ block device to use. ++ ''' ++ self.assert_root() ++ ++ ro_string = self.ui_eval_param(readonly, 'string', None) ++ if ro_string == None: ++ # attempt to detect block device readonly state via ioctl ++ readonly = blk_dev_ro_check(dev) ++ else: ++ readonly = self.ui_eval_param(readonly, 'bool', False) ++ ++ wwn = self.ui_eval_param(wwn, 'string', None) ++ ++ so = RBDStorageObject(name, dev, readonly=readonly, wwn=wwn) ++ ui_so = UIRBDStorageObject(so, self) ++ self.setup_model_alias(so) ++ self.shell.log.info("Created RBD storage object %s using %s." ++ % (name, dev)) ++ return self.new_node(ui_so) ++ ++ def ui_complete_create(self, parameters, text, current_param): ++ ''' ++ Auto-completes the device name ++ ''' ++ if current_param != 'dev': ++ return [] ++ completions = complete_path(text, stat.S_ISBLK) ++ if len(completions) == 1 and not completions[0].endswith('/'): ++ completions = [completions[0] + ' '] ++ return completions ++ + + class UIUserBackedBackstore(UIBackstore): + ''' +@@ -739,6 +783,21 @@ class UIBlockStorageObject(UIStorageObject): + return ("%s (%s) %s%s %s" % (so.udev_path, bytes_to_human(so.size), + ro_str, wb_str, so.status), True) + ++class UIRBDStorageObject(UIStorageObject): ++ def summary(self): ++ so = self.rtsnode ++ ++ if so.write_back: ++ wb_str = "write-back" ++ else: ++ wb_str = "write-thru" ++ ++ ro_str = "" ++ if so.readonly: ++ ro_str = "ro " ++ ++ return ("%s (%s) %s%s %s" % (so.udev_path, bytes_to_human(so.size), ++ ro_str, wb_str, so.status), True) + + class UIUserBackedStorageObject(UIStorageObject): + def summary(self): +-- +2.13.6 + diff --git a/targetcli-fb-2.1.47.tar.xz b/targetcli-fb-2.1.47.tar.xz new file mode 100644 index 0000000..cb9b86d --- /dev/null +++ b/targetcli-fb-2.1.47.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5b7ec8b0984e5f058f237c5b8eaa4d80dbb817f22f5ae45bb9247e1c09f408b +size 29140 diff --git a/targetcli-fb-2.1.fb47.tar.xz b/targetcli-fb-2.1.fb47.tar.xz deleted file mode 100644 index f877fce..0000000 --- a/targetcli-fb-2.1.fb47.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:006c501dfcf464bcde89a548e46c56ee8d897ba560c8659098a791911531737e -size 28956 diff --git a/targetcli-fb.changes b/targetcli-fb.changes index 20cac63..556b496 100644 --- a/targetcli-fb.changes +++ b/targetcli-fb.changes @@ -1,3 +1,22 @@ +------------------------------------------------------------------- +Wed Apr 11 00:00:54 UTC 2018 - ddiss@suse.com + +- Merge RBD support from non-fb version (bsc#1079329) + + Split-out-blockdev-readonly-state-detection-helper.patch + + rbd-support.patch (SLE/Leap only, due to LIO kernel dependency) + + Add explicit Provides for "python-rtslib-rbd" +- Detect write-protected block devices (bsc#1070815) + + Auto-detect-readonly-state-for-iblock-devices.patch + + Use-signed-char-instead-of-char.patch + +------------------------------------------------------------------- +Tue Apr 10 13:32:56 UTC 2018 - ddiss@suse.com + +- Automatically generate version string from upstream tag + + Retain current fb-removed version format used + + Rename targetcli-fb-2.1.fb47.tar.xz to targetcli-fb-2.1.47.tar.xzar.xz + and cleanup hardcoded duplicate name/version values in spec + ------------------------------------------------------------------- Sun Feb 25 08:09:45 UTC 2018 - olaf@aepfle.de diff --git a/targetcli-fb.spec b/targetcli-fb.spec index 1f88395..52bbfad 100644 --- a/targetcli-fb.spec +++ b/targetcli-fb.spec @@ -16,18 +16,16 @@ # -%define oname targetcli-fb -%define realver 2.1.fb47 %{?!python_module:%define python_module() python-%{**} python3-%{**}} -Name: %{oname} +Name: targetcli-fb Version: 2.1.47 Release: 0 Summary: A command shell for managing the Linux LIO kernel target License: Apache-2.0 Group: System/Management -Url: http://github.com/agrover/%{oname} -Source: %{oname}-%{realver}.tar.xz -Source1: %{oname}.service +Url: http://github.com/agrover/%{name} +Source: %{name}-%{version}.tar.xz +Source1: %{name}.service BuildRequires: %{python_module configshell-fb} BuildRequires: %{python_module devel} BuildRequires: %{python_module pyparsing} @@ -44,13 +42,22 @@ Requires: targetcli-fb-common Requires(post): update-alternatives Requires(postun): update-alternatives %ifpython3 -Provides: targetcli-fb = %{version}-%{release} Provides: targetcli = %{version}-%{release} +Provides: targetcli-fb = %{version}-%{release} %endif -Obsoletes: targetcli-fb Obsoletes: targetcli +Obsoletes: targetcli-fb BuildArch: noarch +%if 0%{?sle_version} == 150000 +# explicit Provides advertising RBD support +Provides: targetcli-rbd = %{version} +Obsoletes: targetcli-rbd < %{version} +%endif %{?systemd_requires} +Patch1: Auto-detect-readonly-state-for-iblock-devices.patch +Patch2: Use-signed-char-instead-of-char.patch +Patch3: Split-out-blockdev-readonly-state-detection-helper.patch +Patch4: rbd-support.patch %python_subpackages @@ -74,7 +81,14 @@ targetcli-fb-common is the invariant base package needed by both python2-targetcli-fb and python3-targetcli-fb. %prep -%setup -q -n %{oname}-%{realver}%{?extraver} +%setup -q +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%if 0%{?sle_version} == 150000 +# RBD support is dependent on LIO changes present in the SLE/Leap kernel +%patch4 -p1 +%endif %build %python_build