xref: /onnv-gate/usr/src/cmd/isns/isnsd/obj.c (revision 10152:71b1112ff1d3)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM 
227836SJohn.Forte@Sun.COM /*
23*10152Swl202157@icefox  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247836SJohn.Forte@Sun.COM  * Use is subject to license terms.
257836SJohn.Forte@Sun.COM  */
267836SJohn.Forte@Sun.COM 
277836SJohn.Forte@Sun.COM #include <stdio.h>
287836SJohn.Forte@Sun.COM #include <stdlib.h>
297836SJohn.Forte@Sun.COM #include <string.h>
307836SJohn.Forte@Sun.COM #include <pthread.h>
317836SJohn.Forte@Sun.COM #include <sys/types.h>
327836SJohn.Forte@Sun.COM #include <sys/socket.h>
337836SJohn.Forte@Sun.COM #include <netinet/in.h>
347836SJohn.Forte@Sun.COM #include <arpa/inet.h>
357836SJohn.Forte@Sun.COM 
367836SJohn.Forte@Sun.COM #include "isns_server.h"
377836SJohn.Forte@Sun.COM #include "isns_msgq.h"
387836SJohn.Forte@Sun.COM #include "isns_htab.h"
397836SJohn.Forte@Sun.COM #include "isns_cache.h"
407836SJohn.Forte@Sun.COM #include "isns_pdu.h"
417836SJohn.Forte@Sun.COM #include "isns_obj.h"
427836SJohn.Forte@Sun.COM #include "isns_dd.h"
437836SJohn.Forte@Sun.COM #include "isns_func.h"
447836SJohn.Forte@Sun.COM #include "isns_dseng.h"
457836SJohn.Forte@Sun.COM #include "isns_log.h"
467836SJohn.Forte@Sun.COM #include "isns_scn.h"
477836SJohn.Forte@Sun.COM #include "isns_utils.h"
487836SJohn.Forte@Sun.COM #include "isns_esi.h"
497836SJohn.Forte@Sun.COM 
507836SJohn.Forte@Sun.COM /*
517836SJohn.Forte@Sun.COM  * external variables
527836SJohn.Forte@Sun.COM  */
537836SJohn.Forte@Sun.COM #ifdef DEBUG
547836SJohn.Forte@Sun.COM extern int verbose_mc;
557836SJohn.Forte@Sun.COM extern void print_object(char *, isns_obj_t *);
567836SJohn.Forte@Sun.COM #endif
577836SJohn.Forte@Sun.COM 
587836SJohn.Forte@Sun.COM extern msg_queue_t *sys_q;
597836SJohn.Forte@Sun.COM extern msg_queue_t *scn_q;
607836SJohn.Forte@Sun.COM 
617836SJohn.Forte@Sun.COM extern pthread_mutex_t el_mtx;
627836SJohn.Forte@Sun.COM 
637836SJohn.Forte@Sun.COM extern int cache_flag;
647836SJohn.Forte@Sun.COM 
657836SJohn.Forte@Sun.COM /*
667836SJohn.Forte@Sun.COM  * global data
677836SJohn.Forte@Sun.COM  */
687836SJohn.Forte@Sun.COM 
697836SJohn.Forte@Sun.COM /*
707836SJohn.Forte@Sun.COM  * local variables
717836SJohn.Forte@Sun.COM  */
727836SJohn.Forte@Sun.COM /* type of parent object */
737836SJohn.Forte@Sun.COM const int TYPE_OF_PARENT[MAX_OBJ_TYPE_FOR_SIZE] = {
747836SJohn.Forte@Sun.COM 	0,
757836SJohn.Forte@Sun.COM 	0,
767836SJohn.Forte@Sun.COM 	ISCSI_PARENT_TYPE,
777836SJohn.Forte@Sun.COM 	PORTAL_PARENT_TYPE,
787836SJohn.Forte@Sun.COM 	PG_PARENT_TYPE,
797836SJohn.Forte@Sun.COM 	0,	/* OBJ_DD */
807836SJohn.Forte@Sun.COM 	0,	/* OBJ_DDS */
817836SJohn.Forte@Sun.COM 	0,	/* MAX_OBJ_TYPE */
827836SJohn.Forte@Sun.COM 	0,	/* OBJ_DUMMY1 */
837836SJohn.Forte@Sun.COM 	0,	/* OBJ_DUMMY2 */
847836SJohn.Forte@Sun.COM 	0,	/* OBJ_DUMMY3 */
857836SJohn.Forte@Sun.COM 	0,	/* OBJ_DUMMY4 */
867836SJohn.Forte@Sun.COM 	ASSOC_ISCSI_PARENT_TYPE,
877836SJohn.Forte@Sun.COM 	ASSOC_DD_PARENT_TYPE
887836SJohn.Forte@Sun.COM };
897836SJohn.Forte@Sun.COM 
907836SJohn.Forte@Sun.COM /* number of children object type */
917836SJohn.Forte@Sun.COM const int NUM_OF_CHILD[MAX_OBJ_TYPE] = {
927836SJohn.Forte@Sun.COM 	0,
937836SJohn.Forte@Sun.COM 	MAX_ENTITY_CHILD,
947836SJohn.Forte@Sun.COM 	MAX_ISCSI_CHILD,
957836SJohn.Forte@Sun.COM 	MAX_PORTAL_CHILD,
967836SJohn.Forte@Sun.COM 	MAX_PG_CHILD,
977836SJohn.Forte@Sun.COM 	0,
987836SJohn.Forte@Sun.COM 	0
997836SJohn.Forte@Sun.COM };
1007836SJohn.Forte@Sun.COM 
1017836SJohn.Forte@Sun.COM /* type of a child object */
1027836SJohn.Forte@Sun.COM const int TYPE_OF_CHILD[MAX_OBJ_TYPE][MAX_CHILD_TYPE] = {
1037836SJohn.Forte@Sun.COM 	{ 0, 0 },
1047836SJohn.Forte@Sun.COM 	{ OBJ_ISCSI, OBJ_PORTAL },
1057836SJohn.Forte@Sun.COM 	{ 0, 0 },
1067836SJohn.Forte@Sun.COM 	{ 0, 0 },
1077836SJohn.Forte@Sun.COM 	{ 0, 0 },
1087836SJohn.Forte@Sun.COM 	{ 0, 0 },
1097836SJohn.Forte@Sun.COM 	{ 0, 0 }
1107836SJohn.Forte@Sun.COM };
1117836SJohn.Forte@Sun.COM 
1127836SJohn.Forte@Sun.COM /* number of attributes of certain type of object */
1137836SJohn.Forte@Sun.COM const int NUM_OF_ATTRS[MAX_OBJ_TYPE_FOR_SIZE] = {
1147836SJohn.Forte@Sun.COM 	0,
1157836SJohn.Forte@Sun.COM 	NUM_OF_ENTITY_ATTRS,
1167836SJohn.Forte@Sun.COM 	NUM_OF_ISCSI_ATTRS,
1177836SJohn.Forte@Sun.COM 	NUM_OF_PORTAL_ATTRS,
1187836SJohn.Forte@Sun.COM 	NUM_OF_PG_ATTRS,
1197836SJohn.Forte@Sun.COM 	NUM_OF_DD_ATTRS,
1207836SJohn.Forte@Sun.COM 	NUM_OF_DDS_ATTRS,
1217836SJohn.Forte@Sun.COM 	0,			/* MAX_OBJ_TYPE */
1227836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY1 */
1237836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY2 */
1247836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY3 */
1257836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY4 */
1267836SJohn.Forte@Sun.COM 	NUM_OF_ASSOC_ISCSI_ATTRS,
1277836SJohn.Forte@Sun.COM 	NUM_OF_ASSOC_DD_ATTRS
1287836SJohn.Forte@Sun.COM };
1297836SJohn.Forte@Sun.COM 
1307836SJohn.Forte@Sun.COM /* the tag of UID of each type of object */
1317836SJohn.Forte@Sun.COM static const int UID_TAG[MAX_OBJ_TYPE_FOR_SIZE] = {
1327836SJohn.Forte@Sun.COM 	0,
1337836SJohn.Forte@Sun.COM 	ISNS_ENTITY_INDEX_ATTR_ID,
1347836SJohn.Forte@Sun.COM 	ISNS_ISCSI_NODE_INDEX_ATTR_ID,
1357836SJohn.Forte@Sun.COM 	ISNS_PORTAL_INDEX_ATTR_ID,
1367836SJohn.Forte@Sun.COM 	ISNS_PG_INDEX_ATTR_ID,
1377836SJohn.Forte@Sun.COM 	ISNS_DD_ID_ATTR_ID,
1387836SJohn.Forte@Sun.COM 	ISNS_DD_SET_ID_ATTR_ID,
1397836SJohn.Forte@Sun.COM 	0,			/* MAX_OBJ_TYPE */
1407836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY1 */
1417836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY2 */
1427836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY3 */
1437836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY4 */
1447836SJohn.Forte@Sun.COM 	ISNS_DD_ISCSI_INDEX_ATTR_ID,
1457836SJohn.Forte@Sun.COM 	ISNS_DD_ID_ATTR_ID
1467836SJohn.Forte@Sun.COM };
1477836SJohn.Forte@Sun.COM 
1487836SJohn.Forte@Sun.COM /* the index of UID of each type of object */
1497836SJohn.Forte@Sun.COM const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE] = {
1507836SJohn.Forte@Sun.COM 	0,
1517836SJohn.Forte@Sun.COM 	ATTR_INDEX_ENTITY(ISNS_ENTITY_INDEX_ATTR_ID),
1527836SJohn.Forte@Sun.COM 	ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_INDEX_ATTR_ID),
1537836SJohn.Forte@Sun.COM 	ATTR_INDEX_PORTAL(ISNS_PORTAL_INDEX_ATTR_ID),
1547836SJohn.Forte@Sun.COM 	ATTR_INDEX_PG(ISNS_PG_INDEX_ATTR_ID),
1557836SJohn.Forte@Sun.COM 	ATTR_INDEX_DD(ISNS_DD_ID_ATTR_ID),
1567836SJohn.Forte@Sun.COM 	ATTR_INDEX_DDS(ISNS_DD_SET_ID_ATTR_ID),
1577836SJohn.Forte@Sun.COM 	0,			/* MAX_OBJ_TYPE */
1587836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY1 */
1597836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY2 */
1607836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY3 */
1617836SJohn.Forte@Sun.COM 	0,			/* OBJ_DUMMY4 */
1627836SJohn.Forte@Sun.COM 	ATTR_INDEX_ASSOC_ISCSI(ISNS_DD_ISCSI_INDEX_ATTR_ID),
1637836SJohn.Forte@Sun.COM 	ATTR_INDEX_ASSOC_DD(ISNS_DD_ID_ATTR_ID)
1647836SJohn.Forte@Sun.COM };
1657836SJohn.Forte@Sun.COM 
1667836SJohn.Forte@Sun.COM /* the index of the key attributes of each type of object */
1677836SJohn.Forte@Sun.COM static const int KEY_ATTR_INDEX[MAX_OBJ_TYPE][MAX_KEY_ATTRS] = {
1687836SJohn.Forte@Sun.COM 	{ 0 },
1697836SJohn.Forte@Sun.COM 	{ ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID), 0 },
1707836SJohn.Forte@Sun.COM 	{ ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID),
1717836SJohn.Forte@Sun.COM 		0 },
1727836SJohn.Forte@Sun.COM 	{ ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID),
1737836SJohn.Forte@Sun.COM 		ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID),
1747836SJohn.Forte@Sun.COM 		0 },
1757836SJohn.Forte@Sun.COM 	{ ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID),
1767836SJohn.Forte@Sun.COM 		ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID),
1777836SJohn.Forte@Sun.COM 		ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID) },
1787836SJohn.Forte@Sun.COM 	{ ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID), 0 },
1797836SJohn.Forte@Sun.COM 	{ ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID), 0 }
1807836SJohn.Forte@Sun.COM };
1817836SJohn.Forte@Sun.COM 
1827836SJohn.Forte@Sun.COM /* the operating methods for key attributes of each type of object */
1837836SJohn.Forte@Sun.COM static const int KEY_ATTR_OP[MAX_OBJ_TYPE][MAX_KEY_ATTRS] = {
1847836SJohn.Forte@Sun.COM 	{ 0 },
1857836SJohn.Forte@Sun.COM 	{ OP_STRING, 0 },
1867836SJohn.Forte@Sun.COM 	{ OP_STRING, 0 },
1877836SJohn.Forte@Sun.COM 	{ OP_MEMORY_IP6, OP_INTEGER, 0 },
1887836SJohn.Forte@Sun.COM 	{ OP_STRING, OP_MEMORY_IP6, OP_INTEGER },
1897836SJohn.Forte@Sun.COM 	{ OP_STRING, 0 },
1907836SJohn.Forte@Sun.COM 	{ OP_STRING, 0 }
1917836SJohn.Forte@Sun.COM };
1927836SJohn.Forte@Sun.COM 
1937836SJohn.Forte@Sun.COM /* the size of each type of object */
1947836SJohn.Forte@Sun.COM static const int SIZEOF_OBJ[MAX_OBJ_TYPE_FOR_SIZE] = {
1957836SJohn.Forte@Sun.COM 	0,
1967836SJohn.Forte@Sun.COM 	sizeof (isns_entity_t),
1977836SJohn.Forte@Sun.COM 	sizeof (isns_iscsi_t),
1987836SJohn.Forte@Sun.COM 	sizeof (isns_portal_t),
1997836SJohn.Forte@Sun.COM 	sizeof (isns_pg_t),
2007836SJohn.Forte@Sun.COM 	sizeof (isns_dd_t),
2017836SJohn.Forte@Sun.COM 	sizeof (isns_dds_t),
2027836SJohn.Forte@Sun.COM 	0,
2037836SJohn.Forte@Sun.COM 	0,
2047836SJohn.Forte@Sun.COM 	0,
2057836SJohn.Forte@Sun.COM 	0,
2067836SJohn.Forte@Sun.COM 	0,
2077836SJohn.Forte@Sun.COM 	sizeof (isns_assoc_iscsi_t),
2087836SJohn.Forte@Sun.COM 	sizeof (isns_assoc_dd_t)
2097836SJohn.Forte@Sun.COM };
2107836SJohn.Forte@Sun.COM 
2117836SJohn.Forte@Sun.COM #ifdef DEBUG
2127836SJohn.Forte@Sun.COM const int NUM_OF_REF[MAX_OBJ_TYPE_FOR_SIZE] = {
2137836SJohn.Forte@Sun.COM #else
2147836SJohn.Forte@Sun.COM static const int NUM_OF_REF[MAX_OBJ_TYPE_FOR_SIZE] = {
2157836SJohn.Forte@Sun.COM #endif
2167836SJohn.Forte@Sun.COM 	0,
2177836SJohn.Forte@Sun.COM 	0,
2187836SJohn.Forte@Sun.COM 	0,
2197836SJohn.Forte@Sun.COM 	0,
2207836SJohn.Forte@Sun.COM 	PG_REF_COUNT,
2217836SJohn.Forte@Sun.COM 	0,
2227836SJohn.Forte@Sun.COM 	0,
2237836SJohn.Forte@Sun.COM 	0,
2247836SJohn.Forte@Sun.COM 	0,
2257836SJohn.Forte@Sun.COM 	0,
2267836SJohn.Forte@Sun.COM 	0,
2277836SJohn.Forte@Sun.COM 	0,
2287836SJohn.Forte@Sun.COM 	0,
2297836SJohn.Forte@Sun.COM 	0
2307836SJohn.Forte@Sun.COM };
2317836SJohn.Forte@Sun.COM 
2327836SJohn.Forte@Sun.COM /* the type of the reference object */
2337836SJohn.Forte@Sun.COM static const int TYPE_OF_REF[MAX_OBJ_TYPE][MAX_REF_COUNT + 1] = {
2347836SJohn.Forte@Sun.COM 	{ 0 },
2357836SJohn.Forte@Sun.COM 	{ 0 },
2367836SJohn.Forte@Sun.COM 	{ OBJ_PG, OBJ_PORTAL, 0 },
2377836SJohn.Forte@Sun.COM 	{ OBJ_PG, OBJ_ISCSI, 0 },
2387836SJohn.Forte@Sun.COM 	{ 0, OBJ_ISCSI, OBJ_PORTAL },
2397836SJohn.Forte@Sun.COM 	{ 0 },
2407836SJohn.Forte@Sun.COM 	{ 0 }
2417836SJohn.Forte@Sun.COM };
2427836SJohn.Forte@Sun.COM 
2437836SJohn.Forte@Sun.COM /* the operating method for match operation of the reference object */
2447836SJohn.Forte@Sun.COM #define	MAX_REF_MATCH	(2)
2457836SJohn.Forte@Sun.COM static const int REF_MATCH_OPS[MAX_OBJ_TYPE][MAX_REF_MATCH] = {
2467836SJohn.Forte@Sun.COM 	{ 0, 0 },
2477836SJohn.Forte@Sun.COM 	{ 0, 0 },
2487836SJohn.Forte@Sun.COM 	{ OP_STRING, 0 },
2497836SJohn.Forte@Sun.COM 	{ OP_MEMORY_IP6, OP_INTEGER },
2507836SJohn.Forte@Sun.COM 	{ 0, 0 },
2517836SJohn.Forte@Sun.COM 	{ 0, 0 },
2527836SJohn.Forte@Sun.COM 	{ 0, 0 }
2537836SJohn.Forte@Sun.COM };
2547836SJohn.Forte@Sun.COM 
2557836SJohn.Forte@Sun.COM /* the index of the attribute of being matched object */
2567836SJohn.Forte@Sun.COM static const int REF_MATCH_ID1[MAX_OBJ_TYPE][MAX_REF_MATCH] = {
2577836SJohn.Forte@Sun.COM 	{ 0, 0 },
2587836SJohn.Forte@Sun.COM 	{ 0, 0 },
2597836SJohn.Forte@Sun.COM 	{ ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID), 0 },
2607836SJohn.Forte@Sun.COM 	{ ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID),
2617836SJohn.Forte@Sun.COM 		ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID) },
2627836SJohn.Forte@Sun.COM 	{ 0, 0 },
2637836SJohn.Forte@Sun.COM 	{ 0, 0 },
2647836SJohn.Forte@Sun.COM 	{ 0, 0 }
2657836SJohn.Forte@Sun.COM };
2667836SJohn.Forte@Sun.COM 
2677836SJohn.Forte@Sun.COM /* the index of the attribute of matching object */
2687836SJohn.Forte@Sun.COM static const int REF_MATCH_ID2[MAX_OBJ_TYPE][MAX_REF_MATCH] = {
2697836SJohn.Forte@Sun.COM 	{ 0, 0 },
2707836SJohn.Forte@Sun.COM 	{ 0, 0 },
2717836SJohn.Forte@Sun.COM 	{ ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID), 0 },
2727836SJohn.Forte@Sun.COM 	{ ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID),
2737836SJohn.Forte@Sun.COM 		ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID) },
2747836SJohn.Forte@Sun.COM 	{ 0, 0 },
2757836SJohn.Forte@Sun.COM 	{ 0, 0 },
2767836SJohn.Forte@Sun.COM 	{ 0, 0 }
2777836SJohn.Forte@Sun.COM };
2787836SJohn.Forte@Sun.COM 
2797836SJohn.Forte@Sun.COM /*
2807836SJohn.Forte@Sun.COM  * local functions.
2817836SJohn.Forte@Sun.COM  */
2827836SJohn.Forte@Sun.COM static uint32_t get_reg_period();
2837836SJohn.Forte@Sun.COM static char *make_unique_name(int *, uint32_t);
2847836SJohn.Forte@Sun.COM static lookup_ctrl_t *set_lookup_ctrl(lookup_ctrl_t *, isns_obj_t *);
2857836SJohn.Forte@Sun.COM static int setup_ref_lcp(lookup_ctrl_t *,
2867836SJohn.Forte@Sun.COM 	const isns_obj_t *, const isns_obj_t *);
2877836SJohn.Forte@Sun.COM static int setup_deref_lcp(lookup_ctrl_t *,
2887836SJohn.Forte@Sun.COM 	const isns_obj_t *, isns_type_t);
2897836SJohn.Forte@Sun.COM static int cb_get_parent(void *, void *);
2907836SJohn.Forte@Sun.COM static int cb_node_child(void *, void *);
2917836SJohn.Forte@Sun.COM static int cb_set_ref(void *, void *);
2927836SJohn.Forte@Sun.COM static int cb_clear_ref(void *, void *);
2937836SJohn.Forte@Sun.COM static int cb_add_child(void *, void *);
2947836SJohn.Forte@Sun.COM static int cb_remove_child(void *, void *);
2957836SJohn.Forte@Sun.COM static int cb_verify_ref(void *, void *);
2967836SJohn.Forte@Sun.COM static int cb_ref_new2old(void *, void *);
2977836SJohn.Forte@Sun.COM static int cb_new_ref(void *, void *);
2987836SJohn.Forte@Sun.COM static int ref_new2old(
2997836SJohn.Forte@Sun.COM 	lookup_ctrl_t *, isns_type_t, uint32_t, const isns_obj_t *);
3007836SJohn.Forte@Sun.COM static int ref_new2new(
3017836SJohn.Forte@Sun.COM 	lookup_ctrl_t *, const isns_obj_t *, const isns_obj_t *);
3027836SJohn.Forte@Sun.COM static int new_ref(const isns_obj_t *, const isns_obj_t *);
3037836SJohn.Forte@Sun.COM static uint32_t setup_parent_lcp(lookup_ctrl_t *, isns_obj_t *);
3047836SJohn.Forte@Sun.COM static int set_obj_offline(isns_obj_t *);
3057836SJohn.Forte@Sun.COM static int copy_attrs(isns_obj_t *, const isns_obj_t *);
3067836SJohn.Forte@Sun.COM 
3077836SJohn.Forte@Sun.COM static isns_obj_t *make_default_pg(const isns_obj_t *, const isns_obj_t *);
3087836SJohn.Forte@Sun.COM static isns_obj_t *(*const make_ref[MAX_OBJ_TYPE])
3097836SJohn.Forte@Sun.COM 	(const isns_obj_t *, const isns_obj_t *) = {
3107836SJohn.Forte@Sun.COM 		NULL,
3117836SJohn.Forte@Sun.COM 		NULL,
3127836SJohn.Forte@Sun.COM 		&make_default_pg,
3137836SJohn.Forte@Sun.COM 		&make_default_pg,
3147836SJohn.Forte@Sun.COM 		NULL,
3157836SJohn.Forte@Sun.COM 		NULL,
3167836SJohn.Forte@Sun.COM 		NULL
3177836SJohn.Forte@Sun.COM };
3187836SJohn.Forte@Sun.COM 
3197836SJohn.Forte@Sun.COM static uint32_t entity_hval(void *, uint16_t, uint32_t *);
3207836SJohn.Forte@Sun.COM static uint32_t iscsi_hval(void *, uint16_t, uint32_t *);
3217836SJohn.Forte@Sun.COM static uint32_t portal_hval(void *, uint16_t, uint32_t *);
3227836SJohn.Forte@Sun.COM static uint32_t pg_hval(void *, uint16_t, uint32_t *);
3237836SJohn.Forte@Sun.COM static uint32_t dd_hval(void *, uint16_t, uint32_t *);
3247836SJohn.Forte@Sun.COM static uint32_t dds_hval(void *, uint16_t, uint32_t *);
3257836SJohn.Forte@Sun.COM static uint32_t (*const hval_func[MAX_OBJ_TYPE])
3267836SJohn.Forte@Sun.COM 	(void *, uint16_t, uint32_t *) = {
3277836SJohn.Forte@Sun.COM 		NULL,
3287836SJohn.Forte@Sun.COM 		&entity_hval,
3297836SJohn.Forte@Sun.COM 		&iscsi_hval,
3307836SJohn.Forte@Sun.COM 		&portal_hval,
3317836SJohn.Forte@Sun.COM 		&pg_hval,
3327836SJohn.Forte@Sun.COM 		&dd_hval,
3337836SJohn.Forte@Sun.COM 		&dds_hval
3347836SJohn.Forte@Sun.COM };
3357836SJohn.Forte@Sun.COM 
3367836SJohn.Forte@Sun.COM /*
3377836SJohn.Forte@Sun.COM  * ****************************************************************************
3387836SJohn.Forte@Sun.COM  *
3397836SJohn.Forte@Sun.COM  * entity_hval:
3407836SJohn.Forte@Sun.COM  *	caculate the hash value of a network entity object.
3417836SJohn.Forte@Sun.COM  *
3427836SJohn.Forte@Sun.COM  * p	- the pointer pointers to network entity object or
3437836SJohn.Forte@Sun.COM  *	  the lookup control data, both have the key attribute
3447836SJohn.Forte@Sun.COM  *	  of a network entity object.
3457836SJohn.Forte@Sun.COM  * chunk- which chunk of the hash table.
3467836SJohn.Forte@Sun.COM  * flags- pointer to flags.
3477836SJohn.Forte@Sun.COM  * return - the hash value.
3487836SJohn.Forte@Sun.COM  *
3497836SJohn.Forte@Sun.COM  * ****************************************************************************
3507836SJohn.Forte@Sun.COM  */
3517836SJohn.Forte@Sun.COM static uint32_t
entity_hval(void * p,uint16_t chunk,uint32_t * flags)3527836SJohn.Forte@Sun.COM entity_hval(
3537836SJohn.Forte@Sun.COM 	void *p,
3547836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
3557836SJohn.Forte@Sun.COM 	uint16_t chunk,
3567836SJohn.Forte@Sun.COM 	uint32_t *flags
3577836SJohn.Forte@Sun.COM )
3587836SJohn.Forte@Sun.COM {
3597836SJohn.Forte@Sun.COM 	uchar_t *key;
3607836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
3617836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp;
3627836SJohn.Forte@Sun.COM 
3637836SJohn.Forte@Sun.COM 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
3647836SJohn.Forte@Sun.COM 		/* p pointers to a network entity object */
3657836SJohn.Forte@Sun.COM 		obj = (isns_obj_t *)p;
3667836SJohn.Forte@Sun.COM 		key = obj->attrs[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)].
3677836SJohn.Forte@Sun.COM 		    value.ptr;
3687836SJohn.Forte@Sun.COM 	} else {
3697836SJohn.Forte@Sun.COM 		/* p is lookup control data */
3707836SJohn.Forte@Sun.COM 		lcp = (lookup_ctrl_t *)p;
3717836SJohn.Forte@Sun.COM 		key = lcp->data[0].ptr;
3727836SJohn.Forte@Sun.COM 	}
3737836SJohn.Forte@Sun.COM 
3747836SJohn.Forte@Sun.COM 	return (htab_compute_hval(key));
3757836SJohn.Forte@Sun.COM }
3767836SJohn.Forte@Sun.COM 
3777836SJohn.Forte@Sun.COM /*
3787836SJohn.Forte@Sun.COM  * ****************************************************************************
3797836SJohn.Forte@Sun.COM  *
3807836SJohn.Forte@Sun.COM  * iscsi_hval:
3817836SJohn.Forte@Sun.COM  *	caculate the hash value of an iscsi storage node object.
3827836SJohn.Forte@Sun.COM  *
3837836SJohn.Forte@Sun.COM  * p	- the pointer pointers to iscsi storage node object or
3847836SJohn.Forte@Sun.COM  *	  the lookup control data, both have the key attribute
3857836SJohn.Forte@Sun.COM  *	  of an iscsi storage node object.
3867836SJohn.Forte@Sun.COM  * chunk- which chunk of the hash table.
3877836SJohn.Forte@Sun.COM  * flags- pointer to flags.
3887836SJohn.Forte@Sun.COM  * return - the hash value.
3897836SJohn.Forte@Sun.COM  *
3907836SJohn.Forte@Sun.COM  * ****************************************************************************
3917836SJohn.Forte@Sun.COM  */
3927836SJohn.Forte@Sun.COM static uint32_t
iscsi_hval(void * p,uint16_t chunk,uint32_t * flags)3937836SJohn.Forte@Sun.COM iscsi_hval(
3947836SJohn.Forte@Sun.COM 	void *p,
3957836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
3967836SJohn.Forte@Sun.COM 	uint16_t chunk,
3977836SJohn.Forte@Sun.COM 	uint32_t *flags
3987836SJohn.Forte@Sun.COM )
3997836SJohn.Forte@Sun.COM {
4007836SJohn.Forte@Sun.COM 	uchar_t *key;
4017836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
4027836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp;
4037836SJohn.Forte@Sun.COM 
4047836SJohn.Forte@Sun.COM 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
4057836SJohn.Forte@Sun.COM 		/* p pointers to an iscsi storage node object */
4067836SJohn.Forte@Sun.COM 		obj = (isns_obj_t *)p;
4077836SJohn.Forte@Sun.COM 		key = obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)].
4087836SJohn.Forte@Sun.COM 		    value.ptr;
4097836SJohn.Forte@Sun.COM 	} else {
4107836SJohn.Forte@Sun.COM 		/* p is lookup control data */
4117836SJohn.Forte@Sun.COM 		lcp = (lookup_ctrl_t *)p;
4127836SJohn.Forte@Sun.COM 		key = lcp->data[0].ptr;
4137836SJohn.Forte@Sun.COM 	}
4147836SJohn.Forte@Sun.COM 
4157836SJohn.Forte@Sun.COM 	return (htab_compute_hval(key));
4167836SJohn.Forte@Sun.COM }
4177836SJohn.Forte@Sun.COM 
4187836SJohn.Forte@Sun.COM /*
4197836SJohn.Forte@Sun.COM  * ****************************************************************************
4207836SJohn.Forte@Sun.COM  *
4217836SJohn.Forte@Sun.COM  * portal_hval:
4227836SJohn.Forte@Sun.COM  *	caculate the hash value of a portal object.
4237836SJohn.Forte@Sun.COM  *
4247836SJohn.Forte@Sun.COM  * p	- the pointer pointers to a portal object or the lookup control
4257836SJohn.Forte@Sun.COM  *	  data, both have the key attributes of a portal object.
4267836SJohn.Forte@Sun.COM  * chunk- which chunk of the hash table.
4277836SJohn.Forte@Sun.COM  * flags- pointer to flags.
4287836SJohn.Forte@Sun.COM  * return - the hash value.
4297836SJohn.Forte@Sun.COM  *
4307836SJohn.Forte@Sun.COM  * ****************************************************************************
4317836SJohn.Forte@Sun.COM  */
4327836SJohn.Forte@Sun.COM static uint32_t
portal_hval(void * p,uint16_t chunk,uint32_t * flags)4337836SJohn.Forte@Sun.COM portal_hval(
4347836SJohn.Forte@Sun.COM 	void *p,
4357836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
4367836SJohn.Forte@Sun.COM 	uint16_t chunk,
4377836SJohn.Forte@Sun.COM 	uint32_t *flags
4387836SJohn.Forte@Sun.COM )
4397836SJohn.Forte@Sun.COM {
4407836SJohn.Forte@Sun.COM 	char buff[INET6_ADDRSTRLEN + 8] = { 0 };
4417836SJohn.Forte@Sun.COM 	char buff2[8] = { 0 };
4427836SJohn.Forte@Sun.COM 	uchar_t *key;
4437836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
4447836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp;
4457836SJohn.Forte@Sun.COM 
4467836SJohn.Forte@Sun.COM 	in6_addr_t *ip;
4477836SJohn.Forte@Sun.COM 	uint32_t port;
4487836SJohn.Forte@Sun.COM 
4497836SJohn.Forte@Sun.COM 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
4507836SJohn.Forte@Sun.COM 		/* p pointers to a portal object */
4517836SJohn.Forte@Sun.COM 		obj = (isns_obj_t *)p;
4527836SJohn.Forte@Sun.COM 		ip = obj->attrs[ATTR_INDEX_PORTAL
4537836SJohn.Forte@Sun.COM 		    (ISNS_PORTAL_IP_ADDR_ATTR_ID)].value.ip;
4547836SJohn.Forte@Sun.COM 		port = obj->attrs[ATTR_INDEX_PORTAL
4557836SJohn.Forte@Sun.COM 		    (ISNS_PORTAL_PORT_ATTR_ID)].value.ui;
4567836SJohn.Forte@Sun.COM 	} else {
4577836SJohn.Forte@Sun.COM 		/* p is lookup control data */
4587836SJohn.Forte@Sun.COM 		lcp = (lookup_ctrl_t *)p;
4597836SJohn.Forte@Sun.COM 		ip = lcp->data[0].ip;
4607836SJohn.Forte@Sun.COM 		port = lcp->data[1].ui;
4617836SJohn.Forte@Sun.COM 	}
4627836SJohn.Forte@Sun.COM 
4637836SJohn.Forte@Sun.COM 	key = (uchar_t *)inet_ntop(AF_INET6, (void *)ip,
4647836SJohn.Forte@Sun.COM 	    buff, sizeof (buff));
4657836SJohn.Forte@Sun.COM 	(void) snprintf(buff2, sizeof (buff2), "%d", port);
4667836SJohn.Forte@Sun.COM 	(void) strcat((char *)key, buff2);
4677836SJohn.Forte@Sun.COM 
4687836SJohn.Forte@Sun.COM 	return (htab_compute_hval(key));
4697836SJohn.Forte@Sun.COM }
4707836SJohn.Forte@Sun.COM 
4717836SJohn.Forte@Sun.COM /*
4727836SJohn.Forte@Sun.COM  * ****************************************************************************
4737836SJohn.Forte@Sun.COM  *
4747836SJohn.Forte@Sun.COM  * pg_hval:
4757836SJohn.Forte@Sun.COM  *	caculate the hash value of a portal group object.
4767836SJohn.Forte@Sun.COM  *
4777836SJohn.Forte@Sun.COM  * p	- the pointer pointers to a portal group object or the lookup
4787836SJohn.Forte@Sun.COM  *	  control data, both have the key attributes of a portal object.
4797836SJohn.Forte@Sun.COM  * chunk- which chunk of the hash table.
4807836SJohn.Forte@Sun.COM  * flags- pointer to flags.
4817836SJohn.Forte@Sun.COM  * return - the hash value.
4827836SJohn.Forte@Sun.COM  *
4837836SJohn.Forte@Sun.COM  * ****************************************************************************
4847836SJohn.Forte@Sun.COM  */
4857836SJohn.Forte@Sun.COM static uint32_t
pg_hval(void * p,uint16_t chunk,uint32_t * flags)4867836SJohn.Forte@Sun.COM pg_hval(
4877836SJohn.Forte@Sun.COM 	void *p,
4887836SJohn.Forte@Sun.COM 	uint16_t chunk,
4897836SJohn.Forte@Sun.COM 	uint32_t *flags
4907836SJohn.Forte@Sun.COM )
4917836SJohn.Forte@Sun.COM {
4927836SJohn.Forte@Sun.COM 	char buff[INET6_ADDRSTRLEN + 8] = { 0 };
4937836SJohn.Forte@Sun.COM 	char buff2[8] = { 0 };
4947836SJohn.Forte@Sun.COM 	uchar_t *key = NULL;
4957836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
4967836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp;
4977836SJohn.Forte@Sun.COM 
4987836SJohn.Forte@Sun.COM 	in6_addr_t *ip = NULL;
4997836SJohn.Forte@Sun.COM 	uint32_t port;
5007836SJohn.Forte@Sun.COM 
5017836SJohn.Forte@Sun.COM 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
5027836SJohn.Forte@Sun.COM 		/* p is a portal group object */
5037836SJohn.Forte@Sun.COM 		obj = (isns_obj_t *)p;
5047836SJohn.Forte@Sun.COM 		if (chunk == 0) {
5057836SJohn.Forte@Sun.COM 			/* the first chunk */
5067836SJohn.Forte@Sun.COM 			key = obj->attrs[ATTR_INDEX_PG
5077836SJohn.Forte@Sun.COM 			    (ISNS_PG_ISCSI_NAME_ATTR_ID)].value.ptr;
5087836SJohn.Forte@Sun.COM 		} else {
5097836SJohn.Forte@Sun.COM 			/* another chunk */
5107836SJohn.Forte@Sun.COM 			ip = obj->attrs[ATTR_INDEX_PG
5117836SJohn.Forte@Sun.COM 			    (ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)].value.ip;
5127836SJohn.Forte@Sun.COM 			port = obj->attrs[ATTR_INDEX_PG
5137836SJohn.Forte@Sun.COM 			    (ISNS_PG_PORTAL_PORT_ATTR_ID)].value.ui;
5147836SJohn.Forte@Sun.COM 		}
5157836SJohn.Forte@Sun.COM 	} else {
5167836SJohn.Forte@Sun.COM 		/* p is a lookup control data */
5177836SJohn.Forte@Sun.COM 		lcp = (lookup_ctrl_t *)p;
5187836SJohn.Forte@Sun.COM 		/* clear the chunk flags */
5197836SJohn.Forte@Sun.COM 		*flags &= ~FLAGS_CHUNK_MASK;
5207836SJohn.Forte@Sun.COM 		if (lcp->op[0] == OP_STRING) {
5217836SJohn.Forte@Sun.COM 			/* the first chunk */
5227836SJohn.Forte@Sun.COM 			key = lcp->data[0].ptr;
5237836SJohn.Forte@Sun.COM 		} else {
5247836SJohn.Forte@Sun.COM 			/* another chunk */
5257836SJohn.Forte@Sun.COM 			ip = lcp->data[0].ip;
5267836SJohn.Forte@Sun.COM 			port = lcp->data[1].ui;
5277836SJohn.Forte@Sun.COM 			*flags |= 1;
5287836SJohn.Forte@Sun.COM 		}
5297836SJohn.Forte@Sun.COM 	}
5307836SJohn.Forte@Sun.COM 
5317836SJohn.Forte@Sun.COM 	if (key == NULL) {
5327836SJohn.Forte@Sun.COM 		key = (uchar_t *)inet_ntop(AF_INET6, (void *)ip,
5337836SJohn.Forte@Sun.COM 		    buff, sizeof (buff));
5347836SJohn.Forte@Sun.COM 		(void) snprintf(buff2, sizeof (buff2), "%d", port);
5357836SJohn.Forte@Sun.COM 		(void) strcat((char *)key, buff2);
5367836SJohn.Forte@Sun.COM 	}
5377836SJohn.Forte@Sun.COM 
5387836SJohn.Forte@Sun.COM 	return (htab_compute_hval(key));
5397836SJohn.Forte@Sun.COM }
5407836SJohn.Forte@Sun.COM 
5417836SJohn.Forte@Sun.COM /*
5427836SJohn.Forte@Sun.COM  * ****************************************************************************
5437836SJohn.Forte@Sun.COM  *
5447836SJohn.Forte@Sun.COM  * dd_hval:
5457836SJohn.Forte@Sun.COM  *	caculate the hash value of a DD object.
5467836SJohn.Forte@Sun.COM  *
5477836SJohn.Forte@Sun.COM  * p	- the pointer pointers to a DD object or the lookup control data,
5487836SJohn.Forte@Sun.COM  *	  both have the key attributes of a DD object.
5497836SJohn.Forte@Sun.COM  * chunk- which chunk of the hash table.
5507836SJohn.Forte@Sun.COM  * flags- pointer to flags.
5517836SJohn.Forte@Sun.COM  * return - the hash value.
5527836SJohn.Forte@Sun.COM  *
5537836SJohn.Forte@Sun.COM  * ****************************************************************************
5547836SJohn.Forte@Sun.COM  */
5557836SJohn.Forte@Sun.COM static uint32_t
dd_hval(void * p,uint16_t chunk,uint32_t * flags)5567836SJohn.Forte@Sun.COM dd_hval(
5577836SJohn.Forte@Sun.COM 	void *p,
5587836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
5597836SJohn.Forte@Sun.COM 	uint16_t chunk,
5607836SJohn.Forte@Sun.COM 	uint32_t *flags
5617836SJohn.Forte@Sun.COM )
5627836SJohn.Forte@Sun.COM {
5637836SJohn.Forte@Sun.COM 	uchar_t *key;
5647836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
5657836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp;
5667836SJohn.Forte@Sun.COM 
5677836SJohn.Forte@Sun.COM 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
5687836SJohn.Forte@Sun.COM 		/* p is a DD object */
5697836SJohn.Forte@Sun.COM 		obj = (isns_obj_t *)p;
5707836SJohn.Forte@Sun.COM 		key = obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)].
5717836SJohn.Forte@Sun.COM 		    value.ptr;
5727836SJohn.Forte@Sun.COM 	} else {
5737836SJohn.Forte@Sun.COM 		/* p is a lookup control data */
5747836SJohn.Forte@Sun.COM 		lcp = (lookup_ctrl_t *)p;
5757836SJohn.Forte@Sun.COM 		key = lcp->data[0].ptr;
5767836SJohn.Forte@Sun.COM 	}
5777836SJohn.Forte@Sun.COM 
5787836SJohn.Forte@Sun.COM 	return (htab_compute_hval(key));
5797836SJohn.Forte@Sun.COM }
5807836SJohn.Forte@Sun.COM 
5817836SJohn.Forte@Sun.COM /*
5827836SJohn.Forte@Sun.COM  * ****************************************************************************
5837836SJohn.Forte@Sun.COM  *
5847836SJohn.Forte@Sun.COM  * dds_hval:
5857836SJohn.Forte@Sun.COM  *	caculate the hash value of a DD-set object.
5867836SJohn.Forte@Sun.COM  *
5877836SJohn.Forte@Sun.COM  * p	- the pointer pointers to a DD-set object or the lookup control data,
5887836SJohn.Forte@Sun.COM  *	  both have the key attributes of a DD-set object.
5897836SJohn.Forte@Sun.COM  * chunk- which chunk of the hash table.
5907836SJohn.Forte@Sun.COM  * flags- pointer to flags.
5917836SJohn.Forte@Sun.COM  * return - the hash value.
5927836SJohn.Forte@Sun.COM  *
5937836SJohn.Forte@Sun.COM  * ****************************************************************************
5947836SJohn.Forte@Sun.COM  */
5957836SJohn.Forte@Sun.COM static uint32_t
dds_hval(void * p,uint16_t chunk,uint32_t * flags)5967836SJohn.Forte@Sun.COM dds_hval(
5977836SJohn.Forte@Sun.COM 	void *p,
5987836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
5997836SJohn.Forte@Sun.COM 	uint16_t chunk,
6007836SJohn.Forte@Sun.COM 	uint32_t *flags
6017836SJohn.Forte@Sun.COM )
6027836SJohn.Forte@Sun.COM {
6037836SJohn.Forte@Sun.COM 	uchar_t *key;
6047836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
6057836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp;
6067836SJohn.Forte@Sun.COM 
6077836SJohn.Forte@Sun.COM 	if ((*flags & FLAGS_CTRL_MASK) == 0) {
6087836SJohn.Forte@Sun.COM 		/* p is a DD-set object */
6097836SJohn.Forte@Sun.COM 		obj = (isns_obj_t *)p;
6107836SJohn.Forte@Sun.COM 		key = obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID)].
6117836SJohn.Forte@Sun.COM 		    value.ptr;
6127836SJohn.Forte@Sun.COM 	} else {
6137836SJohn.Forte@Sun.COM 		/* p is lookup control data */
6147836SJohn.Forte@Sun.COM 		lcp = (lookup_ctrl_t *)p;
6157836SJohn.Forte@Sun.COM 		key = lcp->data[0].ptr;
6167836SJohn.Forte@Sun.COM 	}
6177836SJohn.Forte@Sun.COM 
6187836SJohn.Forte@Sun.COM 	return (htab_compute_hval(key));
6197836SJohn.Forte@Sun.COM }
6207836SJohn.Forte@Sun.COM 
6217836SJohn.Forte@Sun.COM /*
6227836SJohn.Forte@Sun.COM  * ****************************************************************************
6237836SJohn.Forte@Sun.COM  *
6247836SJohn.Forte@Sun.COM  * obj_hval:
6257836SJohn.Forte@Sun.COM  *	caculate the hash value of an object.
6267836SJohn.Forte@Sun.COM  *
6277836SJohn.Forte@Sun.COM  * p	- the pointer pointers to an object or lookup control data,
6287836SJohn.Forte@Sun.COM  *	  both has the object type and the key attributes of an object.
6297836SJohn.Forte@Sun.COM  * chunk- which chunk of the hash table.
6307836SJohn.Forte@Sun.COM  * flags- pointer to flags.
6317836SJohn.Forte@Sun.COM  * return - the hash value.
6327836SJohn.Forte@Sun.COM  *
6337836SJohn.Forte@Sun.COM  * ****************************************************************************
6347836SJohn.Forte@Sun.COM  */
6357836SJohn.Forte@Sun.COM uint32_t
obj_hval(void * p,uint16_t chunk,uint32_t * flags)6367836SJohn.Forte@Sun.COM obj_hval(
6377836SJohn.Forte@Sun.COM 	void *p,
6387836SJohn.Forte@Sun.COM 	uint16_t chunk,
6397836SJohn.Forte@Sun.COM 	uint32_t *flags
6407836SJohn.Forte@Sun.COM )
6417836SJohn.Forte@Sun.COM {
6427836SJohn.Forte@Sun.COM 	isns_type_t type = ((isns_obj_t *)p)->type;
6437836SJohn.Forte@Sun.COM 
6447836SJohn.Forte@Sun.COM 	return (hval_func[type](p, chunk, flags));
6457836SJohn.Forte@Sun.COM }
6467836SJohn.Forte@Sun.COM 
6477836SJohn.Forte@Sun.COM /*
6487836SJohn.Forte@Sun.COM  * ****************************************************************************
6497836SJohn.Forte@Sun.COM  *
6507836SJohn.Forte@Sun.COM  * get_obj_uid:
6517836SJohn.Forte@Sun.COM  *	get the UID of an object.
6527836SJohn.Forte@Sun.COM  *
6537836SJohn.Forte@Sun.COM  * p	- the pointer pointers to an object.
6547836SJohn.Forte@Sun.COM  * return - the UID.
6557836SJohn.Forte@Sun.COM  *
6567836SJohn.Forte@Sun.COM  * ****************************************************************************
6577836SJohn.Forte@Sun.COM  */
6587836SJohn.Forte@Sun.COM uint32_t
get_obj_uid(const void * p)6597836SJohn.Forte@Sun.COM get_obj_uid(
6607836SJohn.Forte@Sun.COM 	const void *p
6617836SJohn.Forte@Sun.COM )
6627836SJohn.Forte@Sun.COM {
6637836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p;
6647836SJohn.Forte@Sun.COM 	isns_attr_t *attr = &obj->attrs[UID_ATTR_INDEX[obj->type]];
6657836SJohn.Forte@Sun.COM 	uint32_t uid = attr->value.ui;
6667836SJohn.Forte@Sun.COM 	return (uid);
6677836SJohn.Forte@Sun.COM }
6687836SJohn.Forte@Sun.COM 
6697836SJohn.Forte@Sun.COM /*
6707836SJohn.Forte@Sun.COM  * ****************************************************************************
6717836SJohn.Forte@Sun.COM  *
6727836SJohn.Forte@Sun.COM  * set_obj_uid:
6737836SJohn.Forte@Sun.COM  *	set the UID of an object.
6747836SJohn.Forte@Sun.COM  *
6757836SJohn.Forte@Sun.COM  * p	- the pointer pointers to an object.
6767836SJohn.Forte@Sun.COM  * uid	- the UID.
6777836SJohn.Forte@Sun.COM  * return - the UID.
6787836SJohn.Forte@Sun.COM  *
6797836SJohn.Forte@Sun.COM  * ****************************************************************************
6807836SJohn.Forte@Sun.COM  */
6817836SJohn.Forte@Sun.COM uint32_t
set_obj_uid(void * p,uint32_t uid)6827836SJohn.Forte@Sun.COM set_obj_uid(
6837836SJohn.Forte@Sun.COM 	void *p,
6847836SJohn.Forte@Sun.COM 	uint32_t uid
6857836SJohn.Forte@Sun.COM )
6867836SJohn.Forte@Sun.COM {
6877836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p;
6887836SJohn.Forte@Sun.COM 	isns_attr_t *attr = &obj->attrs[UID_ATTR_INDEX[obj->type]];
6897836SJohn.Forte@Sun.COM 
6907836SJohn.Forte@Sun.COM 	/* set the tag, len and value */
6917836SJohn.Forte@Sun.COM 	attr->tag = UID_TAG[obj->type];
6927836SJohn.Forte@Sun.COM 	attr->len = 4;
6937836SJohn.Forte@Sun.COM 	attr->value.ui = uid;
6947836SJohn.Forte@Sun.COM 
6957836SJohn.Forte@Sun.COM 	return (uid);
6967836SJohn.Forte@Sun.COM }
6977836SJohn.Forte@Sun.COM 
6987836SJohn.Forte@Sun.COM /*
6997836SJohn.Forte@Sun.COM  * ****************************************************************************
7007836SJohn.Forte@Sun.COM  *
7017836SJohn.Forte@Sun.COM  * obj_cmp:
7027836SJohn.Forte@Sun.COM  *	compare between two objects or an object with a lookup control data.
7037836SJohn.Forte@Sun.COM  *
7047836SJohn.Forte@Sun.COM  * p1	- the pointer points to an object.
7057836SJohn.Forte@Sun.COM  * p2	- the pointer points to an object or a lookup control data.
7067836SJohn.Forte@Sun.COM  * flags- 0: p2 is an object; otherwise p2 is a lookup control data.
7077836SJohn.Forte@Sun.COM  * return - the comparsion result.
7087836SJohn.Forte@Sun.COM  *
7097836SJohn.Forte@Sun.COM  * ****************************************************************************
7107836SJohn.Forte@Sun.COM  */
7117836SJohn.Forte@Sun.COM int
obj_cmp(void * p1,void * p2,int flags)7127836SJohn.Forte@Sun.COM obj_cmp(
7137836SJohn.Forte@Sun.COM 	void *p1,
7147836SJohn.Forte@Sun.COM 	void *p2,
7157836SJohn.Forte@Sun.COM 	int flags
7167836SJohn.Forte@Sun.COM )
7177836SJohn.Forte@Sun.COM {
7187836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
7197836SJohn.Forte@Sun.COM 	lookup_ctrl_t buff = { 0 };
7207836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp;
7217836SJohn.Forte@Sun.COM 	uint32_t uid;
7227836SJohn.Forte@Sun.COM 
7237836SJohn.Forte@Sun.COM 	if (flags == 0) {
7247836SJohn.Forte@Sun.COM 		lcp = set_lookup_ctrl(&buff, (isns_obj_t *)p2);
7257836SJohn.Forte@Sun.COM 	} else {
7267836SJohn.Forte@Sun.COM 		lcp = (lookup_ctrl_t *)p2;
7277836SJohn.Forte@Sun.COM 		uid = get_obj_uid(obj);
7287836SJohn.Forte@Sun.COM 		/* the object are linked with decending order by */
7297836SJohn.Forte@Sun.COM 		/* the object UID, if the object UID is greater than */
7307836SJohn.Forte@Sun.COM 		/* or equal to the current UID, it needs to compare */
7317836SJohn.Forte@Sun.COM 		/* for the next one. */
7327836SJohn.Forte@Sun.COM 		if (lcp->curr_uid != 0 && uid >= lcp->curr_uid) {
7337836SJohn.Forte@Sun.COM 			return (-1);
7347836SJohn.Forte@Sun.COM 		}
7357836SJohn.Forte@Sun.COM 	}
7367836SJohn.Forte@Sun.COM 
7377836SJohn.Forte@Sun.COM 	return (key_cmp(lcp, obj));
7387836SJohn.Forte@Sun.COM }
7397836SJohn.Forte@Sun.COM 
7407836SJohn.Forte@Sun.COM /*
7417836SJohn.Forte@Sun.COM  * ****************************************************************************
7427836SJohn.Forte@Sun.COM  *
7437836SJohn.Forte@Sun.COM  * replace_object:
7447836SJohn.Forte@Sun.COM  *	replace an existing object with the new one.
7457836SJohn.Forte@Sun.COM  *
7467836SJohn.Forte@Sun.COM  * p1	- the pointer points to an object being replaced.
7477836SJohn.Forte@Sun.COM  * p2	- the pointer points to a new object.
7487836SJohn.Forte@Sun.COM  * uid_p- points to uid for returning.
7497836SJohn.Forte@Sun.COM  * flag	- 0: do not free the source object, otherwise free it.
7507836SJohn.Forte@Sun.COM  * return - error code.
7517836SJohn.Forte@Sun.COM  *
7527836SJohn.Forte@Sun.COM  * ****************************************************************************
7537836SJohn.Forte@Sun.COM  */
7547836SJohn.Forte@Sun.COM int
replace_object(void * p1,void * p2,uint32_t * uid_p,int flag)7557836SJohn.Forte@Sun.COM replace_object(
7567836SJohn.Forte@Sun.COM 	void *p1,
7577836SJohn.Forte@Sun.COM 	void *p2,
7587836SJohn.Forte@Sun.COM 	uint32_t *uid_p,
7597836SJohn.Forte@Sun.COM 	int flag
7607836SJohn.Forte@Sun.COM )
7617836SJohn.Forte@Sun.COM {
7627836SJohn.Forte@Sun.COM 	int ec = 0;
7637836SJohn.Forte@Sun.COM 
7647836SJohn.Forte@Sun.COM #ifndef SKIP_SRC_AUTH
7657836SJohn.Forte@Sun.COM 	uint32_t *pp_dst, *pp_src, swap;
7667836SJohn.Forte@Sun.COM #endif
7677836SJohn.Forte@Sun.COM 	int online;
7687836SJohn.Forte@Sun.COM 
7697836SJohn.Forte@Sun.COM 	isns_obj_t *dst = (isns_obj_t *)p1;
7707836SJohn.Forte@Sun.COM 	isns_obj_t *src = (isns_obj_t *)p2;
7717836SJohn.Forte@Sun.COM 
7727836SJohn.Forte@Sun.COM 	if (src->type == OBJ_DD || src->type == OBJ_DDS) {
7737836SJohn.Forte@Sun.COM 		/* replace not allowed */
7747836SJohn.Forte@Sun.COM 		return (ERR_NAME_IN_USE);
7757836SJohn.Forte@Sun.COM 	}
7767836SJohn.Forte@Sun.COM 
7777836SJohn.Forte@Sun.COM 	online = is_obj_online(dst);
7787836SJohn.Forte@Sun.COM 
7797836SJohn.Forte@Sun.COM 	/* set cache update flag */
7807836SJohn.Forte@Sun.COM 	SET_CACHE_UPDATED();
7817836SJohn.Forte@Sun.COM 
7827836SJohn.Forte@Sun.COM 	/* update parent uid */
7837836SJohn.Forte@Sun.COM #ifndef SKIP_SRC_AUTH
7847836SJohn.Forte@Sun.COM 	pp_dst = get_parent_p(dst);
7857836SJohn.Forte@Sun.COM 	if (pp_dst != NULL) {
7867836SJohn.Forte@Sun.COM 		pp_src = get_parent_p(src);
7877836SJohn.Forte@Sun.COM 		swap = *pp_dst;
7887836SJohn.Forte@Sun.COM 		*pp_dst = *pp_src;
7897836SJohn.Forte@Sun.COM 		if (swap != 0) {
7907836SJohn.Forte@Sun.COM 			*pp_src = swap;
7917836SJohn.Forte@Sun.COM 		}
7927836SJohn.Forte@Sun.COM 	}
7937836SJohn.Forte@Sun.COM #endif
7947836SJohn.Forte@Sun.COM 
7957836SJohn.Forte@Sun.COM 	/* update all of attributes */
7967836SJohn.Forte@Sun.COM 	if (copy_attrs(dst, src) != 0) {
7977836SJohn.Forte@Sun.COM 		return (ISNS_RSP_INTERNAL_ERROR);
7987836SJohn.Forte@Sun.COM 	}
7997836SJohn.Forte@Sun.COM 
8007836SJohn.Forte@Sun.COM 	/* free up the src object */
8017836SJohn.Forte@Sun.COM 	if (flag != 0) {
8027836SJohn.Forte@Sun.COM 		(void) free_object(src);
8037836SJohn.Forte@Sun.COM 	} else if (online == 0) {
8047836SJohn.Forte@Sun.COM 		(void) set_obj_uid(src, get_obj_uid(dst));
8057836SJohn.Forte@Sun.COM 		(void) set_obj_offline(src);
8067836SJohn.Forte@Sun.COM 	}
8077836SJohn.Forte@Sun.COM 
8087836SJohn.Forte@Sun.COM 	/* update data store */
8097836SJohn.Forte@Sun.COM 	if (sys_q != NULL) {
8107836SJohn.Forte@Sun.COM 		ec = write_data(DATA_UPDATE, dst);
8117836SJohn.Forte@Sun.COM 	} else {
8127836SJohn.Forte@Sun.COM 		/* we should never have duplicated entry in data store */
8137836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
8147836SJohn.Forte@Sun.COM 	}
8157836SJohn.Forte@Sun.COM 
8167836SJohn.Forte@Sun.COM 	/* trigger a scn */
8177836SJohn.Forte@Sun.COM 	if (ec == 0) {
8187836SJohn.Forte@Sun.COM 		if (scn_q != NULL) {
8197836SJohn.Forte@Sun.COM 			(void) make_scn((online == 0) ?
8207836SJohn.Forte@Sun.COM 			    ISNS_OBJECT_ADDED :
8217836SJohn.Forte@Sun.COM 			    ISNS_OBJECT_UPDATED,
8227836SJohn.Forte@Sun.COM 			    dst);
8237836SJohn.Forte@Sun.COM 		}
8247836SJohn.Forte@Sun.COM 		if (uid_p != NULL) {
8257836SJohn.Forte@Sun.COM 			*uid_p = get_obj_uid(dst);
8267836SJohn.Forte@Sun.COM 		}
8277836SJohn.Forte@Sun.COM 	}
8287836SJohn.Forte@Sun.COM 
8297836SJohn.Forte@Sun.COM 	return (ec);
8307836SJohn.Forte@Sun.COM }
8317836SJohn.Forte@Sun.COM 
8327836SJohn.Forte@Sun.COM /*
8337836SJohn.Forte@Sun.COM  * ****************************************************************************
8347836SJohn.Forte@Sun.COM  *
8357836SJohn.Forte@Sun.COM  * add_object:
8367836SJohn.Forte@Sun.COM  *	post function after adding a new object.
8377836SJohn.Forte@Sun.COM  *
8387836SJohn.Forte@Sun.COM  * p	- object which has been added.
8397836SJohn.Forte@Sun.COM  * return - error code.
8407836SJohn.Forte@Sun.COM  *
8417836SJohn.Forte@Sun.COM  * ****************************************************************************
8427836SJohn.Forte@Sun.COM  */
8437836SJohn.Forte@Sun.COM int
add_object(void * p)8447836SJohn.Forte@Sun.COM add_object(
8457836SJohn.Forte@Sun.COM 	void *p
8467836SJohn.Forte@Sun.COM )
8477836SJohn.Forte@Sun.COM {
8487836SJohn.Forte@Sun.COM 	int ec = 0;
8497836SJohn.Forte@Sun.COM 
8507836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p;
8517836SJohn.Forte@Sun.COM 
8527836SJohn.Forte@Sun.COM 	/* add the new object to data store */
8537836SJohn.Forte@Sun.COM 	if (sys_q != NULL) {
8547836SJohn.Forte@Sun.COM 		ec = write_data(DATA_ADD, obj);
8557836SJohn.Forte@Sun.COM 	}
8567836SJohn.Forte@Sun.COM 
8577836SJohn.Forte@Sun.COM 	/* trigger a scn */
8587836SJohn.Forte@Sun.COM 	if (ec == 0 && scn_q != NULL) {
8597836SJohn.Forte@Sun.COM 		(void) make_scn(ISNS_OBJECT_ADDED, obj);
8607836SJohn.Forte@Sun.COM 	}
8617836SJohn.Forte@Sun.COM 
8627836SJohn.Forte@Sun.COM 	return (ec);
8637836SJohn.Forte@Sun.COM }
8647836SJohn.Forte@Sun.COM 
8657836SJohn.Forte@Sun.COM /*
8667836SJohn.Forte@Sun.COM  * ****************************************************************************
8677836SJohn.Forte@Sun.COM  *
8687836SJohn.Forte@Sun.COM  * obj_tab_init:
8697836SJohn.Forte@Sun.COM  *	initialize the object hash tables.
8707836SJohn.Forte@Sun.COM  *
8717836SJohn.Forte@Sun.COM  * c	- points to the cache.
8727836SJohn.Forte@Sun.COM  * return - error code.
8737836SJohn.Forte@Sun.COM  *
8747836SJohn.Forte@Sun.COM  * ****************************************************************************
8757836SJohn.Forte@Sun.COM  */
8767836SJohn.Forte@Sun.COM int
obj_tab_init(struct cache * c)8777836SJohn.Forte@Sun.COM obj_tab_init(
8787836SJohn.Forte@Sun.COM 	struct cache *c
8797836SJohn.Forte@Sun.COM )
8807836SJohn.Forte@Sun.COM {
8817836SJohn.Forte@Sun.COM 	htab_t *t;
8827836SJohn.Forte@Sun.COM 
8837836SJohn.Forte@Sun.COM 	htab_init();
8847836SJohn.Forte@Sun.COM 
8857836SJohn.Forte@Sun.COM 	/*
8867836SJohn.Forte@Sun.COM 	 * allocate an array of pointer for the object hash tables.
8877836SJohn.Forte@Sun.COM 	 */
8887836SJohn.Forte@Sun.COM 	c->t = (struct htab **)calloc(sizeof (struct htab *), MAX_OBJ_TYPE);
8897836SJohn.Forte@Sun.COM 	if (c->t == NULL) {
8907836SJohn.Forte@Sun.COM 		return (1);
8917836SJohn.Forte@Sun.COM 	}
8927836SJohn.Forte@Sun.COM 
8937836SJohn.Forte@Sun.COM 	/*
8947836SJohn.Forte@Sun.COM 	 * hash table for network entity objects.
8957836SJohn.Forte@Sun.COM 	 */
8967836SJohn.Forte@Sun.COM 	t = htab_create(UID_FLAGS_SEQ, 8, 1);
8977836SJohn.Forte@Sun.COM 	if (t != NULL) {
8987836SJohn.Forte@Sun.COM 		t->c = c;
8997836SJohn.Forte@Sun.COM 		c->t[OBJ_ENTITY] = t;
9007836SJohn.Forte@Sun.COM 	} else {
9017836SJohn.Forte@Sun.COM 		return (1);
9027836SJohn.Forte@Sun.COM 	}
9037836SJohn.Forte@Sun.COM 
9047836SJohn.Forte@Sun.COM 	/*
9057836SJohn.Forte@Sun.COM 	 * hash table for iscsi storage node objects.
9067836SJohn.Forte@Sun.COM 	 */
9077836SJohn.Forte@Sun.COM 	t = htab_create(UID_FLAGS_SEQ, 8, 1);
9087836SJohn.Forte@Sun.COM 	if (t != NULL) {
9097836SJohn.Forte@Sun.COM 		t->c = c;
9107836SJohn.Forte@Sun.COM 		c->t[OBJ_ISCSI] = t;
9117836SJohn.Forte@Sun.COM 	} else {
9127836SJohn.Forte@Sun.COM 		return (1);
9137836SJohn.Forte@Sun.COM 	}
9147836SJohn.Forte@Sun.COM 
9157836SJohn.Forte@Sun.COM 	/*
9167836SJohn.Forte@Sun.COM 	 * hash table for portal objects.
9177836SJohn.Forte@Sun.COM 	 */
9187836SJohn.Forte@Sun.COM 	t = htab_create(UID_FLAGS_SEQ, 8, 1);
9197836SJohn.Forte@Sun.COM 	if (t != NULL) {
9207836SJohn.Forte@Sun.COM 		t->c = c;
9217836SJohn.Forte@Sun.COM 		c->t[OBJ_PORTAL] = t;
9227836SJohn.Forte@Sun.COM 	} else {
9237836SJohn.Forte@Sun.COM 		return (1);
9247836SJohn.Forte@Sun.COM 	}
9257836SJohn.Forte@Sun.COM 
9267836SJohn.Forte@Sun.COM 	/*
9277836SJohn.Forte@Sun.COM 	 * hash table for portal group objects.
9287836SJohn.Forte@Sun.COM 	 */
9297836SJohn.Forte@Sun.COM 	t = htab_create(UID_FLAGS_SEQ, 8, 2);
9307836SJohn.Forte@Sun.COM 	if (t != NULL) {
9317836SJohn.Forte@Sun.COM 		t->c = c;
9327836SJohn.Forte@Sun.COM 		c->t[OBJ_PG] = t;
9337836SJohn.Forte@Sun.COM 	} else {
9347836SJohn.Forte@Sun.COM 		return (1);
9357836SJohn.Forte@Sun.COM 	}
9367836SJohn.Forte@Sun.COM 
9377836SJohn.Forte@Sun.COM 	/*
9387836SJohn.Forte@Sun.COM 	 * hash table for discovery domain objects.
9397836SJohn.Forte@Sun.COM 	 */
9407836SJohn.Forte@Sun.COM 	t = htab_create(0, 6, 1);
9417836SJohn.Forte@Sun.COM 	if (t != NULL) {
9427836SJohn.Forte@Sun.COM 		t->c = c;
9437836SJohn.Forte@Sun.COM 		c->t[OBJ_DD] = t;
9447836SJohn.Forte@Sun.COM 	} else {
9457836SJohn.Forte@Sun.COM 		return (1);
9467836SJohn.Forte@Sun.COM 	}
9477836SJohn.Forte@Sun.COM 
9487836SJohn.Forte@Sun.COM 	/*
9497836SJohn.Forte@Sun.COM 	 * hash table for discovery domain set objects.
9507836SJohn.Forte@Sun.COM 	 */
9517836SJohn.Forte@Sun.COM 	t = htab_create(0, 4, 1);
9527836SJohn.Forte@Sun.COM 	if (t != NULL) {
9537836SJohn.Forte@Sun.COM 		t->c = c;
9547836SJohn.Forte@Sun.COM 		c->t[OBJ_DDS] = t;
9557836SJohn.Forte@Sun.COM 	} else {
9567836SJohn.Forte@Sun.COM 		return (1);
9577836SJohn.Forte@Sun.COM 	}
9587836SJohn.Forte@Sun.COM 
9597836SJohn.Forte@Sun.COM 	return (0);
9607836SJohn.Forte@Sun.COM }
9617836SJohn.Forte@Sun.COM 
9627836SJohn.Forte@Sun.COM /*
9637836SJohn.Forte@Sun.COM  * ****************************************************************************
9647836SJohn.Forte@Sun.COM  *
9657836SJohn.Forte@Sun.COM  * get_ref_np:
9667836SJohn.Forte@Sun.COM  *	get the ref pointer of the portal group object.
9677836SJohn.Forte@Sun.COM  *
9687836SJohn.Forte@Sun.COM  * obj	- portal group object.
9697836SJohn.Forte@Sun.COM  * return - ref pointer.
9707836SJohn.Forte@Sun.COM  *
9717836SJohn.Forte@Sun.COM  * ****************************************************************************
9727836SJohn.Forte@Sun.COM  */
9737836SJohn.Forte@Sun.COM static uint32_t *
get_ref_np(isns_obj_t * obj,int n)9747836SJohn.Forte@Sun.COM get_ref_np(
9757836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
9767836SJohn.Forte@Sun.COM 	int n
9777836SJohn.Forte@Sun.COM )
9787836SJohn.Forte@Sun.COM {
9797836SJohn.Forte@Sun.COM 	uint32_t *refp =
9807836SJohn.Forte@Sun.COM 	    obj->type == OBJ_PG ? &((isns_pg_t *)obj)->ref[n] : NULL;
9817836SJohn.Forte@Sun.COM 
9827836SJohn.Forte@Sun.COM 	return (refp);
9837836SJohn.Forte@Sun.COM }
9847836SJohn.Forte@Sun.COM 
9857836SJohn.Forte@Sun.COM #ifdef DEBUG
9867836SJohn.Forte@Sun.COM uint32_t
9877836SJohn.Forte@Sun.COM #else
9887836SJohn.Forte@Sun.COM static uint32_t
9897836SJohn.Forte@Sun.COM #endif
get_ref_n(isns_obj_t * obj,int n)9907836SJohn.Forte@Sun.COM get_ref_n(
9917836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
9927836SJohn.Forte@Sun.COM 	int n
9937836SJohn.Forte@Sun.COM )
9947836SJohn.Forte@Sun.COM {
9957836SJohn.Forte@Sun.COM 	return (*get_ref_np(obj, n));
9967836SJohn.Forte@Sun.COM }
9977836SJohn.Forte@Sun.COM 
9987836SJohn.Forte@Sun.COM static uint32_t *
get_ref_p(isns_obj_t * obj,isns_type_t rt)9997836SJohn.Forte@Sun.COM get_ref_p(
10007836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
10017836SJohn.Forte@Sun.COM 	isns_type_t rt
10027836SJohn.Forte@Sun.COM )
10037836SJohn.Forte@Sun.COM {
10047836SJohn.Forte@Sun.COM 	isns_type_t t = obj->type;
10057836SJohn.Forte@Sun.COM 
10067836SJohn.Forte@Sun.COM 	int i = 0;
10077836SJohn.Forte@Sun.COM 	while (i < NUM_OF_REF[t]) {
10087836SJohn.Forte@Sun.COM 		if (rt == TYPE_OF_REF[t][i + 1]) {
10097836SJohn.Forte@Sun.COM 			return (get_ref_np(obj, i));
10107836SJohn.Forte@Sun.COM 		}
10117836SJohn.Forte@Sun.COM 		i ++;
10127836SJohn.Forte@Sun.COM 	}
10137836SJohn.Forte@Sun.COM 
10147836SJohn.Forte@Sun.COM 	return (NULL);
10157836SJohn.Forte@Sun.COM }
10167836SJohn.Forte@Sun.COM 
10177836SJohn.Forte@Sun.COM uint32_t
get_ref_t(isns_obj_t * obj,isns_type_t type)10187836SJohn.Forte@Sun.COM get_ref_t(
10197836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
10207836SJohn.Forte@Sun.COM 	isns_type_t type
10217836SJohn.Forte@Sun.COM )
10227836SJohn.Forte@Sun.COM {
10237836SJohn.Forte@Sun.COM 	uint32_t *refp = get_ref_p(obj, type);
10247836SJohn.Forte@Sun.COM 
10257836SJohn.Forte@Sun.COM 	if (refp != NULL) {
10267836SJohn.Forte@Sun.COM 		return (*refp);
10277836SJohn.Forte@Sun.COM 	/* LINTED E_NOP_ELSE_STMT */
10287836SJohn.Forte@Sun.COM 	} else {
10297836SJohn.Forte@Sun.COM 		ASSERT(0);
10307836SJohn.Forte@Sun.COM 	}
10317836SJohn.Forte@Sun.COM 
10327836SJohn.Forte@Sun.COM 	return (0);
10337836SJohn.Forte@Sun.COM }
10347836SJohn.Forte@Sun.COM 
10357836SJohn.Forte@Sun.COM /*
10367836SJohn.Forte@Sun.COM  * ****************************************************************************
10377836SJohn.Forte@Sun.COM  *
10387836SJohn.Forte@Sun.COM  * get_parent_p:
10397836SJohn.Forte@Sun.COM  *	get the pointer of the parent object.
10407836SJohn.Forte@Sun.COM  *
10417836SJohn.Forte@Sun.COM  * obj	- an object.
10427836SJohn.Forte@Sun.COM  * return - parent object pointer.
10437836SJohn.Forte@Sun.COM  *
10447836SJohn.Forte@Sun.COM  * ****************************************************************************
10457836SJohn.Forte@Sun.COM  */
10467836SJohn.Forte@Sun.COM uint32_t *const
get_parent_p(const isns_obj_t * obj)10477836SJohn.Forte@Sun.COM get_parent_p(
10487836SJohn.Forte@Sun.COM 	const isns_obj_t *obj
10497836SJohn.Forte@Sun.COM )
10507836SJohn.Forte@Sun.COM {
10517836SJohn.Forte@Sun.COM 	uint32_t *pp;
10527836SJohn.Forte@Sun.COM 	switch (obj->type) {
10537836SJohn.Forte@Sun.COM 	case OBJ_ISCSI:
10547836SJohn.Forte@Sun.COM 		pp = &((isns_iscsi_t *)obj)->puid;
10557836SJohn.Forte@Sun.COM 		break;
10567836SJohn.Forte@Sun.COM 	case OBJ_PORTAL:
10577836SJohn.Forte@Sun.COM 		pp = &((isns_portal_t *)obj)->puid;
10587836SJohn.Forte@Sun.COM 		break;
10597836SJohn.Forte@Sun.COM 	case OBJ_PG:
10607836SJohn.Forte@Sun.COM 		pp = &((isns_pg_t *)obj)->puid;
10617836SJohn.Forte@Sun.COM 		break;
10627836SJohn.Forte@Sun.COM 	case OBJ_ASSOC_ISCSI:
10637836SJohn.Forte@Sun.COM 		pp = &((isns_assoc_iscsi_t *)obj)->puid;
10647836SJohn.Forte@Sun.COM 		break;
10657836SJohn.Forte@Sun.COM 	case OBJ_ASSOC_DD:
10667836SJohn.Forte@Sun.COM 		pp = &((isns_assoc_dd_t *)obj)->puid;
10677836SJohn.Forte@Sun.COM 		break;
10687836SJohn.Forte@Sun.COM 	default:
10697836SJohn.Forte@Sun.COM 		pp = NULL;
10707836SJohn.Forte@Sun.COM 		break;
10717836SJohn.Forte@Sun.COM 	}
10727836SJohn.Forte@Sun.COM 
10737836SJohn.Forte@Sun.COM 	return (pp);
10747836SJohn.Forte@Sun.COM }
10757836SJohn.Forte@Sun.COM 
10767836SJohn.Forte@Sun.COM uint32_t
get_parent_uid(const isns_obj_t * obj)10777836SJohn.Forte@Sun.COM get_parent_uid(
10787836SJohn.Forte@Sun.COM 	const isns_obj_t *obj
10797836SJohn.Forte@Sun.COM )
10807836SJohn.Forte@Sun.COM {
10817836SJohn.Forte@Sun.COM 	uint32_t *pp = get_parent_p(obj);
10827836SJohn.Forte@Sun.COM 	if (pp != NULL) {
10837836SJohn.Forte@Sun.COM 		return (*pp);
10847836SJohn.Forte@Sun.COM 	}
10857836SJohn.Forte@Sun.COM 
10867836SJohn.Forte@Sun.COM 	return (0);
10877836SJohn.Forte@Sun.COM }
10887836SJohn.Forte@Sun.COM 
10897836SJohn.Forte@Sun.COM /*
10907836SJohn.Forte@Sun.COM  * ****************************************************************************
10917836SJohn.Forte@Sun.COM  *
10927836SJohn.Forte@Sun.COM  * get_child_np:
10937836SJohn.Forte@Sun.COM  *	get the pointer of the UID array of the n'th child of an object.
10947836SJohn.Forte@Sun.COM  *
10957836SJohn.Forte@Sun.COM  * obj	- an object.
10967836SJohn.Forte@Sun.COM  * n	- the child index.
10977836SJohn.Forte@Sun.COM  * return - the pointer of the UID array.
10987836SJohn.Forte@Sun.COM  *
10997836SJohn.Forte@Sun.COM  * ****************************************************************************
11007836SJohn.Forte@Sun.COM  */
11017836SJohn.Forte@Sun.COM static uint32_t **
get_child_np(isns_obj_t * obj,int n)11027836SJohn.Forte@Sun.COM get_child_np(
11037836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
11047836SJohn.Forte@Sun.COM 	int n
11057836SJohn.Forte@Sun.COM )
11067836SJohn.Forte@Sun.COM {
11077836SJohn.Forte@Sun.COM 	uint32_t **pp =
11087836SJohn.Forte@Sun.COM 	    obj->type == OBJ_ENTITY ? &((isns_entity_t *)obj)->cuid[n] : NULL;
11097836SJohn.Forte@Sun.COM 
11107836SJohn.Forte@Sun.COM 	return (pp);
11117836SJohn.Forte@Sun.COM }
11127836SJohn.Forte@Sun.COM 
11137836SJohn.Forte@Sun.COM /*
11147836SJohn.Forte@Sun.COM  * ****************************************************************************
11157836SJohn.Forte@Sun.COM  *
11167836SJohn.Forte@Sun.COM  * get_child_n:
11177836SJohn.Forte@Sun.COM  *	get the UID array of the n'th child of an object.
11187836SJohn.Forte@Sun.COM  *
11197836SJohn.Forte@Sun.COM  * obj	- an object.
11207836SJohn.Forte@Sun.COM  * n	- the child index.
11217836SJohn.Forte@Sun.COM  * return - the UID array.
11227836SJohn.Forte@Sun.COM  *
11237836SJohn.Forte@Sun.COM  * ****************************************************************************
11247836SJohn.Forte@Sun.COM  */
11257836SJohn.Forte@Sun.COM #ifdef DEBUG
11267836SJohn.Forte@Sun.COM uint32_t *
11277836SJohn.Forte@Sun.COM #else
11287836SJohn.Forte@Sun.COM static uint32_t *
11297836SJohn.Forte@Sun.COM #endif
get_child_n(isns_obj_t * obj,int n)11307836SJohn.Forte@Sun.COM get_child_n(
11317836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
11327836SJohn.Forte@Sun.COM 	int n
11337836SJohn.Forte@Sun.COM )
11347836SJohn.Forte@Sun.COM {
11357836SJohn.Forte@Sun.COM 	uint32_t **pp = get_child_np(obj, n);
11367836SJohn.Forte@Sun.COM 
11377836SJohn.Forte@Sun.COM 	if (pp != NULL) {
11387836SJohn.Forte@Sun.COM 		return (*pp);
11397836SJohn.Forte@Sun.COM 	}
11407836SJohn.Forte@Sun.COM 
11417836SJohn.Forte@Sun.COM 	ASSERT(0);
11427836SJohn.Forte@Sun.COM 	return (NULL);
11437836SJohn.Forte@Sun.COM }
11447836SJohn.Forte@Sun.COM 
11457836SJohn.Forte@Sun.COM /*
11467836SJohn.Forte@Sun.COM  * ****************************************************************************
11477836SJohn.Forte@Sun.COM  *
11487836SJohn.Forte@Sun.COM  * get_child_p:
11497836SJohn.Forte@Sun.COM  *	get the pointer of the UID array of the child matching the type.
11507836SJohn.Forte@Sun.COM  *
11517836SJohn.Forte@Sun.COM  * base	- an object.
11527836SJohn.Forte@Sun.COM  * child_type	- the child object type.
11537836SJohn.Forte@Sun.COM  * return - the pointer of the UID array.
11547836SJohn.Forte@Sun.COM  *
11557836SJohn.Forte@Sun.COM  * ****************************************************************************
11567836SJohn.Forte@Sun.COM  */
11577836SJohn.Forte@Sun.COM static uint32_t **
get_child_p(isns_obj_t * base,int child_type)11587836SJohn.Forte@Sun.COM get_child_p(
11597836SJohn.Forte@Sun.COM 	isns_obj_t *base,
11607836SJohn.Forte@Sun.COM 	int child_type
11617836SJohn.Forte@Sun.COM )
11627836SJohn.Forte@Sun.COM {
11637836SJohn.Forte@Sun.COM 	uint32_t **pp = NULL;
11647836SJohn.Forte@Sun.COM 	int i = 0;
11657836SJohn.Forte@Sun.COM 	while (i < NUM_OF_CHILD[base->type]) {
11667836SJohn.Forte@Sun.COM 		if (child_type == TYPE_OF_CHILD[base->type][i]) {
11677836SJohn.Forte@Sun.COM 			pp = get_child_np(base, i);
11687836SJohn.Forte@Sun.COM 			break;
11697836SJohn.Forte@Sun.COM 		}
11707836SJohn.Forte@Sun.COM 		i ++;
11717836SJohn.Forte@Sun.COM 	}
11727836SJohn.Forte@Sun.COM 
11737836SJohn.Forte@Sun.COM 	return (pp);
11747836SJohn.Forte@Sun.COM }
11757836SJohn.Forte@Sun.COM 
11767836SJohn.Forte@Sun.COM /*
11777836SJohn.Forte@Sun.COM  * ****************************************************************************
11787836SJohn.Forte@Sun.COM  *
11797836SJohn.Forte@Sun.COM  * get_child_t:
11807836SJohn.Forte@Sun.COM  *	get the UID array of the child object matching the type.
11817836SJohn.Forte@Sun.COM  *
11827836SJohn.Forte@Sun.COM  * base	- an object.
11837836SJohn.Forte@Sun.COM  * child_type	- the child object type.
11847836SJohn.Forte@Sun.COM  * return - the UID array.
11857836SJohn.Forte@Sun.COM  *
11867836SJohn.Forte@Sun.COM  * ****************************************************************************
11877836SJohn.Forte@Sun.COM  */
11887836SJohn.Forte@Sun.COM uint32_t *
get_child_t(isns_obj_t * base,int child_type)11897836SJohn.Forte@Sun.COM get_child_t(
11907836SJohn.Forte@Sun.COM 	isns_obj_t *base,
11917836SJohn.Forte@Sun.COM 	int child_type
11927836SJohn.Forte@Sun.COM )
11937836SJohn.Forte@Sun.COM {
11947836SJohn.Forte@Sun.COM 	uint32_t **pp = get_child_p(base, child_type);
11957836SJohn.Forte@Sun.COM 
11967836SJohn.Forte@Sun.COM 	if (pp != NULL) {
11977836SJohn.Forte@Sun.COM 		return (*pp);
11987836SJohn.Forte@Sun.COM 	} else {
11997836SJohn.Forte@Sun.COM 		return (NULL);
12007836SJohn.Forte@Sun.COM 	}
12017836SJohn.Forte@Sun.COM }
12027836SJohn.Forte@Sun.COM 
12037836SJohn.Forte@Sun.COM /*
12047836SJohn.Forte@Sun.COM  * ****************************************************************************
12057836SJohn.Forte@Sun.COM  *
12067836SJohn.Forte@Sun.COM  * key_cmp:
12077836SJohn.Forte@Sun.COM  *	compare the object against the lookup control data.
12087836SJohn.Forte@Sun.COM  *
12097836SJohn.Forte@Sun.COM  * lcp	- the lookup control data.
12107836SJohn.Forte@Sun.COM  * obj	- an object.
12117836SJohn.Forte@Sun.COM  * return - comparison result.
12127836SJohn.Forte@Sun.COM  *
12137836SJohn.Forte@Sun.COM  * ****************************************************************************
12147836SJohn.Forte@Sun.COM  */
12157836SJohn.Forte@Sun.COM int
key_cmp(lookup_ctrl_t * lcp,isns_obj_t * obj)12167836SJohn.Forte@Sun.COM key_cmp(
12177836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp,
12187836SJohn.Forte@Sun.COM 	isns_obj_t *obj
12197836SJohn.Forte@Sun.COM )
12207836SJohn.Forte@Sun.COM {
12217836SJohn.Forte@Sun.COM 	int i = 0;
12227836SJohn.Forte@Sun.COM 	int match = 1;
12237836SJohn.Forte@Sun.COM 	while (i < MAX_LOOKUP_CTRL && lcp->op[i] > 0 && match) {
12247836SJohn.Forte@Sun.COM 		isns_attr_t *attr = &obj->attrs[lcp->id[i]];
12257836SJohn.Forte@Sun.COM 		switch (lcp->op[i]) {
12267836SJohn.Forte@Sun.COM 			case OP_STRING:
12277836SJohn.Forte@Sun.COM 				match = (strcmp((const char *)lcp->data[i].ptr,
12287836SJohn.Forte@Sun.COM 				    (const char *)attr->value.ptr) == 0);
12297836SJohn.Forte@Sun.COM 				break;
12307836SJohn.Forte@Sun.COM 			case OP_INTEGER:
12317836SJohn.Forte@Sun.COM 				match = (lcp->data[i].ui == attr->value.ui);
12327836SJohn.Forte@Sun.COM 				break;
12337836SJohn.Forte@Sun.COM 			case OP_MEMORY_IP6:
12347836SJohn.Forte@Sun.COM 				match = !memcmp((void *)lcp->data[i].ip,
12357836SJohn.Forte@Sun.COM 				    (void *)attr->value.ip,
12367836SJohn.Forte@Sun.COM 				    sizeof (in6_addr_t));
12377836SJohn.Forte@Sun.COM 				break;
12387836SJohn.Forte@Sun.COM 			default:
12397836SJohn.Forte@Sun.COM 				ASSERT(0);
12407836SJohn.Forte@Sun.COM 				match = 0;
12417836SJohn.Forte@Sun.COM 				break;
12427836SJohn.Forte@Sun.COM 		}
12437836SJohn.Forte@Sun.COM 		i ++;
12447836SJohn.Forte@Sun.COM 	}
12457836SJohn.Forte@Sun.COM 
12467836SJohn.Forte@Sun.COM 	if (i && match) {
12477836SJohn.Forte@Sun.COM 		return (0);
12487836SJohn.Forte@Sun.COM 	} else {
12497836SJohn.Forte@Sun.COM 		return (1);
12507836SJohn.Forte@Sun.COM 	}
12517836SJohn.Forte@Sun.COM }
12527836SJohn.Forte@Sun.COM 
12537836SJohn.Forte@Sun.COM /*
12547836SJohn.Forte@Sun.COM  * ****************************************************************************
12557836SJohn.Forte@Sun.COM  *
12567836SJohn.Forte@Sun.COM  * set_lookup_ctrl:
12577836SJohn.Forte@Sun.COM  *	fill in the lookup control data for an object.
12587836SJohn.Forte@Sun.COM  *
12597836SJohn.Forte@Sun.COM  * lcp	- the lookup control data.
12607836SJohn.Forte@Sun.COM  * obj	- an object.
12617836SJohn.Forte@Sun.COM  * return - the lookup control data.
12627836SJohn.Forte@Sun.COM  *
12637836SJohn.Forte@Sun.COM  * ****************************************************************************
12647836SJohn.Forte@Sun.COM  */
12657836SJohn.Forte@Sun.COM static lookup_ctrl_t *
set_lookup_ctrl(lookup_ctrl_t * lcp,isns_obj_t * obj)12667836SJohn.Forte@Sun.COM set_lookup_ctrl(
12677836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp,
12687836SJohn.Forte@Sun.COM 	isns_obj_t *obj
12697836SJohn.Forte@Sun.COM )
12707836SJohn.Forte@Sun.COM {
12717836SJohn.Forte@Sun.COM 	isns_type_t type = obj->type;
12727836SJohn.Forte@Sun.COM 	uint32_t id, op;
12737836SJohn.Forte@Sun.COM 	int i = 0;
12747836SJohn.Forte@Sun.COM 
12757836SJohn.Forte@Sun.COM 	lcp->type = type;
12767836SJohn.Forte@Sun.COM 	while (i < MAX_KEY_ATTRS) {
12777836SJohn.Forte@Sun.COM 		op = KEY_ATTR_OP[type][i];
12787836SJohn.Forte@Sun.COM 		if (op != 0) {
12797836SJohn.Forte@Sun.COM 			id = KEY_ATTR_INDEX[type][i];
12807836SJohn.Forte@Sun.COM 			lcp->id[i] = id;
12817836SJohn.Forte@Sun.COM 			lcp->op[i] = op;
12827836SJohn.Forte@Sun.COM 			lcp->data[i].ui = obj->attrs[id].value.ui;
12837836SJohn.Forte@Sun.COM 		} else {
12847836SJohn.Forte@Sun.COM 			break;
12857836SJohn.Forte@Sun.COM 		}
12867836SJohn.Forte@Sun.COM 		i ++;
12877836SJohn.Forte@Sun.COM 	}
12887836SJohn.Forte@Sun.COM 
12897836SJohn.Forte@Sun.COM 	return (lcp);
12907836SJohn.Forte@Sun.COM }
12917836SJohn.Forte@Sun.COM 
12927836SJohn.Forte@Sun.COM /*
12937836SJohn.Forte@Sun.COM  * ****************************************************************************
12947836SJohn.Forte@Sun.COM  *
12957836SJohn.Forte@Sun.COM  * assign_attr:
12967836SJohn.Forte@Sun.COM  *	assign an attribute.
12977836SJohn.Forte@Sun.COM  *
12987836SJohn.Forte@Sun.COM  * attr	- the attribute being assigned.
12997836SJohn.Forte@Sun.COM  * tmp	- the attribute.
13007836SJohn.Forte@Sun.COM  * return - error code.
13017836SJohn.Forte@Sun.COM  *
13027836SJohn.Forte@Sun.COM  * ****************************************************************************
13037836SJohn.Forte@Sun.COM  */
13047836SJohn.Forte@Sun.COM int
assign_attr(isns_attr_t * attr,const isns_attr_t * tmp)13057836SJohn.Forte@Sun.COM assign_attr(
13067836SJohn.Forte@Sun.COM 	isns_attr_t *attr,
13077836SJohn.Forte@Sun.COM 	const isns_attr_t *tmp
13087836SJohn.Forte@Sun.COM )
13097836SJohn.Forte@Sun.COM {
13107836SJohn.Forte@Sun.COM 	uint32_t t;
13117836SJohn.Forte@Sun.COM 
13127836SJohn.Forte@Sun.COM 	switch (tmp->tag) {
13137836SJohn.Forte@Sun.COM 	case ISNS_EID_ATTR_ID:
13147836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_NAME_ATTR_ID:
13157836SJohn.Forte@Sun.COM 	case ISNS_DD_NAME_ATTR_ID:
13167836SJohn.Forte@Sun.COM 		if (tmp->len == 0 && attr->len == 0) {
13177836SJohn.Forte@Sun.COM 			int len;
13187836SJohn.Forte@Sun.COM 			char *name = make_unique_name(&len, tmp->tag);
13197836SJohn.Forte@Sun.COM 			if (name != NULL) {
13207836SJohn.Forte@Sun.COM 				attr->value.ptr = (uchar_t *)name;
13217836SJohn.Forte@Sun.COM 				attr->tag = tmp->tag;
13227836SJohn.Forte@Sun.COM 				attr->len = len;
13237836SJohn.Forte@Sun.COM 			} else {
13247836SJohn.Forte@Sun.COM 				/* memory exhausted */
13257836SJohn.Forte@Sun.COM 				return (1);
13267836SJohn.Forte@Sun.COM 			}
13277836SJohn.Forte@Sun.COM 		}
13287836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_NAME_ATTR_ID:
13297836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_NAME_ATTR_ID:
13307836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_ALIAS_ATTR_ID:
13317836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
13327836SJohn.Forte@Sun.COM 	case ISNS_PG_ISCSI_NAME_ATTR_ID:
13337836SJohn.Forte@Sun.COM 	case ISNS_DD_ISCSI_NAME_ATTR_ID:
13347836SJohn.Forte@Sun.COM 		if (tmp->len == 0) {
13357836SJohn.Forte@Sun.COM 			return (0);
1336*10152Swl202157@icefox 		} else if (tmp->len >= attr->len) {
1337*10152Swl202157@icefox 			attr->value.ptr = realloc(
1338*10152Swl202157@icefox 			    attr->value.ptr, tmp->len + 1);
13397836SJohn.Forte@Sun.COM 		}
13407836SJohn.Forte@Sun.COM 		if (attr->value.ptr != NULL) {
1341*10152Swl202157@icefox 			(void) strncpy((char *)attr->value.ptr,
1342*10152Swl202157@icefox 			    (char *)tmp->value.ptr, tmp->len);
1343*10152Swl202157@icefox 			attr->value.ptr[tmp->len] = 0;
13447836SJohn.Forte@Sun.COM 			attr->tag = tmp->tag;
13457836SJohn.Forte@Sun.COM 			attr->len = tmp->len;
13467836SJohn.Forte@Sun.COM 		} else {
13477836SJohn.Forte@Sun.COM 			/* memory exhausted */
13487836SJohn.Forte@Sun.COM 			return (1);
13497836SJohn.Forte@Sun.COM 		}
13507836SJohn.Forte@Sun.COM 		break;
13517836SJohn.Forte@Sun.COM 	case ISNS_MGMT_IP_ADDR_ATTR_ID:
13527836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_IP_ADDR_ATTR_ID:
13537836SJohn.Forte@Sun.COM 	case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
13547836SJohn.Forte@Sun.COM 		if (attr->value.ip == NULL) {
13557836SJohn.Forte@Sun.COM 			attr->value.ip = (in6_addr_t *)calloc(1, tmp->len);
13567836SJohn.Forte@Sun.COM 		}
13577836SJohn.Forte@Sun.COM 		if (attr->value.ip != NULL) {
13587836SJohn.Forte@Sun.COM 			(void) memcpy((void *)attr->value.ip,
13597836SJohn.Forte@Sun.COM 			    (void *)tmp->value.ip, tmp->len);
13607836SJohn.Forte@Sun.COM 			attr->tag = tmp->tag;
13617836SJohn.Forte@Sun.COM 			attr->len = tmp->len;
13627836SJohn.Forte@Sun.COM 		} else {
13637836SJohn.Forte@Sun.COM 			/* memory exhausted */
13647836SJohn.Forte@Sun.COM 			return (1);
13657836SJohn.Forte@Sun.COM 		}
13667836SJohn.Forte@Sun.COM 		break;
13677836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_INDEX_ATTR_ID:
13687836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_INDEX_ATTR_ID:
13697836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
13707836SJohn.Forte@Sun.COM 	case ISNS_PG_INDEX_ATTR_ID:
13717836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_ID_ATTR_ID:
13727836SJohn.Forte@Sun.COM 	case ISNS_DD_ID_ATTR_ID:
13737836SJohn.Forte@Sun.COM 		if (attr->value.ui != 0) {
13747836SJohn.Forte@Sun.COM 			break;
13757836SJohn.Forte@Sun.COM 		}
13767836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_PROTOCOL_ATTR_ID:
13777836SJohn.Forte@Sun.COM 	case ISNS_VERSION_RANGE_ATTR_ID:
13787836SJohn.Forte@Sun.COM 
13797836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_PORT_ATTR_ID:
13807836SJohn.Forte@Sun.COM 	case ISNS_ESI_PORT_ATTR_ID:
13817836SJohn.Forte@Sun.COM 	case ISNS_SCN_PORT_ATTR_ID:
13827836SJohn.Forte@Sun.COM 
13837836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
13847836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_SCN_BITMAP_ATTR_ID:
13857836SJohn.Forte@Sun.COM 
13867836SJohn.Forte@Sun.COM 	case ISNS_PG_PORTAL_PORT_ATTR_ID:
13877836SJohn.Forte@Sun.COM 	case ISNS_PG_TAG_ATTR_ID:
13887836SJohn.Forte@Sun.COM 
13897836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_STATUS_ATTR_ID:
13907836SJohn.Forte@Sun.COM 	case ISNS_DD_ISCSI_INDEX_ATTR_ID:
13917836SJohn.Forte@Sun.COM 		attr->tag = tmp->tag;
13927836SJohn.Forte@Sun.COM 		attr->len = tmp->len;
13937836SJohn.Forte@Sun.COM 		attr->value.ui = tmp->value.ui;
13947836SJohn.Forte@Sun.COM 		break;
13957836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_REG_PERIOD_ATTR_ID:
13967836SJohn.Forte@Sun.COM 		attr->tag = tmp->tag;
13977836SJohn.Forte@Sun.COM 		attr->len = tmp->len;
13987836SJohn.Forte@Sun.COM 		attr->value.ui = tmp->value.ui;
13997836SJohn.Forte@Sun.COM 		t = get_reg_period();
14007836SJohn.Forte@Sun.COM 		if (attr->value.ui > t) {
14017836SJohn.Forte@Sun.COM 			attr->value.ui = t;
14027836SJohn.Forte@Sun.COM 		} else if (attr->value.ui < ONE_DAY) {
14037836SJohn.Forte@Sun.COM 			attr->value.ui = ONE_DAY;
14047836SJohn.Forte@Sun.COM 		}
14057836SJohn.Forte@Sun.COM 		break;
14067836SJohn.Forte@Sun.COM 	case ISNS_ESI_INTERVAL_ATTR_ID:
14077836SJohn.Forte@Sun.COM 		attr->tag = tmp->tag;
14087836SJohn.Forte@Sun.COM 		attr->len = tmp->len;
14097836SJohn.Forte@Sun.COM 		attr->value.ui = tmp->value.ui;
14107836SJohn.Forte@Sun.COM 		if (attr->value.ui > ONE_DAY) {
14117836SJohn.Forte@Sun.COM 			attr->value.ui = ONE_DAY;
14127836SJohn.Forte@Sun.COM 		} else if (attr->value.ui < MIN_ESI_INTVAL) {
14137836SJohn.Forte@Sun.COM 			attr->value.ui = MIN_ESI_INTVAL; /* 20 seconds */
14147836SJohn.Forte@Sun.COM 		}
14157836SJohn.Forte@Sun.COM 		break;
14167836SJohn.Forte@Sun.COM 	default:
14177836SJohn.Forte@Sun.COM 		ASSERT(0);
14187836SJohn.Forte@Sun.COM 		/* don't assign the attribute */
14197836SJohn.Forte@Sun.COM 		break;
14207836SJohn.Forte@Sun.COM 	}
14217836SJohn.Forte@Sun.COM 	return (0);
14227836SJohn.Forte@Sun.COM }
14237836SJohn.Forte@Sun.COM 
14247836SJohn.Forte@Sun.COM /*
14257836SJohn.Forte@Sun.COM  * ****************************************************************************
14267836SJohn.Forte@Sun.COM  *
14277836SJohn.Forte@Sun.COM  * copy_attrs:
14287836SJohn.Forte@Sun.COM  *	copy all of attributes from one object to another.
14297836SJohn.Forte@Sun.COM  *
14307836SJohn.Forte@Sun.COM  * dst	- the destination object.
14317836SJohn.Forte@Sun.COM  * tmp	- the source object.
14327836SJohn.Forte@Sun.COM  * return - error code.
14337836SJohn.Forte@Sun.COM  *
14347836SJohn.Forte@Sun.COM  * ****************************************************************************
14357836SJohn.Forte@Sun.COM  */
14367836SJohn.Forte@Sun.COM static int
copy_attrs(isns_obj_t * dst,const isns_obj_t * src)14377836SJohn.Forte@Sun.COM copy_attrs(
14387836SJohn.Forte@Sun.COM 	isns_obj_t *dst,
14397836SJohn.Forte@Sun.COM 	const isns_obj_t *src
14407836SJohn.Forte@Sun.COM )
14417836SJohn.Forte@Sun.COM {
14427836SJohn.Forte@Sun.COM 	int i = 0;
14437836SJohn.Forte@Sun.COM 	int n = NUM_OF_ATTRS[dst->type];
14447836SJohn.Forte@Sun.COM 
14457836SJohn.Forte@Sun.COM 	isns_attr_t *dst_attr;
14467836SJohn.Forte@Sun.COM 	const isns_attr_t *src_attr;
14477836SJohn.Forte@Sun.COM 
14487836SJohn.Forte@Sun.COM 	while (i < n) {
14497836SJohn.Forte@Sun.COM 		src_attr = &(src->attrs[i]);
14507836SJohn.Forte@Sun.COM 		if (src_attr->tag != 0) {
14517836SJohn.Forte@Sun.COM 			dst_attr = &(dst->attrs[i]);
14527836SJohn.Forte@Sun.COM 			if (assign_attr(dst_attr, src_attr) != 0) {
14537836SJohn.Forte@Sun.COM 				return (1);
14547836SJohn.Forte@Sun.COM 			}
14557836SJohn.Forte@Sun.COM 		}
14567836SJohn.Forte@Sun.COM 		i ++;
14577836SJohn.Forte@Sun.COM 	}
14587836SJohn.Forte@Sun.COM 
14597836SJohn.Forte@Sun.COM 	return (0);
14607836SJohn.Forte@Sun.COM }
14617836SJohn.Forte@Sun.COM 
14627836SJohn.Forte@Sun.COM /*
14637836SJohn.Forte@Sun.COM  * ****************************************************************************
14647836SJohn.Forte@Sun.COM  *
14657836SJohn.Forte@Sun.COM  * extract_attr:
14667836SJohn.Forte@Sun.COM  *	extract an attribute from a TLV format data.
14677836SJohn.Forte@Sun.COM  *
14687836SJohn.Forte@Sun.COM  * attr	- the attribute.
14697836SJohn.Forte@Sun.COM  * tlv	- the TLV format data.
14707836SJohn.Forte@Sun.COM  * return - error code.
14717836SJohn.Forte@Sun.COM  *
14727836SJohn.Forte@Sun.COM  * ****************************************************************************
14737836SJohn.Forte@Sun.COM  */
14747836SJohn.Forte@Sun.COM int
extract_attr(isns_attr_t * attr,const isns_tlv_t * tlv,int flag)14757836SJohn.Forte@Sun.COM extract_attr(
14767836SJohn.Forte@Sun.COM 	isns_attr_t *attr,
14777836SJohn.Forte@Sun.COM 	const isns_tlv_t *tlv,
14787836SJohn.Forte@Sun.COM 	int flag
14797836SJohn.Forte@Sun.COM )
14807836SJohn.Forte@Sun.COM {
14817836SJohn.Forte@Sun.COM 	int ec = 0;
14827836SJohn.Forte@Sun.COM 
14837836SJohn.Forte@Sun.COM 	uint32_t min_len = 4, max_len = 224;
14847836SJohn.Forte@Sun.COM 
14857836SJohn.Forte@Sun.COM 	switch (tlv->attr_id) {
14867836SJohn.Forte@Sun.COM 	case ISNS_EID_ATTR_ID:
14877836SJohn.Forte@Sun.COM 		min_len = 0;
14887836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_NAME_ATTR_ID:
14897836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_ALIAS_ATTR_ID:
14907836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_NAME_ATTR_ID:
14917836SJohn.Forte@Sun.COM 	case ISNS_DD_NAME_ATTR_ID:
14927836SJohn.Forte@Sun.COM 		max_len = 256;
14937836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_NAME_ATTR_ID:
14947836SJohn.Forte@Sun.COM 	case ISNS_PG_ISCSI_NAME_ATTR_ID:
14957836SJohn.Forte@Sun.COM 		if (tlv->attr_len < min_len || tlv->attr_len > max_len) {
14967836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
14977836SJohn.Forte@Sun.COM 		} else {
14987836SJohn.Forte@Sun.COM 			attr->tag = tlv->attr_id;
14997836SJohn.Forte@Sun.COM 			attr->len = tlv->attr_len;
15007836SJohn.Forte@Sun.COM 			attr->value.ptr = (uchar_t *)&(tlv->attr_value[0]);
15017836SJohn.Forte@Sun.COM 		}
15027836SJohn.Forte@Sun.COM 		break;
15037836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
15047836SJohn.Forte@Sun.COM 		attr->tag = tlv->attr_id;
15057836SJohn.Forte@Sun.COM 		attr->len = tlv->attr_len;
15067836SJohn.Forte@Sun.COM 		attr->value.ptr = (uchar_t *)&(tlv->attr_value[0]);
15077836SJohn.Forte@Sun.COM 		break;
15087836SJohn.Forte@Sun.COM 	case ISNS_MGMT_IP_ADDR_ATTR_ID:
15097836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_IP_ADDR_ATTR_ID:
15107836SJohn.Forte@Sun.COM 	case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
15117836SJohn.Forte@Sun.COM 		if (tlv->attr_len != 16) {
15127836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
15137836SJohn.Forte@Sun.COM 		} else {
15147836SJohn.Forte@Sun.COM 			attr->tag = tlv->attr_id;
15157836SJohn.Forte@Sun.COM 			attr->len = tlv->attr_len;
15167836SJohn.Forte@Sun.COM 			attr->value.ip = (void *)&(tlv->attr_value[0]);
15177836SJohn.Forte@Sun.COM 		}
15187836SJohn.Forte@Sun.COM 		break;
15197836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_PROTOCOL_ATTR_ID:
15207836SJohn.Forte@Sun.COM 	case ISNS_VERSION_RANGE_ATTR_ID:
15217836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_REG_PERIOD_ATTR_ID:
15227836SJohn.Forte@Sun.COM 		/* fall throught */
15237836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_PORT_ATTR_ID:
15247836SJohn.Forte@Sun.COM 	case ISNS_ESI_INTERVAL_ATTR_ID:
15257836SJohn.Forte@Sun.COM 	case ISNS_ESI_PORT_ATTR_ID:
15267836SJohn.Forte@Sun.COM 	case ISNS_SCN_PORT_ATTR_ID:
15277836SJohn.Forte@Sun.COM 		/* fall throught */
15287836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
15297836SJohn.Forte@Sun.COM 		/* fall throught */
15307836SJohn.Forte@Sun.COM 	case ISNS_PG_PORTAL_PORT_ATTR_ID:
15317836SJohn.Forte@Sun.COM 		/* fall throught */
15327836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_ID_ATTR_ID:
15337836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_STATUS_ATTR_ID:
15347836SJohn.Forte@Sun.COM 		/* fall throught */
15357836SJohn.Forte@Sun.COM 	case ISNS_DD_ID_ATTR_ID:
15367836SJohn.Forte@Sun.COM 		if (tlv->attr_len != 4) {
15377836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
15387836SJohn.Forte@Sun.COM 			break;
15397836SJohn.Forte@Sun.COM 		}
15407836SJohn.Forte@Sun.COM 	case ISNS_PG_TAG_ATTR_ID:
15417836SJohn.Forte@Sun.COM 		attr->tag = tlv->attr_id;
15427836SJohn.Forte@Sun.COM 		attr->len = tlv->attr_len;
15437836SJohn.Forte@Sun.COM 		if (tlv->attr_len == 4) {
15447836SJohn.Forte@Sun.COM 			attr->value.ui = ntohl(*(uint32_t *)
15457836SJohn.Forte@Sun.COM 			    &(tlv->attr_value[0]));
15467836SJohn.Forte@Sun.COM 		} else {
15477836SJohn.Forte@Sun.COM 			attr->value.ui = 0;
15487836SJohn.Forte@Sun.COM 		}
15497836SJohn.Forte@Sun.COM 		break;
15507836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_SCN_BITMAP_ATTR_ID:
15517836SJohn.Forte@Sun.COM 		/* ignore scn bitmap attribute during object registration, */
15527836SJohn.Forte@Sun.COM 		/* it is registered by scn_reg message. */
15537836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_ISAKMP_P1_ATTR_ID:
15547836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_CERT_ATTR_ID:
15557836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_SEC_BMP_ATTR_ID:
15567836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_ISAKMP_P1_ATTR_ID:
15577836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_ISAKMP_P2_ATTR_ID:
15587836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_CERT_ATTR_ID:
15597836SJohn.Forte@Sun.COM 		break;
15607836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_INDEX_ATTR_ID:
15617836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
15627836SJohn.Forte@Sun.COM 	case ISNS_PG_INDEX_ATTR_ID:
15637836SJohn.Forte@Sun.COM 		if (flag == 0) {
15647836SJohn.Forte@Sun.COM 			if (tlv->attr_len != 4) {
15657836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
15667836SJohn.Forte@Sun.COM 			} else {
15677836SJohn.Forte@Sun.COM 				attr->tag = tlv->attr_id;
15687836SJohn.Forte@Sun.COM 				attr->len = tlv->attr_len;
15697836SJohn.Forte@Sun.COM 				attr->value.ui = ntohl(*(uint32_t *)
15707836SJohn.Forte@Sun.COM 				    &(tlv->attr_value[0]));
15717836SJohn.Forte@Sun.COM 			}
15727836SJohn.Forte@Sun.COM 			break;
15737836SJohn.Forte@Sun.COM 		}
15747836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_INDEX_ATTR_ID:
15757836SJohn.Forte@Sun.COM 	case ISNS_TIMESTAMP_ATTR_ID:
15767836SJohn.Forte@Sun.COM 	default:
15777836SJohn.Forte@Sun.COM 		if (flag == 0) {
15787836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INVALID_QRY;
15797836SJohn.Forte@Sun.COM 		} else {
15807836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INVALID_REGIS;
15817836SJohn.Forte@Sun.COM 		}
15827836SJohn.Forte@Sun.COM 		break;
15837836SJohn.Forte@Sun.COM 	}
15847836SJohn.Forte@Sun.COM 
15857836SJohn.Forte@Sun.COM 	return (ec);
15867836SJohn.Forte@Sun.COM }
15877836SJohn.Forte@Sun.COM 
15887836SJohn.Forte@Sun.COM /*
15897836SJohn.Forte@Sun.COM  * ****************************************************************************
15907836SJohn.Forte@Sun.COM  *
15917836SJohn.Forte@Sun.COM  * copy_attr:
15927836SJohn.Forte@Sun.COM  *	copy an attribute from a TLV format data.
15937836SJohn.Forte@Sun.COM  *
15947836SJohn.Forte@Sun.COM  * attr	- the attribute.
15957836SJohn.Forte@Sun.COM  * tlv	- the TLV format data.
15967836SJohn.Forte@Sun.COM  * return - error code.
15977836SJohn.Forte@Sun.COM  *
15987836SJohn.Forte@Sun.COM  * ****************************************************************************
15997836SJohn.Forte@Sun.COM  */
16007836SJohn.Forte@Sun.COM static int
copy_attr(isns_attr_t * attr,const isns_tlv_t * tlv)16017836SJohn.Forte@Sun.COM copy_attr(
16027836SJohn.Forte@Sun.COM 	isns_attr_t *attr,
16037836SJohn.Forte@Sun.COM 	const isns_tlv_t *tlv
16047836SJohn.Forte@Sun.COM )
16057836SJohn.Forte@Sun.COM {
16067836SJohn.Forte@Sun.COM 	int ec = 0;
16077836SJohn.Forte@Sun.COM 
16087836SJohn.Forte@Sun.COM 	isns_attr_t tmp = { 0 };
16097836SJohn.Forte@Sun.COM 
16107836SJohn.Forte@Sun.COM 	/* extract the attribute first */
16117836SJohn.Forte@Sun.COM 	ec = extract_attr(&tmp, tlv, 1);
16127836SJohn.Forte@Sun.COM 
16137836SJohn.Forte@Sun.COM 	/* assign the attribute */
16147836SJohn.Forte@Sun.COM 	if (ec == 0 && tmp.tag != 0) {
16157836SJohn.Forte@Sun.COM 		if (assign_attr(attr, &tmp) != 0) {
16167836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
16177836SJohn.Forte@Sun.COM 		}
16187836SJohn.Forte@Sun.COM 	}
16197836SJohn.Forte@Sun.COM 
16207836SJohn.Forte@Sun.COM 	return (ec);
16217836SJohn.Forte@Sun.COM }
16227836SJohn.Forte@Sun.COM 
16237836SJohn.Forte@Sun.COM /*
16247836SJohn.Forte@Sun.COM  * ****************************************************************************
16257836SJohn.Forte@Sun.COM  *
16267836SJohn.Forte@Sun.COM  * get_timestamp:
16277836SJohn.Forte@Sun.COM  *	get current timestamp.
16287836SJohn.Forte@Sun.COM  *
16297836SJohn.Forte@Sun.COM  * return - current timestamp.
16307836SJohn.Forte@Sun.COM  *
16317836SJohn.Forte@Sun.COM  * ****************************************************************************
16327836SJohn.Forte@Sun.COM  */
16337836SJohn.Forte@Sun.COM uint32_t
get_timestamp()16347836SJohn.Forte@Sun.COM get_timestamp(
16357836SJohn.Forte@Sun.COM )
16367836SJohn.Forte@Sun.COM {
16377836SJohn.Forte@Sun.COM 	uint32_t t;
16387836SJohn.Forte@Sun.COM 	int flag;
16397836SJohn.Forte@Sun.COM 
16407836SJohn.Forte@Sun.COM 	/* block the scheduler */
16417836SJohn.Forte@Sun.COM 	(void) pthread_mutex_lock(&el_mtx);
16427836SJohn.Forte@Sun.COM 
16437836SJohn.Forte@Sun.COM 	/* get most current time */
16447836SJohn.Forte@Sun.COM 	if (sys_q != NULL) {
16457836SJohn.Forte@Sun.COM 		/* need to wakeup idle */
16467836SJohn.Forte@Sun.COM 		flag = 1;
16477836SJohn.Forte@Sun.COM 	} else {
16487836SJohn.Forte@Sun.COM 		flag = 0;
16497836SJohn.Forte@Sun.COM 	}
16507836SJohn.Forte@Sun.COM 	t = get_stopwatch(flag);
16517836SJohn.Forte@Sun.COM 
16527836SJohn.Forte@Sun.COM 	/* unblock it */
16537836SJohn.Forte@Sun.COM 	(void) pthread_mutex_unlock(&el_mtx);
16547836SJohn.Forte@Sun.COM 
16557836SJohn.Forte@Sun.COM 	return (t);
16567836SJohn.Forte@Sun.COM }
16577836SJohn.Forte@Sun.COM 
16587836SJohn.Forte@Sun.COM /*
16597836SJohn.Forte@Sun.COM  * ****************************************************************************
16607836SJohn.Forte@Sun.COM  *
16617836SJohn.Forte@Sun.COM  * get_reg_period:
16627836SJohn.Forte@Sun.COM  *	get the longest registration period.
16637836SJohn.Forte@Sun.COM  *
16647836SJohn.Forte@Sun.COM  * return - the longest registration period.
16657836SJohn.Forte@Sun.COM  *
16667836SJohn.Forte@Sun.COM  * ****************************************************************************
16677836SJohn.Forte@Sun.COM  */
16687836SJohn.Forte@Sun.COM static uint32_t
get_reg_period()16697836SJohn.Forte@Sun.COM get_reg_period(
16707836SJohn.Forte@Sun.COM )
16717836SJohn.Forte@Sun.COM {
16727836SJohn.Forte@Sun.COM 	uint32_t t;
16737836SJohn.Forte@Sun.COM 	uint32_t period;
16747836SJohn.Forte@Sun.COM 
16757836SJohn.Forte@Sun.COM 	/* get most current time */
16767836SJohn.Forte@Sun.COM 	t = get_timestamp();
16777836SJohn.Forte@Sun.COM 
16787836SJohn.Forte@Sun.COM 	/* just one second before the end of the world */
16797836SJohn.Forte@Sun.COM 	period = INFINITY - t - 1;
16807836SJohn.Forte@Sun.COM 
16817836SJohn.Forte@Sun.COM 	return (period);
16827836SJohn.Forte@Sun.COM }
16837836SJohn.Forte@Sun.COM 
16847836SJohn.Forte@Sun.COM /*
16857836SJohn.Forte@Sun.COM  * ****************************************************************************
16867836SJohn.Forte@Sun.COM  *
16877836SJohn.Forte@Sun.COM  * obj_calloc:
16887836SJohn.Forte@Sun.COM  *	allocate memory space for an object.
16897836SJohn.Forte@Sun.COM  *
16907836SJohn.Forte@Sun.COM  * type	- the object type.
16917836SJohn.Forte@Sun.COM  * return - pointer of the object being allocated.
16927836SJohn.Forte@Sun.COM  *
16937836SJohn.Forte@Sun.COM  * ****************************************************************************
16947836SJohn.Forte@Sun.COM  */
16957836SJohn.Forte@Sun.COM isns_obj_t *
obj_calloc(int type)16967836SJohn.Forte@Sun.COM obj_calloc(
16977836SJohn.Forte@Sun.COM 	int type
16987836SJohn.Forte@Sun.COM )
16997836SJohn.Forte@Sun.COM {
17007836SJohn.Forte@Sun.COM 	isns_obj_t *obj = NULL;
17017836SJohn.Forte@Sun.COM 
17027836SJohn.Forte@Sun.COM 	obj = (isns_obj_t *)calloc(1, SIZEOF_OBJ[type]);
17037836SJohn.Forte@Sun.COM 	if (obj != NULL) {
17047836SJohn.Forte@Sun.COM 		obj->type = type;
17057836SJohn.Forte@Sun.COM #ifdef DEBUG
17067836SJohn.Forte@Sun.COM 	if (verbose_mc) {
17077836SJohn.Forte@Sun.COM 		printf("object(%d) allocated\n", type);
17087836SJohn.Forte@Sun.COM 	}
17097836SJohn.Forte@Sun.COM #endif
17107836SJohn.Forte@Sun.COM 	}
17117836SJohn.Forte@Sun.COM 
17127836SJohn.Forte@Sun.COM 	return (obj);
17137836SJohn.Forte@Sun.COM }
17147836SJohn.Forte@Sun.COM 
17157836SJohn.Forte@Sun.COM /*
17167836SJohn.Forte@Sun.COM  * ****************************************************************************
17177836SJohn.Forte@Sun.COM  *
17187836SJohn.Forte@Sun.COM  * make_default_entity:
17197836SJohn.Forte@Sun.COM  *	generate a default network entity object.
17207836SJohn.Forte@Sun.COM  *
17217836SJohn.Forte@Sun.COM  * return - pointer of the default network entity object.
17227836SJohn.Forte@Sun.COM  *
17237836SJohn.Forte@Sun.COM  * ****************************************************************************
17247836SJohn.Forte@Sun.COM  */
17257836SJohn.Forte@Sun.COM isns_obj_t *
make_default_entity()17267836SJohn.Forte@Sun.COM make_default_entity(
17277836SJohn.Forte@Sun.COM )
17287836SJohn.Forte@Sun.COM {
17297836SJohn.Forte@Sun.COM 	uint32_t t;
17307836SJohn.Forte@Sun.COM 
17317836SJohn.Forte@Sun.COM 	isns_obj_t *obj = obj_calloc(OBJ_ENTITY);
17327836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
17337836SJohn.Forte@Sun.COM 	if (obj != NULL) {
17347836SJohn.Forte@Sun.COM 		int len;
17357836SJohn.Forte@Sun.COM 		char *eid = make_unique_name(&len, ISNS_EID_ATTR_ID);
17367836SJohn.Forte@Sun.COM 		if (!eid) {
17377836SJohn.Forte@Sun.COM 			free(obj);
17387836SJohn.Forte@Sun.COM 			return (NULL);
17397836SJohn.Forte@Sun.COM 		}
17407836SJohn.Forte@Sun.COM 		attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)];
17417836SJohn.Forte@Sun.COM 
17427836SJohn.Forte@Sun.COM 		/* set default entity name */
17437836SJohn.Forte@Sun.COM 		attr->tag = ISNS_EID_ATTR_ID;
17447836SJohn.Forte@Sun.COM 		attr->len = len;
17457836SJohn.Forte@Sun.COM 		attr->value.ptr = (uchar_t *)eid;
17467836SJohn.Forte@Sun.COM 
17477836SJohn.Forte@Sun.COM 		/* set default registration period */
17487836SJohn.Forte@Sun.COM 		attr = &obj->attrs[
17497836SJohn.Forte@Sun.COM 		    ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID)];
17507836SJohn.Forte@Sun.COM 		if (attr->tag == 0) {
17517836SJohn.Forte@Sun.COM 			attr->tag = ISNS_ENTITY_REG_PERIOD_ATTR_ID;
17527836SJohn.Forte@Sun.COM 			attr->len = 4;
17537836SJohn.Forte@Sun.COM 			t = get_reg_period();
17547836SJohn.Forte@Sun.COM 			attr->value.ui = t;
17557836SJohn.Forte@Sun.COM 		}
17567836SJohn.Forte@Sun.COM 	}
17577836SJohn.Forte@Sun.COM 
17587836SJohn.Forte@Sun.COM 	return (obj);
17597836SJohn.Forte@Sun.COM }
17607836SJohn.Forte@Sun.COM 
17617836SJohn.Forte@Sun.COM /*
17627836SJohn.Forte@Sun.COM  * ****************************************************************************
17637836SJohn.Forte@Sun.COM  *
17647836SJohn.Forte@Sun.COM  * make_default_pg:
17657836SJohn.Forte@Sun.COM  *	generate a default portal group object.
17667836SJohn.Forte@Sun.COM  *
17677836SJohn.Forte@Sun.COM  * iscsi  - the iscsi storage node object.
17687836SJohn.Forte@Sun.COM  * portal - the portal object.
17697836SJohn.Forte@Sun.COM  * return - pointer of the default portal group object.
17707836SJohn.Forte@Sun.COM  *
17717836SJohn.Forte@Sun.COM  * ****************************************************************************
17727836SJohn.Forte@Sun.COM  */
17737836SJohn.Forte@Sun.COM static isns_obj_t *
make_default_pg(const isns_obj_t * p1,const isns_obj_t * p2)17747836SJohn.Forte@Sun.COM make_default_pg(
17757836SJohn.Forte@Sun.COM 	const isns_obj_t *p1,
17767836SJohn.Forte@Sun.COM 	const isns_obj_t *p2
17777836SJohn.Forte@Sun.COM )
17787836SJohn.Forte@Sun.COM {
17797836SJohn.Forte@Sun.COM 	const isns_obj_t *iscsi, *portal;
17807836SJohn.Forte@Sun.COM 	const isns_attr_t *name, *addr, *port;
17817836SJohn.Forte@Sun.COM 	isns_obj_t *pg;
17827836SJohn.Forte@Sun.COM 
17837836SJohn.Forte@Sun.COM 	uchar_t *pg_name;
17847836SJohn.Forte@Sun.COM 	in6_addr_t *pg_addr;
17857836SJohn.Forte@Sun.COM 
17867836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
17877836SJohn.Forte@Sun.COM 
17887836SJohn.Forte@Sun.COM 	uint32_t *refp;
17897836SJohn.Forte@Sun.COM 
17907836SJohn.Forte@Sun.COM 	if (p1->type == OBJ_ISCSI) {
17917836SJohn.Forte@Sun.COM 		iscsi = p1;
17927836SJohn.Forte@Sun.COM 		portal = p2;
17937836SJohn.Forte@Sun.COM 	} else {
17947836SJohn.Forte@Sun.COM 		iscsi = p2;
17957836SJohn.Forte@Sun.COM 		portal = p1;
17967836SJohn.Forte@Sun.COM 	}
17977836SJohn.Forte@Sun.COM 	name = &iscsi->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
17987836SJohn.Forte@Sun.COM 	addr = &portal->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID)];
17997836SJohn.Forte@Sun.COM 	port = &portal->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID)];
18007836SJohn.Forte@Sun.COM 
18017836SJohn.Forte@Sun.COM 	pg = obj_calloc(OBJ_PG);
18027836SJohn.Forte@Sun.COM 	pg_name = (uchar_t *)malloc(name->len);
18037836SJohn.Forte@Sun.COM 	pg_addr = (in6_addr_t *)malloc(addr->len);
18047836SJohn.Forte@Sun.COM 	if (pg != NULL && pg_name != NULL && pg_addr != NULL) {
18057836SJohn.Forte@Sun.COM 		(void) strcpy((char *)pg_name, (char *)name->value.ptr);
18067836SJohn.Forte@Sun.COM 		attr = &pg->attrs[ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID)];
18077836SJohn.Forte@Sun.COM 		attr->tag = ISNS_PG_ISCSI_NAME_ATTR_ID;
18087836SJohn.Forte@Sun.COM 		attr->len = name->len;
18097836SJohn.Forte@Sun.COM 		attr->value.ptr = pg_name;
18107836SJohn.Forte@Sun.COM 
18117836SJohn.Forte@Sun.COM 		(void) memcpy((void *)pg_addr,
18127836SJohn.Forte@Sun.COM 		    (void *)addr->value.ip, addr->len);
18137836SJohn.Forte@Sun.COM 		attr = &pg->attrs[ATTR_INDEX_PG(
18147836SJohn.Forte@Sun.COM 		    ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)];
18157836SJohn.Forte@Sun.COM 		attr->tag = ISNS_PG_PORTAL_IP_ADDR_ATTR_ID;
18167836SJohn.Forte@Sun.COM 		attr->len = addr->len;
18177836SJohn.Forte@Sun.COM 		attr->value.ip = pg_addr;
18187836SJohn.Forte@Sun.COM 
18197836SJohn.Forte@Sun.COM 		attr = &pg->attrs[ATTR_INDEX_PG(
18207836SJohn.Forte@Sun.COM 		    ISNS_PG_PORTAL_PORT_ATTR_ID)];
18217836SJohn.Forte@Sun.COM 		attr->tag = ISNS_PG_PORTAL_PORT_ATTR_ID;
18227836SJohn.Forte@Sun.COM 		attr->len = port->len;
18237836SJohn.Forte@Sun.COM 		attr->value.ui = port->value.ui;
18247836SJohn.Forte@Sun.COM 
18257836SJohn.Forte@Sun.COM 		attr = &pg->attrs[ATTR_INDEX_PG(
18267836SJohn.Forte@Sun.COM 		    ISNS_PG_TAG_ATTR_ID)];
18277836SJohn.Forte@Sun.COM 		attr->tag = ISNS_PG_TAG_ATTR_ID;
18287836SJohn.Forte@Sun.COM 		attr->len = 4;
18297836SJohn.Forte@Sun.COM 		attr->value.ui = ISNS_DEFAULT_PGT;
18307836SJohn.Forte@Sun.COM 
18317836SJohn.Forte@Sun.COM 		refp = get_ref_p(pg, OBJ_ISCSI);
18327836SJohn.Forte@Sun.COM 		*refp = get_obj_uid(iscsi);
18337836SJohn.Forte@Sun.COM 
18347836SJohn.Forte@Sun.COM 		refp = get_ref_p(pg, OBJ_PORTAL);
18357836SJohn.Forte@Sun.COM 		*refp = get_obj_uid(portal);
18367836SJohn.Forte@Sun.COM 
18377836SJohn.Forte@Sun.COM 		(void) set_parent_obj(pg, get_parent_uid(iscsi));
18387836SJohn.Forte@Sun.COM 	} else {
18397836SJohn.Forte@Sun.COM 		free(pg);
18407836SJohn.Forte@Sun.COM 		free(pg_name);
18417836SJohn.Forte@Sun.COM 		free(pg_addr);
18427836SJohn.Forte@Sun.COM 		pg = NULL;
18437836SJohn.Forte@Sun.COM 	}
18447836SJohn.Forte@Sun.COM 
18457836SJohn.Forte@Sun.COM 	return (pg);
18467836SJohn.Forte@Sun.COM }
18477836SJohn.Forte@Sun.COM 
18487836SJohn.Forte@Sun.COM /*
18497836SJohn.Forte@Sun.COM  * ****************************************************************************
18507836SJohn.Forte@Sun.COM  *
18517836SJohn.Forte@Sun.COM  * reg_get_entity:
18527836SJohn.Forte@Sun.COM  *	parse the Operating Attributes of the DevAttrReg message and
18537836SJohn.Forte@Sun.COM  *	create the Network Entity object if it has one.
18547836SJohn.Forte@Sun.COM  *
18557836SJohn.Forte@Sun.COM  * p	- the pointer of the object for returning.
18567836SJohn.Forte@Sun.COM  * op	- the operating attributes.
18577836SJohn.Forte@Sun.COM  * op_len - the length of the operating attributes.
18587836SJohn.Forte@Sun.COM  * return - error code.
18597836SJohn.Forte@Sun.COM  *
18607836SJohn.Forte@Sun.COM  * ****************************************************************************
18617836SJohn.Forte@Sun.COM  */
18627836SJohn.Forte@Sun.COM int
reg_get_entity(isns_obj_t ** p,isns_tlv_t ** op,uint16_t * op_len)18637836SJohn.Forte@Sun.COM reg_get_entity(
18647836SJohn.Forte@Sun.COM 	isns_obj_t **p,
18657836SJohn.Forte@Sun.COM 	isns_tlv_t **op,
18667836SJohn.Forte@Sun.COM 	uint16_t *op_len
18677836SJohn.Forte@Sun.COM )
18687836SJohn.Forte@Sun.COM {
18697836SJohn.Forte@Sun.COM 	int ec = 0;
18707836SJohn.Forte@Sun.COM 
18717836SJohn.Forte@Sun.COM 	isns_tlv_t *tmp;
18727836SJohn.Forte@Sun.COM 	uint16_t tmp_len;
18737836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
18747836SJohn.Forte@Sun.COM 
18757836SJohn.Forte@Sun.COM 	isns_obj_t *entity = NULL;
18767836SJohn.Forte@Sun.COM 
18777836SJohn.Forte@Sun.COM 	tmp = *op;
18787836SJohn.Forte@Sun.COM 	tmp_len = *op_len;
18797836SJohn.Forte@Sun.COM 
18807836SJohn.Forte@Sun.COM 	/* parse the entity object */
18817836SJohn.Forte@Sun.COM 	if (tmp_len >= 8 && IS_ENTITY_KEY(tmp->attr_id)) {
18827836SJohn.Forte@Sun.COM 		entity = obj_calloc(OBJ_ENTITY);
18837836SJohn.Forte@Sun.COM 		if (entity != NULL) {
18847836SJohn.Forte@Sun.COM 			do {
18857836SJohn.Forte@Sun.COM 				attr = &entity->attrs[
18867836SJohn.Forte@Sun.COM 				    ATTR_INDEX_ENTITY(tmp->attr_id)];
18877836SJohn.Forte@Sun.COM 				ec = copy_attr(attr, tmp);
18887836SJohn.Forte@Sun.COM 				NEXT_TLV(tmp, tmp_len);
18897836SJohn.Forte@Sun.COM 			} while (ec == 0 &&
18907836SJohn.Forte@Sun.COM 			    tmp_len >= 8 &&
18917836SJohn.Forte@Sun.COM 			    IS_ENTITY_ATTR(tmp->attr_id));
18927836SJohn.Forte@Sun.COM 		} else {
18937836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
18947836SJohn.Forte@Sun.COM 		}
18957836SJohn.Forte@Sun.COM 
18967836SJohn.Forte@Sun.COM 		if (ec == 0) {
18977836SJohn.Forte@Sun.COM 			/* set default registration period */
18987836SJohn.Forte@Sun.COM 			attr = &entity->attrs[
18997836SJohn.Forte@Sun.COM 			    ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID)];
19007836SJohn.Forte@Sun.COM 			if (attr->tag == 0) {
19017836SJohn.Forte@Sun.COM 				attr->tag = ISNS_ENTITY_REG_PERIOD_ATTR_ID;
19027836SJohn.Forte@Sun.COM 				attr->len = 4;
19037836SJohn.Forte@Sun.COM 				attr->value.ui = get_reg_period();
19047836SJohn.Forte@Sun.COM 			}
19057836SJohn.Forte@Sun.COM 		} else if (entity != NULL) {
19067836SJohn.Forte@Sun.COM 			free(entity);
19077836SJohn.Forte@Sun.COM 			entity = NULL;
19087836SJohn.Forte@Sun.COM 		}
19097836SJohn.Forte@Sun.COM 	}
19107836SJohn.Forte@Sun.COM 
19117836SJohn.Forte@Sun.COM 	*p = entity;
19127836SJohn.Forte@Sun.COM 	*op = tmp;
19137836SJohn.Forte@Sun.COM 	*op_len = tmp_len;
19147836SJohn.Forte@Sun.COM 
19157836SJohn.Forte@Sun.COM 	return (ec);
19167836SJohn.Forte@Sun.COM }
19177836SJohn.Forte@Sun.COM 
19187836SJohn.Forte@Sun.COM /*
19197836SJohn.Forte@Sun.COM  * ****************************************************************************
19207836SJohn.Forte@Sun.COM  *
19217836SJohn.Forte@Sun.COM  * reg_get_iscsi:
19227836SJohn.Forte@Sun.COM  *	parse the Operating Attributes of the DevAttrReg message and
19237836SJohn.Forte@Sun.COM  *	create an iSCSI Storage Node object.
19247836SJohn.Forte@Sun.COM  *
19257836SJohn.Forte@Sun.COM  * p	- the pointer of the object for returning.
19267836SJohn.Forte@Sun.COM  * pg_key1 - the pointer of iscsi storage node name for returning.
19277836SJohn.Forte@Sun.COM  * op	- the operating attributes.
19287836SJohn.Forte@Sun.COM  * op_len - the length of the operating attributes.
19297836SJohn.Forte@Sun.COM  * return - error code.
19307836SJohn.Forte@Sun.COM  *
19317836SJohn.Forte@Sun.COM  * ****************************************************************************
19327836SJohn.Forte@Sun.COM  */
19337836SJohn.Forte@Sun.COM static int
reg_get_iscsi(isns_obj_t ** p,isns_attr_t * pg_key1,isns_tlv_t ** op,uint16_t * op_len)19347836SJohn.Forte@Sun.COM reg_get_iscsi(
19357836SJohn.Forte@Sun.COM 	isns_obj_t **p,
19367836SJohn.Forte@Sun.COM 	isns_attr_t *pg_key1,
19377836SJohn.Forte@Sun.COM 	isns_tlv_t **op,
19387836SJohn.Forte@Sun.COM 	uint16_t *op_len
19397836SJohn.Forte@Sun.COM )
19407836SJohn.Forte@Sun.COM {
19417836SJohn.Forte@Sun.COM 	int ec = 0;
19427836SJohn.Forte@Sun.COM 
19437836SJohn.Forte@Sun.COM 	isns_tlv_t *tmp;
19447836SJohn.Forte@Sun.COM 	uint16_t tmp_len;
19457836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
19467836SJohn.Forte@Sun.COM 
19477836SJohn.Forte@Sun.COM 	isns_obj_t *obj = NULL;
19487836SJohn.Forte@Sun.COM 
19497836SJohn.Forte@Sun.COM 	tmp = *op;
19507836SJohn.Forte@Sun.COM 	tmp_len = *op_len;
19517836SJohn.Forte@Sun.COM 
19527836SJohn.Forte@Sun.COM 	/* keep the iscsi storage node name for */
19537836SJohn.Forte@Sun.COM 	/* parsing a pg object which is immediately */
19547836SJohn.Forte@Sun.COM 	/* followed with a PGT by the iscsi storage node */
19557836SJohn.Forte@Sun.COM 	pg_key1->tag = PG_KEY1;
19567836SJohn.Forte@Sun.COM 	pg_key1->len = tmp->attr_len;
19577836SJohn.Forte@Sun.COM 	pg_key1->value.ptr = (uchar_t *)&tmp->attr_value[0];
19587836SJohn.Forte@Sun.COM 
19597836SJohn.Forte@Sun.COM 	/* parse one iscsi storage node object */
19607836SJohn.Forte@Sun.COM 	obj = obj_calloc(OBJ_ISCSI);
19617836SJohn.Forte@Sun.COM 	if (obj != NULL) {
19627836SJohn.Forte@Sun.COM 		/* parse key & non-key attributes */
19637836SJohn.Forte@Sun.COM 		do {
19647836SJohn.Forte@Sun.COM 			attr = &obj->attrs[
19657836SJohn.Forte@Sun.COM 			    ATTR_INDEX_ISCSI(tmp->attr_id)];
19667836SJohn.Forte@Sun.COM 			ec = copy_attr(attr, tmp);
19677836SJohn.Forte@Sun.COM 			NEXT_TLV(tmp, tmp_len);
19687836SJohn.Forte@Sun.COM 		} while (ec == 0 &&
19697836SJohn.Forte@Sun.COM 		    tmp_len >= 8 &&
19707836SJohn.Forte@Sun.COM 		    IS_ISCSI_ATTR(tmp->attr_id));
19717836SJohn.Forte@Sun.COM 	} else {
19727836SJohn.Forte@Sun.COM 		/* no memory */
19737836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
19747836SJohn.Forte@Sun.COM 	}
19757836SJohn.Forte@Sun.COM 
19767836SJohn.Forte@Sun.COM 	*p = obj;
19777836SJohn.Forte@Sun.COM 	*op = tmp;
19787836SJohn.Forte@Sun.COM 	*op_len = tmp_len;
19797836SJohn.Forte@Sun.COM 
19807836SJohn.Forte@Sun.COM 	return (ec);
19817836SJohn.Forte@Sun.COM }
19827836SJohn.Forte@Sun.COM 
19837836SJohn.Forte@Sun.COM /*
19847836SJohn.Forte@Sun.COM  * ****************************************************************************
19857836SJohn.Forte@Sun.COM  *
19867836SJohn.Forte@Sun.COM  * reg_get_portal:
19877836SJohn.Forte@Sun.COM  *	parse the Operating Attributes of the DevAttrReg message and
19887836SJohn.Forte@Sun.COM  *	create a Portal object.
19897836SJohn.Forte@Sun.COM  *
19907836SJohn.Forte@Sun.COM  * p	- the pointer of the object for returning.
19917836SJohn.Forte@Sun.COM  * pg_key1 - the pointer of portal ip addr for returning.
19927836SJohn.Forte@Sun.COM  * pg_key2 - the pointer of portal port for returning.
19937836SJohn.Forte@Sun.COM  * op	- the operating attributes.
19947836SJohn.Forte@Sun.COM  * op_len - the length of the operating attributes.
19957836SJohn.Forte@Sun.COM  * return - error code.
19967836SJohn.Forte@Sun.COM  *
19977836SJohn.Forte@Sun.COM  * ****************************************************************************
19987836SJohn.Forte@Sun.COM  */
19997836SJohn.Forte@Sun.COM static int
reg_get_portal(isns_obj_t ** p,isns_attr_t * pg_key1,isns_attr_t * pg_key2,isns_tlv_t ** op,uint16_t * op_len)20007836SJohn.Forte@Sun.COM reg_get_portal(
20017836SJohn.Forte@Sun.COM 	isns_obj_t **p,
20027836SJohn.Forte@Sun.COM 	isns_attr_t *pg_key1,
20037836SJohn.Forte@Sun.COM 	isns_attr_t *pg_key2,
20047836SJohn.Forte@Sun.COM 	isns_tlv_t **op,
20057836SJohn.Forte@Sun.COM 	uint16_t *op_len
20067836SJohn.Forte@Sun.COM )
20077836SJohn.Forte@Sun.COM {
20087836SJohn.Forte@Sun.COM 	int ec = 0;
20097836SJohn.Forte@Sun.COM 
20107836SJohn.Forte@Sun.COM 	isns_tlv_t *tmp;
20117836SJohn.Forte@Sun.COM 	uint16_t tmp_len;
20127836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
20137836SJohn.Forte@Sun.COM 
20147836SJohn.Forte@Sun.COM 	isns_obj_t *obj = NULL;
20157836SJohn.Forte@Sun.COM 
20167836SJohn.Forte@Sun.COM 	isns_tlv_t *ip;
20177836SJohn.Forte@Sun.COM 
20187836SJohn.Forte@Sun.COM 	tmp = *op;
20197836SJohn.Forte@Sun.COM 	tmp_len = *op_len;
20207836SJohn.Forte@Sun.COM 
20217836SJohn.Forte@Sun.COM 	/* keep the portal ip addr */
20227836SJohn.Forte@Sun.COM 	pg_key1->tag = PG_KEY2;
20237836SJohn.Forte@Sun.COM 	pg_key1->len = tmp->attr_len;
20247836SJohn.Forte@Sun.COM 	pg_key1->value.ip = (void *)&tmp->attr_value[0];
20257836SJohn.Forte@Sun.COM 	ip = tmp;
20267836SJohn.Forte@Sun.COM 
20277836SJohn.Forte@Sun.COM 	NEXT_TLV(tmp, tmp_len);
20287836SJohn.Forte@Sun.COM 	if (tmp_len > 8 &&
20297836SJohn.Forte@Sun.COM 	    tmp->attr_id == PORTAL_KEY2 &&
20307836SJohn.Forte@Sun.COM 	    tmp->attr_len == 4) {
20317836SJohn.Forte@Sun.COM 		/* keep the portal port */
20327836SJohn.Forte@Sun.COM 		pg_key2->tag = PG_KEY3;
20337836SJohn.Forte@Sun.COM 		pg_key2->len = tmp->attr_len;
20347836SJohn.Forte@Sun.COM 		pg_key2->value.ui = ntohl(*(uint32_t *)&tmp->attr_value[0]);
20357836SJohn.Forte@Sun.COM 
20367836SJohn.Forte@Sun.COM 		/* parse one portal object */
20377836SJohn.Forte@Sun.COM 		obj = obj_calloc(OBJ_PORTAL);
20387836SJohn.Forte@Sun.COM 		if (obj != NULL) {
20397836SJohn.Forte@Sun.COM 			/* copy ip addr attribute */
20407836SJohn.Forte@Sun.COM 			attr = &obj->attrs[
20417836SJohn.Forte@Sun.COM 			    ATTR_INDEX_PORTAL(ip->attr_id)];
20427836SJohn.Forte@Sun.COM 			ec = copy_attr(attr, ip);
20437836SJohn.Forte@Sun.COM 			/* copy port attribute */
20447836SJohn.Forte@Sun.COM 			if (ec == 0) {
20457836SJohn.Forte@Sun.COM 				attr = &obj->attrs[
20467836SJohn.Forte@Sun.COM 				    ATTR_INDEX_PORTAL(tmp->attr_id)];
20477836SJohn.Forte@Sun.COM 				ec = copy_attr(attr, tmp);
20487836SJohn.Forte@Sun.COM 			}
20497836SJohn.Forte@Sun.COM 			/* parse non-key attributes */
20507836SJohn.Forte@Sun.COM 			NEXT_TLV(tmp, tmp_len);
20517836SJohn.Forte@Sun.COM 			while (ec == 0 &&
20527836SJohn.Forte@Sun.COM 			    tmp_len >= 8 &&
20537836SJohn.Forte@Sun.COM 			    IS_PORTAL_ATTR(tmp->attr_id)) {
20547836SJohn.Forte@Sun.COM 				attr = &obj->attrs[
20557836SJohn.Forte@Sun.COM 				    ATTR_INDEX_PORTAL(
20567836SJohn.Forte@Sun.COM 				    tmp->attr_id)];
20577836SJohn.Forte@Sun.COM 				ec = copy_attr(attr, tmp);
20587836SJohn.Forte@Sun.COM 				NEXT_TLV(tmp, tmp_len);
20597836SJohn.Forte@Sun.COM 			}
20607836SJohn.Forte@Sun.COM 		} else {
20617836SJohn.Forte@Sun.COM 			/* no memory */
20627836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
20637836SJohn.Forte@Sun.COM 		}
20647836SJohn.Forte@Sun.COM 	} else {
20657836SJohn.Forte@Sun.COM 		/* ip address is not followed by port */
20667836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
20677836SJohn.Forte@Sun.COM 	}
20687836SJohn.Forte@Sun.COM 
20697836SJohn.Forte@Sun.COM 	*p = obj;
20707836SJohn.Forte@Sun.COM 	*op = tmp;
20717836SJohn.Forte@Sun.COM 	*op_len = tmp_len;
20727836SJohn.Forte@Sun.COM 
20737836SJohn.Forte@Sun.COM 	return (ec);
20747836SJohn.Forte@Sun.COM }
20757836SJohn.Forte@Sun.COM 
20767836SJohn.Forte@Sun.COM /*
20777836SJohn.Forte@Sun.COM  * ****************************************************************************
20787836SJohn.Forte@Sun.COM  *
20797836SJohn.Forte@Sun.COM  * reg_get_pg:
20807836SJohn.Forte@Sun.COM  *	parse the Operating Attributes of the DevAttrReg message and
20817836SJohn.Forte@Sun.COM  *	create a Portal Group object.
20827836SJohn.Forte@Sun.COM  *
20837836SJohn.Forte@Sun.COM  * p	- the pointer of the object for returning.
20847836SJohn.Forte@Sun.COM  * op	- the operating attributes.
20857836SJohn.Forte@Sun.COM  * op_len - the length of the operating attributes.
20867836SJohn.Forte@Sun.COM  * return - error code.
20877836SJohn.Forte@Sun.COM  *
20887836SJohn.Forte@Sun.COM  * ****************************************************************************
20897836SJohn.Forte@Sun.COM  */
20907836SJohn.Forte@Sun.COM static int
reg_get_pg(isns_obj_t ** p,isns_tlv_t ** op,uint16_t * op_len)20917836SJohn.Forte@Sun.COM reg_get_pg(
20927836SJohn.Forte@Sun.COM 	isns_obj_t **p,
20937836SJohn.Forte@Sun.COM 	isns_tlv_t **op,
20947836SJohn.Forte@Sun.COM 	uint16_t *op_len
20957836SJohn.Forte@Sun.COM )
20967836SJohn.Forte@Sun.COM {
20977836SJohn.Forte@Sun.COM 	int ec = 0;
20987836SJohn.Forte@Sun.COM 
20997836SJohn.Forte@Sun.COM 	isns_tlv_t *tmp;
21007836SJohn.Forte@Sun.COM 	uint16_t tmp_len;
21017836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
21027836SJohn.Forte@Sun.COM 
21037836SJohn.Forte@Sun.COM 	isns_obj_t *obj = NULL;
21047836SJohn.Forte@Sun.COM 
21057836SJohn.Forte@Sun.COM 	tmp = *op;
21067836SJohn.Forte@Sun.COM 	tmp_len = *op_len;
21077836SJohn.Forte@Sun.COM 
21087836SJohn.Forte@Sun.COM 	/* parse a complete pg object */
21097836SJohn.Forte@Sun.COM 	obj = obj_calloc(OBJ_PG);
21107836SJohn.Forte@Sun.COM 	if (obj != NULL) {
21117836SJohn.Forte@Sun.COM 		/* parse attributes */
21127836SJohn.Forte@Sun.COM 		do {
21137836SJohn.Forte@Sun.COM 			attr = &obj->attrs[
21147836SJohn.Forte@Sun.COM 			    ATTR_INDEX_PG(tmp->attr_id)];
21157836SJohn.Forte@Sun.COM 			ec = copy_attr(attr, tmp);
21167836SJohn.Forte@Sun.COM 			NEXT_TLV(tmp, tmp_len);
21177836SJohn.Forte@Sun.COM 		} while (ec == 0 &&
21187836SJohn.Forte@Sun.COM 		    tmp_len >= 8 &&
21197836SJohn.Forte@Sun.COM 		    IS_PG_ATTR(tmp->attr_id));
21207836SJohn.Forte@Sun.COM 	} else {
21217836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
21227836SJohn.Forte@Sun.COM 	}
21237836SJohn.Forte@Sun.COM 
21247836SJohn.Forte@Sun.COM 	*p = obj;
21257836SJohn.Forte@Sun.COM 	*op = tmp;
21267836SJohn.Forte@Sun.COM 	*op_len = tmp_len;
21277836SJohn.Forte@Sun.COM 
21287836SJohn.Forte@Sun.COM 	return (ec);
21297836SJohn.Forte@Sun.COM }
21307836SJohn.Forte@Sun.COM 
21317836SJohn.Forte@Sun.COM /*
21327836SJohn.Forte@Sun.COM  * ****************************************************************************
21337836SJohn.Forte@Sun.COM  *
21347836SJohn.Forte@Sun.COM  * reg_get_pg1:
21357836SJohn.Forte@Sun.COM  *	parse the Operating Attributes of the DevAttrReg message and
21367836SJohn.Forte@Sun.COM  *	create a Portal Group object which is followed to a Portal object.
21377836SJohn.Forte@Sun.COM  *
21387836SJohn.Forte@Sun.COM  * p	- the pointer of the object for returning.
21397836SJohn.Forte@Sun.COM  * pgt	- the size-3 array of pointers which have the pg portal ip addr, port
21407836SJohn.Forte@Sun.COM  *	  and the pg tag attributes.
21417836SJohn.Forte@Sun.COM  * op	- the operating attributes.
21427836SJohn.Forte@Sun.COM  * op_len - the length of the operating attributes.
21437836SJohn.Forte@Sun.COM  * return - error code.
21447836SJohn.Forte@Sun.COM  *
21457836SJohn.Forte@Sun.COM  * ****************************************************************************
21467836SJohn.Forte@Sun.COM  */
21477836SJohn.Forte@Sun.COM static int
reg_get_pg1(isns_obj_t ** p,isns_attr_t const * pgt,isns_tlv_t ** op,uint16_t * op_len)21487836SJohn.Forte@Sun.COM reg_get_pg1(
21497836SJohn.Forte@Sun.COM 	isns_obj_t **p,
21507836SJohn.Forte@Sun.COM 	isns_attr_t const *pgt,
21517836SJohn.Forte@Sun.COM 	isns_tlv_t **op,
21527836SJohn.Forte@Sun.COM 	uint16_t *op_len
21537836SJohn.Forte@Sun.COM )
21547836SJohn.Forte@Sun.COM {
21557836SJohn.Forte@Sun.COM 	int ec = 0;
21567836SJohn.Forte@Sun.COM 
21577836SJohn.Forte@Sun.COM 	isns_tlv_t *tmp;
21587836SJohn.Forte@Sun.COM 	uint16_t tmp_len;
21597836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
21607836SJohn.Forte@Sun.COM 
21617836SJohn.Forte@Sun.COM 	isns_obj_t *obj = NULL;
21627836SJohn.Forte@Sun.COM 	int i = 0;
21637836SJohn.Forte@Sun.COM 
21647836SJohn.Forte@Sun.COM 	tmp = *op;
21657836SJohn.Forte@Sun.COM 	tmp_len = *op_len;
21667836SJohn.Forte@Sun.COM 
21677836SJohn.Forte@Sun.COM 	if (pgt[0].tag == PG_KEY2 &&
21687836SJohn.Forte@Sun.COM 	    pgt[1].tag == PG_KEY3) {
21697836SJohn.Forte@Sun.COM 		/* the pg iscsi storage node name is */
21707836SJohn.Forte@Sun.COM 		/* followed to a portal group tag */
21717836SJohn.Forte@Sun.COM 		obj = obj_calloc(OBJ_PG);
21727836SJohn.Forte@Sun.COM 		if (obj != NULL) {
21737836SJohn.Forte@Sun.COM 			/* copy pg iscsi storage node name */
21747836SJohn.Forte@Sun.COM 			attr = &obj->attrs[
21757836SJohn.Forte@Sun.COM 			    ATTR_INDEX_PG(tmp->attr_id)];
21767836SJohn.Forte@Sun.COM 			ec = copy_attr(attr, tmp);
21777836SJohn.Forte@Sun.COM 			/* copy pg ip addr, pg port & pgt */
21787836SJohn.Forte@Sun.COM 			while (ec == 0 && i < 3) {
21797836SJohn.Forte@Sun.COM 				attr = &obj->attrs[
21807836SJohn.Forte@Sun.COM 				    ATTR_INDEX_PG(pgt[i].tag)];
21817836SJohn.Forte@Sun.COM 				ec = assign_attr(attr, &pgt[i]);
21827836SJohn.Forte@Sun.COM 				i ++;
21837836SJohn.Forte@Sun.COM 			}
21847836SJohn.Forte@Sun.COM 			NEXT_TLV(tmp, tmp_len);
21857836SJohn.Forte@Sun.COM 		} else {
21867836SJohn.Forte@Sun.COM 			/* no memory */
21877836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
21887836SJohn.Forte@Sun.COM 		}
21897836SJohn.Forte@Sun.COM 	} else {
21907836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
21917836SJohn.Forte@Sun.COM 	}
21927836SJohn.Forte@Sun.COM 
21937836SJohn.Forte@Sun.COM 	*p = obj;
21947836SJohn.Forte@Sun.COM 	*op = tmp;
21957836SJohn.Forte@Sun.COM 	*op_len = tmp_len;
21967836SJohn.Forte@Sun.COM 
21977836SJohn.Forte@Sun.COM 	return (ec);
21987836SJohn.Forte@Sun.COM }
21997836SJohn.Forte@Sun.COM 
22007836SJohn.Forte@Sun.COM /*
22017836SJohn.Forte@Sun.COM  * ****************************************************************************
22027836SJohn.Forte@Sun.COM  *
22037836SJohn.Forte@Sun.COM  * reg_get_pg2:
22047836SJohn.Forte@Sun.COM  *	parse the Operating Attributes of the DevAttrReg message and
22057836SJohn.Forte@Sun.COM  *	create a Portal Group object which is followed to a iSCSI
22067836SJohn.Forte@Sun.COM  *	Storage Node object.
22077836SJohn.Forte@Sun.COM  *
22087836SJohn.Forte@Sun.COM  * p	- the pointer of the object for returning.
22097836SJohn.Forte@Sun.COM  * pgt	- the size-3 array of pointers which have the pg iscsi storage
22107836SJohn.Forte@Sun.COM  *	  node name and the pg tag attributes.
22117836SJohn.Forte@Sun.COM  * op	- the operating attributes.
22127836SJohn.Forte@Sun.COM  * op_len - the length of the operating attributes.
22137836SJohn.Forte@Sun.COM  * return - error code.
22147836SJohn.Forte@Sun.COM  *
22157836SJohn.Forte@Sun.COM  * ****************************************************************************
22167836SJohn.Forte@Sun.COM  */
22177836SJohn.Forte@Sun.COM static int
reg_get_pg2(isns_obj_t ** p,isns_attr_t const * pgt,isns_tlv_t ** op,uint16_t * op_len)22187836SJohn.Forte@Sun.COM reg_get_pg2(
22197836SJohn.Forte@Sun.COM 	isns_obj_t **p,
22207836SJohn.Forte@Sun.COM 	isns_attr_t const *pgt,
22217836SJohn.Forte@Sun.COM 	isns_tlv_t **op,
22227836SJohn.Forte@Sun.COM 	uint16_t *op_len
22237836SJohn.Forte@Sun.COM )
22247836SJohn.Forte@Sun.COM {
22257836SJohn.Forte@Sun.COM 	int ec = 0;
22267836SJohn.Forte@Sun.COM 
22277836SJohn.Forte@Sun.COM 	isns_tlv_t *tmp;
22287836SJohn.Forte@Sun.COM 	uint16_t tmp_len;
22297836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
22307836SJohn.Forte@Sun.COM 
22317836SJohn.Forte@Sun.COM 	isns_obj_t *obj = NULL;
22327836SJohn.Forte@Sun.COM 	int i = 0;
22337836SJohn.Forte@Sun.COM 
22347836SJohn.Forte@Sun.COM 	isns_tlv_t *ip;
22357836SJohn.Forte@Sun.COM 
22367836SJohn.Forte@Sun.COM 	tmp = *op;
22377836SJohn.Forte@Sun.COM 	tmp_len = *op_len;
22387836SJohn.Forte@Sun.COM 
22397836SJohn.Forte@Sun.COM 	/* keep ip address */
22407836SJohn.Forte@Sun.COM 	ip = tmp;
22417836SJohn.Forte@Sun.COM 	NEXT_TLV(tmp, tmp_len);
22427836SJohn.Forte@Sun.COM 
22437836SJohn.Forte@Sun.COM 	if (tmp_len > 8 &&
22447836SJohn.Forte@Sun.COM 	    /* expect pg portal port */
22457836SJohn.Forte@Sun.COM 	    tmp->attr_id == PG_KEY3 &&
22467836SJohn.Forte@Sun.COM 	    tmp->attr_len == 4 &&
22477836SJohn.Forte@Sun.COM 	    /* expect pg tag */
22487836SJohn.Forte@Sun.COM 	    pgt[2].tag == PG_PGT &&
22497836SJohn.Forte@Sun.COM 	    /* expect pg iscsi storage node name only */
22507836SJohn.Forte@Sun.COM 	    pgt[1].tag == 0 &&
22517836SJohn.Forte@Sun.COM 	    pgt[0].tag == PG_KEY1) {
22527836SJohn.Forte@Sun.COM 		/* the pg portal ip addr & port is followed */
22537836SJohn.Forte@Sun.COM 		/* to a pg tag and we have the iscsi storage */
22547836SJohn.Forte@Sun.COM 		/* node parsed previously */
22557836SJohn.Forte@Sun.COM 		obj = obj_calloc(OBJ_PG);
22567836SJohn.Forte@Sun.COM 		if (obj != NULL) {
22577836SJohn.Forte@Sun.COM 			/* copy the pg ip addr */
22587836SJohn.Forte@Sun.COM 			attr = &obj->attrs[
22597836SJohn.Forte@Sun.COM 			    ATTR_INDEX_PG(ip->attr_id)];
22607836SJohn.Forte@Sun.COM 			ec = copy_attr(attr, ip);
22617836SJohn.Forte@Sun.COM 			/* copy the pg port */
22627836SJohn.Forte@Sun.COM 			if (ec == 0) {
22637836SJohn.Forte@Sun.COM 				attr = &obj->attrs[
22647836SJohn.Forte@Sun.COM 				    ATTR_INDEX_PG(tmp->attr_id)];
22657836SJohn.Forte@Sun.COM 				ec = copy_attr(attr, tmp);
22667836SJohn.Forte@Sun.COM 			}
22677836SJohn.Forte@Sun.COM 			/* copy pg iscsi storage node name & pgt */
22687836SJohn.Forte@Sun.COM 			while (ec == 0 && i < 3) {
22697836SJohn.Forte@Sun.COM 				attr = &obj->attrs[
22707836SJohn.Forte@Sun.COM 				    ATTR_INDEX_PG(pgt[i].tag)];
22717836SJohn.Forte@Sun.COM 				ec = assign_attr(attr, &pgt[i]);
22727836SJohn.Forte@Sun.COM 				i += 2;
22737836SJohn.Forte@Sun.COM 			}
22747836SJohn.Forte@Sun.COM 			NEXT_TLV(tmp, tmp_len);
22757836SJohn.Forte@Sun.COM 		} else {
22767836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
22777836SJohn.Forte@Sun.COM 		}
22787836SJohn.Forte@Sun.COM 	} else {
22797836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
22807836SJohn.Forte@Sun.COM 	}
22817836SJohn.Forte@Sun.COM 
22827836SJohn.Forte@Sun.COM 	*p = obj;
22837836SJohn.Forte@Sun.COM 	*op = tmp;
22847836SJohn.Forte@Sun.COM 	*op_len = tmp_len;
22857836SJohn.Forte@Sun.COM 
22867836SJohn.Forte@Sun.COM 	return (ec);
22877836SJohn.Forte@Sun.COM }
22887836SJohn.Forte@Sun.COM 
22897836SJohn.Forte@Sun.COM /*
22907836SJohn.Forte@Sun.COM  * ****************************************************************************
22917836SJohn.Forte@Sun.COM  *
22927836SJohn.Forte@Sun.COM  * reg_get_obj:
22937836SJohn.Forte@Sun.COM  *	parse and create one object from the rest of Operating Attributes
22947836SJohn.Forte@Sun.COM  *	of the DevAttrReg message, the object can be iSCSI Storage Node,
22957836SJohn.Forte@Sun.COM  *	Portal or Portal Group.
22967836SJohn.Forte@Sun.COM  *
22977836SJohn.Forte@Sun.COM  * p	- the pointer of the object for returning.
22987836SJohn.Forte@Sun.COM  * pgt	- an attribute array with size 3, the elements are:
22997836SJohn.Forte@Sun.COM  *	  0: the first pg key attribute, it is either the name of an
23007836SJohn.Forte@Sun.COM  *	     iscsi storage node object or the ip addr of a portal object.
23017836SJohn.Forte@Sun.COM  *	  1: the second pg key attribute, i.e. the portal port.
23027836SJohn.Forte@Sun.COM  *	  2: the portal group tag attribute.
23037836SJohn.Forte@Sun.COM  * op	- the operating attributes.
23047836SJohn.Forte@Sun.COM  * op_len - the length of the operating attributes.
23057836SJohn.Forte@Sun.COM  * return - error code.
23067836SJohn.Forte@Sun.COM  *
23077836SJohn.Forte@Sun.COM  * ****************************************************************************
23087836SJohn.Forte@Sun.COM  */
23097836SJohn.Forte@Sun.COM int
reg_get_obj(isns_obj_t ** p,isns_attr_t * pgt,isns_tlv_t ** op,uint16_t * op_len)23107836SJohn.Forte@Sun.COM reg_get_obj(
23117836SJohn.Forte@Sun.COM 	isns_obj_t **p,
23127836SJohn.Forte@Sun.COM 	isns_attr_t *pgt,
23137836SJohn.Forte@Sun.COM 	isns_tlv_t **op,
23147836SJohn.Forte@Sun.COM 	uint16_t *op_len
23157836SJohn.Forte@Sun.COM )
23167836SJohn.Forte@Sun.COM {
23177836SJohn.Forte@Sun.COM 	int ec = 0;
23187836SJohn.Forte@Sun.COM 
23197836SJohn.Forte@Sun.COM 	int derefd = 0;
23207836SJohn.Forte@Sun.COM 
23217836SJohn.Forte@Sun.COM 	uint32_t pg_tag;
23227836SJohn.Forte@Sun.COM 
23237836SJohn.Forte@Sun.COM 	if (*op_len == 0) {
23247836SJohn.Forte@Sun.COM 		*p = NULL;
23257836SJohn.Forte@Sun.COM 		return (0);
23267836SJohn.Forte@Sun.COM 	}
23277836SJohn.Forte@Sun.COM 
23287836SJohn.Forte@Sun.COM 	switch ((*op)->attr_id) {
23297836SJohn.Forte@Sun.COM 	case ISCSI_KEY:
23307836SJohn.Forte@Sun.COM 		ec = reg_get_iscsi(p, &pgt[0], op, op_len);
23317836SJohn.Forte@Sun.COM 		pgt[1].tag = 0;
23327836SJohn.Forte@Sun.COM 		pgt[2].tag = 0;
23337836SJohn.Forte@Sun.COM 		break;
23347836SJohn.Forte@Sun.COM 	case PORTAL_KEY1:
23357836SJohn.Forte@Sun.COM 		ec = reg_get_portal(p, &pgt[0], &pgt[1], op, op_len);
23367836SJohn.Forte@Sun.COM 		pgt[2].tag = 0;
23377836SJohn.Forte@Sun.COM 		break;
23387836SJohn.Forte@Sun.COM 	case PG_KEY1:
23397836SJohn.Forte@Sun.COM 		if (pgt[2].tag == PG_PGT) {
23407836SJohn.Forte@Sun.COM 			/* pg iscsi storage node name is */
23417836SJohn.Forte@Sun.COM 			/* followed to a pgt */
23427836SJohn.Forte@Sun.COM 			ec = reg_get_pg1(p, pgt, op, op_len);
23437836SJohn.Forte@Sun.COM 		} else {
23447836SJohn.Forte@Sun.COM 			/* a complete pg object */
23457836SJohn.Forte@Sun.COM 			ec = reg_get_pg(p, op, op_len);
23467836SJohn.Forte@Sun.COM 			pgt[0].tag = 0;
23477836SJohn.Forte@Sun.COM 			pgt[1].tag = 0;
23487836SJohn.Forte@Sun.COM 			pgt[2].tag = 0;
23497836SJohn.Forte@Sun.COM 		}
23507836SJohn.Forte@Sun.COM 		break;
23517836SJohn.Forte@Sun.COM 	case PG_KEY2:
23527836SJohn.Forte@Sun.COM 		/* pg portal ip addr is followed to a pgt */
23537836SJohn.Forte@Sun.COM 		ec = reg_get_pg2(p, pgt, op, op_len);
23547836SJohn.Forte@Sun.COM 		break;
23557836SJohn.Forte@Sun.COM 	case PG_PGT:
23567836SJohn.Forte@Sun.COM 		switch (pgt[0].tag) {
23577836SJohn.Forte@Sun.COM 		case 0:
23587836SJohn.Forte@Sun.COM 			/* portal group tag does not follow */
23597836SJohn.Forte@Sun.COM 			/* iscsi storage node or portal object */
23607836SJohn.Forte@Sun.COM 			*p = NULL;
23617836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
23627836SJohn.Forte@Sun.COM 			break;
23637836SJohn.Forte@Sun.COM 		case PG_KEY1:
23647836SJohn.Forte@Sun.COM 		case PG_KEY2:
23657836SJohn.Forte@Sun.COM 			pgt[2].tag = PG_PGT;
23667836SJohn.Forte@Sun.COM 			pgt[2].len = (*op)->attr_len;
23677836SJohn.Forte@Sun.COM 			pg_tag = 0;
23687836SJohn.Forte@Sun.COM 			switch ((*op)->attr_len) {
23697836SJohn.Forte@Sun.COM 			case 4:
23707836SJohn.Forte@Sun.COM 				pg_tag = ntohl(*(uint32_t *)
23717836SJohn.Forte@Sun.COM 				    &(*op)->attr_value[0]);
23727836SJohn.Forte@Sun.COM 			case 0:
23737836SJohn.Forte@Sun.COM 				pgt[2].value.ui = pg_tag;
23747836SJohn.Forte@Sun.COM 				break;
23757836SJohn.Forte@Sun.COM 			default:
23767836SJohn.Forte@Sun.COM 				*p = NULL;
23777836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
23787836SJohn.Forte@Sun.COM 				break;
23797836SJohn.Forte@Sun.COM 			}
23807836SJohn.Forte@Sun.COM 			if (ec == 0) {
23817836SJohn.Forte@Sun.COM 				derefd = 1;
23827836SJohn.Forte@Sun.COM 				NEXT_TLV(*op, *op_len);
23837836SJohn.Forte@Sun.COM 				ec = reg_get_obj(p, pgt, op, op_len);
23847836SJohn.Forte@Sun.COM 			}
23857836SJohn.Forte@Sun.COM 			break;
23867836SJohn.Forte@Sun.COM 		default:
23877836SJohn.Forte@Sun.COM 			/* should never happen */
23887836SJohn.Forte@Sun.COM 			ASSERT(0);
23897836SJohn.Forte@Sun.COM 			*p = NULL;
23907836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
23917836SJohn.Forte@Sun.COM 			break;
23927836SJohn.Forte@Sun.COM 		}
23937836SJohn.Forte@Sun.COM 		break;
23947836SJohn.Forte@Sun.COM 	default:
23957836SJohn.Forte@Sun.COM 		*p = NULL;
23967836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_MSG_FORMAT_ERROR;
23977836SJohn.Forte@Sun.COM 		break;
23987836SJohn.Forte@Sun.COM 	}
23997836SJohn.Forte@Sun.COM 
24007836SJohn.Forte@Sun.COM 	if (ec == 0 && derefd == 0) {
24017836SJohn.Forte@Sun.COM 		ec = update_deref_obj(*p);
24027836SJohn.Forte@Sun.COM 	}
24037836SJohn.Forte@Sun.COM 
24047836SJohn.Forte@Sun.COM 	if (ec != 0 && *p != NULL) {
24057836SJohn.Forte@Sun.COM 		free_one_object(*p);
24067836SJohn.Forte@Sun.COM 		*p = NULL;
24077836SJohn.Forte@Sun.COM 	}
24087836SJohn.Forte@Sun.COM 
24097836SJohn.Forte@Sun.COM 	return (ec);
24107836SJohn.Forte@Sun.COM }
24117836SJohn.Forte@Sun.COM 
24127836SJohn.Forte@Sun.COM /*
24137836SJohn.Forte@Sun.COM  * ****************************************************************************
24147836SJohn.Forte@Sun.COM  *
24157836SJohn.Forte@Sun.COM  * reg_auth_src:
24167836SJohn.Forte@Sun.COM  *	Authorize the source attribute the DevAttrReg message.
24177836SJohn.Forte@Sun.COM  *	The update can only performed by the node who has the owenership.
24187836SJohn.Forte@Sun.COM  *
24197836SJohn.Forte@Sun.COM  * p	- the pointer of the object for returning.
24207836SJohn.Forte@Sun.COM  * pgt	- an attribute array with size 3, the elements are:
24217836SJohn.Forte@Sun.COM  *	  0: the first pg key attribute, it is either the name of an
24227836SJohn.Forte@Sun.COM  *	     iscsi storage node object or the ip addr of a portal object.
24237836SJohn.Forte@Sun.COM  *	  1: the second pg key attribute, i.e. the portal port.
24247836SJohn.Forte@Sun.COM  *	  2: the portal group tag attribute.
24257836SJohn.Forte@Sun.COM  * op	- the operating attributes.
24267836SJohn.Forte@Sun.COM  * op_len - the length of the operating attributes.
24277836SJohn.Forte@Sun.COM  * return - error code.
24287836SJohn.Forte@Sun.COM  *
24297836SJohn.Forte@Sun.COM  * ****************************************************************************
24307836SJohn.Forte@Sun.COM  */
24317836SJohn.Forte@Sun.COM int
reg_auth_src(isns_type_t type,uint32_t uid,uchar_t * src)24327836SJohn.Forte@Sun.COM reg_auth_src(
24337836SJohn.Forte@Sun.COM 	isns_type_t type,
24347836SJohn.Forte@Sun.COM 	uint32_t uid,
24357836SJohn.Forte@Sun.COM 	uchar_t *src
24367836SJohn.Forte@Sun.COM )
24377836SJohn.Forte@Sun.COM {
24387836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
24397836SJohn.Forte@Sun.COM 	uint32_t puid;
24407836SJohn.Forte@Sun.COM 
24417836SJohn.Forte@Sun.COM 	puid = is_parent_there(src);
24427836SJohn.Forte@Sun.COM 
24437836SJohn.Forte@Sun.COM 	if (TYPE_OF_PARENT[type] != 0) {
24447836SJohn.Forte@Sun.COM 		SET_UID_LCP(&lc, type, uid);
24457836SJohn.Forte@Sun.COM 		uid = cache_lookup(&lc, NULL, cb_get_parent);
24467836SJohn.Forte@Sun.COM 		type = TYPE_OF_PARENT[type];
24477836SJohn.Forte@Sun.COM 	}
24487836SJohn.Forte@Sun.COM 
24497836SJohn.Forte@Sun.COM 	if (uid != 0 && puid == 0) {
24507836SJohn.Forte@Sun.COM 		SET_UID_LCP(&lc, type, uid);
24517836SJohn.Forte@Sun.COM 		uid = cache_lookup(&lc, NULL, cb_node_child);
24527836SJohn.Forte@Sun.COM 	}
24537836SJohn.Forte@Sun.COM 
24547836SJohn.Forte@Sun.COM 	if (puid != uid) {
24557836SJohn.Forte@Sun.COM 		return (0);
24567836SJohn.Forte@Sun.COM 	}
24577836SJohn.Forte@Sun.COM 
24587836SJohn.Forte@Sun.COM 	return (1);
24597836SJohn.Forte@Sun.COM }
24607836SJohn.Forte@Sun.COM 
24617836SJohn.Forte@Sun.COM /*
24627836SJohn.Forte@Sun.COM  * ****************************************************************************
24637836SJohn.Forte@Sun.COM  *
24647836SJohn.Forte@Sun.COM  * is_obj_online:
24657836SJohn.Forte@Sun.COM  *	determine if the object is currently registered with the server.
24667836SJohn.Forte@Sun.COM  *
24677836SJohn.Forte@Sun.COM  * obj - the object being checked.
24687836SJohn.Forte@Sun.COM  * return - 0: not registered, otherwise registered.
24697836SJohn.Forte@Sun.COM  *
24707836SJohn.Forte@Sun.COM  * ****************************************************************************
24717836SJohn.Forte@Sun.COM  */
24727836SJohn.Forte@Sun.COM int
is_obj_online(const isns_obj_t * obj)24737836SJohn.Forte@Sun.COM is_obj_online(
24747836SJohn.Forte@Sun.COM 	const isns_obj_t *obj
24757836SJohn.Forte@Sun.COM )
24767836SJohn.Forte@Sun.COM {
24777836SJohn.Forte@Sun.COM 	int online = 1;
24787836SJohn.Forte@Sun.COM 
24797836SJohn.Forte@Sun.COM 	switch (obj->type) {
24807836SJohn.Forte@Sun.COM 	case OBJ_ISCSI:
24817836SJohn.Forte@Sun.COM 		online = obj->attrs[ATTR_INDEX_ISCSI(
24827836SJohn.Forte@Sun.COM 		    ISNS_ISCSI_NODE_TYPE_ATTR_ID)].value.ui == 0 ? 0 : 1;
24837836SJohn.Forte@Sun.COM 		break;
24847836SJohn.Forte@Sun.COM 	default:
24857836SJohn.Forte@Sun.COM 		break;
24867836SJohn.Forte@Sun.COM 	}
24877836SJohn.Forte@Sun.COM 
24887836SJohn.Forte@Sun.COM 	return (online);
24897836SJohn.Forte@Sun.COM }
24907836SJohn.Forte@Sun.COM 
24917836SJohn.Forte@Sun.COM static int
set_obj_offline(isns_obj_t * obj)24927836SJohn.Forte@Sun.COM set_obj_offline(
24937836SJohn.Forte@Sun.COM 	isns_obj_t *obj
24947836SJohn.Forte@Sun.COM )
24957836SJohn.Forte@Sun.COM {
24967836SJohn.Forte@Sun.COM 	switch (obj->type) {
24977836SJohn.Forte@Sun.COM 	case OBJ_ISCSI:
24987836SJohn.Forte@Sun.COM 		obj->attrs[ATTR_INDEX_ISCSI(
24997836SJohn.Forte@Sun.COM 		    ISNS_ISCSI_NODE_TYPE_ATTR_ID)].value.ui = 0;
25007836SJohn.Forte@Sun.COM 		break;
25017836SJohn.Forte@Sun.COM 	default:
25027836SJohn.Forte@Sun.COM 		break;
25037836SJohn.Forte@Sun.COM 	}
25047836SJohn.Forte@Sun.COM 
25057836SJohn.Forte@Sun.COM 	return (0);
25067836SJohn.Forte@Sun.COM }
25077836SJohn.Forte@Sun.COM 
25087836SJohn.Forte@Sun.COM /*
25097836SJohn.Forte@Sun.COM  * ****************************************************************************
25107836SJohn.Forte@Sun.COM  *
25117836SJohn.Forte@Sun.COM  * assoc_clone:
25127836SJohn.Forte@Sun.COM  *	clone the association object.
25137836SJohn.Forte@Sun.COM  *
25147836SJohn.Forte@Sun.COM  * p - the object being cloned.
25157836SJohn.Forte@Sun.COM  * clone_flag - 0: the object is being removed;
25167836SJohn.Forte@Sun.COM  *		1: only the association is being removed.
25177836SJohn.Forte@Sun.COM  * return - the clone object.
25187836SJohn.Forte@Sun.COM  *
25197836SJohn.Forte@Sun.COM  * ****************************************************************************
25207836SJohn.Forte@Sun.COM  */
25217836SJohn.Forte@Sun.COM void *
assoc_clone(void * p,int clone_flag)25227836SJohn.Forte@Sun.COM assoc_clone(
25237836SJohn.Forte@Sun.COM 	void *p,
25247836SJohn.Forte@Sun.COM 	int clone_flag
25257836SJohn.Forte@Sun.COM )
25267836SJohn.Forte@Sun.COM {
25277836SJohn.Forte@Sun.COM 	isns_type_t type;
25287836SJohn.Forte@Sun.COM 	isns_obj_t *clone;
25297836SJohn.Forte@Sun.COM 	const isns_attr_t *src_attr;
25307836SJohn.Forte@Sun.COM 	isns_attr_t *dst_attr;
25317836SJohn.Forte@Sun.COM 	uint32_t id, op;
25327836SJohn.Forte@Sun.COM 	int i = 0;
25337836SJohn.Forte@Sun.COM 
25347836SJohn.Forte@Sun.COM 	const isns_obj_t *obj;
25357836SJohn.Forte@Sun.COM 	uint32_t dd_flag;
25367836SJohn.Forte@Sun.COM 	int online;
25377836SJohn.Forte@Sun.COM 
25387836SJohn.Forte@Sun.COM 	int state;
25397836SJohn.Forte@Sun.COM 
25407836SJohn.Forte@Sun.COM 	obj = (isns_obj_t *)p;
25417836SJohn.Forte@Sun.COM 
25427836SJohn.Forte@Sun.COM 	if (obj->type != OBJ_ISCSI) {
25437836SJohn.Forte@Sun.COM 		return (NULL);
25447836SJohn.Forte@Sun.COM 	}
25457836SJohn.Forte@Sun.COM 
25467836SJohn.Forte@Sun.COM 	dd_flag = (get_dd_id(get_obj_uid(obj), ISNS_DEFAULT_DD_ID) == 0) ?
25477836SJohn.Forte@Sun.COM 	    0 : 1;
25487836SJohn.Forte@Sun.COM 	online = is_obj_online(obj);
25497836SJohn.Forte@Sun.COM 
25507836SJohn.Forte@Sun.COM 	state = (clone_flag << 2) | (dd_flag  << 1) | online;
25517836SJohn.Forte@Sun.COM 
25527836SJohn.Forte@Sun.COM 	/* clone_flag	dd_flag	online	action		*/
25537836SJohn.Forte@Sun.COM 	/* 0		0	0	ASSERT(0)	*/
25547836SJohn.Forte@Sun.COM 	/* 0		0	1	NULL		*/
25557836SJohn.Forte@Sun.COM 	/* 0		1	0	itself		*/
25567836SJohn.Forte@Sun.COM 	/* 0		1	1	clone it	*/
25577836SJohn.Forte@Sun.COM 	/* 1		0	0	NULL		*/
25587836SJohn.Forte@Sun.COM 	/* 1		0	1	itself		*/
25597836SJohn.Forte@Sun.COM 	/* 1		1	0	itself		*/
25607836SJohn.Forte@Sun.COM 	/* 1		1	1	itself		*/
25617836SJohn.Forte@Sun.COM 
25627836SJohn.Forte@Sun.COM 	switch (state) {
25637836SJohn.Forte@Sun.COM 	case 0:
25647836SJohn.Forte@Sun.COM 		ASSERT(0);
25657836SJohn.Forte@Sun.COM 	case 1:
25667836SJohn.Forte@Sun.COM 	case 4:
25677836SJohn.Forte@Sun.COM 		return (NULL);
25687836SJohn.Forte@Sun.COM 	case 2:
25697836SJohn.Forte@Sun.COM 	case 5:
25707836SJohn.Forte@Sun.COM 	case 6:
25717836SJohn.Forte@Sun.COM 	case 7:
25727836SJohn.Forte@Sun.COM 		return (p);
25737836SJohn.Forte@Sun.COM 	case 3:
25747836SJohn.Forte@Sun.COM 	default:
25757836SJohn.Forte@Sun.COM 		break;
25767836SJohn.Forte@Sun.COM 	}
25777836SJohn.Forte@Sun.COM 
25787836SJohn.Forte@Sun.COM 	type = obj->type;
25797836SJohn.Forte@Sun.COM 	clone = obj_calloc(type);
25807836SJohn.Forte@Sun.COM 
25817836SJohn.Forte@Sun.COM 	if (clone != NULL) {
25827836SJohn.Forte@Sun.COM 		id = UID_ATTR_INDEX[type];
25837836SJohn.Forte@Sun.COM 		src_attr = &(obj->attrs[id]);
25847836SJohn.Forte@Sun.COM 		dst_attr = &(clone->attrs[id]);
25857836SJohn.Forte@Sun.COM 		if (assign_attr(dst_attr, src_attr) != 0) {
25867836SJohn.Forte@Sun.COM 			free_one_object(clone);
25877836SJohn.Forte@Sun.COM 			return (NULL);
25887836SJohn.Forte@Sun.COM 		}
25897836SJohn.Forte@Sun.COM 
25907836SJohn.Forte@Sun.COM 		while (i < MAX_KEY_ATTRS) {
25917836SJohn.Forte@Sun.COM 			op = KEY_ATTR_OP[type][i];
25927836SJohn.Forte@Sun.COM 			if (op != 0) {
25937836SJohn.Forte@Sun.COM 				id = KEY_ATTR_INDEX[type][i];
25947836SJohn.Forte@Sun.COM 				src_attr = &(obj->attrs[id]);
25957836SJohn.Forte@Sun.COM 				dst_attr = &(clone->attrs[id]);
25967836SJohn.Forte@Sun.COM 				if (assign_attr(dst_attr, src_attr) != 0) {
25977836SJohn.Forte@Sun.COM 					free_one_object(clone);
25987836SJohn.Forte@Sun.COM 					return (NULL);
25997836SJohn.Forte@Sun.COM 				}
26007836SJohn.Forte@Sun.COM 			} else {
26017836SJohn.Forte@Sun.COM 				break;
26027836SJohn.Forte@Sun.COM 			}
26037836SJohn.Forte@Sun.COM 			i ++;
26047836SJohn.Forte@Sun.COM 		}
26057836SJohn.Forte@Sun.COM 	}
26067836SJohn.Forte@Sun.COM 
26077836SJohn.Forte@Sun.COM 	return ((void *)clone);
26087836SJohn.Forte@Sun.COM }
26097836SJohn.Forte@Sun.COM 
26107836SJohn.Forte@Sun.COM /*
26117836SJohn.Forte@Sun.COM  * ****************************************************************************
26127836SJohn.Forte@Sun.COM  *
26137836SJohn.Forte@Sun.COM  * free_one_object:
26147836SJohn.Forte@Sun.COM  *	free up one object.
26157836SJohn.Forte@Sun.COM  *
26167836SJohn.Forte@Sun.COM  * obj - the object being freed.
26177836SJohn.Forte@Sun.COM  *
26187836SJohn.Forte@Sun.COM  * ****************************************************************************
26197836SJohn.Forte@Sun.COM  */
26207836SJohn.Forte@Sun.COM void
free_one_object(isns_obj_t * obj)26217836SJohn.Forte@Sun.COM free_one_object(
26227836SJohn.Forte@Sun.COM 	isns_obj_t *obj
26237836SJohn.Forte@Sun.COM )
26247836SJohn.Forte@Sun.COM {
26257836SJohn.Forte@Sun.COM 	int i;
26267836SJohn.Forte@Sun.COM 	uint32_t *cuid;
26277836SJohn.Forte@Sun.COM 	if (obj == NULL) {
26287836SJohn.Forte@Sun.COM 		return;
26297836SJohn.Forte@Sun.COM 	}
26307836SJohn.Forte@Sun.COM 	for (i = 0; i < NUM_OF_ATTRS[obj->type]; i++) {
26317836SJohn.Forte@Sun.COM 		isns_attr_t *attr = &obj->attrs[i];
26327836SJohn.Forte@Sun.COM 		switch (attr->tag) {
26337836SJohn.Forte@Sun.COM 			case ISNS_EID_ATTR_ID:
26347836SJohn.Forte@Sun.COM 			case ISNS_ISCSI_NAME_ATTR_ID:
26357836SJohn.Forte@Sun.COM 			case ISNS_ISCSI_ALIAS_ATTR_ID:
26367836SJohn.Forte@Sun.COM 			case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
26377836SJohn.Forte@Sun.COM 			case ISNS_PG_ISCSI_NAME_ATTR_ID:
26387836SJohn.Forte@Sun.COM 			case ISNS_PORTAL_IP_ADDR_ATTR_ID:
26397836SJohn.Forte@Sun.COM 			case ISNS_PORTAL_NAME_ATTR_ID:
26407836SJohn.Forte@Sun.COM 			case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
26417836SJohn.Forte@Sun.COM 			case ISNS_DD_SET_NAME_ATTR_ID:
26427836SJohn.Forte@Sun.COM 			case ISNS_DD_NAME_ATTR_ID:
26437836SJohn.Forte@Sun.COM 			case ISNS_DD_ISCSI_NAME_ATTR_ID:
26447836SJohn.Forte@Sun.COM 			case ISNS_DD_FC_PORT_NAME_ATTR_ID:
26457836SJohn.Forte@Sun.COM 			case ISNS_DD_PORTAL_IP_ADDR_ATTR_ID:
26467836SJohn.Forte@Sun.COM #ifdef DEBUG
26477836SJohn.Forte@Sun.COM 				if (verbose_mc) {
26487836SJohn.Forte@Sun.COM 					printf("memory(%d) deallocated\n",
26497836SJohn.Forte@Sun.COM 					    attr->len);
26507836SJohn.Forte@Sun.COM 				}
26517836SJohn.Forte@Sun.COM #endif
26527836SJohn.Forte@Sun.COM 				free(attr->value.ptr);
26537836SJohn.Forte@Sun.COM 				attr->value.ptr = NULL;
26547836SJohn.Forte@Sun.COM 				break;
26557836SJohn.Forte@Sun.COM 			default:
26567836SJohn.Forte@Sun.COM 				break;
26577836SJohn.Forte@Sun.COM 		}
26587836SJohn.Forte@Sun.COM 	}
26597836SJohn.Forte@Sun.COM 
26607836SJohn.Forte@Sun.COM 	/* free child uids */
26617836SJohn.Forte@Sun.COM 	i = 0;
26627836SJohn.Forte@Sun.COM 	while (i < NUM_OF_CHILD[obj->type]) {
26637836SJohn.Forte@Sun.COM 		cuid = get_child_n(obj, i);
26647836SJohn.Forte@Sun.COM 		free(cuid);
26657836SJohn.Forte@Sun.COM 		i ++;
26667836SJohn.Forte@Sun.COM 	}
26677836SJohn.Forte@Sun.COM 
26687836SJohn.Forte@Sun.COM 	/* at last, free the object itself */
26697836SJohn.Forte@Sun.COM #ifdef DEBUG
26707836SJohn.Forte@Sun.COM 	if (verbose_mc) {
26717836SJohn.Forte@Sun.COM 		printf("object(%d) deallocated\n", obj->type);
26727836SJohn.Forte@Sun.COM 	}
26737836SJohn.Forte@Sun.COM #endif
26747836SJohn.Forte@Sun.COM 	free(obj);
26757836SJohn.Forte@Sun.COM }
26767836SJohn.Forte@Sun.COM 
26777836SJohn.Forte@Sun.COM /*
26787836SJohn.Forte@Sun.COM  * ****************************************************************************
26797836SJohn.Forte@Sun.COM  *
26807836SJohn.Forte@Sun.COM  * free_object:
26817836SJohn.Forte@Sun.COM  *	free up one object.
26827836SJohn.Forte@Sun.COM  *
26837836SJohn.Forte@Sun.COM  * obj - the object being freed.
26847836SJohn.Forte@Sun.COM  *
26857836SJohn.Forte@Sun.COM  * ****************************************************************************
26867836SJohn.Forte@Sun.COM  */
26877836SJohn.Forte@Sun.COM void
free_object(isns_obj_t * obj)26887836SJohn.Forte@Sun.COM free_object(
26897836SJohn.Forte@Sun.COM 	isns_obj_t *obj
26907836SJohn.Forte@Sun.COM )
26917836SJohn.Forte@Sun.COM {
26927836SJohn.Forte@Sun.COM 	free_one_object(obj);
26937836SJohn.Forte@Sun.COM }
26947836SJohn.Forte@Sun.COM 
26957836SJohn.Forte@Sun.COM /*
26967836SJohn.Forte@Sun.COM  * ****************************************************************************
26977836SJohn.Forte@Sun.COM  *
26987836SJohn.Forte@Sun.COM  * set_parent_obj:
26997836SJohn.Forte@Sun.COM  *	set the parent object UID.
27007836SJohn.Forte@Sun.COM  *
27017836SJohn.Forte@Sun.COM  * obj - the child object.
27027836SJohn.Forte@Sun.COM  * puid- the parent object UID.
27037836SJohn.Forte@Sun.COM  * return - error code.
27047836SJohn.Forte@Sun.COM  *
27057836SJohn.Forte@Sun.COM  * ****************************************************************************
27067836SJohn.Forte@Sun.COM  */
27077836SJohn.Forte@Sun.COM int
set_parent_obj(isns_obj_t * obj,uint32_t puid)27087836SJohn.Forte@Sun.COM set_parent_obj(
27097836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
27107836SJohn.Forte@Sun.COM 	uint32_t puid
27117836SJohn.Forte@Sun.COM )
27127836SJohn.Forte@Sun.COM {
27137836SJohn.Forte@Sun.COM 	uint32_t *const p = get_parent_p(obj);
27147836SJohn.Forte@Sun.COM 	if (p != NULL) {
27157836SJohn.Forte@Sun.COM 		*p = puid;
27167836SJohn.Forte@Sun.COM 	}
27177836SJohn.Forte@Sun.COM 
27187836SJohn.Forte@Sun.COM 	return (0);
27197836SJohn.Forte@Sun.COM }
27207836SJohn.Forte@Sun.COM 
27217836SJohn.Forte@Sun.COM /*
27227836SJohn.Forte@Sun.COM  * ****************************************************************************
27237836SJohn.Forte@Sun.COM  *
27247836SJohn.Forte@Sun.COM  * buff_child_obj:
27257836SJohn.Forte@Sun.COM  *	add a child object UID to the child object array.
27267836SJohn.Forte@Sun.COM  *
27277836SJohn.Forte@Sun.COM  * obj - the parent object.
27287836SJohn.Forte@Sun.COM  * child_type - the type of the child object.
27297836SJohn.Forte@Sun.COM  * number  - the number of the child object.
27307836SJohn.Forte@Sun.COM  * return - the length of the child object UID array.
27317836SJohn.Forte@Sun.COM  *
27327836SJohn.Forte@Sun.COM  * ****************************************************************************
27337836SJohn.Forte@Sun.COM  */
27347836SJohn.Forte@Sun.COM int
buff_child_obj(const isns_type_t ptype,const isns_type_t ctype,const void * c,void const *** child)27357836SJohn.Forte@Sun.COM buff_child_obj(
27367836SJohn.Forte@Sun.COM 	const isns_type_t ptype,
27377836SJohn.Forte@Sun.COM 	const isns_type_t ctype,
27387836SJohn.Forte@Sun.COM 	const void *c,
27397836SJohn.Forte@Sun.COM 	void const ***child
27407836SJohn.Forte@Sun.COM )
27417836SJohn.Forte@Sun.COM {
27427836SJohn.Forte@Sun.COM 	int ec = 0;
27437836SJohn.Forte@Sun.COM 
27447836SJohn.Forte@Sun.COM 	int i = 0;
27457836SJohn.Forte@Sun.COM 	void const ***pp, **p;
27467836SJohn.Forte@Sun.COM 	uint32_t num, new_num;
27477836SJohn.Forte@Sun.COM 
27487836SJohn.Forte@Sun.COM 	pp = NULL;
27497836SJohn.Forte@Sun.COM 	/* get the pointer of the array which the child belongs to */
27507836SJohn.Forte@Sun.COM 	while (i < NUM_OF_CHILD[ptype]) {
27517836SJohn.Forte@Sun.COM 		if (TYPE_OF_CHILD[ptype][i] == ctype) {
27527836SJohn.Forte@Sun.COM 			pp = &child[i];
27537836SJohn.Forte@Sun.COM 			break;
27547836SJohn.Forte@Sun.COM 		}
27557836SJohn.Forte@Sun.COM 		i ++;
27567836SJohn.Forte@Sun.COM 	}
27577836SJohn.Forte@Sun.COM 
27587836SJohn.Forte@Sun.COM 	/* the child type is not applicable */
27597836SJohn.Forte@Sun.COM 	if (pp == NULL) {
27607836SJohn.Forte@Sun.COM 		return (ec);
27617836SJohn.Forte@Sun.COM 	}
27627836SJohn.Forte@Sun.COM 
27637836SJohn.Forte@Sun.COM 	p = *pp;
27647836SJohn.Forte@Sun.COM 	/* get an empty slot from the uid array for this child */
27657836SJohn.Forte@Sun.COM 	if (p != NULL) {
27667836SJohn.Forte@Sun.COM 		num = (uint32_t)*p;
27677836SJohn.Forte@Sun.COM 		i = 0;
27687836SJohn.Forte@Sun.COM 		while (i < num) {
27697836SJohn.Forte@Sun.COM 			if (p[++i] == NULL) {
27707836SJohn.Forte@Sun.COM 				/* found it */
27717836SJohn.Forte@Sun.COM 				p[i] = c;
27727836SJohn.Forte@Sun.COM 				return (ec);
27737836SJohn.Forte@Sun.COM 			}
27747836SJohn.Forte@Sun.COM 		}
27757836SJohn.Forte@Sun.COM 		p = *pp;
27767836SJohn.Forte@Sun.COM 		new_num = num + 1;
27777836SJohn.Forte@Sun.COM 	} else {
27787836SJohn.Forte@Sun.COM 		num = 0;
27797836SJohn.Forte@Sun.COM 		new_num = 1;
27807836SJohn.Forte@Sun.COM 	}
27817836SJohn.Forte@Sun.COM 
27827836SJohn.Forte@Sun.COM 	/* the array is full, enlarge the child uid array */
27837836SJohn.Forte@Sun.COM 	p = (void const **)realloc(p, (new_num + 1) * sizeof (void *));
27847836SJohn.Forte@Sun.COM 	if (p != NULL) {
27857836SJohn.Forte@Sun.COM 		*pp = p;
27867836SJohn.Forte@Sun.COM 		*p = (void *)new_num;
27877836SJohn.Forte@Sun.COM 		p[new_num] = c;
27887836SJohn.Forte@Sun.COM 	} else {
27897836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
27907836SJohn.Forte@Sun.COM 	}
27917836SJohn.Forte@Sun.COM 
27927836SJohn.Forte@Sun.COM 	return (ec);
27937836SJohn.Forte@Sun.COM }
27947836SJohn.Forte@Sun.COM 
27957836SJohn.Forte@Sun.COM /*
27967836SJohn.Forte@Sun.COM  * ****************************************************************************
27977836SJohn.Forte@Sun.COM  *
27987836SJohn.Forte@Sun.COM  * update_child_object:
27997836SJohn.Forte@Sun.COM  *	update the child object of a network entity object.
28007836SJohn.Forte@Sun.COM  *
28017836SJohn.Forte@Sun.COM  * puid - the UID of the parent object, i.e. the network entity object.
28027836SJohn.Forte@Sun.COM  * child_type - the type of the child object.
28037836SJohn.Forte@Sun.COM  * child_uid  - the uid of the child object.
28047836SJohn.Forte@Sun.COM  * return - error code.
28057836SJohn.Forte@Sun.COM  *
28067836SJohn.Forte@Sun.COM  * ****************************************************************************
28077836SJohn.Forte@Sun.COM  */
28087836SJohn.Forte@Sun.COM int
update_child_obj(const isns_type_t ptype,const uint32_t puid,void const *** child,int child_flag)28097836SJohn.Forte@Sun.COM update_child_obj(
28107836SJohn.Forte@Sun.COM 	const isns_type_t ptype,
28117836SJohn.Forte@Sun.COM 	const uint32_t puid,
28127836SJohn.Forte@Sun.COM 	void const ***child,
28137836SJohn.Forte@Sun.COM 	int child_flag
28147836SJohn.Forte@Sun.COM )
28157836SJohn.Forte@Sun.COM {
28167836SJohn.Forte@Sun.COM 	int ec = 0;
28177836SJohn.Forte@Sun.COM 
28187836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
28197836SJohn.Forte@Sun.COM 
28207836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, ptype, puid);
28217836SJohn.Forte@Sun.COM 
28227836SJohn.Forte@Sun.COM 	lc.data[1].ptr = (uchar_t *)child;
28237836SJohn.Forte@Sun.COM 	lc.data[2].ui = child_flag;
28247836SJohn.Forte@Sun.COM 
28257836SJohn.Forte@Sun.COM 	ec = cache_lookup(&lc, NULL, cb_add_child);
28267836SJohn.Forte@Sun.COM 
28277836SJohn.Forte@Sun.COM 	return (ec);
28287836SJohn.Forte@Sun.COM }
28297836SJohn.Forte@Sun.COM 
28307836SJohn.Forte@Sun.COM int
update_ref_obj(const isns_obj_t * obj)28317836SJohn.Forte@Sun.COM update_ref_obj(
28327836SJohn.Forte@Sun.COM 	const isns_obj_t *obj
28337836SJohn.Forte@Sun.COM )
28347836SJohn.Forte@Sun.COM {
28357836SJohn.Forte@Sun.COM 	uint32_t uid;
28367836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
28377836SJohn.Forte@Sun.COM 	isns_type_t t;
28387836SJohn.Forte@Sun.COM 
28397836SJohn.Forte@Sun.COM 	t = obj->type;
28407836SJohn.Forte@Sun.COM 
28417836SJohn.Forte@Sun.COM 	if (TYPE_OF_REF[t][0] != 0) {
28427836SJohn.Forte@Sun.COM 		(void) setup_ref_lcp(&lc, obj, NULL);
28437836SJohn.Forte@Sun.COM 
28447836SJohn.Forte@Sun.COM 		lc.id[2] = t;
28457836SJohn.Forte@Sun.COM 		lc.data[2].ui = get_obj_uid(obj);
28467836SJohn.Forte@Sun.COM 
28477836SJohn.Forte@Sun.COM 		uid = 0;
28487836SJohn.Forte@Sun.COM 		do {
28497836SJohn.Forte@Sun.COM 			lc.curr_uid = uid;
28507836SJohn.Forte@Sun.COM 			(void) cache_lookup(&lc, &uid, cb_set_ref);
28517836SJohn.Forte@Sun.COM 		} while (uid != 0);
28527836SJohn.Forte@Sun.COM 	}
28537836SJohn.Forte@Sun.COM 
28547836SJohn.Forte@Sun.COM 	return (0);
28557836SJohn.Forte@Sun.COM }
28567836SJohn.Forte@Sun.COM 
28577836SJohn.Forte@Sun.COM /*
28587836SJohn.Forte@Sun.COM  * ****************************************************************************
28597836SJohn.Forte@Sun.COM  *
28607836SJohn.Forte@Sun.COM  * verify_ref_obj:
28617836SJohn.Forte@Sun.COM  *	update the reference bit of a portal group object.
28627836SJohn.Forte@Sun.COM  *
28637836SJohn.Forte@Sun.COM  * obj - the object being ref'ed.
28647836SJohn.Forte@Sun.COM  * return - error code.
28657836SJohn.Forte@Sun.COM  *
28667836SJohn.Forte@Sun.COM  * ****************************************************************************
28677836SJohn.Forte@Sun.COM  */
28687836SJohn.Forte@Sun.COM int
verify_ref_obj(const isns_type_t ptype,const uint32_t puid,void const *** child)28697836SJohn.Forte@Sun.COM verify_ref_obj(
28707836SJohn.Forte@Sun.COM 	const isns_type_t ptype,
28717836SJohn.Forte@Sun.COM 	const uint32_t puid,
28727836SJohn.Forte@Sun.COM 	void const ***child
28737836SJohn.Forte@Sun.COM )
28747836SJohn.Forte@Sun.COM {
28757836SJohn.Forte@Sun.COM 	int ec = 0;
28767836SJohn.Forte@Sun.COM 
28777836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
28787836SJohn.Forte@Sun.COM 
28797836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, ptype, puid);
28807836SJohn.Forte@Sun.COM 
28817836SJohn.Forte@Sun.COM 	lc.data[1].ptr = (uchar_t *)child;
28827836SJohn.Forte@Sun.COM 
28837836SJohn.Forte@Sun.COM 	ec = cache_lookup(&lc, NULL, cb_verify_ref);
28847836SJohn.Forte@Sun.COM 
28857836SJohn.Forte@Sun.COM 	return (ec);
28867836SJohn.Forte@Sun.COM }
28877836SJohn.Forte@Sun.COM 
28887836SJohn.Forte@Sun.COM int
update_deref_obj(isns_obj_t * obj)28897836SJohn.Forte@Sun.COM update_deref_obj(
28907836SJohn.Forte@Sun.COM 	isns_obj_t *obj
28917836SJohn.Forte@Sun.COM )
28927836SJohn.Forte@Sun.COM {
28937836SJohn.Forte@Sun.COM 	int ec = 0;
28947836SJohn.Forte@Sun.COM 
28957836SJohn.Forte@Sun.COM 	isns_type_t t, rt;
28967836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
28977836SJohn.Forte@Sun.COM 	int i, ref_count;
28987836SJohn.Forte@Sun.COM 
28997836SJohn.Forte@Sun.COM 	uint32_t uid, *refp;
29007836SJohn.Forte@Sun.COM 
29017836SJohn.Forte@Sun.COM 	t = obj->type;
29027836SJohn.Forte@Sun.COM 	i = ref_count = 0;
29037836SJohn.Forte@Sun.COM 	while (i < NUM_OF_REF[t]) {
29047836SJohn.Forte@Sun.COM 		rt = TYPE_OF_REF[t][i + 1];
29057836SJohn.Forte@Sun.COM 		(void) setup_deref_lcp(&lc, obj, rt);
29067836SJohn.Forte@Sun.COM 		uid = is_obj_there(&lc);
29077836SJohn.Forte@Sun.COM 		if (uid != 0) {
29087836SJohn.Forte@Sun.COM 			refp = get_ref_p(obj, lc.type);
29097836SJohn.Forte@Sun.COM 			*refp = uid;
29107836SJohn.Forte@Sun.COM 			ref_count ++;
29117836SJohn.Forte@Sun.COM 		}
29127836SJohn.Forte@Sun.COM 		i ++;
29137836SJohn.Forte@Sun.COM 	}
29147836SJohn.Forte@Sun.COM 
29157836SJohn.Forte@Sun.COM 	if (i > 0 && ref_count == 0) {
29167836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INVALID_REGIS;
29177836SJohn.Forte@Sun.COM 	}
29187836SJohn.Forte@Sun.COM 
29197836SJohn.Forte@Sun.COM 	return (ec);
29207836SJohn.Forte@Sun.COM }
29217836SJohn.Forte@Sun.COM 
29227836SJohn.Forte@Sun.COM /*
29237836SJohn.Forte@Sun.COM  * ****************************************************************************
29247836SJohn.Forte@Sun.COM  *
29257836SJohn.Forte@Sun.COM  * register_object:
29267836SJohn.Forte@Sun.COM  *	add one object to the object container.
29277836SJohn.Forte@Sun.COM  *
29287836SJohn.Forte@Sun.COM  * obj	- the object being added.
29297836SJohn.Forte@Sun.COM  * uid_p- the pointer for returning object UID.
29307836SJohn.Forte@Sun.COM  * update_p- the pointer for returning flag which indicates if the object
29317836SJohn.Forte@Sun.COM  *		is newly registered or updated with an existing one.
29327836SJohn.Forte@Sun.COM  * return - error code.
29337836SJohn.Forte@Sun.COM  *
29347836SJohn.Forte@Sun.COM  * ****************************************************************************
29357836SJohn.Forte@Sun.COM  */
29367836SJohn.Forte@Sun.COM int
register_object(isns_obj_t * obj,uint32_t * uid_p,int * update_p)29377836SJohn.Forte@Sun.COM register_object(
29387836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
29397836SJohn.Forte@Sun.COM 	uint32_t *uid_p,
29407836SJohn.Forte@Sun.COM 	int *update_p
29417836SJohn.Forte@Sun.COM )
29427836SJohn.Forte@Sun.COM {
29437836SJohn.Forte@Sun.COM 	return (cache_add(obj, 0, uid_p, update_p));
29447836SJohn.Forte@Sun.COM }
29457836SJohn.Forte@Sun.COM 
29467836SJohn.Forte@Sun.COM /*
29477836SJohn.Forte@Sun.COM  * ****************************************************************************
29487836SJohn.Forte@Sun.COM  *
29497836SJohn.Forte@Sun.COM  * register_assoc:
29507836SJohn.Forte@Sun.COM  *	add one association object to the object container, the association
29517836SJohn.Forte@Sun.COM  *	object has only the information for discovery domain membership, i.e.
29527836SJohn.Forte@Sun.COM  *	a name and UID only.
29537836SJohn.Forte@Sun.COM  *
29547836SJohn.Forte@Sun.COM  * obj	- the association object being added.
29557836SJohn.Forte@Sun.COM  * uid_p- the pointer for returning object UID.
29567836SJohn.Forte@Sun.COM  * return - error code.
29577836SJohn.Forte@Sun.COM  *
29587836SJohn.Forte@Sun.COM  * ****************************************************************************
29597836SJohn.Forte@Sun.COM  */
29607836SJohn.Forte@Sun.COM int
register_assoc(isns_obj_t * obj,uint32_t * uid_p)29617836SJohn.Forte@Sun.COM register_assoc(
29627836SJohn.Forte@Sun.COM 	isns_obj_t *obj,
29637836SJohn.Forte@Sun.COM 	uint32_t *uid_p
29647836SJohn.Forte@Sun.COM )
29657836SJohn.Forte@Sun.COM {
29667836SJohn.Forte@Sun.COM 	return (cache_add(obj, 1, uid_p, NULL));
29677836SJohn.Forte@Sun.COM }
29687836SJohn.Forte@Sun.COM 
29697836SJohn.Forte@Sun.COM /*
29707836SJohn.Forte@Sun.COM  * ****************************************************************************
29717836SJohn.Forte@Sun.COM  *
29727836SJohn.Forte@Sun.COM  * is_obj_there:
29737836SJohn.Forte@Sun.COM  *	check if the object is registered or not.
29747836SJohn.Forte@Sun.COM  *
29757836SJohn.Forte@Sun.COM  * lcp	- the lookup control data.
29767836SJohn.Forte@Sun.COM  * return - the object UID.
29777836SJohn.Forte@Sun.COM  *
29787836SJohn.Forte@Sun.COM  * ****************************************************************************
29797836SJohn.Forte@Sun.COM  */
29807836SJohn.Forte@Sun.COM uint32_t
is_obj_there(lookup_ctrl_t * lcp)29817836SJohn.Forte@Sun.COM is_obj_there(
29827836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
29837836SJohn.Forte@Sun.COM )
29847836SJohn.Forte@Sun.COM {
29857836SJohn.Forte@Sun.COM 	uint32_t uid;
29867836SJohn.Forte@Sun.COM 
29877836SJohn.Forte@Sun.COM 	(void) cache_lookup(lcp, &uid, NULL);
29887836SJohn.Forte@Sun.COM 
29897836SJohn.Forte@Sun.COM 	return (uid);
29907836SJohn.Forte@Sun.COM }
29917836SJohn.Forte@Sun.COM 
29927836SJohn.Forte@Sun.COM uint32_t
is_parent_there(uchar_t * src)29937836SJohn.Forte@Sun.COM is_parent_there(
29947836SJohn.Forte@Sun.COM 	uchar_t *src
29957836SJohn.Forte@Sun.COM )
29967836SJohn.Forte@Sun.COM {
29977836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
29987836SJohn.Forte@Sun.COM 
29997836SJohn.Forte@Sun.COM 	lc.curr_uid = 0;
30007836SJohn.Forte@Sun.COM 	lc.type = OBJ_ISCSI;
30017836SJohn.Forte@Sun.COM 	lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
30027836SJohn.Forte@Sun.COM 	lc.op[0] = OP_STRING;
30037836SJohn.Forte@Sun.COM 	lc.data[0].ptr = src;
30047836SJohn.Forte@Sun.COM 	lc.op[1] = 0;
30057836SJohn.Forte@Sun.COM 
30067836SJohn.Forte@Sun.COM 	return (cache_lookup(&lc, NULL, cb_get_parent));
30077836SJohn.Forte@Sun.COM }
30087836SJohn.Forte@Sun.COM 
30097836SJohn.Forte@Sun.COM /*
30107836SJohn.Forte@Sun.COM  * ****************************************************************************
30117836SJohn.Forte@Sun.COM  *
30127836SJohn.Forte@Sun.COM  * setup_ref_lcp:
30137836SJohn.Forte@Sun.COM  *	prepare the lookup control data for looking up a portal group
30147836SJohn.Forte@Sun.COM  *	object which references to a iscsi stroage node and/or a portal
30157836SJohn.Forte@Sun.COM  *	object.
30167836SJohn.Forte@Sun.COM  *
30177836SJohn.Forte@Sun.COM  * lcp	- the lookup control data.
30187836SJohn.Forte@Sun.COM  * iscsi- the ref'ed iscsi storage node object.
30197836SJohn.Forte@Sun.COM  * portal- the ref'ed portal object.
30207836SJohn.Forte@Sun.COM  * return - error code.
30217836SJohn.Forte@Sun.COM  *
30227836SJohn.Forte@Sun.COM  * ****************************************************************************
30237836SJohn.Forte@Sun.COM  */
30247836SJohn.Forte@Sun.COM static int
setup_ref_lcp(lookup_ctrl_t * lcp,const isns_obj_t * iscsi,const isns_obj_t * portal)30257836SJohn.Forte@Sun.COM setup_ref_lcp(
30267836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp,
30277836SJohn.Forte@Sun.COM 	const isns_obj_t *iscsi,
30287836SJohn.Forte@Sun.COM 	const isns_obj_t *portal
30297836SJohn.Forte@Sun.COM )
30307836SJohn.Forte@Sun.COM {
30317836SJohn.Forte@Sun.COM 	int i = 0, j = 0;
30327836SJohn.Forte@Sun.COM 
30337836SJohn.Forte@Sun.COM 	lcp->curr_uid = 0;
30347836SJohn.Forte@Sun.COM 	lcp->type = TYPE_OF_REF[iscsi->type][0];
30357836SJohn.Forte@Sun.COM 
30367836SJohn.Forte@Sun.COM 	/* extrace the matching attributes from iscsi storage node object */
30377836SJohn.Forte@Sun.COM 	while (iscsi != NULL &&
30387836SJohn.Forte@Sun.COM 	    i < MAX_REF_MATCH &&
30397836SJohn.Forte@Sun.COM 	    REF_MATCH_OPS[iscsi->type][i] > 0) {
30407836SJohn.Forte@Sun.COM 		lcp->id[i] = REF_MATCH_ID2[iscsi->type][i];
30417836SJohn.Forte@Sun.COM 		lcp->op[i] = REF_MATCH_OPS[iscsi->type][i];
30427836SJohn.Forte@Sun.COM 		lcp->data[i].ptr = iscsi->attrs[
30437836SJohn.Forte@Sun.COM 		    REF_MATCH_ID1[iscsi->type][i]].value.ptr;
30447836SJohn.Forte@Sun.COM 		i ++;
30457836SJohn.Forte@Sun.COM 	}
30467836SJohn.Forte@Sun.COM 
30477836SJohn.Forte@Sun.COM 	/* extrace the matching attributes from portal object */
30487836SJohn.Forte@Sun.COM 	while (portal != NULL &&
30497836SJohn.Forte@Sun.COM 	    i < MAX_LOOKUP_CTRL &&
30507836SJohn.Forte@Sun.COM 	    j < MAX_REF_MATCH &&
30517836SJohn.Forte@Sun.COM 	    REF_MATCH_OPS[portal->type][j] > 0) {
30527836SJohn.Forte@Sun.COM 		lcp->id[i] = REF_MATCH_ID2[portal->type][j];
30537836SJohn.Forte@Sun.COM 		lcp->op[i] = REF_MATCH_OPS[portal->type][j];
30547836SJohn.Forte@Sun.COM 		lcp->data[i].ptr = portal->attrs[
30557836SJohn.Forte@Sun.COM 		    REF_MATCH_ID1[portal->type][j]].value.ptr;
30567836SJohn.Forte@Sun.COM 		j ++;
30577836SJohn.Forte@Sun.COM 		i ++;
30587836SJohn.Forte@Sun.COM 	}
30597836SJohn.Forte@Sun.COM 
30607836SJohn.Forte@Sun.COM 	if (i < MAX_LOOKUP_CTRL) {
30617836SJohn.Forte@Sun.COM 		lcp->op[i] = 0;
30627836SJohn.Forte@Sun.COM 	}
30637836SJohn.Forte@Sun.COM 
30647836SJohn.Forte@Sun.COM 	return (0);
30657836SJohn.Forte@Sun.COM }
30667836SJohn.Forte@Sun.COM 
30677836SJohn.Forte@Sun.COM static int
setup_deref_lcp(lookup_ctrl_t * lcp,const isns_obj_t * pg,isns_type_t t)30687836SJohn.Forte@Sun.COM setup_deref_lcp(
30697836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp,
30707836SJohn.Forte@Sun.COM 	const isns_obj_t *pg,
30717836SJohn.Forte@Sun.COM 	isns_type_t t
30727836SJohn.Forte@Sun.COM )
30737836SJohn.Forte@Sun.COM {
30747836SJohn.Forte@Sun.COM 	int i = 0;
30757836SJohn.Forte@Sun.COM 
30767836SJohn.Forte@Sun.COM 	lcp->curr_uid = 0;
30777836SJohn.Forte@Sun.COM 	lcp->type = t;
30787836SJohn.Forte@Sun.COM 
30797836SJohn.Forte@Sun.COM 	/* extrace the matching attributes from iscsi storage node object */
30807836SJohn.Forte@Sun.COM 	while (i < MAX_REF_MATCH &&
30817836SJohn.Forte@Sun.COM 	    REF_MATCH_OPS[t][i] > 0) {
30827836SJohn.Forte@Sun.COM 		lcp->id[i] = REF_MATCH_ID1[t][i];
30837836SJohn.Forte@Sun.COM 		lcp->op[i] = REF_MATCH_OPS[t][i];
30847836SJohn.Forte@Sun.COM 		lcp->data[i].ptr = pg->attrs[
30857836SJohn.Forte@Sun.COM 		    REF_MATCH_ID2[t][i]].value.ptr;
30867836SJohn.Forte@Sun.COM 		i ++;
30877836SJohn.Forte@Sun.COM 	}
30887836SJohn.Forte@Sun.COM 
30897836SJohn.Forte@Sun.COM 	if (i < MAX_LOOKUP_CTRL) {
30907836SJohn.Forte@Sun.COM 		lcp->op[i] = 0;
30917836SJohn.Forte@Sun.COM 	}
30927836SJohn.Forte@Sun.COM 
30937836SJohn.Forte@Sun.COM 	return (0);
30947836SJohn.Forte@Sun.COM }
30957836SJohn.Forte@Sun.COM 
30967836SJohn.Forte@Sun.COM /*
30977836SJohn.Forte@Sun.COM  * ****************************************************************************
30987836SJohn.Forte@Sun.COM  *
30997836SJohn.Forte@Sun.COM  * setup_parent_lcp:
31007836SJohn.Forte@Sun.COM  *	prepare the lookup control data for looking up parent object
31017836SJohn.Forte@Sun.COM  *	with a child object.
31027836SJohn.Forte@Sun.COM  *
31037836SJohn.Forte@Sun.COM  * lcp	- the lookup control data.
31047836SJohn.Forte@Sun.COM  * obj	- the child object.
31057836SJohn.Forte@Sun.COM  * return - parent object UID.
31067836SJohn.Forte@Sun.COM  *
31077836SJohn.Forte@Sun.COM  * ****************************************************************************
31087836SJohn.Forte@Sun.COM  */
31097836SJohn.Forte@Sun.COM static uint32_t
setup_parent_lcp(lookup_ctrl_t * lcp,isns_obj_t * obj)31107836SJohn.Forte@Sun.COM setup_parent_lcp(
31117836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp,
31127836SJohn.Forte@Sun.COM 	isns_obj_t *obj
31137836SJohn.Forte@Sun.COM )
31147836SJohn.Forte@Sun.COM {
31157836SJohn.Forte@Sun.COM 	isns_type_t ptype;
31167836SJohn.Forte@Sun.COM 	uint32_t puid;
31177836SJohn.Forte@Sun.COM 
31187836SJohn.Forte@Sun.COM 	puid = get_parent_uid(obj);
31197836SJohn.Forte@Sun.COM 	if (puid != 0) {
31207836SJohn.Forte@Sun.COM 		ptype = TYPE_OF_PARENT[obj->type];
31217836SJohn.Forte@Sun.COM 		SET_UID_LCP(lcp, ptype, puid);
31227836SJohn.Forte@Sun.COM 		lcp->data[1].ui = obj->type;
31237836SJohn.Forte@Sun.COM 		lcp->data[2].ui = get_obj_uid(obj);
31247836SJohn.Forte@Sun.COM 	}
31257836SJohn.Forte@Sun.COM 
31267836SJohn.Forte@Sun.COM 	return (puid);
31277836SJohn.Forte@Sun.COM }
31287836SJohn.Forte@Sun.COM 
31297836SJohn.Forte@Sun.COM static int
cb_get_parent(void * p1,void * p2)31307836SJohn.Forte@Sun.COM cb_get_parent(
31317836SJohn.Forte@Sun.COM 	void *p1,
31327836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
31337836SJohn.Forte@Sun.COM 	void *p2
31347836SJohn.Forte@Sun.COM )
31357836SJohn.Forte@Sun.COM {
31367836SJohn.Forte@Sun.COM 	return (get_parent_uid(p1));
31377836SJohn.Forte@Sun.COM }
31387836SJohn.Forte@Sun.COM 
31397836SJohn.Forte@Sun.COM static int
cb_node_child(void * p1,void * p2)31407836SJohn.Forte@Sun.COM cb_node_child(
31417836SJohn.Forte@Sun.COM 	void *p1,
31427836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
31437836SJohn.Forte@Sun.COM 	void *p2
31447836SJohn.Forte@Sun.COM )
31457836SJohn.Forte@Sun.COM {
31467836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
31477836SJohn.Forte@Sun.COM 
31487836SJohn.Forte@Sun.COM 	uint32_t num, uid;
31497836SJohn.Forte@Sun.COM 
31507836SJohn.Forte@Sun.COM 	uint32_t *cuid = get_child_t(obj, OBJ_ISCSI);
31517836SJohn.Forte@Sun.COM 
31527836SJohn.Forte@Sun.COM 	if (cuid != NULL) {
31537836SJohn.Forte@Sun.COM 		num = *cuid;
31547836SJohn.Forte@Sun.COM 	} else {
31557836SJohn.Forte@Sun.COM 		num = 0;
31567836SJohn.Forte@Sun.COM 	}
31577836SJohn.Forte@Sun.COM 
31587836SJohn.Forte@Sun.COM 	while (num > 0) {
31597836SJohn.Forte@Sun.COM 		uid = *++cuid;
31607836SJohn.Forte@Sun.COM 		if (uid != 0) {
31617836SJohn.Forte@Sun.COM 			return (uid);
31627836SJohn.Forte@Sun.COM 		}
31637836SJohn.Forte@Sun.COM 		num --;
31647836SJohn.Forte@Sun.COM 	}
31657836SJohn.Forte@Sun.COM 
31667836SJohn.Forte@Sun.COM 	return (0);
31677836SJohn.Forte@Sun.COM }
31687836SJohn.Forte@Sun.COM 
31697836SJohn.Forte@Sun.COM /*
31707836SJohn.Forte@Sun.COM  * ****************************************************************************
31717836SJohn.Forte@Sun.COM  *
31727836SJohn.Forte@Sun.COM  * cb_set_ref:
31737836SJohn.Forte@Sun.COM  *	callback function which sets the reference bit to 1 according to
31747836SJohn.Forte@Sun.COM  *	the type of object.
31757836SJohn.Forte@Sun.COM  *
31767836SJohn.Forte@Sun.COM  * p1	- the object.
31777836SJohn.Forte@Sun.COM  * p2	- the lcp.
31787836SJohn.Forte@Sun.COM  * return - error code.
31797836SJohn.Forte@Sun.COM  *
31807836SJohn.Forte@Sun.COM  * ****************************************************************************
31817836SJohn.Forte@Sun.COM  */
31827836SJohn.Forte@Sun.COM static int
cb_set_ref(void * p1,void * p2)31837836SJohn.Forte@Sun.COM cb_set_ref(
31847836SJohn.Forte@Sun.COM 	void *p1,
31857836SJohn.Forte@Sun.COM 	void *p2
31867836SJohn.Forte@Sun.COM )
31877836SJohn.Forte@Sun.COM {
31887836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
31897836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
31907836SJohn.Forte@Sun.COM 
31917836SJohn.Forte@Sun.COM 	isns_type_t t;
31927836SJohn.Forte@Sun.COM 	uint32_t u;
31937836SJohn.Forte@Sun.COM 
31947836SJohn.Forte@Sun.COM 	uint32_t *refp;
31957836SJohn.Forte@Sun.COM 
31967836SJohn.Forte@Sun.COM 	t = lcp->id[2];
31977836SJohn.Forte@Sun.COM 	u = lcp->data[2].ui;
31987836SJohn.Forte@Sun.COM 	refp = get_ref_p(obj, t);
31997836SJohn.Forte@Sun.COM 	*refp = u;
32007836SJohn.Forte@Sun.COM 
32017836SJohn.Forte@Sun.COM 	/* successful */
32027836SJohn.Forte@Sun.COM 	return (0);
32037836SJohn.Forte@Sun.COM }
32047836SJohn.Forte@Sun.COM 
32057836SJohn.Forte@Sun.COM /*
32067836SJohn.Forte@Sun.COM  * ****************************************************************************
32077836SJohn.Forte@Sun.COM  *
32087836SJohn.Forte@Sun.COM  * cb_clear_ref:
32097836SJohn.Forte@Sun.COM  *	callback function which clears the reference bit according to
32107836SJohn.Forte@Sun.COM  *	the type of object.
32117836SJohn.Forte@Sun.COM  *
32127836SJohn.Forte@Sun.COM  * p1	- the object.
32137836SJohn.Forte@Sun.COM  * p2	- the lcp.
32147836SJohn.Forte@Sun.COM  * return - 1: the object is no longer ref'ed, 0: otherwise.
32157836SJohn.Forte@Sun.COM  *
32167836SJohn.Forte@Sun.COM  * ****************************************************************************
32177836SJohn.Forte@Sun.COM  */
32187836SJohn.Forte@Sun.COM static int
cb_clear_ref(void * p1,void * p2)32197836SJohn.Forte@Sun.COM cb_clear_ref(
32207836SJohn.Forte@Sun.COM 	void *p1,
32217836SJohn.Forte@Sun.COM 	void *p2
32227836SJohn.Forte@Sun.COM )
32237836SJohn.Forte@Sun.COM {
32247836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
32257836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
32267836SJohn.Forte@Sun.COM 
32277836SJohn.Forte@Sun.COM 	isns_type_t t;
32287836SJohn.Forte@Sun.COM 	uint32_t *refp;
32297836SJohn.Forte@Sun.COM 
32307836SJohn.Forte@Sun.COM 	int i = 0;
32317836SJohn.Forte@Sun.COM 	uint32_t ref;
32327836SJohn.Forte@Sun.COM 
32337836SJohn.Forte@Sun.COM 	t = lcp->data[2].ui;
32347836SJohn.Forte@Sun.COM 	refp = get_ref_p(obj, t);
32357836SJohn.Forte@Sun.COM 	*refp = 0;
32367836SJohn.Forte@Sun.COM 
32377836SJohn.Forte@Sun.COM 	while (i < NUM_OF_REF[obj->type]) {
32387836SJohn.Forte@Sun.COM 		ref = get_ref_n(obj, i);
32397836SJohn.Forte@Sun.COM 		if (ref != 0) {
32407836SJohn.Forte@Sun.COM 			return (0);
32417836SJohn.Forte@Sun.COM 		}
32427836SJohn.Forte@Sun.COM 		i ++;
32437836SJohn.Forte@Sun.COM 	}
32447836SJohn.Forte@Sun.COM 
32457836SJohn.Forte@Sun.COM 	return (1);
32467836SJohn.Forte@Sun.COM }
32477836SJohn.Forte@Sun.COM 
32487836SJohn.Forte@Sun.COM static int
cb_add_child(void * p1,void * p2)32497836SJohn.Forte@Sun.COM cb_add_child(
32507836SJohn.Forte@Sun.COM 	void *p1,
32517836SJohn.Forte@Sun.COM 	void *p2
32527836SJohn.Forte@Sun.COM )
32537836SJohn.Forte@Sun.COM {
32547836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
32557836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
32567836SJohn.Forte@Sun.COM 
32577836SJohn.Forte@Sun.COM 	const void ***child;
32587836SJohn.Forte@Sun.COM 	const void **vpp;
32597836SJohn.Forte@Sun.COM 	uint32_t vnum;
32607836SJohn.Forte@Sun.COM 	int child_flag;
32617836SJohn.Forte@Sun.COM 
32627836SJohn.Forte@Sun.COM 	uint32_t **upp, *up;
32637836SJohn.Forte@Sun.COM 	uint32_t num;
32647836SJohn.Forte@Sun.COM 
32657836SJohn.Forte@Sun.COM 	isns_obj_t *o;
32667836SJohn.Forte@Sun.COM 
32677836SJohn.Forte@Sun.COM 	int i = 0;
32687836SJohn.Forte@Sun.COM 
32697836SJohn.Forte@Sun.COM 	child = (const void ***)lcp->data[1].ptr;
32707836SJohn.Forte@Sun.COM 	child_flag = lcp->data[2].ui;
32717836SJohn.Forte@Sun.COM 
32727836SJohn.Forte@Sun.COM 	while (i < NUM_OF_CHILD[obj->type]) {
32737836SJohn.Forte@Sun.COM 		vpp = child[i];
32747836SJohn.Forte@Sun.COM 		if (vpp != NULL &&
32757836SJohn.Forte@Sun.COM 		    (vnum = (uint32_t)*vpp) > 0 &&
32767836SJohn.Forte@Sun.COM 		    *(vpp + 1) != NULL) {
32777836SJohn.Forte@Sun.COM 			upp = get_child_np(obj, i);
32787836SJohn.Forte@Sun.COM 			if (*upp == NULL) {
32797836SJohn.Forte@Sun.COM 				if (child_flag == 0 &&
32807836SJohn.Forte@Sun.COM 				    sizeof (typeof (**upp)) ==
32817836SJohn.Forte@Sun.COM 				    sizeof (typeof (**child))) {
32827836SJohn.Forte@Sun.COM 					*upp = (uint32_t *)vpp;
32837836SJohn.Forte@Sun.COM 					vpp = NULL;
32847836SJohn.Forte@Sun.COM 					child[i] = NULL;
32857836SJohn.Forte@Sun.COM 				}
32867836SJohn.Forte@Sun.COM 				num = vnum;
32877836SJohn.Forte@Sun.COM 			} else {
32887836SJohn.Forte@Sun.COM 				num = **upp + vnum;
32897836SJohn.Forte@Sun.COM 			}
32907836SJohn.Forte@Sun.COM 			if (vpp != NULL) {
32917836SJohn.Forte@Sun.COM 				/* copy required */
32927836SJohn.Forte@Sun.COM 				up = (uint32_t *)realloc(*upp,
32937836SJohn.Forte@Sun.COM 				    (num + 1) * sizeof (uint32_t));
32947836SJohn.Forte@Sun.COM 				if (up == NULL) {
32957836SJohn.Forte@Sun.COM 					return (ISNS_RSP_INTERNAL_ERROR);
32967836SJohn.Forte@Sun.COM 				}
32977836SJohn.Forte@Sun.COM 				*upp = up;
32987836SJohn.Forte@Sun.COM 				*up = num;
32997836SJohn.Forte@Sun.COM 				up += num;
33007836SJohn.Forte@Sun.COM 				vpp += vnum;
33017836SJohn.Forte@Sun.COM 				while (vnum > 0) {
33027836SJohn.Forte@Sun.COM 					if (*vpp == NULL) {
33037836SJohn.Forte@Sun.COM 						*up = 0;
33047836SJohn.Forte@Sun.COM 					} else if (child_flag == 0) {
33057836SJohn.Forte@Sun.COM 						*up = (uint32_t)*vpp;
33067836SJohn.Forte@Sun.COM 						*vpp = NULL;
33077836SJohn.Forte@Sun.COM 					} else {
33087836SJohn.Forte@Sun.COM 						o = (isns_obj_t *)*vpp;
33097836SJohn.Forte@Sun.COM 						*up = get_obj_uid(o);
33107836SJohn.Forte@Sun.COM 						if (is_obj_online(o) == 0) {
33117836SJohn.Forte@Sun.COM 							free_object(o);
33127836SJohn.Forte@Sun.COM 						}
33137836SJohn.Forte@Sun.COM 						*vpp = NULL;
33147836SJohn.Forte@Sun.COM 					}
33157836SJohn.Forte@Sun.COM 					up --;
33167836SJohn.Forte@Sun.COM 					vpp --;
33177836SJohn.Forte@Sun.COM 					vnum --;
33187836SJohn.Forte@Sun.COM 				}
33197836SJohn.Forte@Sun.COM 			}
33207836SJohn.Forte@Sun.COM 		}
33217836SJohn.Forte@Sun.COM 		i ++;
33227836SJohn.Forte@Sun.COM 	}
33237836SJohn.Forte@Sun.COM 
33247836SJohn.Forte@Sun.COM 	return (0);
33257836SJohn.Forte@Sun.COM }
33267836SJohn.Forte@Sun.COM 
33277836SJohn.Forte@Sun.COM /*
33287836SJohn.Forte@Sun.COM  * ****************************************************************************
33297836SJohn.Forte@Sun.COM  *
33307836SJohn.Forte@Sun.COM  * cb_remove_child:
33317836SJohn.Forte@Sun.COM  *	callback function which removes a child object UID from the
33327836SJohn.Forte@Sun.COM  *	children objet UID array of the parent object.
33337836SJohn.Forte@Sun.COM  *
33347836SJohn.Forte@Sun.COM  * p1	- the object.
33357836SJohn.Forte@Sun.COM  * p2	- the lcp.
33367836SJohn.Forte@Sun.COM  * return - 1: no more such type of child object, 0: otherwise.
33377836SJohn.Forte@Sun.COM  *
33387836SJohn.Forte@Sun.COM  * ****************************************************************************
33397836SJohn.Forte@Sun.COM  */
33407836SJohn.Forte@Sun.COM static int
cb_remove_child(void * p1,void * p2)33417836SJohn.Forte@Sun.COM cb_remove_child(
33427836SJohn.Forte@Sun.COM 	void *p1,
33437836SJohn.Forte@Sun.COM 	void *p2
33447836SJohn.Forte@Sun.COM )
33457836SJohn.Forte@Sun.COM {
33467836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
33477836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
33487836SJohn.Forte@Sun.COM 	uint32_t child_type = lcp->data[1].ui;
33497836SJohn.Forte@Sun.COM 	uint32_t child_uid = lcp->data[2].ui;
33507836SJohn.Forte@Sun.COM 	uint32_t *cuidp, cuid, num_of_child = 0;
33517836SJohn.Forte@Sun.COM 	int i;
33527836SJohn.Forte@Sun.COM 
33537836SJohn.Forte@Sun.COM 	/* get the children object UID array */
33547836SJohn.Forte@Sun.COM 	cuidp = get_child_t(obj, child_type);
33557836SJohn.Forte@Sun.COM 	if (cuidp != NULL) {
33567836SJohn.Forte@Sun.COM 		num_of_child = *cuidp;
33577836SJohn.Forte@Sun.COM 	}
33587836SJohn.Forte@Sun.COM 
33597836SJohn.Forte@Sun.COM 	/* remove it */
33607836SJohn.Forte@Sun.COM 	while (num_of_child > 0) {
33617836SJohn.Forte@Sun.COM 		cuid = *++cuidp;
33627836SJohn.Forte@Sun.COM 		if (cuid == child_uid) {
33637836SJohn.Forte@Sun.COM 			*cuidp = 0;
33647836SJohn.Forte@Sun.COM 			break;
33657836SJohn.Forte@Sun.COM 		}
33667836SJohn.Forte@Sun.COM 		num_of_child --;
33677836SJohn.Forte@Sun.COM 	}
33687836SJohn.Forte@Sun.COM 
33697836SJohn.Forte@Sun.COM 	/* check if all of child object UIDs are removed */
33707836SJohn.Forte@Sun.COM 	i = 0;
33717836SJohn.Forte@Sun.COM 	while (i < NUM_OF_CHILD[obj->type]) {
33727836SJohn.Forte@Sun.COM 		cuidp = get_child_n(obj, i);
33737836SJohn.Forte@Sun.COM 		if (cuidp != NULL) {
33747836SJohn.Forte@Sun.COM 			num_of_child = *cuidp;
33757836SJohn.Forte@Sun.COM 			while (num_of_child > 0) {
33767836SJohn.Forte@Sun.COM 				cuid = *++cuidp;
33777836SJohn.Forte@Sun.COM 				if (cuid != 0) {
33787836SJohn.Forte@Sun.COM 					return (0);
33797836SJohn.Forte@Sun.COM 				}
33807836SJohn.Forte@Sun.COM 				num_of_child --;
33817836SJohn.Forte@Sun.COM 			}
33827836SJohn.Forte@Sun.COM 		}
33837836SJohn.Forte@Sun.COM 		i ++;
33847836SJohn.Forte@Sun.COM 	}
33857836SJohn.Forte@Sun.COM 
33867836SJohn.Forte@Sun.COM 	return (1);
33877836SJohn.Forte@Sun.COM }
33887836SJohn.Forte@Sun.COM 
33897836SJohn.Forte@Sun.COM static int
cb_verify_ref(void * p1,void * p2)33907836SJohn.Forte@Sun.COM cb_verify_ref(
33917836SJohn.Forte@Sun.COM 	void *p1,
33927836SJohn.Forte@Sun.COM 	void *p2
33937836SJohn.Forte@Sun.COM )
33947836SJohn.Forte@Sun.COM {
33957836SJohn.Forte@Sun.COM 	int ec = 0;
33967836SJohn.Forte@Sun.COM 
33977836SJohn.Forte@Sun.COM 	isns_obj_t *parent = (isns_obj_t *)p1;
33987836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
33997836SJohn.Forte@Sun.COM 
34007836SJohn.Forte@Sun.COM 	const void ***child;
34017836SJohn.Forte@Sun.COM 
34027836SJohn.Forte@Sun.COM 	const void **vpp;
34037836SJohn.Forte@Sun.COM 	const void *vp;
34047836SJohn.Forte@Sun.COM 	uint32_t vnum;
34057836SJohn.Forte@Sun.COM 
34067836SJohn.Forte@Sun.COM 	const void **evpp;
34077836SJohn.Forte@Sun.COM 	const void *evp;
34087836SJohn.Forte@Sun.COM 	uint32_t evnum;
34097836SJohn.Forte@Sun.COM 
34107836SJohn.Forte@Sun.COM 	isns_type_t pt; /* parent object type */
34117836SJohn.Forte@Sun.COM 	isns_type_t ct; /* child object type */
34127836SJohn.Forte@Sun.COM 	isns_type_t rt; /* ref object type */
34137836SJohn.Forte@Sun.COM 	isns_type_t et; /* peer object type */
34147836SJohn.Forte@Sun.COM 
34157836SJohn.Forte@Sun.COM 	uint32_t *up;
34167836SJohn.Forte@Sun.COM 	uint32_t u;
34177836SJohn.Forte@Sun.COM 	uint32_t unum;
34187836SJohn.Forte@Sun.COM 
34197836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
34207836SJohn.Forte@Sun.COM 	uint8_t flag[MAX_OBJ_TYPE + 1] = { 0 };
34217836SJohn.Forte@Sun.COM 
34227836SJohn.Forte@Sun.COM 	int i, j, k;
34237836SJohn.Forte@Sun.COM 
34247836SJohn.Forte@Sun.COM 	pt = parent->type;
34257836SJohn.Forte@Sun.COM 
34267836SJohn.Forte@Sun.COM 	child = (const void ***)lcp->data[1].ptr;
34277836SJohn.Forte@Sun.COM 
34287836SJohn.Forte@Sun.COM 	for (i = 0; i < NUM_OF_CHILD[pt]; i++) {
34297836SJohn.Forte@Sun.COM 		ct = TYPE_OF_CHILD[pt][i];
34307836SJohn.Forte@Sun.COM 		rt = TYPE_OF_REF[ct][0];
34317836SJohn.Forte@Sun.COM 		if (rt == 0) {
34327836SJohn.Forte@Sun.COM 			continue;
34337836SJohn.Forte@Sun.COM 		}
34347836SJohn.Forte@Sun.COM 
34357836SJohn.Forte@Sun.COM 		et = TYPE_OF_REF[ct][1];
34367836SJohn.Forte@Sun.COM 		vpp = child[i];
34377836SJohn.Forte@Sun.COM 		if (vpp != NULL) {
34387836SJohn.Forte@Sun.COM 			vnum = (uint32_t)*vpp;
34397836SJohn.Forte@Sun.COM 			up = get_child_t(parent, et);
34407836SJohn.Forte@Sun.COM 			if (up != NULL) {
34417836SJohn.Forte@Sun.COM 				unum = *up;
34427836SJohn.Forte@Sun.COM 			} else {
34437836SJohn.Forte@Sun.COM 				unum = 0;
34447836SJohn.Forte@Sun.COM 			}
34457836SJohn.Forte@Sun.COM 		} else {
34467836SJohn.Forte@Sun.COM 			vnum = 0;
34477836SJohn.Forte@Sun.COM 		}
34487836SJohn.Forte@Sun.COM 
34497836SJohn.Forte@Sun.COM 		j = vnum;
34507836SJohn.Forte@Sun.COM 		while (j > 0) {
34517836SJohn.Forte@Sun.COM 			vp = vpp[j];
34527836SJohn.Forte@Sun.COM 			if (vp != NULL) {
34537836SJohn.Forte@Sun.COM 				(void) setup_ref_lcp(&lc, vp, NULL);
34547836SJohn.Forte@Sun.COM 				k = unum;
34557836SJohn.Forte@Sun.COM 				while (k > 0) {
34567836SJohn.Forte@Sun.COM 					u = up[k];
34577836SJohn.Forte@Sun.COM 					if (u != 0) {
34587836SJohn.Forte@Sun.COM 						ec = ref_new2old(
34597836SJohn.Forte@Sun.COM 						    &lc, et, u, vp);
34607836SJohn.Forte@Sun.COM 						if (ec != 0) {
34617836SJohn.Forte@Sun.COM 							return (ec);
34627836SJohn.Forte@Sun.COM 						}
34637836SJohn.Forte@Sun.COM 					}
34647836SJohn.Forte@Sun.COM 					k --;
34657836SJohn.Forte@Sun.COM 				} /* End of while each unum */
34667836SJohn.Forte@Sun.COM 			}
34677836SJohn.Forte@Sun.COM 			j --;
34687836SJohn.Forte@Sun.COM 		} /* End of while each vnum */
34697836SJohn.Forte@Sun.COM 
34707836SJohn.Forte@Sun.COM 		if (flag[ct] != 0) {
34717836SJohn.Forte@Sun.COM 			continue;
34727836SJohn.Forte@Sun.COM 		}
34737836SJohn.Forte@Sun.COM 
34747836SJohn.Forte@Sun.COM 		evnum = 0;
34757836SJohn.Forte@Sun.COM 		j = 0;
34767836SJohn.Forte@Sun.COM 		while (j < NUM_OF_CHILD[pt]) {
34777836SJohn.Forte@Sun.COM 			if (TYPE_OF_CHILD[pt][j] == et) {
34787836SJohn.Forte@Sun.COM 				evpp = child[j];
34797836SJohn.Forte@Sun.COM 				if (evpp != NULL) {
34807836SJohn.Forte@Sun.COM 					evnum = (uint32_t)*evpp;
34817836SJohn.Forte@Sun.COM 				}
34827836SJohn.Forte@Sun.COM 				break;
34837836SJohn.Forte@Sun.COM 			}
34847836SJohn.Forte@Sun.COM 			j ++;
34857836SJohn.Forte@Sun.COM 		}
34867836SJohn.Forte@Sun.COM 
34877836SJohn.Forte@Sun.COM 		j = vnum;
34887836SJohn.Forte@Sun.COM 		while (j > 0) {
34897836SJohn.Forte@Sun.COM 			vp = vpp[j];
34907836SJohn.Forte@Sun.COM 			k = evnum;
34917836SJohn.Forte@Sun.COM 			while (k > 0) {
34927836SJohn.Forte@Sun.COM 				evp = evpp[k];
34937836SJohn.Forte@Sun.COM 				if (vp != NULL && evp != NULL) {
34947836SJohn.Forte@Sun.COM 					(void) setup_ref_lcp(&lc, vp, evp);
34957836SJohn.Forte@Sun.COM 					ec = ref_new2new(&lc, vp, evp);
34967836SJohn.Forte@Sun.COM 					if (ec != 0) {
34977836SJohn.Forte@Sun.COM 						return (ec);
34987836SJohn.Forte@Sun.COM 					}
34997836SJohn.Forte@Sun.COM 				}
35007836SJohn.Forte@Sun.COM 				k --;
35017836SJohn.Forte@Sun.COM 			}
35027836SJohn.Forte@Sun.COM 			j --;
35037836SJohn.Forte@Sun.COM 		} /* End of while each vnum */
35047836SJohn.Forte@Sun.COM 
35057836SJohn.Forte@Sun.COM 		flag[et] = 1;
35067836SJohn.Forte@Sun.COM 	} /* End of for each type of child */
35077836SJohn.Forte@Sun.COM 
35087836SJohn.Forte@Sun.COM 	return (ec);
35097836SJohn.Forte@Sun.COM }
35107836SJohn.Forte@Sun.COM 
35117836SJohn.Forte@Sun.COM static int
cb_ref_new2old(void * p1,void * p2)35127836SJohn.Forte@Sun.COM cb_ref_new2old(
35137836SJohn.Forte@Sun.COM 	void *p1,
35147836SJohn.Forte@Sun.COM 	void *p2
35157836SJohn.Forte@Sun.COM )
35167836SJohn.Forte@Sun.COM {
35177836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
35187836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
35197836SJohn.Forte@Sun.COM 
35207836SJohn.Forte@Sun.COM 	isns_type_t et;
35217836SJohn.Forte@Sun.COM 	uint32_t uu;
35227836SJohn.Forte@Sun.COM 
35237836SJohn.Forte@Sun.COM 	uint32_t ref;
35247836SJohn.Forte@Sun.COM 
35257836SJohn.Forte@Sun.COM 	int match;
35267836SJohn.Forte@Sun.COM 
35277836SJohn.Forte@Sun.COM 	et = lcp->id[2];
35287836SJohn.Forte@Sun.COM 	uu = lcp->data[2].ui;
35297836SJohn.Forte@Sun.COM 
35307836SJohn.Forte@Sun.COM 	ref = get_ref_t(obj, et);
35317836SJohn.Forte@Sun.COM 
35327836SJohn.Forte@Sun.COM 	if (ref == uu) {
35337836SJohn.Forte@Sun.COM 		match = 1;
35347836SJohn.Forte@Sun.COM 	} else {
35357836SJohn.Forte@Sun.COM 		match = 0;
35367836SJohn.Forte@Sun.COM 	}
35377836SJohn.Forte@Sun.COM 
35387836SJohn.Forte@Sun.COM 	return (match);
35397836SJohn.Forte@Sun.COM }
35407836SJohn.Forte@Sun.COM 
35417836SJohn.Forte@Sun.COM static int
cb_new_ref(void * p1,void * p2)35427836SJohn.Forte@Sun.COM cb_new_ref(
35437836SJohn.Forte@Sun.COM 	void *p1,
35447836SJohn.Forte@Sun.COM 	void *p2
35457836SJohn.Forte@Sun.COM )
35467836SJohn.Forte@Sun.COM {
35477836SJohn.Forte@Sun.COM 	int ec = 0;
35487836SJohn.Forte@Sun.COM 
35497836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
35507836SJohn.Forte@Sun.COM 	isns_obj_t *a = (isns_obj_t *)p1;
35517836SJohn.Forte@Sun.COM 	isns_obj_t *b = (isns_obj_t *)lcp->data[2].ptr;
35527836SJohn.Forte@Sun.COM 
35537836SJohn.Forte@Sun.COM 	ec = new_ref(a, b);
35547836SJohn.Forte@Sun.COM 
35557836SJohn.Forte@Sun.COM 	return (ec);
35567836SJohn.Forte@Sun.COM }
35577836SJohn.Forte@Sun.COM 
35587836SJohn.Forte@Sun.COM static int
ref_new2old(lookup_ctrl_t * lcp,isns_type_t et,uint32_t uu,const isns_obj_t * vp)35597836SJohn.Forte@Sun.COM ref_new2old(
35607836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp,
35617836SJohn.Forte@Sun.COM 	isns_type_t et,
35627836SJohn.Forte@Sun.COM 	uint32_t uu,
35637836SJohn.Forte@Sun.COM 	const isns_obj_t *vp
35647836SJohn.Forte@Sun.COM )
35657836SJohn.Forte@Sun.COM {
35667836SJohn.Forte@Sun.COM 	int ec = 0;
35677836SJohn.Forte@Sun.COM 
35687836SJohn.Forte@Sun.COM 	int match;
35697836SJohn.Forte@Sun.COM 	uint32_t uid;
35707836SJohn.Forte@Sun.COM 
35717836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
35727836SJohn.Forte@Sun.COM 
35737836SJohn.Forte@Sun.COM 	lcp->id[2] = et;
35747836SJohn.Forte@Sun.COM 	lcp->data[2].ui = uu;
35757836SJohn.Forte@Sun.COM 
35767836SJohn.Forte@Sun.COM 	uid = 0;
35777836SJohn.Forte@Sun.COM 	do {
35787836SJohn.Forte@Sun.COM 		lcp->curr_uid = uid;
35797836SJohn.Forte@Sun.COM 		match = cache_lookup(lcp, &uid, cb_ref_new2old);
35807836SJohn.Forte@Sun.COM 	} while (match == 0 && uid != 0);
35817836SJohn.Forte@Sun.COM 
35827836SJohn.Forte@Sun.COM 	if (match == 0) {
35837836SJohn.Forte@Sun.COM 		/* no such ref, create a default one */
35847836SJohn.Forte@Sun.COM 		SET_UID_LCP(&lc, et, uu);
35857836SJohn.Forte@Sun.COM 
35867836SJohn.Forte@Sun.COM 		lc.data[2].ptr = (uchar_t *)vp;
35877836SJohn.Forte@Sun.COM 
35887836SJohn.Forte@Sun.COM 		ec = cache_lookup(&lc, NULL, cb_new_ref);
35897836SJohn.Forte@Sun.COM 	}
35907836SJohn.Forte@Sun.COM 
35917836SJohn.Forte@Sun.COM 	return (ec);
35927836SJohn.Forte@Sun.COM }
35937836SJohn.Forte@Sun.COM 
35947836SJohn.Forte@Sun.COM static int
ref_new2new(lookup_ctrl_t * lcp,const isns_obj_t * p1,const isns_obj_t * p2)35957836SJohn.Forte@Sun.COM ref_new2new(
35967836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp,
35977836SJohn.Forte@Sun.COM 	const isns_obj_t *p1,
35987836SJohn.Forte@Sun.COM 	const isns_obj_t *p2
35997836SJohn.Forte@Sun.COM )
36007836SJohn.Forte@Sun.COM {
36017836SJohn.Forte@Sun.COM 	int ec = 0;
36027836SJohn.Forte@Sun.COM 
36037836SJohn.Forte@Sun.COM 	if (is_obj_there(lcp) != 0) {
36047836SJohn.Forte@Sun.COM 		return (0);
36057836SJohn.Forte@Sun.COM 	}
36067836SJohn.Forte@Sun.COM 
36077836SJohn.Forte@Sun.COM 	ec = new_ref(p1, p2);
36087836SJohn.Forte@Sun.COM 
36097836SJohn.Forte@Sun.COM 	return (ec);
36107836SJohn.Forte@Sun.COM }
36117836SJohn.Forte@Sun.COM 
36127836SJohn.Forte@Sun.COM static int
new_ref(const isns_obj_t * p1,const isns_obj_t * p2)36137836SJohn.Forte@Sun.COM new_ref(
36147836SJohn.Forte@Sun.COM 	const isns_obj_t *p1,
36157836SJohn.Forte@Sun.COM 	const isns_obj_t *p2
36167836SJohn.Forte@Sun.COM )
36177836SJohn.Forte@Sun.COM {
36187836SJohn.Forte@Sun.COM 	int ec = 0;
36197836SJohn.Forte@Sun.COM 
36207836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
36217836SJohn.Forte@Sun.COM 
36227836SJohn.Forte@Sun.COM 	obj = make_ref[p1->type](p1, p2);
36237836SJohn.Forte@Sun.COM 	if (obj != NULL) {
36247836SJohn.Forte@Sun.COM 		ec = register_object(obj, NULL, NULL);
36257836SJohn.Forte@Sun.COM 	} else {
36267836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
36277836SJohn.Forte@Sun.COM 	}
36287836SJohn.Forte@Sun.COM 
36297836SJohn.Forte@Sun.COM 	return (ec);
36307836SJohn.Forte@Sun.COM }
36317836SJohn.Forte@Sun.COM 
36327836SJohn.Forte@Sun.COM /*
36337836SJohn.Forte@Sun.COM  * ****************************************************************************
36347836SJohn.Forte@Sun.COM  *
36357836SJohn.Forte@Sun.COM  * do_dereg:
36367836SJohn.Forte@Sun.COM  *	Physically remove an object along with the children objects,
36377836SJohn.Forte@Sun.COM  *	the reference object and the parent object recursively.
36387836SJohn.Forte@Sun.COM  *	Apporiate SCN is triggered.
36397836SJohn.Forte@Sun.COM  *
36407836SJohn.Forte@Sun.COM  * lcp	- the lookup control for the object being removed.
36417836SJohn.Forte@Sun.COM  * parent_flag	- 1: the object being removed is the parent object;
36427836SJohn.Forte@Sun.COM  *		  0: otherwise.
36437836SJohn.Forte@Sun.COM  * child_flag	- 1: the object being removed is a child object;
36447836SJohn.Forte@Sun.COM  *		  0: otherwise.
36457836SJohn.Forte@Sun.COM  * pending	- 1: do not remove the ESI entry immediately;
36467836SJohn.Forte@Sun.COM  *		  0: remove the ESI entry without any delay.
36477836SJohn.Forte@Sun.COM  * return - error code.
36487836SJohn.Forte@Sun.COM  *
36497836SJohn.Forte@Sun.COM  * ****************************************************************************
36507836SJohn.Forte@Sun.COM  */
36517836SJohn.Forte@Sun.COM static int
do_dereg(lookup_ctrl_t * lcp,int parent_flag,int child_flag,int pending)36527836SJohn.Forte@Sun.COM do_dereg(
36537836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp,
36547836SJohn.Forte@Sun.COM 	int parent_flag,
36557836SJohn.Forte@Sun.COM 	int child_flag,
36567836SJohn.Forte@Sun.COM 	int pending
36577836SJohn.Forte@Sun.COM )
36587836SJohn.Forte@Sun.COM {
36597836SJohn.Forte@Sun.COM 	int ec = 0;
36607836SJohn.Forte@Sun.COM 
36617836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
36627836SJohn.Forte@Sun.COM 	uint32_t *cuidp, num;
36637836SJohn.Forte@Sun.COM 	isns_type_t type;
36647836SJohn.Forte@Sun.COM 	uint32_t uid;
36657836SJohn.Forte@Sun.COM 	int i;
36667836SJohn.Forte@Sun.COM 
36677836SJohn.Forte@Sun.COM 	/* remove the object from object container */
36687836SJohn.Forte@Sun.COM 	obj = cache_remove(lcp, 0);
36697836SJohn.Forte@Sun.COM 
36707836SJohn.Forte@Sun.COM 	if (obj == NULL) {
36717836SJohn.Forte@Sun.COM 		return (0);
36727836SJohn.Forte@Sun.COM 	}
36737836SJohn.Forte@Sun.COM 
36747836SJohn.Forte@Sun.COM 	/* trigger a scn */
36757836SJohn.Forte@Sun.COM 	if (scn_q != NULL) {
36767836SJohn.Forte@Sun.COM 		(void) make_scn(ISNS_OBJECT_REMOVED, obj);
36777836SJohn.Forte@Sun.COM 	}
36787836SJohn.Forte@Sun.COM 
36797836SJohn.Forte@Sun.COM 	/* dereg children */
36807836SJohn.Forte@Sun.COM 	i = 0;
36817836SJohn.Forte@Sun.COM 	while (ec == 0 && !parent_flag &&
36827836SJohn.Forte@Sun.COM 	    i < NUM_OF_CHILD[obj->type]) {
36837836SJohn.Forte@Sun.COM 		type = TYPE_OF_CHILD[obj->type][i];
36847836SJohn.Forte@Sun.COM 		cuidp = get_child_n(obj, i);
36857836SJohn.Forte@Sun.COM 		if (cuidp != NULL) {
36867836SJohn.Forte@Sun.COM 			num = *cuidp;
36877836SJohn.Forte@Sun.COM 		} else {
36887836SJohn.Forte@Sun.COM 			num = 0;
36897836SJohn.Forte@Sun.COM 		}
36907836SJohn.Forte@Sun.COM 		while (ec == 0 && num > 0) {
36917836SJohn.Forte@Sun.COM 			uid = cuidp[num];
36927836SJohn.Forte@Sun.COM 			if (uid != 0) {
36937836SJohn.Forte@Sun.COM 				SET_UID_LCP(lcp, type, uid);
36947836SJohn.Forte@Sun.COM 				ec = do_dereg(lcp,
36957836SJohn.Forte@Sun.COM 				    parent_flag,
36967836SJohn.Forte@Sun.COM 				    1,
36977836SJohn.Forte@Sun.COM 				    pending);
36987836SJohn.Forte@Sun.COM 			}
36997836SJohn.Forte@Sun.COM 			num --;
37007836SJohn.Forte@Sun.COM 		}
37017836SJohn.Forte@Sun.COM 		i ++;
37027836SJohn.Forte@Sun.COM 	}
37037836SJohn.Forte@Sun.COM 
37047836SJohn.Forte@Sun.COM 	/* clear the ref bit on the ref'd object */
37057836SJohn.Forte@Sun.COM 	if (ec == 0 && TYPE_OF_REF[obj->type][0] > 0) {
37067836SJohn.Forte@Sun.COM 		uid = 0;
37077836SJohn.Forte@Sun.COM 		do {
37087836SJohn.Forte@Sun.COM 			(void) setup_ref_lcp(lcp, obj, NULL);
37097836SJohn.Forte@Sun.COM 			lcp->curr_uid = uid;
37107836SJohn.Forte@Sun.COM 			lcp->data[2].ui = obj->type;
37117836SJohn.Forte@Sun.COM 			if (cache_lookup(lcp, &uid, cb_clear_ref) != 0) {
37127836SJohn.Forte@Sun.COM 				UPDATE_LCP_UID(lcp, uid);
37137836SJohn.Forte@Sun.COM 				ec = do_dereg(lcp,
37147836SJohn.Forte@Sun.COM 				    parent_flag,
37157836SJohn.Forte@Sun.COM 				    child_flag,
37167836SJohn.Forte@Sun.COM 				    pending);
37177836SJohn.Forte@Sun.COM 			}
37187836SJohn.Forte@Sun.COM 		} while (uid != 0);
37197836SJohn.Forte@Sun.COM 	}
37207836SJohn.Forte@Sun.COM 
37217836SJohn.Forte@Sun.COM 	/* remove it from the parent */
37227836SJohn.Forte@Sun.COM 	if (ec == 0 && !child_flag &&
37237836SJohn.Forte@Sun.COM 	    TYPE_OF_PARENT[obj->type] > 0 &&
37247836SJohn.Forte@Sun.COM 	    (uid = setup_parent_lcp(lcp, obj)) != 0) {
37257836SJohn.Forte@Sun.COM 		if (cache_lookup(lcp, NULL, cb_remove_child) != 0) {
37267836SJohn.Forte@Sun.COM 			UPDATE_LCP_UID(lcp, uid);
37277836SJohn.Forte@Sun.COM 			ec = do_dereg(lcp,
37287836SJohn.Forte@Sun.COM 			    1,
37297836SJohn.Forte@Sun.COM 			    child_flag,
37307836SJohn.Forte@Sun.COM 			    0);
37317836SJohn.Forte@Sun.COM 		}
37327836SJohn.Forte@Sun.COM 	}
37337836SJohn.Forte@Sun.COM 
37347836SJohn.Forte@Sun.COM 	if (ec == 0 && !child_flag) {
37357836SJohn.Forte@Sun.COM 		/* remove it from persistent data store */
37367836SJohn.Forte@Sun.COM 		if (sys_q) {
37377836SJohn.Forte@Sun.COM 			ec = write_data(DATA_DELETE, obj);
37387836SJohn.Forte@Sun.COM 		}
37397836SJohn.Forte@Sun.COM 		/* remove esi event entry */
37407836SJohn.Forte@Sun.COM 		if (ec == 0) {
37417836SJohn.Forte@Sun.COM 			(void) esi_remove_obj(obj, pending);
37427836SJohn.Forte@Sun.COM 		}
37437836SJohn.Forte@Sun.COM 
37447836SJohn.Forte@Sun.COM 		/* save the parent uid for caller */
37457836SJohn.Forte@Sun.COM 		if (TYPE_OF_PARENT[obj->type] != 0) {
37467836SJohn.Forte@Sun.COM 			lcp->curr_uid = get_parent_uid(obj);
37477836SJohn.Forte@Sun.COM 		} else {
37487836SJohn.Forte@Sun.COM 			/* it's the parent itself */
37497836SJohn.Forte@Sun.COM 			lcp->curr_uid = get_obj_uid(obj);
37507836SJohn.Forte@Sun.COM 		}
37517836SJohn.Forte@Sun.COM 	}
37527836SJohn.Forte@Sun.COM 
37537836SJohn.Forte@Sun.COM 	/* remove this portal from scn registry */
37547836SJohn.Forte@Sun.COM 	if (ec == 0 &&
37557836SJohn.Forte@Sun.COM 	    obj->type == OBJ_PORTAL) {
37567836SJohn.Forte@Sun.COM 		(void) remove_scn_portal(get_obj_uid(obj));
37577836SJohn.Forte@Sun.COM 	}
37587836SJohn.Forte@Sun.COM 
37597836SJohn.Forte@Sun.COM 	/* free the object */
37607836SJohn.Forte@Sun.COM 	(void) free_object(obj);
37617836SJohn.Forte@Sun.COM 
37627836SJohn.Forte@Sun.COM 	return (ec);
37637836SJohn.Forte@Sun.COM }
37647836SJohn.Forte@Sun.COM 
37657836SJohn.Forte@Sun.COM /*
37667836SJohn.Forte@Sun.COM  * ****************************************************************************
37677836SJohn.Forte@Sun.COM  *
37687836SJohn.Forte@Sun.COM  * dereg_assoc:
37697836SJohn.Forte@Sun.COM  *	Remove one association object from object container.
37707836SJohn.Forte@Sun.COM  *
37717836SJohn.Forte@Sun.COM  * lcp	- the lookup control for the object being removed.
37727836SJohn.Forte@Sun.COM  * return - error code.
37737836SJohn.Forte@Sun.COM  *
37747836SJohn.Forte@Sun.COM  * ****************************************************************************
37757836SJohn.Forte@Sun.COM  */
37767836SJohn.Forte@Sun.COM int
dereg_assoc(lookup_ctrl_t * lcp)37777836SJohn.Forte@Sun.COM dereg_assoc(
37787836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
37797836SJohn.Forte@Sun.COM )
37807836SJohn.Forte@Sun.COM {
37817836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
37827836SJohn.Forte@Sun.COM 
37837836SJohn.Forte@Sun.COM 	obj = cache_remove(lcp, 1);
37847836SJohn.Forte@Sun.COM 
37857836SJohn.Forte@Sun.COM 	/* free the object */
37867836SJohn.Forte@Sun.COM 	if (obj != NULL) {
37877836SJohn.Forte@Sun.COM 		free_object(obj);
37887836SJohn.Forte@Sun.COM 	}
37897836SJohn.Forte@Sun.COM 
37907836SJohn.Forte@Sun.COM 	return (0);
37917836SJohn.Forte@Sun.COM }
37927836SJohn.Forte@Sun.COM 
37937836SJohn.Forte@Sun.COM /*
37947836SJohn.Forte@Sun.COM  * ****************************************************************************
37957836SJohn.Forte@Sun.COM  *
37967836SJohn.Forte@Sun.COM  * dereg_object:
37977836SJohn.Forte@Sun.COM  *	Remove one object from object container.
37987836SJohn.Forte@Sun.COM  *
37997836SJohn.Forte@Sun.COM  * lcp	- the lookup control for the object being removed.
38007836SJohn.Forte@Sun.COM  * return - error code.
38017836SJohn.Forte@Sun.COM  *
38027836SJohn.Forte@Sun.COM  * ****************************************************************************
38037836SJohn.Forte@Sun.COM  */
38047836SJohn.Forte@Sun.COM int
dereg_object(lookup_ctrl_t * lcp,int pending)38057836SJohn.Forte@Sun.COM dereg_object(
38067836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp,
38077836SJohn.Forte@Sun.COM 	int pending
38087836SJohn.Forte@Sun.COM )
38097836SJohn.Forte@Sun.COM {
38107836SJohn.Forte@Sun.COM 	return (do_dereg(lcp, 0, 0, pending));
38117836SJohn.Forte@Sun.COM }
38127836SJohn.Forte@Sun.COM 
38137836SJohn.Forte@Sun.COM /*
38147836SJohn.Forte@Sun.COM  * ****************************************************************************
38157836SJohn.Forte@Sun.COM  *
38167836SJohn.Forte@Sun.COM  * data_sync:
38177836SJohn.Forte@Sun.COM  *	Synchronize the cache with persistent data store.
38187836SJohn.Forte@Sun.COM  *	Flush the cache data to data store if the input ec is zero,
38197836SJohn.Forte@Sun.COM  *	retreat the changes in cache and ignore data store update
38207836SJohn.Forte@Sun.COM  *	if there is an error.
38217836SJohn.Forte@Sun.COM  *
38227836SJohn.Forte@Sun.COM  * ec	- error code.
38237836SJohn.Forte@Sun.COM  * return - error code.
38247836SJohn.Forte@Sun.COM  *
38257836SJohn.Forte@Sun.COM  * ****************************************************************************
38267836SJohn.Forte@Sun.COM  */
38277836SJohn.Forte@Sun.COM int
data_sync(int ec)38287836SJohn.Forte@Sun.COM data_sync(
38297836SJohn.Forte@Sun.COM 	int ec
38307836SJohn.Forte@Sun.COM )
38317836SJohn.Forte@Sun.COM {
38327836SJohn.Forte@Sun.COM 	/* cache is updated successfully, commit the data to data store */
38337836SJohn.Forte@Sun.COM 	if (IS_CACHE_UPDATED()) {
38347836SJohn.Forte@Sun.COM 		if (ec == 0) {
38357836SJohn.Forte@Sun.COM 			ec = write_data(DATA_COMMIT, NULL);
38367836SJohn.Forte@Sun.COM 		}
38377836SJohn.Forte@Sun.COM 		if (ec == 0) {
38387836SJohn.Forte@Sun.COM 			/* successful, trigger the SCN */
38397836SJohn.Forte@Sun.COM 			(void) queue_msg_set(scn_q, SCN_TRIGGER, (void *)NULL);
38407836SJohn.Forte@Sun.COM 		} else {
38417836SJohn.Forte@Sun.COM 			shutdown_server();
38427836SJohn.Forte@Sun.COM 		}
38437836SJohn.Forte@Sun.COM 	} else {
38447836SJohn.Forte@Sun.COM 		/* ignore all SCNs which have been generated */
38457836SJohn.Forte@Sun.COM 		(void) queue_msg_set(scn_q, SCN_IGNORE, (void *)NULL);
38467836SJohn.Forte@Sun.COM 
38477836SJohn.Forte@Sun.COM 		(void) write_data(DATA_RETREAT, NULL);
38487836SJohn.Forte@Sun.COM 	}
38497836SJohn.Forte@Sun.COM 
38507836SJohn.Forte@Sun.COM 	return (ec);
38517836SJohn.Forte@Sun.COM }
38527836SJohn.Forte@Sun.COM 
38537836SJohn.Forte@Sun.COM static pthread_mutex_t name_mtx[3] = {
38547836SJohn.Forte@Sun.COM 	PTHREAD_MUTEX_INITIALIZER,
38557836SJohn.Forte@Sun.COM 	PTHREAD_MUTEX_INITIALIZER,
38567836SJohn.Forte@Sun.COM 	PTHREAD_MUTEX_INITIALIZER
38577836SJohn.Forte@Sun.COM };
38587836SJohn.Forte@Sun.COM static const char *name_pattern[3] = {
38597836SJohn.Forte@Sun.COM 	"ENTITY_ID_%d",
38607836SJohn.Forte@Sun.COM 	"DD_%d",
38617836SJohn.Forte@Sun.COM 	"DD-Set_%d"
38627836SJohn.Forte@Sun.COM };
38637836SJohn.Forte@Sun.COM static uint32_t name_count[3] = {
38647836SJohn.Forte@Sun.COM 	0,
38657836SJohn.Forte@Sun.COM 	0,
38667836SJohn.Forte@Sun.COM 	0
38677836SJohn.Forte@Sun.COM };
38687836SJohn.Forte@Sun.COM 
38697836SJohn.Forte@Sun.COM /*
38707836SJohn.Forte@Sun.COM  * ****************************************************************************
38717836SJohn.Forte@Sun.COM  *
38727836SJohn.Forte@Sun.COM  * make_unique_name:
38737836SJohn.Forte@Sun.COM  *	make a default unique name for a newly registered network entity,
38747836SJohn.Forte@Sun.COM  *	discovery domain or discovery domain set object.
38757836SJohn.Forte@Sun.COM  *
38767836SJohn.Forte@Sun.COM  * len	- pointer of the length of the new name for returning.
38777836SJohn.Forte@Sun.COM  * tag	- which attribute of the new name is for.
38787836SJohn.Forte@Sun.COM  * return - the name being made.
38797836SJohn.Forte@Sun.COM  *
38807836SJohn.Forte@Sun.COM  * ****************************************************************************
38817836SJohn.Forte@Sun.COM  */
38827836SJohn.Forte@Sun.COM static char *
make_unique_name(int * len,uint32_t tag)38837836SJohn.Forte@Sun.COM make_unique_name(
38847836SJohn.Forte@Sun.COM 	int *len,
38857836SJohn.Forte@Sun.COM 	uint32_t tag
38867836SJohn.Forte@Sun.COM )
38877836SJohn.Forte@Sun.COM {
38887836SJohn.Forte@Sun.COM 	int i;
38897836SJohn.Forte@Sun.COM 	int count;
38907836SJohn.Forte@Sun.COM 	char name[32] = { 0 };
38917836SJohn.Forte@Sun.COM 
38927836SJohn.Forte@Sun.COM 	char *p;
38937836SJohn.Forte@Sun.COM 
38947836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
38957836SJohn.Forte@Sun.COM 
38967836SJohn.Forte@Sun.COM 	lc.curr_uid = 0;
38977836SJohn.Forte@Sun.COM 
38987836SJohn.Forte@Sun.COM 	switch (tag) {
38997836SJohn.Forte@Sun.COM 	case ISNS_EID_ATTR_ID:
39007836SJohn.Forte@Sun.COM 		i = 0;
39017836SJohn.Forte@Sun.COM 		lc.type = OBJ_ENTITY;
39027836SJohn.Forte@Sun.COM 		lc.id[0] = ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID);
39037836SJohn.Forte@Sun.COM 		break;
39047836SJohn.Forte@Sun.COM 	case ISNS_DD_NAME_ATTR_ID:
39057836SJohn.Forte@Sun.COM 		i = 1;
39067836SJohn.Forte@Sun.COM 		lc.type = OBJ_DD;
39077836SJohn.Forte@Sun.COM 		lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
39087836SJohn.Forte@Sun.COM 		break;
39097836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_NAME_ATTR_ID:
39107836SJohn.Forte@Sun.COM 		i = 2;
39117836SJohn.Forte@Sun.COM 		lc.type = OBJ_DDS;
39127836SJohn.Forte@Sun.COM 		lc.id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
39137836SJohn.Forte@Sun.COM 		break;
39147836SJohn.Forte@Sun.COM 	default:
39157836SJohn.Forte@Sun.COM 		ASSERT(0);
39167836SJohn.Forte@Sun.COM 		break;
39177836SJohn.Forte@Sun.COM 	}
39187836SJohn.Forte@Sun.COM 
39197836SJohn.Forte@Sun.COM 	lc.op[0] = OP_STRING;
39207836SJohn.Forte@Sun.COM 	lc.op[1] = 0;
39217836SJohn.Forte@Sun.COM 	do {
39227836SJohn.Forte@Sun.COM 		(void) pthread_mutex_lock(&name_mtx[i]);
39237836SJohn.Forte@Sun.COM 		count = ++ name_count[i];
39247836SJohn.Forte@Sun.COM 		(void) pthread_mutex_unlock(&name_mtx[i]);
39257836SJohn.Forte@Sun.COM 		/* no more space, failure */
39267836SJohn.Forte@Sun.COM 		if (count == 0) {
39277836SJohn.Forte@Sun.COM 			return (NULL);
39287836SJohn.Forte@Sun.COM 		}
39297836SJohn.Forte@Sun.COM 		(void) sprintf(name, name_pattern[i], count);
39307836SJohn.Forte@Sun.COM 		lc.data[0].ptr = (uchar_t *)name;
39317836SJohn.Forte@Sun.COM 	} while (is_obj_there(&lc) != 0);
39327836SJohn.Forte@Sun.COM 
39337836SJohn.Forte@Sun.COM 	/* 4-bytes aligned length */
39347836SJohn.Forte@Sun.COM 	*len = strlen(name);
39357836SJohn.Forte@Sun.COM 	*len = *len + (4 - *len % 4);
39367836SJohn.Forte@Sun.COM 	p = (char *)malloc(*len);
39377836SJohn.Forte@Sun.COM 	if (p != NULL) {
39387836SJohn.Forte@Sun.COM 		(void) strcpy(p, name);
39397836SJohn.Forte@Sun.COM 	}
39407836SJohn.Forte@Sun.COM 	return (p);
39417836SJohn.Forte@Sun.COM }
39427836SJohn.Forte@Sun.COM 
39437836SJohn.Forte@Sun.COM #ifdef DEBUG
39447836SJohn.Forte@Sun.COM void
obj_dump(void * p)39457836SJohn.Forte@Sun.COM obj_dump(
39467836SJohn.Forte@Sun.COM 	void *p
39477836SJohn.Forte@Sun.COM )
39487836SJohn.Forte@Sun.COM {
39497836SJohn.Forte@Sun.COM 	print_object(NULL, (isns_obj_t *)p);
39507836SJohn.Forte@Sun.COM }
39517836SJohn.Forte@Sun.COM #endif
3952