Example #1
0
def access_group_init_add(req, ag_name, init_id, init_type):
    if init_type != 'iscsi':
        raise TargetdError(TargetdError.NO_SUPPORT, "Only support iscsi")

    tpg = _get_iscsi_tpg()
    # Pre-check:
    #   1. Already in requested access group, return silently.
    #   2. Initiator does not exist.
    #   3. Initiator not used by other access group.

    if init_id in list(NodeACLGroup(tpg, ag_name).wwns):
        return

    for node_acl_group in tpg.node_acl_groups:
        if init_id in list(node_acl_group.wwns):
            raise TargetdError(
                TargetdError.EXISTS_INITIATOR,
                "Requested init_id is used by other access group")
    for node_acl in tpg.node_acls:
        if init_id == node_acl.node_wwn:
            raise TargetdError(TargetdError.EXISTS_INITIATOR,
                               "Requested init_id is in use")

    NodeACLGroup(tpg, ag_name).add_acl(init_id)
    RTSRoot().save_to_file()
Example #2
0
 def refresh(self):
     self._children = set([])
     for so in RTSRoot().storage_objects:
         if so.plugin == 'user':
             idx = so.config.find("/")
             handler = so.config[:idx]
             if handler == self.handler:
                 ui_so = self.so_cls(so, self)
Example #3
0
    def __init__(self):
        self.block_store = {}
        self.target = {}
        self.root = RTSRoot()
        self.iscsi = FabricModule('iscsi')
        self.mapped_luns = {}

        self.get_block_store_objects()
        self.get_targets()
Example #4
0
def access_group_init_del(req, ag_name, init_id, init_type):
    if init_type != 'iscsi':
        raise TargetdError(TargetdError.NO_SUPPORT, "Only support iscsi")

    tpg = _get_iscsi_tpg()

    # Pre-check:
    #   1. Initiator is not in requested access group, return silently.
    if init_id not in list(NodeACLGroup(tpg, ag_name).wwns):
        return

    NodeACLGroup(tpg, ag_name).remove_acl(init_id)
    RTSRoot().save_to_file()
Example #5
0
def access_group_map_destroy(req, pool_name, vol_name, ag_name):
    tpg = _get_iscsi_tpg()
    node_acl_group = NodeACLGroup(tpg, ag_name)
    tpg_lun = _tpg_lun_of(tpg, pool_name, vol_name)
    for map_group in node_acl_group.mapped_lun_groups:
        if map_group.tpg_lun == tpg_lun:
            map_group.delete()

    if not any(tpg_lun.mapped_luns):
        # If LUN is not masked to any access group or initiator
        # remove LUN instance.
        lun_so = tpg_lun.storage_object
        tpg_lun.delete()
        lun_so.delete()

    RTSRoot().save_to_file()
Example #6
0
def export_create(req, pool, vol, initiator_wwn, lun):

    fm = FabricModule('iscsi')
    t = Target(fm, target_name)
    tpg = TPG(t, 1)
    tpg.enable = True
    tpg.set_attribute("authentication", '0')
    NetworkPortal(tpg, "0.0.0.0")
    na = NodeACL(tpg, initiator_wwn)

    tpg_lun = _tpg_lun_of(tpg, pool, vol)

    # only add mapped lun if it doesn't exist
    for tmp_mlun in tpg_lun.mapped_luns:
        if tmp_mlun.mapped_lun == lun and tmp_mlun.parent_nodeacl == na:
            break
    else:
        MappedLUN(na, lun, tpg_lun)

    RTSRoot().save_to_file()
Example #7
0
def access_group_map_create(req, pool_name, vol_name, ag_name, h_lun_id=None):
    tpg = _get_iscsi_tpg()
    tpg.enable = True
    tpg.set_attribute("authentication", '0')

    set_portal_addresses(tpg)

    tpg_lun = _tpg_lun_of(tpg, pool_name, vol_name)

    # Pre-Check:
    #   1. Already mapped to requested access group, return None
    if any(tpg_lun.mapped_luns):
        tgt_map_list = access_group_map_list(req)
        for tgt_map in tgt_map_list:
            if tgt_map['ag_name'] == ag_name and \
                    tgt_map['pool_name'] == pool_name and \
                    tgt_map['vol_name'] == vol_name:
                # Already masked.
                return None

    node_acl_group = NodeACLGroup(tpg, ag_name)
    if not any(node_acl_group.wwns):
        # Non-existent access group means volume mapping status will not be
        # stored. This should be considered as an error instead of silently
        # returning.
        raise TargetdError(TargetdError.NOT_FOUND_ACCESS_GROUP,
                           "Access group not found")

    if h_lun_id is None:
        # Find out next available host LUN ID
        # Assuming max host LUN ID is MAX_LUN
        free_h_lun_ids = set(range(MAX_LUN + 1)) - \
                         set([int(x.mapped_lun) for x in tpg_lun.mapped_luns])
        if len(free_h_lun_ids) == 0:
            raise TargetdError(TargetdError.NO_FREE_HOST_LUN_ID,
                               "All host LUN ID 0 ~ %d is in use" % MAX_LUN)
        else:
            h_lun_id = free_h_lun_ids.pop()

    node_acl_group.mapped_lun_group(h_lun_id, tpg_lun)
    RTSRoot().save_to_file()
