From e30bb2917c0362dcc925843cd4ff4dfb4b865463 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Aug 06 2019 11:00:30 +0000 Subject: import python-rtslib-2.1.fb69-3.el7 --- diff --git a/.gitignore b/.gitignore index 49a15e7..c26a4c1 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/rtslib-fb-2.1.fb63.tar.gz +SOURCES/rtslib-fb-2.1.fb69.tar.gz diff --git a/.python-rtslib.metadata b/.python-rtslib.metadata index 40b74a9..f5dc9d2 100644 --- a/.python-rtslib.metadata +++ b/.python-rtslib.metadata @@ -1 +1 @@ -d09530859a0d8004fab0dd9dcee358a709dca119 SOURCES/rtslib-fb-2.1.fb63.tar.gz +4148d5c9083d72a952d431809db1adbea93668de SOURCES/rtslib-fb-2.1.fb69.tar.gz diff --git a/SOURCES/0001-Turn-off-unsupported-fabrics.patch b/SOURCES/0001-Turn-off-unsupported-fabrics.patch index dedea71..a1754da 100644 --- a/SOURCES/0001-Turn-off-unsupported-fabrics.patch +++ b/SOURCES/0001-Turn-off-unsupported-fabrics.patch @@ -1,15 +1,5 @@ -From 60b9fc9c9baf2f05e5021c8b27e173733ea62ea5 Mon Sep 17 00:00:00 2001 -From: Andy Grover -Date: Mon, 7 Oct 2013 15:32:27 -0700 -Subject: [PATCH] Turn off unsupported fabrics - -Signed-off-by: Andy Grover ---- - rtslib/fabric.py | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - diff --git a/rtslib/fabric.py b/rtslib/fabric.py -index 2887783..a44aa7e 100644 +index b529f14..8264c37 100644 --- a/rtslib/fabric.py +++ b/rtslib/fabric.py @@ -465,12 +465,12 @@ fabric_modules = { @@ -21,10 +11,10 @@ index 2887783..a44aa7e 100644 "tcm_fc": FCoEFabricModule, # "usb_gadget": USBGadgetFabricModule, # very rare, don't show - "vhost": VhostFabricModule, -- "xen_pvscsi": XenPvScsiFabricModule, +- "xen-pvscsi": XenPvScsiFabricModule, - "ibmvscsis": IbmvscsisFabricModule, +# "vhost": VhostFabricModule, -+# "xen_pvscsi": XenPvScsiFabricModule, ++# "xen-pvscsi": XenPvScsiFabricModule, +# "ibmvscsis": IbmvscsisFabricModule, } diff --git a/SOURCES/0003-Fix-exception-in-convert_scsi_hctl_to_path.patch b/SOURCES/0003-Fix-exception-in-convert_scsi_hctl_to_path.patch deleted file mode 100644 index 4b8b166..0000000 --- a/SOURCES/0003-Fix-exception-in-convert_scsi_hctl_to_path.patch +++ /dev/null @@ -1,25 +0,0 @@ -From e6b267ec3712b5d13c352c6090dffbd0144ed028 Mon Sep 17 00:00:00 2001 -From: Andy Grover -Date: Wed, 17 May 2017 09:37:59 -0700 -Subject: [PATCH] Fix exception in convert_scsi_hctl_to_path - -Convert integers to string before using them with .join(). - -Signed-off-by: Andy Grover ---- - rtslib/utils.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/rtslib/utils.py b/rtslib/utils.py -index 1a5315e..eeb1f6c 100644 ---- a/rtslib/utils.py -+++ b/rtslib/utils.py -@@ -294,7 +294,7 @@ def convert_scsi_hctl_to_path(host, controller, target, lun): - raise RTSLibError( - "The host, controller, target and lun parameter must be integers") - -- hctl = [host, controller, target, lun] -+ hctl = [str(host), str(controller), str(target), str(lun)] - try: - scsi_device = pyudev.Device.from_name(_CONTEXT, 'scsi', ':'.join(hctl)) - except pyudev.DeviceNotFoundError: diff --git a/SOURCES/0003-report-the-correct-size-for-partitions.patch b/SOURCES/0003-report-the-correct-size-for-partitions.patch new file mode 100644 index 0000000..dd7b6b8 --- /dev/null +++ b/SOURCES/0003-report-the-correct-size-for-partitions.patch @@ -0,0 +1,35 @@ +From 560ee483a9ff0fbaa130e70573c7f27ba7a413ad Mon Sep 17 00:00:00 2001 +From: Maurizio Lombardi +Date: Fri, 19 Oct 2018 10:52:01 +0200 +Subject: [PATCH] report the correct size for partitions + +If you use a partition instead of the whole device as the backstore device, +rtslib will always report its size as 0 bytes. + +This happens because rtslib tries to read the "queue/logical_block_size" +attribute, which can only be found in the parent's node. +This patch fixes the bug by loading the parent node's attributes if +it detects that the device is a partition. + +Signed-off-by: Maurizio Lombardi +--- + rtslib/utils.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/rtslib/utils.py b/rtslib/utils.py +index b4e68fb..eff2205 100644 +--- a/rtslib/utils.py ++++ b/rtslib/utils.py +@@ -134,6 +134,9 @@ def _get_size_for_dev(device): + except (KeyError, UnicodeDecodeError, ValueError): + return 0 + ++ if device['DEVTYPE'] == 'partition': ++ attributes = device.parent.attributes ++ + try: + logical_block_size = attributes.asint('queue/logical_block_size') + except (KeyError, UnicodeDecodeError, ValueError): +-- +1.8.3.1 + diff --git a/SOURCES/0004-Support-Reconfiguration-of-device-path.patch b/SOURCES/0004-Support-Reconfiguration-of-device-path.patch deleted file mode 100644 index 4793d88..0000000 --- a/SOURCES/0004-Support-Reconfiguration-of-device-path.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 2a816d67e95ac0edc6d56076595b29eddfeb433b Mon Sep 17 00:00:00 2001 -From: "Bryant G. Ly" -Date: Thu, 1 Jun 2017 13:11:37 -0500 -Subject: [PATCH] Support Reconfiguration of device path - -This patch allows users to pass in a string into the -attributes. Prior it would throw: - -Traceback (most recent call last): -File "/usr/bin/targetcli", line 121, in - main() -File "/usr/bin/targetcli", line 117, in main - root_node.ui_command_saveconfig() -File "/usr/lib/python3/dist-packages/targetcli/ui_root.py", line 98, in ui_command_saveconfig - self.rtsroot.save_to_file(savefile) -File "/usr/lib/python3/dist-packages/rtslib_fb/root.py", line 270, in save_to_file - f.write(json.dumps(self.dump(), sort_keys=True, indent=2)) -File "/usr/lib/python3/dist-packages/rtslib_fb/root.py", line 160, in dump - d['storage_objects'] = [so.dump() for so in self.storage_objects] -File "/usr/lib/python3/dist-packages/rtslib_fb/root.py", line 160, in - d['storage_objects'] = [so.dump() for so in self.storage_objects] -File "/usr/lib/python3/dist-packages/rtslib_fb/tcm.py", line 850, in dump - d = super(UserBackedStorageObject, self).dump() -File "/usr/lib/python3/dist-packages/rtslib_fb/tcm.py", line 294, in dump - d = super(StorageObject, self).dump() -File "/usr/lib/python3/dist-packages/rtslib_fb/node.py", line 217, in dump - attrs[item] = int(self.get_attribute(item)) -ValueError: invalid literal for int() with base 10: 'file//home/neo/test.raw' - -This error is due to set attribute dev_path being a non integer. - -Signed-off-by: Bryant G. Ly ---- - rtslib/node.py | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/rtslib/node.py b/rtslib/node.py -index c319a5b..c0092fc 100644 ---- a/rtslib/node.py -+++ b/rtslib/node.py -@@ -214,7 +214,10 @@ class CFSNode(object): - attrs = {} - params = {} - for item in self.list_attributes(writable=True): -- attrs[item] = int(self.get_attribute(item)) -+ try: -+ attrs[item] = int(self.get_attribute(item)) -+ except ValueError: -+ attrs[item] = self.get_attribute(item) - if attrs: - d['attributes'] = attrs - for item in self.list_parameters(writable=True): --- -1.8.3.1 - diff --git a/SOURCES/0004-save_to_file-function-breaks-symbolic-link-when-savi.patch b/SOURCES/0004-save_to_file-function-breaks-symbolic-link-when-savi.patch new file mode 100644 index 0000000..8412e64 --- /dev/null +++ b/SOURCES/0004-save_to_file-function-breaks-symbolic-link-when-savi.patch @@ -0,0 +1,64 @@ +From 5626a4d593df9384fff5129e7bdb6c909f5f2b11 Mon Sep 17 00:00:00 2001 +From: Maurizio Lombardi +Date: Fri, 8 Feb 2019 14:36:34 +0100 +Subject: [PATCH] save_to_file() function breaks symbolic link when saving + configuration + +Currently the location of the targetcli configuration file is not +configurable (saveconfig.json). The location is : /etc/target +Some users use stateless VMs, with just a persistent device +mounted under /var/lib/diskless. + +In order to circumvent the non configurable location of +saveconfig.json, they create a symbolic link in /etc/target +pointing to /var/lib/diskless + +Unfortunately, the rtslib save_to_file() function breaks +this symbolic link and creates a new regular file in place of it, +due to the creation of a saveconfig.json.temp file which is +then renamed to saveconfig.json using the os.rename() function. + +This patch replace os.rename() with shutil.copyfile() + os.remove(), +using copyfile() instead of rename() will preserve the symbolic link + +Signed-off-by: Maurizio Lombardi +--- + rtslib/root.py | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/rtslib/root.py b/rtslib/root.py +index 5c0a98c..c93e65b 100644 +--- a/rtslib/root.py ++++ b/rtslib/root.py +@@ -23,6 +23,7 @@ import stat + import json + import glob + import errno ++import shutil + + from .node import CFSNode + from .target import Target +@@ -386,7 +387,9 @@ class RTSRoot(CFSNode): + else: + saveconf = self.dump() + +- with open(save_file+".temp", "w+") as f: ++ tmp_file = save_file + ".temp" ++ ++ with open(tmp_file, "w+") as f: + os.fchmod(f.fileno(), stat.S_IRUSR | stat.S_IWUSR) + f.write(json.dumps(saveconf, sort_keys=True, indent=2)) + f.write("\n") +@@ -394,7 +397,8 @@ class RTSRoot(CFSNode): + os.fsync(f.fileno()) + f.close() + +- os.rename(save_file+".temp", save_file) ++ shutil.copyfile(tmp_file, save_file) ++ os.remove(tmp_file) + + def restore_from_file(self, restore_file=None, clear_existing=True, abort_on_error=False): + ''' +-- +2.21.0 + diff --git a/SOURCES/0005-Remove-hba-only-directories-in-clear_existing.patch b/SOURCES/0005-Remove-hba-only-directories-in-clear_existing.patch deleted file mode 100644 index 4ba85d8..0000000 --- a/SOURCES/0005-Remove-hba-only-directories-in-clear_existing.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 12e626b649ef4a928aa95e60d8b8c58b20bd3372 Mon Sep 17 00:00:00 2001 -From: Andy Grover -Date: Thu, 21 Sep 2017 16:45:30 -0700 -Subject: [PATCH] Remove hba-only directories in clear_existing() - -rtslib never creates hba directories without a storage object within it, -but if under some circumstance these existed then clear_existing() wouldn't -remove them, since StorageObject::all()'s glob ignores them. - -Add code to ensure these are also removed. - -Signed-off-by: Andy Grover ---- - rtslib/root.py | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/rtslib/root.py b/rtslib/root.py -index 0c3c231..72c0299 100644 ---- a/rtslib/root.py -+++ b/rtslib/root.py -@@ -21,6 +21,7 @@ under the License. - import os - import stat - import json -+import glob - - from .node import CFSNode - from .target import Target -@@ -206,6 +207,11 @@ class RTSRoot(CFSNode): - for so in self.storage_objects: - so.delete() - -+ # If somehow some hbas still exist (no storage object within?) clean -+ # them up too. -+ for hba_dir in glob.glob("%s/core/*_*" % self.configfs_dir): -+ os.rmdir(hba_dir) -+ - def restore(self, config, clear_existing=False, abort_on_error=False): - ''' - Takes a dict generated by dump() and reconfigures the target to match. --- -1.8.3.1 - diff --git a/SOURCES/0006-create-remove-stale-hba-only-dir.patch b/SOURCES/0006-create-remove-stale-hba-only-dir.patch deleted file mode 100644 index 0e5caf8..0000000 --- a/SOURCES/0006-create-remove-stale-hba-only-dir.patch +++ /dev/null @@ -1,54 +0,0 @@ -From f06103354394ffa86817696a37edb7ddd351bc10 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Fri, 9 Feb 2018 17:20:26 +0530 -Subject: [PATCH] create: remove stale hba-only dir - -curretly if there exist any stale hba-only directories, - -$ ls /sys/kernel/config/target/core/user_0/ -hba_info hba_mode - -Then backend creation fails, - -$ targetcli /backstores/fileio create block file 1M -This _Backstore already exists in configFS - -We will have to restart target.service or restore the configuration -again to clear the stale hba-only dirs. - -This patch checks for hba directory before creating one, -if it is already existing and found to be stale then removes it. - -Thanks to "Maurizio Lombardi " for debugging along - -Signed-off-by: Prasanna Kumar Kalever ---- - rtslib/node.py | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/rtslib/node.py b/rtslib/node.py -index c0092fc..1d77cd1 100644 ---- a/rtslib/node.py -+++ b/rtslib/node.py -@@ -52,9 +52,16 @@ class CFSNode(object): - ''' - if mode not in ['any', 'lookup', 'create']: - raise RTSLibError("Invalid mode: %s" % mode) -+ - if self.exists and mode == 'create': -- raise RTSLibError("This %s already exists in configFS" -- % self.__class__.__name__) -+ # ensure that self.path is not stale hba-only dir -+ if os.path.samefile(os.path.dirname(self.path), self.configfs_dir+'/core') \ -+ and not next(os.walk(self.path))[1]: -+ os.rmdir(self.path) -+ else: -+ raise RTSLibError("This %s already exists in configFS" -+ % self.__class__.__name__) -+ - elif not self.exists and mode == 'lookup': - raise RTSLibNotInCFS("No such %s in configfs: %s" - % (self.__class__.__name__, self.path)) --- -1.8.3.1 - diff --git a/SOURCES/0007-alua-enable-alua-for-pscsi-tcmu-if-kernel-reports-su.patch b/SOURCES/0007-alua-enable-alua-for-pscsi-tcmu-if-kernel-reports-su.patch deleted file mode 100644 index a7e9321..0000000 --- a/SOURCES/0007-alua-enable-alua-for-pscsi-tcmu-if-kernel-reports-su.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 86fed9fdab8803fd8d321c8242097e7b4f952ada Mon Sep 17 00:00:00 2001 -From: Maurizio Lombardi -Date: Tue, 27 Mar 2018 14:50:09 +0200 -Subject: [PATCH] alua: enable alua for pscsi/tcmu if kernel reports support - -4.14 (it is currently the 4.13 feature window and I think we will -miss it) will add this patch - -https://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git/commit/?h=for-next&id=c17d5d5f51f72f24e0e17a4450ae5010bf6962d9 - -commit c17d5d5f51f72f24e0e17a4450ae5010bf6962d9 -Author: Mike Christie -Date: Mon Jul 10 14:53:31 2017 -0500 - - target: export lio pgr/alua support as device attr - -which has the lio device report if it supports lio based ALUA. -We can then check this configfs file and know if we are using -a modern kernel with support and not worry about possibly crashing -the system. - -Signed-off-by: Maurizio Lombardi ---- - rtslib/alua.py | 4 ---- - rtslib/tcm.py | 23 ++++++++++++++++++----- - 2 files changed, 18 insertions(+), 9 deletions(-) - -diff --git a/rtslib/alua.py b/rtslib/alua.py -index 390e74a..fadc225 100644 ---- a/rtslib/alua.py -+++ b/rtslib/alua.py -@@ -46,10 +46,6 @@ class ALUATargetPortGroup(CFSNode): - @param tag: target port group id. If not passed in, try to look - up existing ALUA TPG with the same name - """ -- # kernel partially sets up default_tg_pt_gp and will let you partially -- # setup ALUA groups for pscsi and user, but writing to some of the -- # files will crash the kernel. Just fail to even create groups until -- # the kernel is fixed. - if storage_object.alua_supported is False: - raise RTSLibALUANotSupported("Backend does not support ALUA setup") - -diff --git a/rtslib/tcm.py b/rtslib/tcm.py -index aa3530a..bf681fe 100644 ---- a/rtslib/tcm.py -+++ b/rtslib/tcm.py -@@ -32,6 +32,19 @@ from .utils import convert_scsi_path_to_hctl, convert_scsi_hctl_to_path - from .utils import is_dev_in_use, get_blockdev_type - from .utils import get_size_for_blk_dev, get_size_for_disk_name - -+def storage_object_get_alua_support_attr(so): -+ ''' -+ Helper function that can be called by passthrough type of backends. -+ ''' -+ try: -+ if int(so.get_attribute("alua_support")) == 1: -+ return True -+ except RTSLibError: -+ pass -+ # Default to false because older kernels will crash when -+ # reading/writing to some ALUA files when ALUA was not -+ # fully supported by pscsi and tcmu. -+ return False - - class StorageObject(CFSNode): - ''' -@@ -227,7 +240,7 @@ class StorageObject(CFSNode): - - def _get_alua_supported(self): - ''' -- Children should override and return false if ALUA setup is not supported. -+ Children should override if the backend did not always support ALUA - ''' - self._check_self() - return True -@@ -420,7 +433,7 @@ class PSCSIStorageObject(StorageObject): - - def _get_alua_supported(self): - self._check_self() -- return False -+ return storage_object_get_alua_support_attr(self) - - # PSCSIStorageObject public stuff - -@@ -442,7 +455,7 @@ class PSCSIStorageObject(StorageObject): - lun = property(_get_lun, - doc="Get the SCSI device LUN") - alua_supported = property(_get_alua_supported, -- doc="ALUA cannot be setup with rtslib, so False is returned."); -+ doc="Returns true if ALUA can be setup. False if not supported.") - - def dump(self): - d = super(PSCSIStorageObject, self).dump() -@@ -826,14 +839,14 @@ class UserBackedStorageObject(StorageObject): - - def _get_alua_supported(self): - self._check_self() -- return False -+ return storage_object_get_alua_support_attr(self) - - size = property(_get_size, - doc="Get the size in bytes.") - config = property(_get_config, - doc="Get the TCMU config.") - alua_supported = property(_get_alua_supported, -- doc="ALUA cannot be setup with rtslib, so False is returned."); -+ doc="Returns true if ALUA can be setup. False if not supported.") - - def dump(self): - d = super(UserBackedStorageObject, self).dump() --- -1.8.3.1 - diff --git a/SOURCES/0008-save_to_file-support-saveconfig-at-storage-object-le.patch b/SOURCES/0008-save_to_file-support-saveconfig-at-storage-object-le.patch deleted file mode 100644 index 73f69da..0000000 --- a/SOURCES/0008-save_to_file-support-saveconfig-at-storage-object-le.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 7cc8531b03f5391f8c2fa1208c4f6b6e7b030b66 Mon Sep 17 00:00:00 2001 -From: Maurizio Lombardi -Date: Tue, 10 Apr 2018 15:18:37 +0200 -Subject: [PATCH] save_to_file: support saveconfig at storage object level - -Added an option to update configuration for single storage object at a time. -As of today changes done for one storage object needs the whole configuration -update. This option will enable us to save changes done to a give storage object. - -$ targetcli /backstores/user:glfs/block1 help -[...] -AVAILABLE COMMANDS -[...] - - saveconfig [savefile] - - set [group] [parameter=value...] - - status - - version - -$ targetcli /backstores/user:glfs/block1 saveconfig -Storage Object 'user:block1' config saved to /etc/target/saveconfig.json - -Signed-off-by: Prasanna Kumar Kalever -Signed-off-by: Maurizio Lombardi ---- - rtslib/root.py | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 84 insertions(+), 2 deletions(-) - -diff --git a/rtslib/root.py b/rtslib/root.py -index 99a25b7..c6697cf 100644 ---- a/rtslib/root.py -+++ b/rtslib/root.py -@@ -148,6 +148,83 @@ class RTSRoot(CFSNode): - def __str__(self): - return "rtslib" - -+ def _get_saveconf(self, so_path, save_file): -+ ''' -+ Fetch the configuration of all the blocks and return conf with -+ updated storageObject info and its related target configuraion of -+ given storage object path -+ ''' -+ current = self.dump() -+ -+ with open(save_file, "r") as f: -+ saveconf = json.loads(f.read()) -+ f.close() -+ -+ fetch_cur_so = False -+ fetch_cur_tg = False -+ # Get the given block current storageObj configuration -+ for sidx, sobj in enumerate(current.get('storage_objects', [])): -+ if '/backstores/' + sobj['plugin'] + '/' + sobj['name'] == so_path: -+ current_so = current['storage_objects'][sidx] -+ fetch_cur_so = True -+ break -+ -+ # Get the given block current target configuration -+ if fetch_cur_so: -+ for tidx, tobj in enumerate(current.get('targets', [])): -+ if fetch_cur_tg: -+ break -+ for luns in tobj.get('tpgs', []): -+ if fetch_cur_tg: -+ break -+ for lun in luns.get('luns', []): -+ if lun['storage_object'] == so_path: -+ current_tg = current['targets'][tidx] -+ fetch_cur_tg = True -+ break -+ -+ fetch_sav_so = False -+ fetch_sav_tg = False -+ # Get the given block storageObj from saved configuration -+ for sidx, sobj in enumerate(saveconf.get('storage_objects', [])): -+ if '/backstores/' + sobj['plugin'] + '/' + sobj['name'] == so_path: -+ # Merge StorageObj -+ if fetch_cur_so: -+ saveconf['storage_objects'][sidx] = current_so; -+ # Remove StorageObj -+ else: -+ saveconf['storage_objects'].remove(saveconf['storage_objects'][sidx]) -+ fetch_sav_so = True -+ break -+ -+ # Get the given block target from saved configuration -+ if fetch_sav_so: -+ for tidx, tobj in enumerate(saveconf.get('targets', [])): -+ if fetch_sav_tg: -+ break -+ for luns in tobj.get('tpgs', []): -+ if fetch_sav_tg: -+ break -+ for lun in luns.get('luns', []): -+ if lun['storage_object'] == so_path: -+ # Merge target -+ if fetch_cur_tg: -+ saveconf['targets'][tidx] = current_tg; -+ # Remove target -+ else: -+ saveconf['targets'].remove(saveconf['targets'][tidx]) -+ fetch_sav_tg = True -+ break -+ -+ # Insert storageObj -+ if fetch_cur_so and not fetch_sav_so: -+ saveconf['storage_objects'].append(current_so) -+ # Insert target -+ if fetch_cur_tg and not fetch_sav_tg: -+ saveconf['targets'].append(current_tg) -+ -+ return saveconf -+ - # RTSRoot public stuff - - def dump(self): -@@ -257,7 +334,7 @@ class RTSRoot(CFSNode): - - return errors - -- def save_to_file(self, save_file=None): -+ def save_to_file(self, save_file=None, so_path=None): - ''' - Write the configuration in json format to a file. - Save file defaults to '/etc/targets/saveconfig.json'. -@@ -265,9 +342,14 @@ class RTSRoot(CFSNode): - if not save_file: - save_file = default_save_file - -+ if so_path: -+ saveconf = self._get_saveconf(so_path, save_file) -+ else: -+ saveconf = self.dump() -+ - with open(save_file+".temp", "w+") as f: - os.fchmod(f.fileno(), stat.S_IRUSR | stat.S_IWUSR) -- f.write(json.dumps(self.dump(), sort_keys=True, indent=2)) -+ f.write(json.dumps(saveconf, sort_keys=True, indent=2)) - f.write("\n") - f.flush() - os.fsync(f.fileno()) --- -1.8.3.1 - diff --git a/SOURCES/0009-restoreconfig-fix-alua-tpg-config-setup.patch b/SOURCES/0009-restoreconfig-fix-alua-tpg-config-setup.patch deleted file mode 100644 index a07d1fc..0000000 --- a/SOURCES/0009-restoreconfig-fix-alua-tpg-config-setup.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 515e1b10bbdbeeca4a4f24aa2157beb1bcea3304 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Wed, 4 Apr 2018 16:30:42 +0530 -Subject: [PATCH] restoreconfig: fix alua tpg config setup - -Problem: ---- -$ cat myconfig.json -{ - "storage_objects": [ - { - "alua_tpgs": [ - { - "alua_access_type": 0, - "name": "glfs_tg_pt_gp", - "tg_pt_gp_id": 1 - } - ], - "config": "glfs/test@192.168.124.227/block-store/2e189467-00ae-4388-bbd2-a8b4df154671", - "name": "blockX", - "plugin": "user", - "size": 1073741824 - } - ], - "targets": [] -} - -$ targetcli restoreconfig myconfig.json -All configuration cleared -'alua_access_state' - -And attributes won't be effected as per myconfig.json: -$ targetcli/backstores/user:glfs/blockX/alua/glfs_tg_pt_gp get alua alua_access_type -alua_access_type=3 - -Fix: ---- -This patch fix the problem by calling setattr for available attribs in the -configfile and rest all will be as per kernel defaults. - -Signed-off-by: Prasanna Kumar Kalever ---- - rtslib/alua.py | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/rtslib/alua.py b/rtslib/alua.py -index 8a4b30d..9a7af0d 100644 ---- a/rtslib/alua.py -+++ b/rtslib/alua.py -@@ -19,6 +19,7 @@ a copy of the License at - - from .node import CFSNode - from .utils import RTSLibError, RTSLibALUANotSupported, fread, fwrite -+import six - - alua_rw_params = ['alua_access_state', 'alua_access_status', - 'alua_write_metadata', 'alua_access_type', 'preferred', -@@ -393,5 +394,10 @@ class ALUATargetPortGroup(CFSNode): - return - - alua_tpg_obj = cls(storage_obj, name, alua_tpg['tg_pt_gp_id']) -- for param in alua_rw_params: -- setattr(alua_tpg_obj, param, alua_tpg[param]) -+ for param, value in six.iteritems(alua_tpg): -+ if param != 'name' and param != 'tg_pt_gp_id': -+ try: -+ setattr(alua_tpg_obj, param, value) -+ except: -+ raise RTSLibError("Could not set attribute '%s' for alua tpg '%s'" -+ % (param, alua_tpg['name'])) --- -1.8.3.1 - diff --git a/SOURCES/0010-Support-tcmu-hw-max-sectors.patch b/SOURCES/0010-Support-tcmu-hw-max-sectors.patch deleted file mode 100644 index 8070b8e..0000000 --- a/SOURCES/0010-Support-tcmu-hw-max-sectors.patch +++ /dev/null @@ -1,77 +0,0 @@ -diff --git a/rtslib/tcm.py b/rtslib/tcm.py -index bf681fe..cb52386 100644 ---- a/rtslib/tcm.py -+++ b/rtslib/tcm.py -@@ -785,7 +785,8 @@ class UserBackedStorageObject(StorageObject): - An interface to configFS storage objects for userspace-backed backstore. - ''' - -- def __init__(self, name, config=None, size=None, wwn=None): -+ def __init__(self, name, config=None, size=None, wwn=None, -+ hw_max_sectors=None): - ''' - @param name: The name of the UserBackedStorageObject. - @type name: string -@@ -796,6 +797,8 @@ class UserBackedStorageObject(StorageObject): - @type size: int - @param wwn: T10 WWN Unit Serial, will generate if None - @type wwn: string -+ @hw_max_sectors: Max sectors per command limit to export to initiators. -+ @type hw_max_sectors: int - @return: A UserBackedStorageObject object. - ''' - -@@ -808,20 +811,22 @@ class UserBackedStorageObject(StorageObject): - "from its configuration string") - super(UserBackedStorageObject, self).__init__(name, 'create') - try: -- self._configure(config, size, wwn) -+ self._configure(config, size, wwn, hw_max_sectors) - except: - self.delete() - raise - else: - super(UserBackedStorageObject, self).__init__(name, 'lookup') - -- def _configure(self, config, size, wwn): -+ def _configure(self, config, size, wwn, hw_max_sectors): - self._check_self() - - if ':' in config: - raise RTSLibError("':' not allowed in config string") - self._control("dev_config=%s" % config) - self._control("dev_size=%d" % size) -+ if hw_max_sectors is not None: -+ self._control("hw_max_sectors=%s" % hw_max_sectors) - self._enable() - - super(UserBackedStorageObject, self)._configure(wwn) -@@ -830,6 +835,10 @@ class UserBackedStorageObject(StorageObject): - self._check_self() - return int(self._parse_info('Size')) - -+ def _get_hw_max_sectors(self): -+ self._check_self() -+ return int(self._parse_info('HwMaxSectors')) -+ - def _get_config(self): - self._check_self() - val = self._parse_info('Config') -@@ -841,6 +850,8 @@ class UserBackedStorageObject(StorageObject): - self._check_self() - return storage_object_get_alua_support_attr(self) - -+ hw_max_sectors = property(_get_hw_max_sectors, -+ doc="Get the max sectors per command.") - size = property(_get_size, - doc="Get the size in bytes.") - config = property(_get_config, -@@ -853,6 +864,8 @@ class UserBackedStorageObject(StorageObject): - d['wwn'] = self.wwn - d['size'] = self.size - d['config'] = self.config -+ d['hw_max_sectors'] = self.hw_max_sectors -+ - return d - - diff --git a/SOURCES/0011-saveconfig-dump-control-string-containing-control-va.patch b/SOURCES/0011-saveconfig-dump-control-string-containing-control-va.patch deleted file mode 100644 index f552042..0000000 --- a/SOURCES/0011-saveconfig-dump-control-string-containing-control-va.patch +++ /dev/null @@ -1,93 +0,0 @@ -From eff378068812503ee2394baffba37b5cadd9a0f7 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Fri, 6 Apr 2018 13:03:28 +0530 -Subject: [PATCH] saveconfig: dump control string containing control=value - tuples - -Problem: -------- -$ targetcli /backstores/user:glfs create blockX1 1073741824 \ - test@192.168.124.227/block-store/e59309bb-d591-4121-a891-e98ff3416446,max_data_area_mb=32 - -$ targetcli / saveconfig - -$ cat /etc/target/saveconfig.json -{ - "storage_objects": [ - { - "alua_tpgs": [], - "attributes": { - ... - }, - "config": "glfs/test@192.168.124.227/block-store/e59309bb-d591-4121-a891-e98ff3416446", - "hw_max_sectors": 128, - "name": "blockX1", - "plugin": "user", - "size": 1073741824, - "wwn": "3aa072d6-a007-45a3-8eac-e85b53655515" - } - ], - "targets": [] -} - -Note max_data_area_mb is not dumped into the configfile and hence on restart of -target service or node reboot this storageObject property is lost. - -Fix: ----- -This patch make sure to dump control string containing control=value tuples, like: -$ cat /etc/target/saveconfig.json -{ - ... - "config": "glfs/test@192.168.124.227/block-store/e59309bb-d591-4121-a891-e98ff3416446", - "control": "max_data_area_mb=32", - ... -} - -Signed-off-by: Prasanna Kumar Kalever ---- - rtslib/tcm.py | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/rtslib/tcm.py b/rtslib/tcm.py -index efe685a..4feb738 100644 ---- a/rtslib/tcm.py -+++ b/rtslib/tcm.py -@@ -845,6 +845,17 @@ class UserBackedStorageObject(StorageObject): - self._check_self() - return int(self._parse_info('HwMaxSectors')) - -+ def _get_control_tuples(self): -+ self._check_self() -+ tuples = [] -+ # 1. max_data_area_mb -+ val = self._parse_info('MaxDataAreaMB') -+ if val != "NULL": -+ tuples.append("max_data_area_mb=%s" % val) -+ # 2. add next ... -+ -+ return ",".join(tuples) -+ - def _get_config(self): - self._check_self() - val = self._parse_info('Config') -@@ -858,6 +869,8 @@ class UserBackedStorageObject(StorageObject): - - hw_max_sectors = property(_get_hw_max_sectors, - doc="Get the max sectors per command.") -+ control_tuples = property(_get_control_tuples, -+ doc="Get the comma separated string containing control=value tuples.") - size = property(_get_size, - doc="Get the size in bytes.") - config = property(_get_config, -@@ -871,6 +884,7 @@ class UserBackedStorageObject(StorageObject): - d['size'] = self.size - d['config'] = self.config - d['hw_max_sectors'] = self.hw_max_sectors -+ d['control'] = self.control_tuples - - return d - --- -1.8.3.1 - diff --git a/SOURCES/0012-tcmu-add-control-constructor-arg.patch b/SOURCES/0012-tcmu-add-control-constructor-arg.patch deleted file mode 100644 index 9b29897..0000000 --- a/SOURCES/0012-tcmu-add-control-constructor-arg.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 9637223b9d8cee3abc527f58fc9e14a1bcbe4b29 Mon Sep 17 00:00:00 2001 -From: Mike Christie -Date: Wed, 7 Mar 2018 19:47:34 -0600 -Subject: [PATCH] tcmu: add control constructor arg - -Add format control constructor arg so user does not have to hack -in extra settings through the config option. - -Signed-off-by: Mike Christie ---- - rtslib/tcm.py | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/rtslib/tcm.py b/rtslib/tcm.py -index 1aeea23..efe685a 100644 ---- a/rtslib/tcm.py -+++ b/rtslib/tcm.py -@@ -787,7 +787,7 @@ class UserBackedStorageObject(StorageObject): - ''' - - def __init__(self, name, config=None, size=None, wwn=None, -- hw_max_sectors=None): -+ hw_max_sectors=None, control=None): - ''' - @param name: The name of the UserBackedStorageObject. - @type name: string -@@ -800,6 +800,9 @@ class UserBackedStorageObject(StorageObject): - @type wwn: string - @hw_max_sectors: Max sectors per command limit to export to initiators. - @type hw_max_sectors: int -+ @control: String of control=value tuples separate by a ',' that will -+ passed to the kernel control file. -+ @type: string - @return: A UserBackedStorageObject object. - ''' - -@@ -812,14 +815,14 @@ class UserBackedStorageObject(StorageObject): - "from its configuration string") - super(UserBackedStorageObject, self).__init__(name, 'create') - try: -- self._configure(config, size, wwn, hw_max_sectors) -+ self._configure(config, size, wwn, hw_max_sectors, control) - except: - self.delete() - raise - else: - super(UserBackedStorageObject, self).__init__(name, 'lookup') - -- def _configure(self, config, size, wwn, hw_max_sectors): -+ def _configure(self, config, size, wwn, hw_max_sectors, control): - self._check_self() - - if ':' in config: -@@ -828,6 +831,8 @@ class UserBackedStorageObject(StorageObject): - self._control("dev_size=%d" % size) - if hw_max_sectors is not None: - self._control("hw_max_sectors=%s" % hw_max_sectors) -+ if control is not None: -+ self._control(control) - self._enable() - - super(UserBackedStorageObject, self)._configure(wwn) --- -1.8.3.1 - diff --git a/SOURCES/0013-saveconfig-fix-failure-in-absence-of-save-file.patch b/SOURCES/0013-saveconfig-fix-failure-in-absence-of-save-file.patch deleted file mode 100644 index 1674b47..0000000 --- a/SOURCES/0013-saveconfig-fix-failure-in-absence-of-save-file.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1dccdd8f1415c7fe63fb59044618435a09619e45 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Tue, 24 Apr 2018 16:33:36 +0530 -Subject: [PATCH] saveconfig: fix failure in absence of save file - -$ ls /etc/target/ -backup - -$ targetcli /backstores/user:glfs/testX saveconfig -[Errno 2] No such file or directory: '/etc/target/saveconfig.json' - -Signed-off-by: Prasanna Kumar Kalever ---- - rtslib/root.py | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/rtslib/root.py b/rtslib/root.py -index 913d8ea..d5a6e43 100644 ---- a/rtslib/root.py -+++ b/rtslib/root.py -@@ -184,9 +184,12 @@ class RTSRoot(CFSNode): - ''' - current = self.dump() - -- with open(save_file, "r") as f: -- saveconf = json.loads(f.read()) -- f.close() -+ if not os.path.exists(save_file): -+ saveconf = {'storage_objects': [], 'targets': []} -+ else: -+ with open(save_file, "r") as f: -+ saveconf = json.loads(f.read()) -+ f.close() - - fetch_cur_so = False - fetch_cur_tg = False --- -1.8.3.1 - diff --git a/SOURCES/0014-saveconfig-handle-no-attr-exception-in-_parse_info.patch b/SOURCES/0014-saveconfig-handle-no-attr-exception-in-_parse_info.patch deleted file mode 100644 index 5d52002..0000000 --- a/SOURCES/0014-saveconfig-handle-no-attr-exception-in-_parse_info.patch +++ /dev/null @@ -1,48 +0,0 @@ -From b10c921a2d3bf2b84531ee7303a494919de67ae5 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Fri, 1 Jun 2018 14:05:14 +0530 -Subject: [PATCH] saveconfig: handle no attr exception in _parse_info() - -$ targetcli / saveconfig -'NoneType' object has no attribute 'group' - -Signed-off-by: Prasanna Kumar Kalever ---- - rtslib/tcm.py | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/rtslib/tcm.py b/rtslib/tcm.py -index 4feb738..4ed96b4 100644 ---- a/rtslib/tcm.py -+++ b/rtslib/tcm.py -@@ -184,8 +184,11 @@ class StorageObject(CFSNode): - def _parse_info(self, key): - self._check_self() - info = fread("%s/info" % self.path) -- return re.search(".*%s: ([^: ]+).*" \ -- % key, ' '.join(info.split())).group(1) -+ try: -+ return re.search(".*%s: ([^: ]+).*" \ -+ % key, ' '.join(info.split())).group(1) -+ except AttributeError: -+ return None - - def _get_status(self): - self._check_self() -@@ -994,8 +997,11 @@ class _Backstore(CFSNode): - def _parse_info(self, key): - self._check_self() - info = fread("%s/hba_info" % self.path) -- return re.search(".*%s: ([^: ]+).*" \ -- % key, ' '.join(info.split())).group(1) -+ try: -+ return re.search(".*%s: ([^: ]+).*" \ -+ % key, ' '.join(info.split())).group(1) -+ except AttributeError: -+ return None - - def _get_version(self): - self._check_self() --- -1.8.3.1 - diff --git a/SOURCES/0015-saveconfig-fix-missing-import.patch b/SOURCES/0015-saveconfig-fix-missing-import.patch deleted file mode 100644 index 3bdbd28..0000000 --- a/SOURCES/0015-saveconfig-fix-missing-import.patch +++ /dev/null @@ -1,28 +0,0 @@ -From f5db37f59f69bccbef9ca6b2a792031bc4d70ee2 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Fri, 1 Jun 2018 15:15:18 +0530 -Subject: [PATCH] saveconfig: fix missing import - -$ targetcli /backstores/user:glfs/test saveconfig -NameError: "global name 'errno' is not defined" - -Signed-off-by: Prasanna Kumar Kalever ---- - rtslib/root.py | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/rtslib/root.py b/rtslib/root.py -index 13401e5..7ea06fa 100644 ---- a/rtslib/root.py -+++ b/rtslib/root.py -@@ -22,6 +22,7 @@ import os - import stat - import json - import glob -+import errno - - from .node import CFSNode - from .target import Target --- -1.8.3.1 - diff --git a/SOURCES/0016-saveconfig-way-for-block-level-save-with-delete-comm.patch b/SOURCES/0016-saveconfig-way-for-block-level-save-with-delete-comm.patch deleted file mode 100644 index 3e9115f..0000000 --- a/SOURCES/0016-saveconfig-way-for-block-level-save-with-delete-comm.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 7213c27f03e5cbabb755da8e6cbe39c75c68c351 Mon Sep 17 00:00:00 2001 -From: Prasanna Kumar Kalever -Date: Fri, 1 Jun 2018 15:18:18 +0530 -Subject: [PATCH] saveconfig: way for block-level save with delete command - -currently, we can use block-level save feature for create command and -reconfig of different attributes, but there is no way to use block-level -feature for delete command. - -This patch introduces 'save' flag (False on default), which can trigger -saveconfig internally as part of delete command. - -$ targetcli /backstores/user:glfs delete test save=True -Deleted storage object test. - -Signed-off-by: Prasanna Kumar Kalever ---- - rtslib/tcm.py | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/rtslib/tcm.py b/rtslib/tcm.py -index 4ed96b4..58952d6 100644 ---- a/rtslib/tcm.py -+++ b/rtslib/tcm.py -@@ -251,7 +251,7 @@ class StorageObject(CFSNode): - - # StorageObject public stuff - -- def delete(self): -+ def delete(self, save=False): - ''' - Recursively deletes a StorageObject object. - This will delete all attached LUNs currently using the StorageObject -@@ -274,6 +274,9 @@ class StorageObject(CFSNode): - - super(StorageObject, self).delete() - self._backstore.delete() -+ if save: -+ from .root import RTSRoot, default_save_file -+ RTSRoot().save_to_file(default_save_file, '/backstores/' + self.plugin + '/' + self._name) - - def is_configured(self): - ''' --- -1.8.3.1 - diff --git a/SPECS/python-rtslib.spec b/SPECS/python-rtslib.spec index 1071cd2..8a581e4 100644 --- a/SPECS/python-rtslib.spec +++ b/SPECS/python-rtslib.spec @@ -8,27 +8,15 @@ Name: python-rtslib License: ASL 2.0 Group: System Environment/Libraries Summary: API for Linux kernel LIO SCSI target -Version: 2.1.fb63 -Release: 13%{?dist} +Version: 2.1.fb69 +Release: 3%{?dist} URL: https://fedorahosted.org/targetcli-fb/ Source: https://fedorahosted.org/released/targetcli-fb/%{oname}-%{version}.tar.gz Source1: target.service Patch0: 0001-Turn-off-unsupported-fabrics.patch Patch1: 0002-Fix-comparisons-to-None.patch -Patch2: 0003-Fix-exception-in-convert_scsi_hctl_to_path.patch -Patch3: 0004-Support-Reconfiguration-of-device-path.patch -Patch4: 0005-Remove-hba-only-directories-in-clear_existing.patch -Patch5: 0006-create-remove-stale-hba-only-dir.patch -Patch6: 0007-alua-enable-alua-for-pscsi-tcmu-if-kernel-reports-su.patch -Patch7: 0008-save_to_file-support-saveconfig-at-storage-object-le.patch -Patch8: 0009-restoreconfig-fix-alua-tpg-config-setup.patch -Patch9: 0010-Support-tcmu-hw-max-sectors.patch -Patch10: 0011-saveconfig-dump-control-string-containing-control-va.patch -Patch11: 0012-tcmu-add-control-constructor-arg.patch -Patch12: 0013-saveconfig-fix-failure-in-absence-of-save-file.patch -Patch13: 0014-saveconfig-handle-no-attr-exception-in-_parse_info.patch -Patch14: 0015-saveconfig-fix-missing-import.patch -Patch15: 0016-saveconfig-way-for-block-level-save-with-delete-comm.patch +Patch2: 0003-report-the-correct-size-for-partitions.patch +Patch3: 0004-save_to_file-function-breaks-symbolic-link-when-savi.patch BuildArch: noarch BuildRequires: python-devel epydoc python-setuptools systemd-units python-six python-pyudev Requires: python-kmod python-six python-pyudev @@ -69,18 +57,6 @@ API for generic Linux SCSI kernel target. %patch1 -p1 %patch2 -p1 %patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 %if 0%{?with_python3} rm -rf %{py3dir} @@ -154,6 +130,15 @@ popd %doc doc/html %changelog +* Tue May 14 2019 Maurizio Lombardi - 2.1.fb69-3 +- save_to_file() function breaks symbolic link when saving configuration + +* Thu Feb 14 2019 Maurizio Lombardi - 2.1.fb69-2 +- report the correct size for partitions + +* Tue Jan 29 2019 Maurizio Lombardi - 2.1.fb69-1 +- Rebase rtslib to upstream version 2.1.fb69 + * Wed Aug 08 2018 Maurizio Lombardi - 2.1.fb63-13 - respin a new release to avoid problems with TPS tests