def create_filtered_volume(req, handler=None, name=None, filters=None, device=None, serial=None): filters = filters or [] handler = handler or "mp_filter_stack" if not name: raise TargetdError(GENERAL_TARGETD_ERROR, "No name specified.") err = _alnum(name, extras='_-') if err: raise TargetdError(GENERAL_TARGETD_ERROR, "%r: %s" % (name, err)) if not (device or serial): raise TargetdError(GENERAL_TARGETD_ERROR, "No device specified.") if serial and not device: device = _device_from_serial(serial) if not device or not os.path.exists(device): raise TargetdError(GENERAL_TARGETD_ERROR, "Device not found.") _validate_filters(filters) filterstack = '>'.join(filters) if filterstack: filterstack += '>' config_str = handler + '/>' + filterstack + device filtered_dev = rtslib.UserBackedStorageObject(name, config=config_str, size=_device_size(device)) log.debug("Created %s on %s" % (name, filterstack + device)) tcm_loop = rtslib.FabricModule("loopback") target = rtslib.Target(tcm_loop) tpg = rtslib.TPG(target, 1) lun = rtslib.LUN(tpg, 0, filtered_dev) log.debug("Created loopback target %s on %s" % (target.wwn, name)) for delay in range(1, 4): time.sleep(delay) dev = _device_from_wwn(filtered_dev.wwn) if dev: log.debug("Target %s is at %s" % (target.wwn, dev)) return dev
def _start_lio(iqn, portal_port, device): try: storage = rtslib_fb.BlockStorageObject(name=iqn, dev=device) target = rtslib_fb.Target(rtslib_fb.FabricModule('iscsi'), iqn, mode='create') tpg = rtslib_fb.TPG(target, mode='create') # disable all authentication tpg.set_attribute('authentication', '0') tpg.set_attribute('demo_mode_write_protect', '0') tpg.set_attribute('generate_node_acls', '1') # lun=1 is hardcoded in ironic rtslib_fb.LUN(tpg, storage_object=storage, lun=1) tpg.enable = 1 except rtslib_fb.utils.RTSLibError as exc: msg = 'Failed to create a target: {}'.format(exc) raise errors.ISCSIError(msg) try: # bind to the default port on all interfaces listen_ip = netutils.wrap_ipv6(netutils.get_wildcard_address()) rtslib_fb.NetworkPortal(tpg, listen_ip, portal_port) except rtslib_fb.utils.RTSLibError as exc: msg = 'Failed to publish a target: {}'.format(exc) raise errors.ISCSIError(msg)
def create(backing_device, name, userid, password, iser_enabled, initiator_iqns=None, portals_ips=None, portals_port=3260): # List of IPS that will not raise an error when they fail binding. # Originally we will fail on all binding errors. ips_allow_fail = () try: rtsroot = rtslib_fb.root.RTSRoot() except rtslib_fb.utils.RTSLibError: print(_('Ensure that configfs is mounted at /sys/kernel/config.')) raise # Look to see if BlockStorageObject already exists for x in rtsroot.storage_objects: if x.name == name: # Already exists, use this one return so_new = rtslib_fb.BlockStorageObject(name=name, dev=backing_device) target_new = rtslib_fb.Target(rtslib_fb.FabricModule('iscsi'), name, 'create') tpg_new = rtslib_fb.TPG(target_new, mode='create') tpg_new.set_attribute('authentication', '1') lun_new = rtslib_fb.LUN(tpg_new, storage_object=so_new) if initiator_iqns: initiator_iqns = initiator_iqns.strip(' ') for i in initiator_iqns.split(','): acl_new = rtslib_fb.NodeACL(tpg_new, i, mode='create') acl_new.chap_userid = userid acl_new.chap_password = password rtslib_fb.MappedLUN(acl_new, lun_new.lun, lun_new.lun) tpg_new.enable = 1 # If no ips are given we'll bind to all IPv4 and v6 if not portals_ips: portals_ips = ('0.0.0.0', '::0') # TODO(emh): Binding to IPv6 fails sometimes -- let pass for now. ips_allow_fail = ('::0',) for ip in portals_ips: try:
def create(backing_device, name, userid, password, iser_enabled, initiator_iqns=None, portals_ips=None, portals_port=3260): # List of IPS that will not raise an error when they fail binding. # Originally we will fail on all binding errors. ips_allow_fail = () try: rtsroot = rtslib_fb.root.RTSRoot() except rtslib_fb.utils.RTSLibError: print(_('Ensure that configfs is mounted at /sys/kernel/config.')) raise # Look to see if BlockStorageObject already exists for x in rtsroot.storage_objects: if x.name == name: # Already exists, use this one return so_new = rtslib_fb.BlockStorageObject(name=name, dev=backing_device) target_new = rtslib_fb.Target(rtslib_fb.FabricModule('iscsi'), name, 'create') tpg_new = rtslib_fb.TPG(target_new, mode='create') tpg_new.set_attribute('authentication', '1') lun_new = rtslib_fb.LUN(tpg_new, storage_object=so_new) if initiator_iqns: initiator_iqns = initiator_iqns.strip(' ') for i in initiator_iqns.split(','): acl_new = rtslib_fb.NodeACL(tpg_new, i, mode='create') acl_new.chap_userid = userid acl_new.chap_password = password rtslib_fb.MappedLUN(acl_new, lun_new.lun, lun_new.lun) tpg_new.enable = 1 # If no ips are given we'll bind to all IPv4 and v6 if not portals_ips: portals_ips = ('0.0.0.0', '::0') # TODO(emh): Binding to IPv6 fails sometimes -- let pass for now. ips_allow_fail = ('::0', ) for ip in portals_ips: try: portal = rtslib_fb.NetworkPortal(tpg_new, ip, portals_port, mode='any') except rtslib_fb.utils.RTSLibError: raise_exc = ip not in ips_allow_fail msg_type = 'Error' if raise_exc else 'Warning' print( _('%(msg_type)s: creating NetworkPortal: ensure port ' '%(port)d on ip %(ip)s is not in use by another service.') % { 'msg_type': msg_type, 'port': portals_port, 'ip': ip }) if raise_exc: raise else: try: if iser_enabled == 'True': portal.iser = True except rtslib_fb.utils.RTSLibError: print( _('Error enabling iSER for NetworkPortal: please ensure ' 'that RDMA is supported on your iSCSI port %(port)d ' 'on ip %(ip)s.') % { 'port': portals_port, 'ip': ip }) raise
#!/usr/bin/env python import rtslib_fb import commands ips = commands.getoutput( "/sbin/ifconfig | grep -i \"inet\" | grep -iv \"inet6\" | " + "awk {'print $2'} | grep -v 127.0.0.1").splitlines() iscsi = rtslib_fb.FabricModule("iscsi") f = rtslib_fb.FileIOStorageObject("test1", "/tmp/test.img", 2000000000) f2 = rtslib_fb.FileIOStorageObject("test2", "/tmp/test2.img", 2000000000) target = rtslib_fb.Target(iscsi) tpg = rtslib_fb.TPG(target, 1) tpg.enable = True tpg.set_attribute("authentication", False) tpg.set_attribute("demo_mode_write_protect", False) for ip in ips: rtslib_fb.NetworkPortal(tpg, ip, 3260) lun = rtslib_fb.LUN(tpg, 0, f) lun2 = rtslib_fb.LUN(tpg, 1, f2) tpg.set_attribute("cache_dynamic_acls", True) tpg.set_attribute("generate_node_acls", True) print target.wwn
def create_base_user_backstores( name, config, size, userid, password, iser_enabled, initiator_iqns=None, portals_ips=None, portals_port=3260): ''' This function allow you to create a target base an userspace backstores, for example, user:rbd, user:glfs, user:qcow etc. you should install and run tcmu-runner first, see more information: https://github.com/open-iscsi/tcmu-runner ''' # List of IPS that will not raise an error when they fail binding. # Originally we will fail on all binding errors. ips_allow_fail = () try: rtsroot = rtslib_fb.root.RTSRoot() except rtslib_fb.utils.RTSLibError: print(_('Ensure that configfs is mounted at /sys/kernel/config.')) raise # Look to see if UserBackedStorageObject already exists for x in rtsroot.storage_objects: if x.name == name: # Already exists, use this one return # create an object of class UserBackedStorageObject: so_new so_new = rtslib_fb.UserBackedStorageObject(name=name, config=config, size=size) # create an object of class Target: target_new target_new = rtslib_fb.Target(rtslib_fb.FabricModule('iscsi'), name, 'create') # create an object of class TPG: tpg_new tpg_new = rtslib_fb.TPG(target_new, mode='create') tpg_new.set_attribute('authentication', '1') # create an object of class LUN: lun_new lun_new = rtslib_fb.LUN(tpg_new, storage_object=so_new) if initiator_iqns: initiator_iqns = initiator_iqns.strip(' ') for i in initiator_iqns.split(','): acl_new = rtslib_fb.NodeACL(tpg_new, i, mode='create') acl_new.chap_userid = userid acl_new.chap_password = password rtslib_fb.MappedLUN(acl_new, lun_new.lun, lun_new.lun) tpg_new.enable = 1 # If no ips are given we'll bind to all IPv4 and v6 if not portals_ips: portals_ips = ('0.0.0.0', '[::0]') # TODO(emh): Binding to IPv6 fails sometimes -- let pass for now. ips_allow_fail = ('[::0]',) for ip in portals_ips: try: # rtslib expects IPv6 addresses to be surrounded by brackets portal = rtslib_fb.NetworkPortal(tpg_new, _canonicalize_ip(ip), portals_port, mode='any') except rtslib_fb.utils.RTSLibError: raise_exc = ip not in ips_allow_fail msg_type = 'Error' if raise_exc else 'Warning' print(_('%(msg_type)s: creating NetworkPortal: ensure port ' '%(port)d on ip %(ip)s is not in use by another service.') % {'msg_type': msg_type, 'port': portals_port, 'ip': ip}) if raise_exc: raise else: try: if iser_enabled == 'True': portal.iser = True except rtslib_fb.utils.RTSLibError: print(_('Error enabling iSER for NetworkPortal: please ensure ' 'that RDMA is supported on your iSCSI port %(port)d ' 'on ip %(ip)s.') % {'port': portals_port, 'ip': ip}) raise
def add_device_to_luns(device, luns): """ Add a new LUN entry for the provided device path. Returns an updated LUN dict and a status message string. Checks for same device path already being shared and skips making changes. Changing to check for duplicate names/serial numbers instead could be better but there would need to be a lot of checking to make sure bad lookups/duplicate serials don't creep in and ruin the show. """ # Cleanup the device name and make sure it exists t = fix_device_path(device) if not t: msg = "Failed to find device %s - Not adding to LUNs" % device logger.warning(msg) return (luns, msg) device = t # Make sure the device is not already in the list device_exists = 0 for lunid in luns: if luns[lunid]['device'] == device: msg = "Device %s already mapped to LUN %s" % (device, lunid) logger.info(msg) return (luns, msg) # Lookup the device prefered path, serial, and name (device, serial) = fetch_device_path_and_serial(device) if config.getboolean('lookup', 'enable'): name = translate_serial_to_name(serial) else: name = serial # Find the lowest free LUN over 0 and add a new entry for i in range(1, 255): lunid = str(i) if not lunid in luns: # Found one! luns[lunid] = {} luns[lunid]['device'] = device luns[lunid]['name'] = name luns[lunid]['serial'] = serial break if not lunid: # No free LUN IDs found. Not good. msg = "Unable to map device %s (path %s, serial %s) - No free LUNs found" % ( name, device, serial) logger.warning(msg) return (luns, msg) # Build the backing device try: bso = rtslib.BlockStorageObject(name=name, dev=device, wwn=name) except rtslib.utils.RTSLibError as err: raise GeneralError( "RTSLib error when trying to define block device object %s: %s" % (device, err)) # Get the device control path for the iBlock storage luns[lunid]['device_syspath'] = bso.path # Map the LUN try: target = fetch_target(config['system']['target_name']) # Only target group 1 is supported at this time. If you want different # auth sets/etc then make another whole target/WWN tpgs = next(target.tpgs) lun = rtslib.LUN(tpgs, lun=lunid, storage_object=bso, alias=name) except rtslib.utils.RTSLibError as err: raise GeneralError( "RTSLib error when trying to map LUN %s to device object %s: %s" % (lunid, device, err)) msg = "Mapped device %s (path %s, serial %s) to LUN %s" % (name, device, serial, lunid) logger.info(msg) return (luns, msg)