Example #8
0
def initiator_set_auth(req, initiator_wwn, in_user, in_pass, out_user,
                       out_pass):
    fm = FabricModule('iscsi')
    t = Target(fm, target_name)
    tpg = TPG(t, 1)
    na = NodeACL(tpg, initiator_wwn)

    if not in_user or not in_pass:
        # rtslib treats '' as its NULL value for these
        in_user = in_pass = ''

    if not out_user or not out_pass:
        out_user = out_pass = ''

    na.chap_userid = in_user
    na.chap_password = in_pass

    na.chap_mutual_userid = out_user
    na.chap_mutual_password = out_pass

    RTSRoot().save_to_file()
Example #9
0
def export_destroy(req, pool, vol, initiator_wwn):
    mod = pool_module(pool)
    fm = FabricModule('iscsi')
    t = Target(fm, target_name)
    tpg = TPG(t, 1)
    na = NodeACL(tpg, initiator_wwn)

    pool_dev_name = mod.pool2dev_name(pool)

    for mlun in na.mapped_luns:
        # all SOs are Block so we can access udev_path safely
        if mod.has_udev_path(mlun.tpg_lun.storage_object.udev_path):
            mlun_vg, mlun_name = \
                mod.split_udev_path(mlun.tpg_lun.storage_object.udev_path)

            if mlun_vg == pool_dev_name and mlun_name == vol:
                tpg_lun = mlun.tpg_lun
                mlun.delete()
                # be tidy and delete unused tpg lun mappings?
                if not any(tpg_lun.mapped_luns):
                    so = tpg_lun.storage_object
                    tpg_lun.delete()
                    so.delete()
                break
    else:
        raise TargetdError(TargetdError.NOT_FOUND_VOLUME_EXPORT,
                           "Volume '%s' not found in %s exports" %
                           (vol, initiator_wwn))

    # Clean up tree if branch has no leaf
    if not any(na.mapped_luns):
        na.delete()
        if not any(tpg.node_acls):
            tpg.delete()
            if not any(t.tpgs):
                t.delete()

    RTSRoot().save_to_file()
Example #10
0
def access_group_create(req, ag_name, init_id, init_type):
    if init_type != 'iscsi':
        raise TargetdError(TargetdError.NO_SUPPORT, "Only support iscsi")

    name_check(ag_name)

    tpg = _get_iscsi_tpg()

    # Pre-check:
    #   1. Name conflict: requested name is in use
    #   2. Initiator conflict:  request initiator is in use

    for node_acl_group in tpg.node_acl_groups:
        if node_acl_group.name == ag_name:
            raise TargetdError(TargetdError.NAME_CONFLICT,
                               "Requested access group name is in use")

    if init_id in list(i.node_wwn for i in tpg.node_acls):
        raise TargetdError(TargetdError.EXISTS_INITIATOR,
                           "Requested init_id is in use")

    node_acl_group = NodeACLGroup(tpg, ag_name)
    node_acl_group.add_acl(init_id)
    RTSRoot().save_to_file()
