/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <sys/byteorder.h>
#include <sys/stmf_ioctl.h>
#include "stmf_impl.h"
#include "lun_map.h"
#include "stmf_state.h"
/*
* Init the view
*/
void
{
}
/*
* Clear config database here
*/
void
{
sizeof (void *));
}
}
}
/* clear the views for lus */
}
if (idmemb->id_pt_to_object) {
}
}
}
/* free all the host group */
idmemb = idmemb_next) {
}
}
}
}
/* free all the target group */
idmemb = idmemb_next) {
}
}
}
}
}
}
/*
* Create luns map for session based on the view
*/
{
/*
* get the view entry map,
*/
ve_map = stmf_duplicate_ve_map(0);
continue;
}
continue;
}
&ve_map, 0);
}
}
}
/* not configured, cannot access any luns for now */
return (STMF_SUCCESS);
}
/*
* destroy lun map for session
*/
/* ARGSUSED */
{
uint16_t n;
/*
* to avoid conflict with updating session's map,
* which only grab stmf_lock
*/
if (sm->lm_nentries) {
for (n = 0; n < sm->lm_nentries; n++) {
!= NULL) {
if (ent->ent_itl_datap) {
}
ilu = (stmf_i_lu_t *)
sizeof (stmf_lun_map_ent_t));
}
}
}
return (STMF_SUCCESS);
}
/*
* Expects the session lock to be held.
*/
{
int i;
if (nluns == 0) {
data_size += 8;
}
return (NULL);
if (nluns == 0) {
return (xd);
}
ent = 0;
continue;
/* Fill in the entry */
ent++;
}
return (xd);
}
/*
* Add a lu to active sessions based on LUN inventory.
* Only invoked when the lu is onlined
*/
void
{
if (!luid) {
/* we did not configure view for this lun, so just return */
return;
}
}
}
/*
* Unmap a lun from all sessions
*/
void
{
if (ilu->ilu_ref_cnt == 0)
return;
if (!luid) {
/*
* we did not configure view for this lun, this should be
* an error
*/
return;
}
if (ilu->ilu_ref_cnt == 0)
break;
}
}
/*
* add lu to a session, stmf_lock is already held
*/
{
}
/*
* do not set lun inventory flag for standby port
* as this would be handled from peer
*/
if (ilport->ilport_standby == 0) {
}
return (STMF_SUCCESS);
}
/*
* remvoe lu from a session, stmf_lock is already held
*/
/* ARGSUSED */
{
if (lun_map_ent->ent_itl_datap) {
}
return (STMF_SUCCESS);
}
/*
* add or remove lu from all related sessions based on view entry,
* action is 0 for delete, 1 for add
*/
void
{
if (!lu) {
if (!ilu_tmp)
return;
} else {
}
all_hg = 1;
all_tg = 1;
/* No sessions to be updated */
return;
continue;
/* This ilport belongs to the target group */
continue;
/* This host belongs to the host group */
if (action == 0) { /* to remove */
if (ilu_tmp->ilu_ref_cnt == 0) {
return;
}
} else {
}
}
}
}
/*
* add luns in view entry map to a session,
* and stmf_lock is already held
*/
void
{
uint32_t i;
for (i = 0; i < vemap->lm_nentries; i++) {
if (!ve)
continue;
}
}
}
/* remove luns in view entry map from a session */
void
{
uint32_t i;
for (i = 0; i < vemap->lm_nentries; i++) {
if (!ve)
continue;
}
}
}
{
if (additional_size) {
}
return (id);
}
void
{
}
{
return (id);
}
}
return (NULL);
}
/* Return the target group which a target belong to */
{
ident_size, ident);
if (target)
return (tgid);
}
return (NULL);
}
/* Return the host group which a host belong to */
{
ident_size, ident);
if (host)
return (hgid);
}
return (NULL);
}
void
{
} else {
}
}
void
{
} else {
}
} else {
}
}
/*
* The refcnts of objects in a view entry are updated when then entry
* is successfully added. ve_map is just another representation of the
* view enrtries in a LU. Duplicating or merging a ve map does not
* affect any refcnts.
*/
{
int i;
return (dst);
if (src->lm_nentries) {
sizeof (void *), KM_SLEEP);
for (i = 0; i < dst->lm_nentries; i++) {
}
}
return (dst);
}
void
{
if (dst->lm_nentries) {
}
}
int
{
int i;
int nentries;
int to_create_space = 0;
return (1);
}
if (mf & MERGE_FLAG_RETURN_NEW_MAP)
else
*pp_ret_map = dst;
return (1);
}
if (mf & MERGE_FLAG_RETURN_NEW_MAP) {
to_create_space = 1;
} else {
*pp_ret_map = dst;
/* If there is not enough space in dst map */
to_create_space = 1;
}
}
if (to_create_space) {
void **p;
if (dst->lm_nentries) {
dst->lm_nentries * sizeof (void *));
}
if (mf & (MERGE_FLAG_RETURN_NEW_MAP == 0))
dst->lm_nentries * sizeof (void *));
(*pp_ret_map)->lm_plus = p;
}
for (i = 0; i < src->lm_nentries; i++) {
continue;
if (mf & MERGE_FLAG_NO_DUPLICATE) {
if (mf & MERGE_FLAG_RETURN_NEW_MAP) {
*pp_ret_map = NULL;
}
return (0);
}
} else {
}
}
return (1);
}
/*
* add host group, id_impl_specific point to a list of hosts,
* on return, if error happened, err_detail may be assigned if
* the pointer is not NULL
*/
{
if (!allow_special) {
if (hg_name[0] == '*')
return (STMF_INVALID_ARG);
}
if (err_detail)
return (STMF_ALREADY);
}
return (STMF_SUCCESS);
}
/* add target group */
{
if (!allow_special) {
if (tg_name[0] == '*')
return (STMF_INVALID_ARG);
}
if (err_detail)
return (STMF_ALREADY);
}
return (STMF_SUCCESS);
}
/*
* insert view entry into list for a luid, if ve->ve_id is 0xffffffff,
* pick up a smallest available veid for it, and return the veid in ve->ve_id.
* The view entries list is sorted based on veid.
*/
{
break;
return (STMF_ALREADY);
}
}
} else {
/* search the smallest available veid */
break;
veid++;
if (veid == 0xffffffff)
return (STMF_NOT_SUPPORTED);
}
}
/* insert before ve_tmp if it exist */
if (ve_tmp) {
}
if (ve_prev) {
} else {
}
return (STMF_SUCCESS);
}
/* stmf_lock is already held, err_detail may be assigned if error happens */
{
char luid_new;
if (ilu) {
}
luid_new = 1;
} else {
luid_new = 0;
}
/* The view entry won't be added if there is any confilict */
*conflicting = ve;
ret = STMF_ALREADY;
goto add_ve_err_ret;
}
}
ve_map = stmf_duplicate_ve_map(0);
continue;
}
continue;
}
&ve_map, 0);
}
}
/* Pick a LUN number */
if (lun_num > 0x3FFF) {
goto add_ve_err_ret;
}
} else {
!= NULL) {
goto add_ve_err_ret;
}
}
/* All is well, do the actual addition now */
goto add_ve_err_ret;
}
if (luid_new) {
}
KM_SLEEP);
KM_SLEEP);
}
KM_SLEEP);
}
/* we need to update the affected session */
if (stmf_state.stmf_service_running) {
}
return (STMF_SUCCESS);
if (luid_new) {
if (ilu)
}
return (ret);
}
{
uint16_t n;
return (STMF_FAILURE);
return (STMF_SUCCESS);
} else {
return (STMF_LUN_TAKEN);
}
} else {
void **pplu;
uint16_t m = n + 1;
m = ((m + 7) & ~7) & 0x7FFF;
lm->lm_nentries * sizeof (void *));
lm->lm_nentries = m;
goto try_again_to_add;
}
}
{
uint16_t n, i;
if (lutype != 0)
return (STMF_FAILURE);
if (n >= lm->lm_nentries)
return (STMF_NOT_FOUND);
return (STMF_NOT_FOUND);
for (i = 0; i < lm->lm_nentries; i++) {
break;
}
i &= ~15;
if (i >= 16) {
void **pplu;
uint16_t m;
m = lm->lm_nentries - i;
lm->lm_nentries = m;
}
return (STMF_SUCCESS);
}
{
break;
}
} else {
return (0xFFFF);
}
if (lun) {
}
return (luNbr);
}
void *
{
if ((lun_num & 0xC000) == 0) {
else
return (NULL);
}
return (NULL);
}
int
{
if (!hg) {
return (ENOENT); /* could not find group */
}
if (!tg) {
return (ENOENT); /* could not find group */
}
&conflictve, err_detail);
if (ret == STMF_ALREADY) {
return (EALREADY);
} else if (ret == STMF_LUN_TAKEN) {
return (EEXIST);
} else if (ret == STMF_NOT_SUPPORTED) {
return (E2BIG);
} else if (ret != STMF_SUCCESS) {
return (EINVAL);
}
return (0);
}
int
{
int found = 0;
return (ENODEV);
}
break;
}
}
if (!ve) {
return (ENODEV);
}
/* remove the ve */
else {
if (!luid->id_impl_specific) {
/* don't have any view entries related to this lu */
if (ilu)
}
}
/* we need to update ver_hg->verh_ve_map */
found = 1;
break;
}
}
found = 0;
found = 1;
break;
}
}
/* free verhg if it don't have any ve entries related */
/* we don't have any view entry related */
if (prev_vhg)
else
/* Free entries in case the map still has memory */
sizeof (void *));
}
if (!vtg->vert_verh_list) {
/* we don't have any ve related */
if (prev_vtg)
else
}
}
}
return (0);
}
int
{
if (group_type == STMF_ID_TYPE_HOST_GROUP)
else if (group_type == STMF_ID_TYPE_TARGET_GROUP)
else {
return (EINVAL);
}
switch (status) {
case STMF_SUCCESS:
return (0);
case STMF_INVALID_ARG:
return (EINVAL);
case STMF_ALREADY:
return (EEXIST);
default:
return (EIO);
}
}
/*
* Group can only be removed only when it does not have
* any view entry related
*/
int
{
if (grpname[0] == '*')
return (EINVAL);
if (group_type == STMF_ID_TYPE_HOST_GROUP)
else if (group_type == STMF_ID_TYPE_TARGET_GROUP)
if (!id) {
return (ENODEV); /* no such grp */
}
/* fail, still have viewentry related to it */
return (EBUSY);
}
}
}
}
} else {
}
}
}
return (0);
}
int
{
if (entry_type == STMF_ID_TYPE_HOST) {
} else {
}
return (ENODEV); /* not found */
}
/* Check whether this member already bound to a group */
if (id_grp_tmp) {
if (id_grp_tmp != id_grp) {
return (EEXIST); /* already added into another grp */
}
else
return (0);
}
/* verify target is offline */
if (entry_type == STMF_ID_TYPE_TARGET) {
return (EBUSY);
}
}
entry_ident, 0);
if (entry_type == STMF_ID_TYPE_TARGET) {
if (ilport)
return (0);
}
/* For host group member, update the session if needed */
return (0);
/* Need to consider all target group + this host group */
1, &grpname_forall);
/* check whether there are sessions may be affected */
continue;
if (iss) {
if (tgid) {
if (vemap)
}
if (vemap_alltgt)
iss, vemap_alltgt);
}
}
return (0);
}
int
{
if (entry_type == STMF_ID_TYPE_HOST) {
} else {
}
return (ENODEV); /* no such group */
}
if (!id_member) {
return (ENODEV); /* no such member */
}
/* verify target is offline */
if (entry_type == STMF_ID_TYPE_TARGET) {
return (EBUSY);
}
}
if (entry_type == STMF_ID_TYPE_TARGET) {
if (ilport)
return (0);
}
/* For host group member, update the session */
return (0);
/* Need to consider all target group + this host group */
1, &grpname_forall);
/* check if there are session related, if so, update it */
continue;
if (iss) {
if (tgid) {
if (vemap)
}
if (vemap_alltgt)
iss, vemap_alltgt);
}
}
return (0);
}
/* Assert stmf_lock is already held */
{
return (ilport);
}
}
return (NULL);
}
{
return (iss);
}
}
return (NULL);
}
{
return (ilu);
}
return (NULL);
}
/*
* Assert stmf_lock is already held,
* Just get the view map for the specific target group and host group
* tgid and hgid can not be NULL
*/
{
int found = 0;
found = 1;
break;
}
}
if (!found)
return (NULL);
return (&verhg->verh_ve_map);
}
}
return (NULL);
}
{
ve_map = stmf_duplicate_ve_map(0);
continue;
}
continue;
}
&ve_map, 0);
}
}
ret = STMF_SUCCESS;
/* Return an available lun number */
/* Pick a LUN number */
if (lun_num > 0x3FFF)
} else {
}
}
return (ret);
}
int
{
if (!hg) {
return (ENOENT); /* could not find group */
}
if (!tg) {
return (ENOENT); /* could not find group */
}
if (ret == STMF_LUN_TAKEN) {
return (EEXIST);
} else if (ret == STMF_NOT_SUPPORTED) {
return (E2BIG);
} else if (ret != STMF_SUCCESS) {
return (EINVAL);
}
return (0);
}