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 pool_check(pool_name):
    """
    pool_name *cannot* be trusted, funcs taking a pool param must call
    this or vgopen() to ensure passed-in pool name is one targetd has
    been configured to use.
    """
    pool_to_check = get_vg_lv(pool_name)[0]

    if pool_to_check not in [get_vg_lv(x)[0] for x in pools]:
        raise TargetdError(-110, "Invalid pool")
Example #3
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')
    NetworkPortal(tpg, "0.0.0.0")

    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 LUN.MAX_LUN
        free_h_lun_ids = set(range(LUN.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" % LUN.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 #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 destroy(req, pool, name):
    with ignored(RTSLibNotInCFS):
        fm = FabricModule('iscsi')
        t = Target(fm, target_name, mode='lookup')
        tpg = TPG(t, 1, mode='lookup')

        so_name = "%s:%s" % (pool, name)
        if so_name in (lun.storage_object.name for lun in tpg.luns):
            raise TargetdError(
                -303, "Volume '%s' cannot be "
                "removed while exported" % name)

    with vgopen(get_vg_lv(pool)[0]) as vg:
        vg.lvFromName(name).remove()
Example #6
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 #7
0
def create(req, pool, name, size):

    # Check to ensure that we don't have a volume with this name already,
    # lvm will fail if we try to create a LV with a duplicate name
    if any(v['name'] == name for v in volumes(req, pool)):
        raise TargetdError(TargetdError.NAME_CONFLICT,
                           "Volume with that name exists")

    vg_name, lv_pool = get_vg_lv(pool)
    with vgopen(vg_name) as vg:
        if lv_pool:
            # Fall back to non-thinp if needed
            try:
                vg.createLvThin(lv_pool, name, int(size))
            except AttributeError:
                vg.createLvLinear(name, int(size))
        else:
            vg.createLvLinear(name, int(size))
Example #8
0
def copy(req, pool, vol_orig, vol_new, timeout=10):
    """
    Create a new volume that is a copy of an existing one.
    Since 0.6, requires thinp support.
    """
    if any(v['name'] == vol_new for v in volumes(req, pool)):
        raise TargetdError(TargetdError.NAME_CONFLICT,
                           "Volume with that name exists")

    vg_name, thin_pool = get_vg_lv(pool)

    with vgopen(vg_name) as vg:
        if not thin_pool:
            raise RuntimeError("copy requires thin-provisioned volumes")

        try:
            vg.lvFromName(vol_orig).snapshot(vol_new)
        except AttributeError:
            raise NotImplementedError("liblvm lacks thin snap support")
Example #9
0
def initialize(config_dict):

    global pools
    pools = config_dict['block_pools']

    global target_name
    target_name = config_dict['target_name']

    # fail early if can't access any vg
    for pool in pools:
        vg_name, thin_pool = get_vg_lv(pool)
        test_vg = lvm.vgOpen(vg_name)
        test_vg.close()

        # Allowed multi-pool configs:
        # two thinpools from a single vg: ok
        # two vgs: ok
        # vg and a thinpool from that vg: BAD
        #
        if thin_pool and vg_name in pools:
            raise TargetdError(
                -1, "VG pool and thin pool from same VG not supported")

    return dict(
        vol_list=volumes,
        vol_create=create,
        vol_destroy=destroy,
        vol_copy=copy,
        export_list=export_list,
        export_create=export_create,
        export_destroy=export_destroy,
        initiator_set_auth=initiator_set_auth,
        initiator_list=initiator_list,
        access_group_list=access_group_list,
        access_group_create=access_group_create,
        access_group_destroy=access_group_destroy,
        access_group_init_add=access_group_init_add,
        access_group_init_del=access_group_init_del,
        access_group_map_list=access_group_map_list,
        access_group_map_create=access_group_map_create,
        access_group_map_destroy=access_group_map_destroy,
    )
Example #10
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()