File Auto-detect-readonly-state-for-iblock-devices.patch of Package targetcli-fb

From 5d1abab36be9375f46210dd19d5293cf73433681 Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@suse.de>
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 <ddiss@suse.de>
(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

openSUSE Build Service is sponsored by