summaryrefslogtreecommitdiff
path: root/targetcli
diff options
context:
space:
mode:
authorDavid Disseldorp <ddiss@suse.de>2017-12-07 15:25:35 +0100
committerDavid Disseldorp <ddiss@suse.de>2017-12-12 11:46:33 +0100
commit1a0886ecbcba6d5b2d9756ecadb3e2eaab99d29e (patch)
tree01c45e5b66d5f9a5d131660fe7409f5ed28a5a56 /targetcli
parenta448b15419cf928e1bbb8ffc17c0b0726df86ae9 (diff)
downloadtargetcli-1a0886ecbcba6d5b2d9756ecadb3e2eaab99d29e.tar.gz
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>
Diffstat (limited to 'targetcli')
-rw-r--r--targetcli/ui_backstore.py30
1 files changed, 29 insertions, 1 deletions
diff --git a/targetcli/ui_backstore.py b/targetcli/ui_backstore.py
index 2140e88..3a2db10 100644
--- a/targetcli/ui_backstore.py
+++ b/targetcli/ui_backstore.py
@@ -20,6 +20,9 @@ under the License.
from gi.repository import Gio
import glob
import os
+import fcntl
+import array
+import struct
import re
import stat
@@ -526,6 +529,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
@@ -533,7 +555,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)