Example #11
0
def export_destroy(req, pool, vol, initiator_wwn):
    pool_check(pool)
    fm = FabricModule('iscsi')
    t = Target(fm, target_name)
    tpg = TPG(t, 1)
    na = NodeACL(tpg, initiator_wwn)

    vg_name, thin_pool = get_vg_lv(pool)

    for mlun in na.mapped_luns:
        # all SOs are Block so we can access udev_path safely
        mlun_vg, mlun_name = \
            mlun.tpg_lun.storage_object.udev_path.split("/")[2:]

        if mlun_vg == vg_name and mlun_name == vol:
            tpg_lun = mlun.tpg_lun
            mlun.delete()
            # be tidy and delete unused tpg lun mappings?
            if not any(tpg_lun.mapped_luns):
                so = tpg_lun.storage_object
                tpg_lun.delete()
                so.delete()
            break
    else:
        raise TargetdError(
            -151, "Volume '%s' not found in %s exports" % (vol, initiator_wwn))

    # Clean up tree if branch has no leaf
    if not any(na.mapped_luns):
        na.delete()
        if not any(tpg.node_acls):
            tpg.delete()
            if not any(t.tpgs):
                t.delete()

    RTSRoot().save_to_file()
Example #12
0
 def __init__(self, shell, as_root=False):
     UINode.__init__(self, '/', shell=shell)
     self.as_root = as_root
     self.rtsroot = RTSRoot()
Example #13
0
def access_group_destroy(req, ag_name):
    NodeACLGroup(_get_iscsi_tpg(), ag_name).delete()
    RTSRoot().save_to_file()
Example #14
0
    def ui_command_create(self,
                          name,
                          file_or_dev,
                          size=None,
                          write_back=None,
                          sparse=None,
                          wwn=None):
        '''
        Creates a FileIO storage object. If I{file_or_dev} is a path
        to a regular file to be used as backend, then the I{size}
        parameter is mandatory. Else, if I{file_or_dev} is a path to a
        block device, the size parameter B{must} be ommited. If
        present, I{size} is the size of the file to be used, I{file}
        the path to the file or I{dev} the path to a block device. The
        I{write_back} parameter is a boolean controlling write
        caching. It is enabled by default. The I{sparse} parameter is
        only applicable when creating a new backing file. It is a
        boolean stating if the created file should be created as a
        sparse file (the default), or fully initialized.

        SIZE SYNTAX
        ===========
        - If size is an int, it represents a number of bytes.
        - If size is a string, the following units can be used:
            - B{B} or no unit present for bytes
            - B{k}, B{K}, B{kB}, B{KB} for kB (kilobytes)
            - B{m}, B{M}, B{mB}, B{MB} for MB (megabytes)
            - B{g}, B{G}, B{gB}, B{GB} for GB (gigabytes)
            - B{t}, B{T}, B{tB}, B{TB} for TB (terabytes)
        '''
        self.assert_root()

        sparse = self.ui_eval_param(sparse, 'bool', True)
        write_back = self.ui_eval_param(write_back, 'bool', True)
        wwn = self.ui_eval_param(wwn, 'string', None)

        self.shell.log.debug("Using params size=%s write_back=%s sparse=%s" %
                             (size, write_back, sparse))

        file_or_dev = os.path.expanduser(file_or_dev)
        # can't use is_dev_in_use() on files so just check against other
        # storage object paths
        if os.path.exists(file_or_dev):
            for so in RTSRoot().storage_objects:
                if so.udev_path and os.path.samefile(file_or_dev,
                                                     so.udev_path):
                    raise ExecutionError("storage object for %s already exists: %s" % \
                                             (file_or_dev, so.name))

        if get_block_type(file_or_dev) is not None:
            if size:
                self.shell.log.info("Block device, size parameter ignored")
                size = None
            self.shell.log.info(
                "Note: block backstore preferred for best results")
        else:
            # use given file size only if backing file does not exist
            if os.path.isfile(file_or_dev):
                new_size = os.path.getsize(file_or_dev)
                if size:
                    self.shell.log.info(
                        "%s exists, using its size (%s bytes) instead" %
                        (file_or_dev, new_size))
                size = new_size
            elif os.path.exists(file_or_dev):
                raise ExecutionError("Path %s exists but is not a file" %
                                     file_or_dev)
            else:
                # create file and extend to given file size
                if not size:
                    raise ExecutionError("Attempting to create file for new" +
                                         " fileio backstore, need a size")
                size = human_to_bytes(size)
                self._create_file(file_or_dev, size, sparse)

        so = FileIOStorageObject(name,
                                 file_or_dev,
                                 size,
                                 write_back=write_back,
                                 wwn=wwn)
        ui_so = UIFileioStorageObject(so, self)
        self.setup_model_alias(so)
        self.shell.log.info("Created fileio %s with size %s" % (name, so.size))
        return self.new_node(ui_so)
Example #15
0
 def refresh(self):
     self._children = set([])
     for so in RTSRoot().storage_objects:
         if so.plugin == self.name:
             ui_so = self.so_cls(so, self)