File rtslib-fb-rbd-support.patch of Package python-rtslib.1545
rtslib-fb patches backported to SLE12 rtslib, obtained from:
http://permalink.gmane.org/gmane.comp.file-systems.ceph.devel/26263
Index: rtslib-2.2/rtslib/tcm.py
===================================================================
--- rtslib-2.2.orig/rtslib/tcm.py
+++ rtslib-2.2/rtslib/tcm.py
@@ -262,6 +262,41 @@ class IBlockBackstore(Backstore):
return IBlockStorageObject(self, name=name, dev=dev,
gen_wwn=gen_wwn)
+class RBDBackstore(Backstore):
+ '''
+ This is an interface to Ceph RBD backstore plugin objects in configFS.
+ An RBDBackstore object is identified by its backstore index.
+ '''
+
+ # RBDBackstore private stuff
+
+ def __init__(self, index, mode='any'):
+ '''
+ @param index: The backstore index.
+ @type index: int
+ @param mode: An optional string containing the object creation mode:
+ - I{'any'} the configFS object will be either lookupd or created.
+ - I{'lookup'} the object MUST already exist configFS.
+ - I{'create'} the object must NOT already exist in configFS.
+ @type mode:string
+ @return: An RBDBackstore object.
+ '''
+
+ super(RBDBackstore, self).__init__("rbd", RBDStorageObject,
+ index, mode)
+
+ # RBDBackstore public stuff
+
+ def storage_object(self, name, dev=None, wwn=None, readonly=False,
+ write_back=False):
+ '''
+ Same as RBDStorageObject() without specifying the backstore
+ '''
+ self._check_self()
+ return RBDStorageObject(self, name=name, dev=dev, wwn=wwn,
+ readonly=readonly, write_back=write_back)
+
+
class StorageObject(CFSNode):
'''
This is an interface to storage objects in configFS. A StorageObject is
@@ -954,6 +989,110 @@ class IBlockStorageObject(StorageObject)
minor = property(_get_minor,
doc="Get the block device minor number")
+class RBDStorageObject(StorageObject):
+ '''
+ An interface to configFS storage objects for RBD backstore.
+ '''
+
+ # RBDStorageObject private stuff
+
+ def __init__(self, backstore, name, dev=None, wwn=None, readonly=False,
+ write_back=False):
+ '''
+ A RBDIOStorageObject can be instantiated in two ways:
+ - B{Creation mode}: If I{dev} is specified, the underlying configFS
+ object will be created with that parameter.
+ No RBDIOStorageObject with the same I{name} can pre-exist in
+ the parent Backstore in that mode.
+ - B{Lookup mode}: If I{dev} is not set, then the
+ RBDIOStorageObject will be bound to the existing configFS
+ object in the parent Backstore having the specified
+ I{name}. The underlying configFS object must already exist in
+ that mode, or instantiation will fail.
+
+ @param name: The name of the RBDIOStorageObject.
+ @type name: string
+ @param dev: The path to the backend rbd device to be used.
+ - Example: I{dev="/dev/sda"}.
+ - The only device type that is accepted I{TYPE_DISK}.
+ For other device types, use pscsi.
+ @type dev: string
+ @param wwn: T10 WWN Unit Serial, will generate if None
+ @type wwn: string
+ @return: A RBDIOStorageObject object.
+ '''
+
+ if dev is not None:
+ super(RBDStorageObject, self).__init__(backstore,
+ RBDBackstore,
+ name,
+ 'create')
+ try:
+ self._configure(dev, wwn, readonly)
+ except:
+ self.delete()
+ raise
+ else:
+ super(RBDStorageObject, self).__init__(backstore,
+ RBDBackstore,
+ name,
+ 'lookup')
+
+ def _configure(self, dev, wwn, readonly):
+ self._check_self()
+ if get_block_type(dev) != 0:
+ raise RTSLibError("Device %s is not a TYPE_DISK rbd device" % dev)
+ if is_dev_in_use(dev):
+ raise RTSLibError("Cannot configure StorageObject because "
+ + "device %s is already in use." % dev)
+ self._set_udev_path(dev)
+ self._control("udev_path=%s" % dev)
+ self._control("readonly=%d" % readonly)
+ self._enable()
+ if wwn:
+ self.wwn = wwn
+ else:
+ self.wwn = generate_wwn('unit_serial')
+
+ def _get_major(self):
+ self._check_self()
+ return int(self._parse_info('Major'))
+
+ def _get_minor(self):
+ self._check_self()
+ return int(self._parse_info('Minor'))
+
+ def _get_wb_enabled(self):
+ self._check_self()
+ return bool(int(self.get_attribute("emulate_write_cache")))
+
+ def _get_readonly(self):
+ self._check_self()
+ # 'readonly' not present before kernel 3.6
+ try:
+ return bool(int(self._parse_info('readonly')))
+ except AttributeError:
+ return False
+
+ # RBDStorageObject public stuff
+
+ major = property(_get_major,
+ doc="Get the block device major number")
+ minor = property(_get_minor,
+ doc="Get the block device minor number")
+ write_back = property(_get_wb_enabled,
+ doc="True if write-back, False if write-through (write cache disabled)")
+ readonly = property(_get_readonly,
+ doc="True if the device is read-only, False if read/write")
+
+ def dump(self):
+ d = super(RBDStorageObject, self).dump()
+ d['write_back'] = self.write_back
+ d['readonly'] = self.readonly
+ d['wwn'] = self.wwn
+ d['dev'] = self.udev_path
+ return d
+
def _test():
import doctest
doctest.testmod()
Index: rtslib-2.2/rtslib/__init__.py
===================================================================
--- rtslib-2.2.orig/rtslib/__init__.py
+++ rtslib-2.2/rtslib/__init__.py
@@ -27,6 +27,7 @@ from tcm import FileIOBackstore, IBlockB
from tcm import FileIOStorageObject, IBlockStorageObject
from tcm import PSCSIBackstore, RDMCPBackstore
from tcm import PSCSIStorageObject, RDMCPStorageObject
+from tcm import RBDBackstore, RBDStorageObject
from config_filters import *
from config import Config, ConfigError
Index: rtslib-2.2/rtslib/root.py
===================================================================
--- rtslib-2.2.orig/rtslib/root.py
+++ rtslib-2.2/rtslib/root.py
@@ -25,6 +25,7 @@ from node import CFSNode
from target import Target, FabricModule
from tcm import FileIOBackstore, IBlockBackstore
from tcm import PSCSIBackstore, RDMCPBackstore
+from tcm import RBDBackstore
from utils import RTSLibError, RTSLibBrokenLink, modprobe, mount_configfs
class RTSRoot(CFSNode):
@@ -91,6 +92,8 @@ class RTSRoot(CFSNode):
yield IBlockBackstore(int(regex.group(3)), 'lookup')
elif regex.group(1) == "rd_mcp":
yield RDMCPBackstore(int(regex.group(3)), 'lookup')
+ elif regex.group(1) == "rbd":
+ yield RBDBackstore(int(regex.group(3)), 'lookup')
def _list_storage_objects(self):
self._check_self()
Index: rtslib-2.2/rtslib/config_live.py
===================================================================
--- rtslib-2.2.orig/rtslib/config_live.py
+++ rtslib-2.2/rtslib/config_live.py
@@ -32,7 +32,8 @@ from rtslib import (RTSRoot, Target, Fab
FileIOStorageObject, IBlockBackstore,
IBlockStorageObject, PSCSIBackstore,
PSCSIStorageObject, RDMCPBackstore,
- RDMCPStorageObject, RTSLibError)
+ RDMCPStorageObject, RBDBackstore,
+ RBDStorageObject, RTSLibError)
# TODO There seems to be a bug in LIO, affecting both this API and rtslib:
# when a tpg does not contain any objects, it cannot be removed.
@@ -96,7 +97,7 @@ def dump_live_storage():
dump.append("storage %s disk %s {"
% (so.backstore.plugin, so.name))
attrs = []
- if so.backstore.plugin in ['fileio', 'pscsi', 'iblock']:
+ if so.backstore.plugin in ['fileio', 'pscsi', 'iblock', 'rbd']:
attrs.append("%spath %s" % (_indent, so.udev_path))
if so.backstore.plugin in ['fileio', 'rd_mcp']:
attrs.append("%ssize %s" % (_indent, _b2h(so.size)))
@@ -509,6 +510,12 @@ def apply_create_obj(obj):
nullio = obj_attr(obj, "nullio")
lio_so = lio_bs.storage_object(name, size, True, nullio)
apply_group_attrs(obj, lio_so)
+ elif plugin == 'rbd':
+ # TODO Add policy for rbd
+ lio_bs = RBDBackstore(idx)
+ dev = obj_attr(obj, "path")
+ lio_so = lio_bs.storage_object(name, dev)
+ apply_group_attrs(obj, lio_so)
else:
raise ConfigError("Unknown backend '%s' for backstore '%s'"
% (plugin, obj))
Index: rtslib-2.2/policy/backstore_rbd.lio
===================================================================
--- /dev/null
+++ rtslib-2.2/policy/backstore_rbd.lio
@@ -0,0 +1,28 @@
+storage rbd disk %str {
+ path %str
+ attribute {
+ block_size %int(512)
+ emulate_3pc %bool(yes)
+ emulate_caw %bool(yes)
+ emulate_dpo %bool(no)
+ emulate_fua_read %bool(no)
+ emulate_fua_write %bool(yes)
+ emulate_model_alias %bool(no)
+ emulate_rest_reord %bool(no)
+ emulate_tas %bool(yes)
+ emulate_tpu %bool(no)
+ emulate_tpws %bool(no)
+ emulate_ua_intlck_ctrl %bool(no)
+ emulate_write_cache %bool(no)
+ enforce_pr_isids %bool(yes)
+ fabric_max_sectors %int(8192)
+ is_nonrot %bool(yes)
+ max_unmap_block_desc_count %int(0)
+ max_unmap_lba_count %int(0)
+ max_write_same_len %int(65535)
+ optimal_sectors %int(8192)
+ queue_depth %int(128)
+ unmap_granularity %int(0)
+ unmap_granularity_alignment %int(0)
+ }
+}