xref: /onnv-gate/usr/src/cmd/isns/isnsd/dd.c (revision 7836:4e95154b5b7a)
1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM  * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM  *
4*7836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM  *
8*7836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM  * and limitations under the License.
12*7836SJohn.Forte@Sun.COM  *
13*7836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM  *
19*7836SJohn.Forte@Sun.COM  * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM  */
21*7836SJohn.Forte@Sun.COM 
22*7836SJohn.Forte@Sun.COM /*
23*7836SJohn.Forte@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*7836SJohn.Forte@Sun.COM  * Use is subject to license terms.
25*7836SJohn.Forte@Sun.COM  */
26*7836SJohn.Forte@Sun.COM 
27*7836SJohn.Forte@Sun.COM #include <stdio.h>
28*7836SJohn.Forte@Sun.COM #include <stdlib.h>
29*7836SJohn.Forte@Sun.COM #include <string.h>
30*7836SJohn.Forte@Sun.COM 
31*7836SJohn.Forte@Sun.COM #include "isns_server.h"
32*7836SJohn.Forte@Sun.COM #include "isns_msgq.h"
33*7836SJohn.Forte@Sun.COM #include "isns_htab.h"
34*7836SJohn.Forte@Sun.COM #include "isns_dd.h"
35*7836SJohn.Forte@Sun.COM #include "isns_cache.h"
36*7836SJohn.Forte@Sun.COM #include "isns_obj.h"
37*7836SJohn.Forte@Sun.COM #include "isns_pdu.h"
38*7836SJohn.Forte@Sun.COM #include "isns_dseng.h"
39*7836SJohn.Forte@Sun.COM #include "isns_scn.h"
40*7836SJohn.Forte@Sun.COM #include "isns_utils.h"
41*7836SJohn.Forte@Sun.COM 
42*7836SJohn.Forte@Sun.COM /*
43*7836SJohn.Forte@Sun.COM  * extern global variables
44*7836SJohn.Forte@Sun.COM  */
45*7836SJohn.Forte@Sun.COM extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
46*7836SJohn.Forte@Sun.COM 
47*7836SJohn.Forte@Sun.COM extern msg_queue_t *sys_q;
48*7836SJohn.Forte@Sun.COM extern msg_queue_t *scn_q;
49*7836SJohn.Forte@Sun.COM 
50*7836SJohn.Forte@Sun.COM extern int cache_flag;
51*7836SJohn.Forte@Sun.COM 
52*7836SJohn.Forte@Sun.COM /*
53*7836SJohn.Forte@Sun.COM  * extern functions.
54*7836SJohn.Forte@Sun.COM  */
55*7836SJohn.Forte@Sun.COM 
56*7836SJohn.Forte@Sun.COM /*
57*7836SJohn.Forte@Sun.COM  * global variables
58*7836SJohn.Forte@Sun.COM  */
59*7836SJohn.Forte@Sun.COM 
60*7836SJohn.Forte@Sun.COM /*
61*7836SJohn.Forte@Sun.COM  * local variables
62*7836SJohn.Forte@Sun.COM  */
63*7836SJohn.Forte@Sun.COM 
64*7836SJohn.Forte@Sun.COM /*
65*7836SJohn.Forte@Sun.COM  * local functions.
66*7836SJohn.Forte@Sun.COM  */
67*7836SJohn.Forte@Sun.COM static matrix_t *new_matrix(uint32_t, uint32_t);
68*7836SJohn.Forte@Sun.COM 
69*7836SJohn.Forte@Sun.COM static int
cb_update_ds_attr(void * p1,void * p2)70*7836SJohn.Forte@Sun.COM cb_update_ds_attr(
71*7836SJohn.Forte@Sun.COM 	void *p1,
72*7836SJohn.Forte@Sun.COM 	void *p2
73*7836SJohn.Forte@Sun.COM )
74*7836SJohn.Forte@Sun.COM {
75*7836SJohn.Forte@Sun.COM 	int ec = 0;
76*7836SJohn.Forte@Sun.COM 
77*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
78*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
79*7836SJohn.Forte@Sun.COM 	uint32_t tag = lcp->id[1];
80*7836SJohn.Forte@Sun.COM 	uint32_t which;
81*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
82*7836SJohn.Forte@Sun.COM 
83*7836SJohn.Forte@Sun.COM 	uint32_t len;
84*7836SJohn.Forte@Sun.COM 	uchar_t *name;
85*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
86*7836SJohn.Forte@Sun.COM 	uint32_t uid;
87*7836SJohn.Forte@Sun.COM 
88*7836SJohn.Forte@Sun.COM 	switch (tag) {
89*7836SJohn.Forte@Sun.COM 	case ISNS_DD_NAME_ATTR_ID:
90*7836SJohn.Forte@Sun.COM 		which = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
91*7836SJohn.Forte@Sun.COM 		break;
92*7836SJohn.Forte@Sun.COM 	case ISNS_DD_FEATURES_ATTR_ID:
93*7836SJohn.Forte@Sun.COM 		which = ATTR_INDEX_DD(ISNS_DD_FEATURES_ATTR_ID);
94*7836SJohn.Forte@Sun.COM 		break;
95*7836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_NAME_ATTR_ID:
96*7836SJohn.Forte@Sun.COM 		which = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
97*7836SJohn.Forte@Sun.COM 		break;
98*7836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_STATUS_ATTR_ID:
99*7836SJohn.Forte@Sun.COM 		which = ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID);
100*7836SJohn.Forte@Sun.COM 		break;
101*7836SJohn.Forte@Sun.COM 	default:
102*7836SJohn.Forte@Sun.COM 		ASSERT(0);
103*7836SJohn.Forte@Sun.COM 		break;
104*7836SJohn.Forte@Sun.COM 	}
105*7836SJohn.Forte@Sun.COM 
106*7836SJohn.Forte@Sun.COM 	attr = &obj->attrs[which];
107*7836SJohn.Forte@Sun.COM 
108*7836SJohn.Forte@Sun.COM 	switch (tag) {
109*7836SJohn.Forte@Sun.COM 	case ISNS_DD_NAME_ATTR_ID:
110*7836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_NAME_ATTR_ID:
111*7836SJohn.Forte@Sun.COM 		len = lcp->data[1].ui;
112*7836SJohn.Forte@Sun.COM 		name = lcp->data[2].ptr;
113*7836SJohn.Forte@Sun.COM 		lc.type = lcp->type;
114*7836SJohn.Forte@Sun.COM 		lc.curr_uid = 0;
115*7836SJohn.Forte@Sun.COM 		lc.id[0] = which;
116*7836SJohn.Forte@Sun.COM 		lc.op[0] = OP_STRING;
117*7836SJohn.Forte@Sun.COM 		lc.data[0].ptr = name;
118*7836SJohn.Forte@Sun.COM 		lc.op[1] = 0;
119*7836SJohn.Forte@Sun.COM 		/* check if the name is in use */
120*7836SJohn.Forte@Sun.COM 		uid = is_obj_there(&lc);
121*7836SJohn.Forte@Sun.COM 		if (uid != 0) {
122*7836SJohn.Forte@Sun.COM 			if (uid != get_obj_uid(obj)) {
123*7836SJohn.Forte@Sun.COM 				ec = ERR_NAME_IN_USE;
124*7836SJohn.Forte@Sun.COM 			}
125*7836SJohn.Forte@Sun.COM 			return (ec);
126*7836SJohn.Forte@Sun.COM 		}
127*7836SJohn.Forte@Sun.COM 		if (len > attr->len) {
128*7836SJohn.Forte@Sun.COM 			uchar_t *tmp = (uchar_t *)malloc(len);
129*7836SJohn.Forte@Sun.COM 			if (tmp != NULL) {
130*7836SJohn.Forte@Sun.COM 				free(attr->value.ptr);
131*7836SJohn.Forte@Sun.COM 				attr->value.ptr = tmp;
132*7836SJohn.Forte@Sun.COM 			} else {
133*7836SJohn.Forte@Sun.COM 				/* memory exhausted */
134*7836SJohn.Forte@Sun.COM 				return (ISNS_RSP_INTERNAL_ERROR);
135*7836SJohn.Forte@Sun.COM 			}
136*7836SJohn.Forte@Sun.COM 		}
137*7836SJohn.Forte@Sun.COM 		(void) strcpy((char *)attr->value.ptr, (char *)name);
138*7836SJohn.Forte@Sun.COM 		attr->len = len;
139*7836SJohn.Forte@Sun.COM 		break;
140*7836SJohn.Forte@Sun.COM 	case ISNS_DD_FEATURES_ATTR_ID:
141*7836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_STATUS_ATTR_ID:
142*7836SJohn.Forte@Sun.COM 		if (attr->tag != tag ||
143*7836SJohn.Forte@Sun.COM 		    attr->value.ui != lcp->data[1].ui) {
144*7836SJohn.Forte@Sun.COM 			attr->tag = tag;
145*7836SJohn.Forte@Sun.COM 			attr->len = 4;
146*7836SJohn.Forte@Sun.COM 			attr->value.ui = lcp->data[1].ui;
147*7836SJohn.Forte@Sun.COM 		} else {
148*7836SJohn.Forte@Sun.COM 			return (ec);
149*7836SJohn.Forte@Sun.COM 		}
150*7836SJohn.Forte@Sun.COM 		break;
151*7836SJohn.Forte@Sun.COM 	}
152*7836SJohn.Forte@Sun.COM 
153*7836SJohn.Forte@Sun.COM 	/* cache has been updated, set the flag */
154*7836SJohn.Forte@Sun.COM 	SET_CACHE_UPDATED();
155*7836SJohn.Forte@Sun.COM 
156*7836SJohn.Forte@Sun.COM 	/* update data store */
157*7836SJohn.Forte@Sun.COM 	if (sys_q != NULL) {
158*7836SJohn.Forte@Sun.COM 		ec = write_data(DATA_UPDATE, obj);
159*7836SJohn.Forte@Sun.COM 	}
160*7836SJohn.Forte@Sun.COM 
161*7836SJohn.Forte@Sun.COM 	return (ec);
162*7836SJohn.Forte@Sun.COM }
163*7836SJohn.Forte@Sun.COM 
164*7836SJohn.Forte@Sun.COM static isns_obj_t *
make_member_node(const uint32_t uid,isns_attr_t * attr1)165*7836SJohn.Forte@Sun.COM make_member_node(
166*7836SJohn.Forte@Sun.COM 	const uint32_t uid,
167*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr1
168*7836SJohn.Forte@Sun.COM )
169*7836SJohn.Forte@Sun.COM {
170*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = NULL;
171*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
172*7836SJohn.Forte@Sun.COM 	isns_attr_t tmp;
173*7836SJohn.Forte@Sun.COM 
174*7836SJohn.Forte@Sun.COM 	switch (attr1->tag) {
175*7836SJohn.Forte@Sun.COM 	case ISNS_DD_ISCSI_NAME_ATTR_ID:
176*7836SJohn.Forte@Sun.COM 		obj = obj_calloc(OBJ_ISCSI);
177*7836SJohn.Forte@Sun.COM 		attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
178*7836SJohn.Forte@Sun.COM 		tmp.tag = ISNS_ISCSI_NAME_ATTR_ID;
179*7836SJohn.Forte@Sun.COM 		tmp.len = attr1->len;
180*7836SJohn.Forte@Sun.COM 		tmp.value.ptr = attr1->value.ptr;
181*7836SJohn.Forte@Sun.COM 		if (assign_attr(attr, &tmp) != 0) {
182*7836SJohn.Forte@Sun.COM 			free_object(obj);
183*7836SJohn.Forte@Sun.COM 			obj = NULL;
184*7836SJohn.Forte@Sun.COM 		} else if (uid != 0) {
185*7836SJohn.Forte@Sun.COM 			(void) set_obj_uid(obj, uid);
186*7836SJohn.Forte@Sun.COM 		}
187*7836SJohn.Forte@Sun.COM 		break;
188*7836SJohn.Forte@Sun.COM 	default:
189*7836SJohn.Forte@Sun.COM 		ASSERT(0);
190*7836SJohn.Forte@Sun.COM 		break;
191*7836SJohn.Forte@Sun.COM 	}
192*7836SJohn.Forte@Sun.COM 
193*7836SJohn.Forte@Sun.COM 	return (obj);
194*7836SJohn.Forte@Sun.COM }
195*7836SJohn.Forte@Sun.COM 
196*7836SJohn.Forte@Sun.COM static isns_obj_t *
make_member_dd(const uint32_t uid)197*7836SJohn.Forte@Sun.COM make_member_dd(
198*7836SJohn.Forte@Sun.COM 	const uint32_t uid
199*7836SJohn.Forte@Sun.COM )
200*7836SJohn.Forte@Sun.COM {
201*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = NULL;
202*7836SJohn.Forte@Sun.COM 	isns_attr_t name = { 0 };
203*7836SJohn.Forte@Sun.COM 
204*7836SJohn.Forte@Sun.COM 	obj = obj_calloc(OBJ_DD);
205*7836SJohn.Forte@Sun.COM 	if (obj != NULL) {
206*7836SJohn.Forte@Sun.COM 		(void) set_obj_uid(obj, uid);
207*7836SJohn.Forte@Sun.COM 		name.tag = ISNS_DD_NAME_ATTR_ID;
208*7836SJohn.Forte@Sun.COM 		if (assign_attr(
209*7836SJohn.Forte@Sun.COM 		    &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)],
210*7836SJohn.Forte@Sun.COM 		    &name) != 0) {
211*7836SJohn.Forte@Sun.COM 			free_object(obj);
212*7836SJohn.Forte@Sun.COM 			obj = NULL;
213*7836SJohn.Forte@Sun.COM 		}
214*7836SJohn.Forte@Sun.COM 	}
215*7836SJohn.Forte@Sun.COM 
216*7836SJohn.Forte@Sun.COM 	return (obj);
217*7836SJohn.Forte@Sun.COM }
218*7836SJohn.Forte@Sun.COM 
219*7836SJohn.Forte@Sun.COM static int
get_member_info(isns_obj_t * assoc,uint32_t * m_type,uint32_t * m_id,int flag)220*7836SJohn.Forte@Sun.COM get_member_info(
221*7836SJohn.Forte@Sun.COM 	isns_obj_t *assoc,
222*7836SJohn.Forte@Sun.COM 	uint32_t *m_type,
223*7836SJohn.Forte@Sun.COM 	uint32_t *m_id,
224*7836SJohn.Forte@Sun.COM 	int flag
225*7836SJohn.Forte@Sun.COM )
226*7836SJohn.Forte@Sun.COM {
227*7836SJohn.Forte@Sun.COM 	int ec = 0;
228*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc = { 0 };
229*7836SJohn.Forte@Sun.COM 
230*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
231*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr1, *attr2;
232*7836SJohn.Forte@Sun.COM 	uint32_t tmp_id = 0;
233*7836SJohn.Forte@Sun.COM 	int i = 0;
234*7836SJohn.Forte@Sun.COM 
235*7836SJohn.Forte@Sun.COM 	*m_type = 0;
236*7836SJohn.Forte@Sun.COM 	*m_id = 0;
237*7836SJohn.Forte@Sun.COM 
238*7836SJohn.Forte@Sun.COM 	attr1 = &assoc->attrs[ATTR_INDEX_ASSOC_ISCSI(
239*7836SJohn.Forte@Sun.COM 	    ISNS_DD_ISCSI_INDEX_ATTR_ID)];
240*7836SJohn.Forte@Sun.COM 	attr2 = &assoc->attrs[ATTR_INDEX_ASSOC_ISCSI(
241*7836SJohn.Forte@Sun.COM 	    ISNS_DD_ISCSI_NAME_ATTR_ID)];
242*7836SJohn.Forte@Sun.COM 
243*7836SJohn.Forte@Sun.COM 	lc.type = OBJ_ISCSI;
244*7836SJohn.Forte@Sun.COM 	if (attr1->tag != 0 && attr1->value.ui != 0) {
245*7836SJohn.Forte@Sun.COM 		*m_id = attr1->value.ui;
246*7836SJohn.Forte@Sun.COM 		lc.id[i] = UID_ATTR_INDEX[OBJ_ISCSI];
247*7836SJohn.Forte@Sun.COM 		lc.op[i] = OP_INTEGER;
248*7836SJohn.Forte@Sun.COM 		lc.data[i].ui = *m_id;
249*7836SJohn.Forte@Sun.COM 		i ++;
250*7836SJohn.Forte@Sun.COM 	}
251*7836SJohn.Forte@Sun.COM 	if (attr2->tag != 0) {
252*7836SJohn.Forte@Sun.COM 		lc.id[i] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
253*7836SJohn.Forte@Sun.COM 		lc.op[i] = OP_STRING;
254*7836SJohn.Forte@Sun.COM 		lc.data[i].ptr = attr2->value.ptr;
255*7836SJohn.Forte@Sun.COM 		i ++;
256*7836SJohn.Forte@Sun.COM 	} else if (scn_q != NULL || sys_q != NULL) {
257*7836SJohn.Forte@Sun.COM 		lc.id[i] = ISNS_ISCSI_NAME_ATTR_ID;
258*7836SJohn.Forte@Sun.COM 	}
259*7836SJohn.Forte@Sun.COM 
260*7836SJohn.Forte@Sun.COM 	/* a member id or member name is required */
261*7836SJohn.Forte@Sun.COM 	if (i == 0) {
262*7836SJohn.Forte@Sun.COM 		if (flag != 0) {
263*7836SJohn.Forte@Sun.COM 			/* add member */
264*7836SJohn.Forte@Sun.COM 			return (ISNS_RSP_INVALID_REGIS);
265*7836SJohn.Forte@Sun.COM 		} else {
266*7836SJohn.Forte@Sun.COM 			/* remove member (isnsp msg request only) */
267*7836SJohn.Forte@Sun.COM 			return (0);
268*7836SJohn.Forte@Sun.COM 		}
269*7836SJohn.Forte@Sun.COM 	}
270*7836SJohn.Forte@Sun.COM 
271*7836SJohn.Forte@Sun.COM 	ec = cache_lookup(&lc, &tmp_id, cb_clone_attrs);
272*7836SJohn.Forte@Sun.COM 
273*7836SJohn.Forte@Sun.COM 	if (ec == 0 && tmp_id == 0) {
274*7836SJohn.Forte@Sun.COM 		if (flag != 0) {
275*7836SJohn.Forte@Sun.COM 			/* add member */
276*7836SJohn.Forte@Sun.COM 			if (attr1->tag == 0 || sys_q == NULL) {
277*7836SJohn.Forte@Sun.COM 				/* object does not exist, create one */
278*7836SJohn.Forte@Sun.COM 				obj = make_member_node(*m_id, attr2);
279*7836SJohn.Forte@Sun.COM 				if (obj == NULL) {
280*7836SJohn.Forte@Sun.COM 					ec = ISNS_RSP_INTERNAL_ERROR;
281*7836SJohn.Forte@Sun.COM 				} else {
282*7836SJohn.Forte@Sun.COM 					ec = register_assoc(obj, &tmp_id);
283*7836SJohn.Forte@Sun.COM 					if (ec != 0) {
284*7836SJohn.Forte@Sun.COM 						free_object(obj);
285*7836SJohn.Forte@Sun.COM 					}
286*7836SJohn.Forte@Sun.COM 				}
287*7836SJohn.Forte@Sun.COM 			} else {
288*7836SJohn.Forte@Sun.COM 				/* don't create it if uid is specified */
289*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_NO_SUCH_ENTRY;
290*7836SJohn.Forte@Sun.COM 			}
291*7836SJohn.Forte@Sun.COM 		} else {
292*7836SJohn.Forte@Sun.COM 			/* remove member */
293*7836SJohn.Forte@Sun.COM 			ec = ERR_NO_SUCH_ASSOCIATION;
294*7836SJohn.Forte@Sun.COM 		}
295*7836SJohn.Forte@Sun.COM 	}
296*7836SJohn.Forte@Sun.COM 
297*7836SJohn.Forte@Sun.COM 	if (attr1->tag == 0) {
298*7836SJohn.Forte@Sun.COM 		attr1->tag = ISNS_DD_ISCSI_INDEX_ATTR_ID;
299*7836SJohn.Forte@Sun.COM 		attr1->len = 4;
300*7836SJohn.Forte@Sun.COM 		attr1->value.ui = tmp_id;
301*7836SJohn.Forte@Sun.COM 	} else if (attr2->tag == 0) {
302*7836SJohn.Forte@Sun.COM 		attr2->tag = ISNS_DD_ISCSI_NAME_ATTR_ID;
303*7836SJohn.Forte@Sun.COM 		attr2->len = strlen((char *)lc.data[1].ptr);
304*7836SJohn.Forte@Sun.COM 		attr2->len += 4 - (attr2->len % 4);
305*7836SJohn.Forte@Sun.COM 		attr2->value.ptr = lc.data[1].ptr;
306*7836SJohn.Forte@Sun.COM 	}
307*7836SJohn.Forte@Sun.COM 
308*7836SJohn.Forte@Sun.COM 	*m_type = OBJ_ISCSI;
309*7836SJohn.Forte@Sun.COM 	*m_id = tmp_id;
310*7836SJohn.Forte@Sun.COM 
311*7836SJohn.Forte@Sun.COM 	return (ec);
312*7836SJohn.Forte@Sun.COM }
313*7836SJohn.Forte@Sun.COM 
314*7836SJohn.Forte@Sun.COM static int
get_dds_member_info(uint32_t m_id)315*7836SJohn.Forte@Sun.COM get_dds_member_info(
316*7836SJohn.Forte@Sun.COM 	uint32_t m_id
317*7836SJohn.Forte@Sun.COM )
318*7836SJohn.Forte@Sun.COM {
319*7836SJohn.Forte@Sun.COM 	int ec = 0;
320*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
321*7836SJohn.Forte@Sun.COM 
322*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
323*7836SJohn.Forte@Sun.COM 	uint32_t tmp_id;
324*7836SJohn.Forte@Sun.COM 
325*7836SJohn.Forte@Sun.COM 	if (m_id != 0) {
326*7836SJohn.Forte@Sun.COM 		SET_UID_LCP(&lc, OBJ_DD, m_id);
327*7836SJohn.Forte@Sun.COM 	} else {
328*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_INVALID_REGIS);
329*7836SJohn.Forte@Sun.COM 	}
330*7836SJohn.Forte@Sun.COM 
331*7836SJohn.Forte@Sun.COM 	tmp_id = is_obj_there(&lc);
332*7836SJohn.Forte@Sun.COM 
333*7836SJohn.Forte@Sun.COM 	if (tmp_id == 0) {
334*7836SJohn.Forte@Sun.COM 		/* object does not exist, create one */
335*7836SJohn.Forte@Sun.COM 		obj = make_member_dd(m_id);
336*7836SJohn.Forte@Sun.COM 		if (obj != NULL) {
337*7836SJohn.Forte@Sun.COM 			ec = register_object(obj, NULL, NULL);
338*7836SJohn.Forte@Sun.COM 		} else {
339*7836SJohn.Forte@Sun.COM 			/* no memory */
340*7836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
341*7836SJohn.Forte@Sun.COM 		}
342*7836SJohn.Forte@Sun.COM 	}
343*7836SJohn.Forte@Sun.COM 
344*7836SJohn.Forte@Sun.COM 	return (ec);
345*7836SJohn.Forte@Sun.COM }
346*7836SJohn.Forte@Sun.COM 
347*7836SJohn.Forte@Sun.COM static int
update_matrix(matrix_t * matrix,const uchar_t op,const uint32_t puid,const uint32_t m_id,int ddd_flag)348*7836SJohn.Forte@Sun.COM update_matrix(
349*7836SJohn.Forte@Sun.COM 	matrix_t *matrix,
350*7836SJohn.Forte@Sun.COM 	const uchar_t op,
351*7836SJohn.Forte@Sun.COM 	const uint32_t puid,
352*7836SJohn.Forte@Sun.COM 	const uint32_t m_id,
353*7836SJohn.Forte@Sun.COM 	int ddd_flag
354*7836SJohn.Forte@Sun.COM )
355*7836SJohn.Forte@Sun.COM {
356*7836SJohn.Forte@Sun.COM 	int ec = 0;
357*7836SJohn.Forte@Sun.COM 
358*7836SJohn.Forte@Sun.COM 	uint32_t new_x = 0, new_y = 0;
359*7836SJohn.Forte@Sun.COM 	matrix_t *tmp_matrix;
360*7836SJohn.Forte@Sun.COM 
361*7836SJohn.Forte@Sun.COM 	uint32_t i, j, k = 0;
362*7836SJohn.Forte@Sun.COM 	uint32_t x_info;
363*7836SJohn.Forte@Sun.COM 	bmp_t *bmp, *tmp_bmp;
364*7836SJohn.Forte@Sun.COM 
365*7836SJohn.Forte@Sun.COM 	uint32_t primary = GET_PRIMARY(m_id);
366*7836SJohn.Forte@Sun.COM 	uint32_t second = GET_SECOND(m_id);
367*7836SJohn.Forte@Sun.COM 
368*7836SJohn.Forte@Sun.COM 	if (primary >= matrix->x) {
369*7836SJohn.Forte@Sun.COM 		if (op == '-') {
370*7836SJohn.Forte@Sun.COM 			ec = ERR_NO_SUCH_ASSOCIATION;
371*7836SJohn.Forte@Sun.COM 			goto update_matrix_done;
372*7836SJohn.Forte@Sun.COM 		}
373*7836SJohn.Forte@Sun.COM 		/* enlarge the matrix on x axis */
374*7836SJohn.Forte@Sun.COM 		if (primary >= matrix->x * 2) {
375*7836SJohn.Forte@Sun.COM 			new_x = primary + 1;
376*7836SJohn.Forte@Sun.COM 		} else {
377*7836SJohn.Forte@Sun.COM 			new_x = matrix->x * 2;
378*7836SJohn.Forte@Sun.COM 		}
379*7836SJohn.Forte@Sun.COM 	}
380*7836SJohn.Forte@Sun.COM 
381*7836SJohn.Forte@Sun.COM 	i = 0;
382*7836SJohn.Forte@Sun.COM 	while (i < matrix->y) {
383*7836SJohn.Forte@Sun.COM 		bmp = MATRIX_X_UNIT(matrix, i);
384*7836SJohn.Forte@Sun.COM 		x_info = MATRIX_X_INFO(bmp);
385*7836SJohn.Forte@Sun.COM 		if (x_info == puid) {
386*7836SJohn.Forte@Sun.COM 			break;
387*7836SJohn.Forte@Sun.COM 		} else if (x_info == 0 && k == 0) {
388*7836SJohn.Forte@Sun.COM 			/* the first available slot */
389*7836SJohn.Forte@Sun.COM 			k = i;
390*7836SJohn.Forte@Sun.COM 		}
391*7836SJohn.Forte@Sun.COM 		i ++;
392*7836SJohn.Forte@Sun.COM 	}
393*7836SJohn.Forte@Sun.COM 	if (i == matrix->y) {
394*7836SJohn.Forte@Sun.COM 		if (op == '-') {
395*7836SJohn.Forte@Sun.COM 			ec = ERR_NO_SUCH_ASSOCIATION;
396*7836SJohn.Forte@Sun.COM 			goto update_matrix_done;
397*7836SJohn.Forte@Sun.COM 		} else if (k == 0) {
398*7836SJohn.Forte@Sun.COM 			new_y = matrix->y * 2;
399*7836SJohn.Forte@Sun.COM 		} else {
400*7836SJohn.Forte@Sun.COM 			i = k;
401*7836SJohn.Forte@Sun.COM 		}
402*7836SJohn.Forte@Sun.COM 	}
403*7836SJohn.Forte@Sun.COM 
404*7836SJohn.Forte@Sun.COM 	/*
405*7836SJohn.Forte@Sun.COM 	 * enlarge the matrix.
406*7836SJohn.Forte@Sun.COM 	 */
407*7836SJohn.Forte@Sun.COM 	if (new_x != 0 || new_y != 0) {
408*7836SJohn.Forte@Sun.COM 		if (new_x == 0) {
409*7836SJohn.Forte@Sun.COM 			new_x = matrix->x;
410*7836SJohn.Forte@Sun.COM 		}
411*7836SJohn.Forte@Sun.COM 		if (new_y == 0) {
412*7836SJohn.Forte@Sun.COM 			new_y = matrix->y;
413*7836SJohn.Forte@Sun.COM 		}
414*7836SJohn.Forte@Sun.COM 		tmp_matrix = new_matrix(new_x, new_y);
415*7836SJohn.Forte@Sun.COM 		if (tmp_matrix != NULL) {
416*7836SJohn.Forte@Sun.COM 			j = 0;
417*7836SJohn.Forte@Sun.COM 			while (j < matrix->y) {
418*7836SJohn.Forte@Sun.COM 				bmp = MATRIX_X_UNIT(matrix, j);
419*7836SJohn.Forte@Sun.COM 				x_info = MATRIX_X_INFO(bmp);
420*7836SJohn.Forte@Sun.COM 				if (x_info != 0) {
421*7836SJohn.Forte@Sun.COM 					tmp_bmp = MATRIX_X_UNIT(tmp_matrix, j);
422*7836SJohn.Forte@Sun.COM 					(void) memcpy((void *)tmp_bmp,
423*7836SJohn.Forte@Sun.COM 					    (void *)bmp, SIZEOF_X_UNIT(matrix));
424*7836SJohn.Forte@Sun.COM 				}
425*7836SJohn.Forte@Sun.COM 				j ++;
426*7836SJohn.Forte@Sun.COM 			}
427*7836SJohn.Forte@Sun.COM 			free(matrix->m);
428*7836SJohn.Forte@Sun.COM 			matrix->x = tmp_matrix->x;
429*7836SJohn.Forte@Sun.COM 			matrix->y = tmp_matrix->y;
430*7836SJohn.Forte@Sun.COM 			matrix->m = tmp_matrix->m;
431*7836SJohn.Forte@Sun.COM 			free(tmp_matrix);
432*7836SJohn.Forte@Sun.COM 		} else {
433*7836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
434*7836SJohn.Forte@Sun.COM 			goto update_matrix_done;
435*7836SJohn.Forte@Sun.COM 		}
436*7836SJohn.Forte@Sun.COM 	}
437*7836SJohn.Forte@Sun.COM 
438*7836SJohn.Forte@Sun.COM 	bmp = MATRIX_X_UNIT(matrix, i);
439*7836SJohn.Forte@Sun.COM 
440*7836SJohn.Forte@Sun.COM 	MATRIX_X_INFO(bmp) = puid;
441*7836SJohn.Forte@Sun.COM 	if (op == '+') {
442*7836SJohn.Forte@Sun.COM 		if (TEST_MEMBERSHIP(bmp, primary, second) == 0) {
443*7836SJohn.Forte@Sun.COM 			SET_MEMBERSHIP(bmp, primary, second);
444*7836SJohn.Forte@Sun.COM 			SET_CACHE_UPDATED();
445*7836SJohn.Forte@Sun.COM 			if (ddd_flag != 0) {
446*7836SJohn.Forte@Sun.COM 				bmp = MATRIX_X_UNIT(matrix, 0);
447*7836SJohn.Forte@Sun.COM 				ASSERT(MATRIX_X_INFO(bmp) ==
448*7836SJohn.Forte@Sun.COM 				    ISNS_DEFAULT_DD_ID);
449*7836SJohn.Forte@Sun.COM 				CLEAR_MEMBERSHIP(bmp, primary, second);
450*7836SJohn.Forte@Sun.COM 			}
451*7836SJohn.Forte@Sun.COM 		} else {
452*7836SJohn.Forte@Sun.COM 			ec = ERR_ALREADY_ASSOCIATED;
453*7836SJohn.Forte@Sun.COM 		}
454*7836SJohn.Forte@Sun.COM 	} else if (op == '-') {
455*7836SJohn.Forte@Sun.COM 		if (TEST_MEMBERSHIP(bmp, primary, second) != 0) {
456*7836SJohn.Forte@Sun.COM 			CLEAR_MEMBERSHIP(bmp, primary, second);
457*7836SJohn.Forte@Sun.COM 			SET_CACHE_UPDATED();
458*7836SJohn.Forte@Sun.COM 			if (ddd_flag != 0) {
459*7836SJohn.Forte@Sun.COM 				i = 1;
460*7836SJohn.Forte@Sun.COM 				while (i < matrix->y) {
461*7836SJohn.Forte@Sun.COM 					bmp = MATRIX_X_UNIT(matrix, i);
462*7836SJohn.Forte@Sun.COM 					x_info = MATRIX_X_INFO(bmp);
463*7836SJohn.Forte@Sun.COM 					if (x_info != 0 &&
464*7836SJohn.Forte@Sun.COM 					    TEST_MEMBERSHIP(bmp,
465*7836SJohn.Forte@Sun.COM 					    primary, second) != 0) {
466*7836SJohn.Forte@Sun.COM 						break;
467*7836SJohn.Forte@Sun.COM 					}
468*7836SJohn.Forte@Sun.COM 					i ++;
469*7836SJohn.Forte@Sun.COM 				}
470*7836SJohn.Forte@Sun.COM 				if (i == matrix->y) {
471*7836SJohn.Forte@Sun.COM 					bmp = MATRIX_X_UNIT(matrix, 0);
472*7836SJohn.Forte@Sun.COM 					ASSERT(MATRIX_X_INFO(bmp) ==
473*7836SJohn.Forte@Sun.COM 					    ISNS_DEFAULT_DD_ID);
474*7836SJohn.Forte@Sun.COM 					SET_MEMBERSHIP(bmp, primary, second);
475*7836SJohn.Forte@Sun.COM 				}
476*7836SJohn.Forte@Sun.COM 			}
477*7836SJohn.Forte@Sun.COM 		} else {
478*7836SJohn.Forte@Sun.COM 			ec = ERR_NO_SUCH_ASSOCIATION;
479*7836SJohn.Forte@Sun.COM 		}
480*7836SJohn.Forte@Sun.COM 	}
481*7836SJohn.Forte@Sun.COM 
482*7836SJohn.Forte@Sun.COM update_matrix_done:
483*7836SJohn.Forte@Sun.COM 	return (ec);
484*7836SJohn.Forte@Sun.COM }
485*7836SJohn.Forte@Sun.COM 
486*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
487*7836SJohn.Forte@Sun.COM static int
update_dd_matrix(const uchar_t op,const uint32_t dd_id,const uint32_t m_type,const uint32_t m_id)488*7836SJohn.Forte@Sun.COM update_dd_matrix(
489*7836SJohn.Forte@Sun.COM 	const uchar_t op,
490*7836SJohn.Forte@Sun.COM 	const uint32_t dd_id,
491*7836SJohn.Forte@Sun.COM 	const uint32_t m_type,
492*7836SJohn.Forte@Sun.COM 	const uint32_t m_id
493*7836SJohn.Forte@Sun.COM )
494*7836SJohn.Forte@Sun.COM {
495*7836SJohn.Forte@Sun.COM 	matrix_t *matrix;
496*7836SJohn.Forte@Sun.COM 
497*7836SJohn.Forte@Sun.COM 	ASSERT(m_type == OBJ_ISCSI);
498*7836SJohn.Forte@Sun.COM 
499*7836SJohn.Forte@Sun.COM 	matrix = cache_get_matrix(OBJ_DD);
500*7836SJohn.Forte@Sun.COM 
501*7836SJohn.Forte@Sun.COM 	return (update_matrix(matrix, op, dd_id, m_id, 1));
502*7836SJohn.Forte@Sun.COM }
503*7836SJohn.Forte@Sun.COM 
504*7836SJohn.Forte@Sun.COM static int
update_dds_matrix(const uchar_t op,const uint32_t dds_id,const uint32_t m_id)505*7836SJohn.Forte@Sun.COM update_dds_matrix(
506*7836SJohn.Forte@Sun.COM 	const uchar_t op,
507*7836SJohn.Forte@Sun.COM 	const uint32_t dds_id,
508*7836SJohn.Forte@Sun.COM 	const uint32_t m_id
509*7836SJohn.Forte@Sun.COM )
510*7836SJohn.Forte@Sun.COM {
511*7836SJohn.Forte@Sun.COM 	matrix_t *dds_matrix = cache_get_matrix(OBJ_DDS);
512*7836SJohn.Forte@Sun.COM 
513*7836SJohn.Forte@Sun.COM 	return (update_matrix(dds_matrix, op, dds_id, m_id, 0));
514*7836SJohn.Forte@Sun.COM }
515*7836SJohn.Forte@Sun.COM 
516*7836SJohn.Forte@Sun.COM static int
clear_matrix(matrix_t * matrix,const uint32_t uid,bmp_t ** p,uint32_t * n,int ddd_flag)517*7836SJohn.Forte@Sun.COM clear_matrix(
518*7836SJohn.Forte@Sun.COM 	matrix_t *matrix,
519*7836SJohn.Forte@Sun.COM 	const uint32_t uid,
520*7836SJohn.Forte@Sun.COM 	bmp_t **p,
521*7836SJohn.Forte@Sun.COM 	uint32_t *n,
522*7836SJohn.Forte@Sun.COM 	int ddd_flag
523*7836SJohn.Forte@Sun.COM )
524*7836SJohn.Forte@Sun.COM {
525*7836SJohn.Forte@Sun.COM 	int ec = 0;
526*7836SJohn.Forte@Sun.COM 	bmp_t *bmp;
527*7836SJohn.Forte@Sun.COM 	uint32_t x_info;
528*7836SJohn.Forte@Sun.COM 	int i, j;
529*7836SJohn.Forte@Sun.COM 
530*7836SJohn.Forte@Sun.COM 	uint32_t primary;
531*7836SJohn.Forte@Sun.COM 	uint32_t second;
532*7836SJohn.Forte@Sun.COM 
533*7836SJohn.Forte@Sun.COM 	if (p != NULL) {
534*7836SJohn.Forte@Sun.COM 		*p = NULL;
535*7836SJohn.Forte@Sun.COM 		*n = 0;
536*7836SJohn.Forte@Sun.COM 	}
537*7836SJohn.Forte@Sun.COM 
538*7836SJohn.Forte@Sun.COM 	i = 0;
539*7836SJohn.Forte@Sun.COM 	while (i < matrix->y) {
540*7836SJohn.Forte@Sun.COM 		bmp = MATRIX_X_UNIT(matrix, i);
541*7836SJohn.Forte@Sun.COM 		x_info = MATRIX_X_INFO(bmp);
542*7836SJohn.Forte@Sun.COM 		if (x_info == uid) {
543*7836SJohn.Forte@Sun.COM 			if (p != NULL) {
544*7836SJohn.Forte@Sun.COM 				/* dup it for caller */
545*7836SJohn.Forte@Sun.COM 				*n = matrix->x;
546*7836SJohn.Forte@Sun.COM 				*p = (bmp_t *)malloc(*n * sizeof (bmp_t));
547*7836SJohn.Forte@Sun.COM 				if (*p != NULL) {
548*7836SJohn.Forte@Sun.COM 					(void) memcpy(*p, &bmp[MATRIX_X_HEADER],
549*7836SJohn.Forte@Sun.COM 					    *n * sizeof (bmp_t));
550*7836SJohn.Forte@Sun.COM 				} else {
551*7836SJohn.Forte@Sun.COM 					ec = ISNS_RSP_INTERNAL_ERROR;
552*7836SJohn.Forte@Sun.COM 				}
553*7836SJohn.Forte@Sun.COM 			}
554*7836SJohn.Forte@Sun.COM 			/* clean it */
555*7836SJohn.Forte@Sun.COM 			(void) memset(bmp, 0, SIZEOF_X_UNIT(matrix));
556*7836SJohn.Forte@Sun.COM 			break;
557*7836SJohn.Forte@Sun.COM 		}
558*7836SJohn.Forte@Sun.COM 		i ++;
559*7836SJohn.Forte@Sun.COM 	}
560*7836SJohn.Forte@Sun.COM 
561*7836SJohn.Forte@Sun.COM 	if (ddd_flag != 0 && p != NULL) {
562*7836SJohn.Forte@Sun.COM 		bmp = MATRIX_X_UNIT(matrix, 0);
563*7836SJohn.Forte@Sun.COM 		ASSERT(MATRIX_X_INFO(bmp) == ISNS_DEFAULT_DD_ID);
564*7836SJohn.Forte@Sun.COM 		/* Test the membership for each node which is a */
565*7836SJohn.Forte@Sun.COM 		/* member in the dd that is being deleted. */
566*7836SJohn.Forte@Sun.COM 		FOR_EACH_MEMBER(*p, *n, i, {
567*7836SJohn.Forte@Sun.COM 			j = get_dd_id(i, 0);
568*7836SJohn.Forte@Sun.COM 			if (j == 0) {
569*7836SJohn.Forte@Sun.COM 				/* put it to the default dd */
570*7836SJohn.Forte@Sun.COM 				primary = GET_PRIMARY(i);
571*7836SJohn.Forte@Sun.COM 				second = GET_SECOND(i);
572*7836SJohn.Forte@Sun.COM 				SET_MEMBERSHIP(bmp, primary, second);
573*7836SJohn.Forte@Sun.COM 			}
574*7836SJohn.Forte@Sun.COM 		});
575*7836SJohn.Forte@Sun.COM 	}
576*7836SJohn.Forte@Sun.COM 
577*7836SJohn.Forte@Sun.COM 	return (ec);
578*7836SJohn.Forte@Sun.COM }
579*7836SJohn.Forte@Sun.COM 
580*7836SJohn.Forte@Sun.COM static int
get_matrix(matrix_t * matrix,const uint32_t uid,bmp_t ** p,uint32_t * n)581*7836SJohn.Forte@Sun.COM get_matrix(
582*7836SJohn.Forte@Sun.COM 	matrix_t *matrix,
583*7836SJohn.Forte@Sun.COM 	const uint32_t uid,
584*7836SJohn.Forte@Sun.COM 	bmp_t **p,
585*7836SJohn.Forte@Sun.COM 	uint32_t *n
586*7836SJohn.Forte@Sun.COM )
587*7836SJohn.Forte@Sun.COM {
588*7836SJohn.Forte@Sun.COM 	int ec = 0;
589*7836SJohn.Forte@Sun.COM 	bmp_t *bmp;
590*7836SJohn.Forte@Sun.COM 	uint32_t x_info;
591*7836SJohn.Forte@Sun.COM 	int i;
592*7836SJohn.Forte@Sun.COM 
593*7836SJohn.Forte@Sun.COM 	*n = 0;
594*7836SJohn.Forte@Sun.COM 	*p = NULL;
595*7836SJohn.Forte@Sun.COM 
596*7836SJohn.Forte@Sun.COM 	i = 0;
597*7836SJohn.Forte@Sun.COM 	while (i < matrix->y) {
598*7836SJohn.Forte@Sun.COM 		bmp = MATRIX_X_UNIT(matrix, i);
599*7836SJohn.Forte@Sun.COM 		x_info = MATRIX_X_INFO(bmp);
600*7836SJohn.Forte@Sun.COM 		if (x_info == uid) {
601*7836SJohn.Forte@Sun.COM 			/* dup it for caller */
602*7836SJohn.Forte@Sun.COM 			*n = matrix->x;
603*7836SJohn.Forte@Sun.COM 			*p = (bmp_t *)malloc(*n * sizeof (bmp_t));
604*7836SJohn.Forte@Sun.COM 			if (*p != NULL) {
605*7836SJohn.Forte@Sun.COM 				(void) memcpy(*p, &bmp[MATRIX_X_HEADER],
606*7836SJohn.Forte@Sun.COM 				    *n * sizeof (bmp_t));
607*7836SJohn.Forte@Sun.COM 			} else {
608*7836SJohn.Forte@Sun.COM 				*n = 0;
609*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_INTERNAL_ERROR;
610*7836SJohn.Forte@Sun.COM 			}
611*7836SJohn.Forte@Sun.COM 			break;
612*7836SJohn.Forte@Sun.COM 		}
613*7836SJohn.Forte@Sun.COM 		i ++;
614*7836SJohn.Forte@Sun.COM 	}
615*7836SJohn.Forte@Sun.COM 
616*7836SJohn.Forte@Sun.COM 	return (ec);
617*7836SJohn.Forte@Sun.COM }
618*7836SJohn.Forte@Sun.COM 
619*7836SJohn.Forte@Sun.COM static int
clear_dd_matrix(const uint32_t dd_id,bmp_t ** p,uint32_t * n)620*7836SJohn.Forte@Sun.COM clear_dd_matrix(
621*7836SJohn.Forte@Sun.COM 	const uint32_t dd_id,
622*7836SJohn.Forte@Sun.COM 	bmp_t **p,
623*7836SJohn.Forte@Sun.COM 	uint32_t *n
624*7836SJohn.Forte@Sun.COM )
625*7836SJohn.Forte@Sun.COM {
626*7836SJohn.Forte@Sun.COM 	matrix_t *matrix = cache_get_matrix(OBJ_DD);
627*7836SJohn.Forte@Sun.COM 
628*7836SJohn.Forte@Sun.COM 	return (clear_matrix(matrix, dd_id, p, n, 1));
629*7836SJohn.Forte@Sun.COM }
630*7836SJohn.Forte@Sun.COM 
631*7836SJohn.Forte@Sun.COM static int
clear_dds_matrix(const uint32_t dds_id)632*7836SJohn.Forte@Sun.COM clear_dds_matrix(
633*7836SJohn.Forte@Sun.COM 	const uint32_t dds_id
634*7836SJohn.Forte@Sun.COM )
635*7836SJohn.Forte@Sun.COM {
636*7836SJohn.Forte@Sun.COM 	matrix_t *matrix = cache_get_matrix(OBJ_DDS);
637*7836SJohn.Forte@Sun.COM 
638*7836SJohn.Forte@Sun.COM 	return (clear_matrix(matrix, dds_id, NULL, NULL, 0));
639*7836SJohn.Forte@Sun.COM }
640*7836SJohn.Forte@Sun.COM 
641*7836SJohn.Forte@Sun.COM int
get_dd_matrix(const uint32_t dd_id,bmp_t ** p,uint32_t * n)642*7836SJohn.Forte@Sun.COM get_dd_matrix(
643*7836SJohn.Forte@Sun.COM 	const uint32_t dd_id,
644*7836SJohn.Forte@Sun.COM 	bmp_t **p,
645*7836SJohn.Forte@Sun.COM 	uint32_t *n
646*7836SJohn.Forte@Sun.COM )
647*7836SJohn.Forte@Sun.COM {
648*7836SJohn.Forte@Sun.COM 	matrix_t *matrix = cache_get_matrix(OBJ_DD);
649*7836SJohn.Forte@Sun.COM 
650*7836SJohn.Forte@Sun.COM 	return (get_matrix(matrix, dd_id, p, n));
651*7836SJohn.Forte@Sun.COM }
652*7836SJohn.Forte@Sun.COM 
653*7836SJohn.Forte@Sun.COM int
get_dds_matrix(const uint32_t dds_id,bmp_t ** p,uint32_t * n)654*7836SJohn.Forte@Sun.COM get_dds_matrix(
655*7836SJohn.Forte@Sun.COM 	const uint32_t dds_id,
656*7836SJohn.Forte@Sun.COM 	bmp_t **p,
657*7836SJohn.Forte@Sun.COM 	uint32_t *n
658*7836SJohn.Forte@Sun.COM )
659*7836SJohn.Forte@Sun.COM {
660*7836SJohn.Forte@Sun.COM 	matrix_t *matrix = cache_get_matrix(OBJ_DDS);
661*7836SJohn.Forte@Sun.COM 
662*7836SJohn.Forte@Sun.COM 	return (get_matrix(matrix, dds_id, p, n));
663*7836SJohn.Forte@Sun.COM }
664*7836SJohn.Forte@Sun.COM 
665*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
666*7836SJohn.Forte@Sun.COM static int
cb_get_dds_status(void * p1,void * p2)667*7836SJohn.Forte@Sun.COM cb_get_dds_status(
668*7836SJohn.Forte@Sun.COM 	void *p1,
669*7836SJohn.Forte@Sun.COM 	void *p2
670*7836SJohn.Forte@Sun.COM )
671*7836SJohn.Forte@Sun.COM {
672*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
673*7836SJohn.Forte@Sun.COM 
674*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr = &obj->attrs[
675*7836SJohn.Forte@Sun.COM 	    ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID)];
676*7836SJohn.Forte@Sun.COM 
677*7836SJohn.Forte@Sun.COM 	return (DDS_ENABLED(attr->value.ui) ? 1 : 0);
678*7836SJohn.Forte@Sun.COM }
679*7836SJohn.Forte@Sun.COM 
680*7836SJohn.Forte@Sun.COM static int
get_dds_status(uint32_t dds_id)681*7836SJohn.Forte@Sun.COM get_dds_status(
682*7836SJohn.Forte@Sun.COM 	uint32_t dds_id
683*7836SJohn.Forte@Sun.COM )
684*7836SJohn.Forte@Sun.COM {
685*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
686*7836SJohn.Forte@Sun.COM 
687*7836SJohn.Forte@Sun.COM 	if (dds_id == 0) {
688*7836SJohn.Forte@Sun.COM 		return (0);
689*7836SJohn.Forte@Sun.COM 	}
690*7836SJohn.Forte@Sun.COM 
691*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_DDS, dds_id);
692*7836SJohn.Forte@Sun.COM 
693*7836SJohn.Forte@Sun.COM 	return (cache_lookup(&lc, NULL, cb_get_dds_status));
694*7836SJohn.Forte@Sun.COM }
695*7836SJohn.Forte@Sun.COM 
696*7836SJohn.Forte@Sun.COM int
is_dd_active(uint32_t dd_id)697*7836SJohn.Forte@Sun.COM is_dd_active(
698*7836SJohn.Forte@Sun.COM 	uint32_t dd_id
699*7836SJohn.Forte@Sun.COM )
700*7836SJohn.Forte@Sun.COM {
701*7836SJohn.Forte@Sun.COM 	int active = 0;
702*7836SJohn.Forte@Sun.COM 
703*7836SJohn.Forte@Sun.COM 	matrix_t *dds_matrix;
704*7836SJohn.Forte@Sun.COM 	uint32_t primary;
705*7836SJohn.Forte@Sun.COM 	uint32_t second;
706*7836SJohn.Forte@Sun.COM 	uint32_t x_info;
707*7836SJohn.Forte@Sun.COM 	bmp_t *bmp;
708*7836SJohn.Forte@Sun.COM 	int i;
709*7836SJohn.Forte@Sun.COM 
710*7836SJohn.Forte@Sun.COM 	if (dd_id == 0) {
711*7836SJohn.Forte@Sun.COM 		return (active);
712*7836SJohn.Forte@Sun.COM 	}
713*7836SJohn.Forte@Sun.COM 
714*7836SJohn.Forte@Sun.COM 	dds_matrix = cache_get_matrix(OBJ_DDS);
715*7836SJohn.Forte@Sun.COM 	primary = GET_PRIMARY(dd_id);
716*7836SJohn.Forte@Sun.COM 	second = GET_SECOND(dd_id);
717*7836SJohn.Forte@Sun.COM 
718*7836SJohn.Forte@Sun.COM 	if (primary < dds_matrix->x) {
719*7836SJohn.Forte@Sun.COM 		i = 0;
720*7836SJohn.Forte@Sun.COM 		while (i < dds_matrix->y) {
721*7836SJohn.Forte@Sun.COM 			bmp = MATRIX_X_UNIT(dds_matrix, i);
722*7836SJohn.Forte@Sun.COM 			x_info = MATRIX_X_INFO(bmp);
723*7836SJohn.Forte@Sun.COM 			if (x_info != 0 &&
724*7836SJohn.Forte@Sun.COM 			    TEST_MEMBERSHIP(bmp, primary, second) != 0) {
725*7836SJohn.Forte@Sun.COM 				if (get_dds_status(x_info) != 0) {
726*7836SJohn.Forte@Sun.COM 					active = 1;
727*7836SJohn.Forte@Sun.COM 					break;
728*7836SJohn.Forte@Sun.COM 				}
729*7836SJohn.Forte@Sun.COM 			}
730*7836SJohn.Forte@Sun.COM 			i ++;
731*7836SJohn.Forte@Sun.COM 		}
732*7836SJohn.Forte@Sun.COM 	}
733*7836SJohn.Forte@Sun.COM 
734*7836SJohn.Forte@Sun.COM 	return (active);
735*7836SJohn.Forte@Sun.COM }
736*7836SJohn.Forte@Sun.COM 
737*7836SJohn.Forte@Sun.COM int
get_scope(uchar_t * node_name,bmp_t ** p,uint32_t * n)738*7836SJohn.Forte@Sun.COM get_scope(
739*7836SJohn.Forte@Sun.COM 	uchar_t *node_name,
740*7836SJohn.Forte@Sun.COM 	bmp_t **p,
741*7836SJohn.Forte@Sun.COM 	uint32_t *n
742*7836SJohn.Forte@Sun.COM )
743*7836SJohn.Forte@Sun.COM {
744*7836SJohn.Forte@Sun.COM 	int ec = 0;
745*7836SJohn.Forte@Sun.COM 
746*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
747*7836SJohn.Forte@Sun.COM 	uint32_t uid;
748*7836SJohn.Forte@Sun.COM 
749*7836SJohn.Forte@Sun.COM 	matrix_t *dd_matrix;
750*7836SJohn.Forte@Sun.COM 	uint32_t primary;
751*7836SJohn.Forte@Sun.COM 	uint32_t second;
752*7836SJohn.Forte@Sun.COM 	uint32_t x_info;
753*7836SJohn.Forte@Sun.COM 	bmp_t *bmp;
754*7836SJohn.Forte@Sun.COM 	int i, j;
755*7836SJohn.Forte@Sun.COM 
756*7836SJohn.Forte@Sun.COM 	bmp_t *tmp_p;
757*7836SJohn.Forte@Sun.COM 	uint32_t tmp_n;
758*7836SJohn.Forte@Sun.COM 
759*7836SJohn.Forte@Sun.COM 	bmp_t *short_p;
760*7836SJohn.Forte@Sun.COM 	uint32_t short_n;
761*7836SJohn.Forte@Sun.COM 
762*7836SJohn.Forte@Sun.COM 	/* clear it */
763*7836SJohn.Forte@Sun.COM 	*p = NULL;
764*7836SJohn.Forte@Sun.COM 	*n = 0;
765*7836SJohn.Forte@Sun.COM 
766*7836SJohn.Forte@Sun.COM 	/* get the source object uid */
767*7836SJohn.Forte@Sun.COM 	lc.curr_uid = 0;
768*7836SJohn.Forte@Sun.COM 	lc.type = OBJ_ISCSI;
769*7836SJohn.Forte@Sun.COM 	lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
770*7836SJohn.Forte@Sun.COM 	lc.op[0] = OP_STRING;
771*7836SJohn.Forte@Sun.COM 	lc.data[0].ptr = node_name;
772*7836SJohn.Forte@Sun.COM 	lc.op[1] = 0;
773*7836SJohn.Forte@Sun.COM 
774*7836SJohn.Forte@Sun.COM 	uid = is_obj_there(&lc);
775*7836SJohn.Forte@Sun.COM 
776*7836SJohn.Forte@Sun.COM 	/* no such object */
777*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
778*7836SJohn.Forte@Sun.COM 		return (ec);
779*7836SJohn.Forte@Sun.COM 	}
780*7836SJohn.Forte@Sun.COM 
781*7836SJohn.Forte@Sun.COM 	dd_matrix = cache_get_matrix(OBJ_DD);
782*7836SJohn.Forte@Sun.COM 	primary = GET_PRIMARY(uid);
783*7836SJohn.Forte@Sun.COM 	second = GET_SECOND(uid);
784*7836SJohn.Forte@Sun.COM 
785*7836SJohn.Forte@Sun.COM 	if (primary < dd_matrix->x) {
786*7836SJohn.Forte@Sun.COM 		i = 0;
787*7836SJohn.Forte@Sun.COM 		while (i < dd_matrix->y) {
788*7836SJohn.Forte@Sun.COM 			bmp = MATRIX_X_UNIT(dd_matrix, i);
789*7836SJohn.Forte@Sun.COM 			x_info = MATRIX_X_INFO(bmp);
790*7836SJohn.Forte@Sun.COM 			if (ec == 0 && x_info != 0 &&
791*7836SJohn.Forte@Sun.COM 			    TEST_MEMBERSHIP(bmp, primary, second) != 0) {
792*7836SJohn.Forte@Sun.COM 				if (is_dd_active(x_info) != 0 &&
793*7836SJohn.Forte@Sun.COM 				    (ec = get_dd_matrix(x_info,
794*7836SJohn.Forte@Sun.COM 				    &tmp_p, &tmp_n)) == 0) {
795*7836SJohn.Forte@Sun.COM 					if (*p == NULL) {
796*7836SJohn.Forte@Sun.COM 						*p = tmp_p;
797*7836SJohn.Forte@Sun.COM 						*n = tmp_n;
798*7836SJohn.Forte@Sun.COM 					} else {
799*7836SJohn.Forte@Sun.COM 						if (*n >= tmp_n) {
800*7836SJohn.Forte@Sun.COM 							short_p = tmp_p;
801*7836SJohn.Forte@Sun.COM 							short_n = tmp_n;
802*7836SJohn.Forte@Sun.COM 						} else {
803*7836SJohn.Forte@Sun.COM 							short_p = *p;
804*7836SJohn.Forte@Sun.COM 							short_n = *n;
805*7836SJohn.Forte@Sun.COM 							*p = tmp_p;
806*7836SJohn.Forte@Sun.COM 							*n = tmp_n;
807*7836SJohn.Forte@Sun.COM 						}
808*7836SJohn.Forte@Sun.COM 						j = 0;
809*7836SJohn.Forte@Sun.COM 						while (j < short_n) {
810*7836SJohn.Forte@Sun.COM 							(*p)[j] |= short_p[j];
811*7836SJohn.Forte@Sun.COM 							j ++;
812*7836SJohn.Forte@Sun.COM 						}
813*7836SJohn.Forte@Sun.COM 						free(short_p);
814*7836SJohn.Forte@Sun.COM 					}
815*7836SJohn.Forte@Sun.COM 				}
816*7836SJohn.Forte@Sun.COM 			}
817*7836SJohn.Forte@Sun.COM 			i ++;
818*7836SJohn.Forte@Sun.COM 		}
819*7836SJohn.Forte@Sun.COM 	}
820*7836SJohn.Forte@Sun.COM 
821*7836SJohn.Forte@Sun.COM 	primary ++;
822*7836SJohn.Forte@Sun.COM 	if (ec == 0 && *p == NULL) {
823*7836SJohn.Forte@Sun.COM 		*p = (bmp_t *)calloc(primary, sizeof (bmp_t));
824*7836SJohn.Forte@Sun.COM 		if (*p != NULL) {
825*7836SJohn.Forte@Sun.COM 			*n = primary;
826*7836SJohn.Forte@Sun.COM 		} else {
827*7836SJohn.Forte@Sun.COM 			*n = 0;
828*7836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
829*7836SJohn.Forte@Sun.COM 		}
830*7836SJohn.Forte@Sun.COM 	}
831*7836SJohn.Forte@Sun.COM 
832*7836SJohn.Forte@Sun.COM 	if (*p != NULL) {
833*7836SJohn.Forte@Sun.COM 		(*p)[primary - 1] |= (1 << second);
834*7836SJohn.Forte@Sun.COM 	}
835*7836SJohn.Forte@Sun.COM 
836*7836SJohn.Forte@Sun.COM 	return (ec);
837*7836SJohn.Forte@Sun.COM }
838*7836SJohn.Forte@Sun.COM 
839*7836SJohn.Forte@Sun.COM int
cb_clone_attrs(void * p1,void * p2)840*7836SJohn.Forte@Sun.COM cb_clone_attrs(
841*7836SJohn.Forte@Sun.COM 	void *p1,
842*7836SJohn.Forte@Sun.COM 	void *p2
843*7836SJohn.Forte@Sun.COM )
844*7836SJohn.Forte@Sun.COM {
845*7836SJohn.Forte@Sun.COM 	int ec = 0;
846*7836SJohn.Forte@Sun.COM 
847*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
848*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
849*7836SJohn.Forte@Sun.COM 
850*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
851*7836SJohn.Forte@Sun.COM 
852*7836SJohn.Forte@Sun.COM 	int i = 1;
853*7836SJohn.Forte@Sun.COM 
854*7836SJohn.Forte@Sun.COM 	while (i < MAX_LOOKUP_CTRL &&
855*7836SJohn.Forte@Sun.COM 	    lcp->op[i] != 0) {
856*7836SJohn.Forte@Sun.COM 		i ++;
857*7836SJohn.Forte@Sun.COM 	}
858*7836SJohn.Forte@Sun.COM 
859*7836SJohn.Forte@Sun.COM 	while (ec == 0 &&
860*7836SJohn.Forte@Sun.COM 	    i < MAX_LOOKUP_CTRL &&
861*7836SJohn.Forte@Sun.COM 	    lcp->id[i] != 0) {
862*7836SJohn.Forte@Sun.COM 		switch (lcp->id[i]) {
863*7836SJohn.Forte@Sun.COM 		case ISNS_ISCSI_NAME_ATTR_ID:
864*7836SJohn.Forte@Sun.COM 			attr = &obj->attrs[ATTR_INDEX_ISCSI(
865*7836SJohn.Forte@Sun.COM 			    ISNS_ISCSI_NAME_ATTR_ID)];
866*7836SJohn.Forte@Sun.COM 			lcp->data[i].ptr = (uchar_t *)malloc(attr->len);
867*7836SJohn.Forte@Sun.COM 			if (lcp->data[i].ptr != NULL) {
868*7836SJohn.Forte@Sun.COM 				(void) strcpy((char *)lcp->data[i].ptr,
869*7836SJohn.Forte@Sun.COM 				    (char *)attr->value.ptr);
870*7836SJohn.Forte@Sun.COM 			} else {
871*7836SJohn.Forte@Sun.COM 				/* memory exhausted */
872*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_INTERNAL_ERROR;
873*7836SJohn.Forte@Sun.COM 			}
874*7836SJohn.Forte@Sun.COM 			break;
875*7836SJohn.Forte@Sun.COM 		case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
876*7836SJohn.Forte@Sun.COM 			attr = &obj->attrs[ATTR_INDEX_ISCSI(
877*7836SJohn.Forte@Sun.COM 			    ISNS_ISCSI_NODE_TYPE_ATTR_ID)];
878*7836SJohn.Forte@Sun.COM 			lcp->data[i].ui = attr->value.ui;
879*7836SJohn.Forte@Sun.COM 			break;
880*7836SJohn.Forte@Sun.COM 		case ISNS_PG_ISCSI_NAME_ATTR_ID:
881*7836SJohn.Forte@Sun.COM 			attr = &obj->attrs[ATTR_INDEX_PG(
882*7836SJohn.Forte@Sun.COM 			    ISNS_PG_ISCSI_NAME_ATTR_ID)];
883*7836SJohn.Forte@Sun.COM 			lcp->data[i].ptr = (uchar_t *)malloc(attr->len);
884*7836SJohn.Forte@Sun.COM 			if (lcp->data[i].ptr != NULL) {
885*7836SJohn.Forte@Sun.COM 				(void) strcpy((char *)lcp->data[i].ptr,
886*7836SJohn.Forte@Sun.COM 				    (char *)attr->value.ptr);
887*7836SJohn.Forte@Sun.COM 			} else {
888*7836SJohn.Forte@Sun.COM 				/* memory exhausted */
889*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_INTERNAL_ERROR;
890*7836SJohn.Forte@Sun.COM 			}
891*7836SJohn.Forte@Sun.COM 			break;
892*7836SJohn.Forte@Sun.COM 		case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
893*7836SJohn.Forte@Sun.COM 			attr = &obj->attrs[ATTR_INDEX_PG(
894*7836SJohn.Forte@Sun.COM 			    ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)];
895*7836SJohn.Forte@Sun.COM 			lcp->data[i].ip = (in6_addr_t *)malloc(attr->len);
896*7836SJohn.Forte@Sun.COM 			if (lcp->data[i].ip != NULL) {
897*7836SJohn.Forte@Sun.COM 				(void) memcpy(lcp->data[i].ip,
898*7836SJohn.Forte@Sun.COM 				    attr->value.ip, attr->len);
899*7836SJohn.Forte@Sun.COM 			} else {
900*7836SJohn.Forte@Sun.COM 				/* memory exhausted */
901*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_INTERNAL_ERROR;
902*7836SJohn.Forte@Sun.COM 			}
903*7836SJohn.Forte@Sun.COM 			break;
904*7836SJohn.Forte@Sun.COM 		case ISNS_PG_PORTAL_PORT_ATTR_ID:
905*7836SJohn.Forte@Sun.COM 			attr = &obj->attrs[ATTR_INDEX_PG(
906*7836SJohn.Forte@Sun.COM 			    ISNS_PG_PORTAL_PORT_ATTR_ID)];
907*7836SJohn.Forte@Sun.COM 			lcp->data[i].ui = attr->value.ui;
908*7836SJohn.Forte@Sun.COM 			break;
909*7836SJohn.Forte@Sun.COM 		case ISNS_PORTAL_IP_ADDR_ATTR_ID:
910*7836SJohn.Forte@Sun.COM 			attr = &obj->attrs[ATTR_INDEX_PORTAL(
911*7836SJohn.Forte@Sun.COM 			    ISNS_PORTAL_IP_ADDR_ATTR_ID)];
912*7836SJohn.Forte@Sun.COM 			lcp->data[i].ip = (in6_addr_t *)malloc(attr->len);
913*7836SJohn.Forte@Sun.COM 			if (lcp->data[i].ip != NULL) {
914*7836SJohn.Forte@Sun.COM 				(void) memcpy(lcp->data[i].ip,
915*7836SJohn.Forte@Sun.COM 				    attr->value.ip, attr->len);
916*7836SJohn.Forte@Sun.COM 			} else {
917*7836SJohn.Forte@Sun.COM 				/* memory exhausted */
918*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_INTERNAL_ERROR;
919*7836SJohn.Forte@Sun.COM 			}
920*7836SJohn.Forte@Sun.COM 			break;
921*7836SJohn.Forte@Sun.COM 		case ISNS_PORTAL_PORT_ATTR_ID:
922*7836SJohn.Forte@Sun.COM 		case ISNS_ESI_PORT_ATTR_ID:
923*7836SJohn.Forte@Sun.COM 			attr = &obj->attrs[ATTR_INDEX_PORTAL(lcp->id[i])];
924*7836SJohn.Forte@Sun.COM 			if (attr->tag != 0 && attr->value.ui != 0) {
925*7836SJohn.Forte@Sun.COM 				lcp->data[i].ui = attr->value.ui;
926*7836SJohn.Forte@Sun.COM 			} else {
927*7836SJohn.Forte@Sun.COM 				lcp->data[i].ui = 0;
928*7836SJohn.Forte@Sun.COM 			}
929*7836SJohn.Forte@Sun.COM 			break;
930*7836SJohn.Forte@Sun.COM 		default:
931*7836SJohn.Forte@Sun.COM 			ASSERT(0);
932*7836SJohn.Forte@Sun.COM 			lcp->data[i].ui = 0;
933*7836SJohn.Forte@Sun.COM 			break;
934*7836SJohn.Forte@Sun.COM 		}
935*7836SJohn.Forte@Sun.COM 		i ++;
936*7836SJohn.Forte@Sun.COM 	}
937*7836SJohn.Forte@Sun.COM 
938*7836SJohn.Forte@Sun.COM 	return (ec);
939*7836SJohn.Forte@Sun.COM }
940*7836SJohn.Forte@Sun.COM 
941*7836SJohn.Forte@Sun.COM static matrix_t *
new_matrix(uint32_t x,uint32_t y)942*7836SJohn.Forte@Sun.COM new_matrix(
943*7836SJohn.Forte@Sun.COM 	uint32_t x,
944*7836SJohn.Forte@Sun.COM 	uint32_t y
945*7836SJohn.Forte@Sun.COM )
946*7836SJohn.Forte@Sun.COM {
947*7836SJohn.Forte@Sun.COM 	matrix_t *matrix;
948*7836SJohn.Forte@Sun.COM 
949*7836SJohn.Forte@Sun.COM 	matrix = (matrix_t *)malloc(sizeof (matrix_t));
950*7836SJohn.Forte@Sun.COM 	if (matrix != NULL) {
951*7836SJohn.Forte@Sun.COM 		matrix->x = x;
952*7836SJohn.Forte@Sun.COM 		matrix->y = y;
953*7836SJohn.Forte@Sun.COM 		matrix->m = (bmp_t *)calloc(y, SIZEOF_X_UNIT(matrix));
954*7836SJohn.Forte@Sun.COM 		if (matrix->m == NULL) {
955*7836SJohn.Forte@Sun.COM 			free(matrix);
956*7836SJohn.Forte@Sun.COM 			matrix = NULL;
957*7836SJohn.Forte@Sun.COM 		}
958*7836SJohn.Forte@Sun.COM 	}
959*7836SJohn.Forte@Sun.COM 
960*7836SJohn.Forte@Sun.COM 	return (matrix);
961*7836SJohn.Forte@Sun.COM }
962*7836SJohn.Forte@Sun.COM 
963*7836SJohn.Forte@Sun.COM int
dd_matrix_init(struct cache * c)964*7836SJohn.Forte@Sun.COM dd_matrix_init(
965*7836SJohn.Forte@Sun.COM 	struct cache *c
966*7836SJohn.Forte@Sun.COM )
967*7836SJohn.Forte@Sun.COM {
968*7836SJohn.Forte@Sun.COM 	matrix_t *x;
969*7836SJohn.Forte@Sun.COM 	bmp_t *bmp;
970*7836SJohn.Forte@Sun.COM 	uint32_t primary;
971*7836SJohn.Forte@Sun.COM 	uint32_t second;
972*7836SJohn.Forte@Sun.COM 
973*7836SJohn.Forte@Sun.COM 	/*
974*7836SJohn.Forte@Sun.COM 	 * allocate an array of pointer for dd and dd-set matrix.
975*7836SJohn.Forte@Sun.COM 	 */
976*7836SJohn.Forte@Sun.COM 	c->x = (matrix_t **)calloc(2, sizeof (matrix_t *));
977*7836SJohn.Forte@Sun.COM 	if (c->x == NULL) {
978*7836SJohn.Forte@Sun.COM 		return (1);
979*7836SJohn.Forte@Sun.COM 	}
980*7836SJohn.Forte@Sun.COM 
981*7836SJohn.Forte@Sun.COM 	/*
982*7836SJohn.Forte@Sun.COM 	 * create dd matrix.
983*7836SJohn.Forte@Sun.COM 	 */
984*7836SJohn.Forte@Sun.COM 	x = new_matrix(8, 64);
985*7836SJohn.Forte@Sun.COM 	if (x != NULL) {
986*7836SJohn.Forte@Sun.COM 		x->c = c;
987*7836SJohn.Forte@Sun.COM 		c->x[0] = x;
988*7836SJohn.Forte@Sun.COM 	} else {
989*7836SJohn.Forte@Sun.COM 		return (1);
990*7836SJohn.Forte@Sun.COM 	}
991*7836SJohn.Forte@Sun.COM 
992*7836SJohn.Forte@Sun.COM 	/*
993*7836SJohn.Forte@Sun.COM 	 * Mark the first array on the y axis for Default DD.
994*7836SJohn.Forte@Sun.COM 	 */
995*7836SJohn.Forte@Sun.COM 	bmp = MATRIX_X_UNIT(x, 0);
996*7836SJohn.Forte@Sun.COM 	MATRIX_X_INFO(bmp) = ISNS_DEFAULT_DD_ID;
997*7836SJohn.Forte@Sun.COM 
998*7836SJohn.Forte@Sun.COM 	/*
999*7836SJohn.Forte@Sun.COM 	 * create dd set matrix.
1000*7836SJohn.Forte@Sun.COM 	 */
1001*7836SJohn.Forte@Sun.COM 	x = new_matrix(2, 16);
1002*7836SJohn.Forte@Sun.COM 	if (x != NULL) {
1003*7836SJohn.Forte@Sun.COM 		x->c = c;
1004*7836SJohn.Forte@Sun.COM 		c->x[1] = x;
1005*7836SJohn.Forte@Sun.COM 	} else {
1006*7836SJohn.Forte@Sun.COM 		return (1);
1007*7836SJohn.Forte@Sun.COM 	}
1008*7836SJohn.Forte@Sun.COM 
1009*7836SJohn.Forte@Sun.COM 	/*
1010*7836SJohn.Forte@Sun.COM 	 * Mark the first array on the y axis for Default DD-set.
1011*7836SJohn.Forte@Sun.COM 	 */
1012*7836SJohn.Forte@Sun.COM 	bmp = MATRIX_X_UNIT(x, 0);
1013*7836SJohn.Forte@Sun.COM 	MATRIX_X_INFO(bmp) = ISNS_DEFAULT_DD_SET_ID;
1014*7836SJohn.Forte@Sun.COM 
1015*7836SJohn.Forte@Sun.COM 	/*
1016*7836SJohn.Forte@Sun.COM 	 * Add Default DD as a member of Default DD-set.
1017*7836SJohn.Forte@Sun.COM 	 */
1018*7836SJohn.Forte@Sun.COM 	primary = GET_PRIMARY(ISNS_DEFAULT_DD_ID);
1019*7836SJohn.Forte@Sun.COM 	second = GET_SECOND(ISNS_DEFAULT_DD_ID);
1020*7836SJohn.Forte@Sun.COM 	SET_MEMBERSHIP(bmp, primary, second);
1021*7836SJohn.Forte@Sun.COM 
1022*7836SJohn.Forte@Sun.COM 	return (0);
1023*7836SJohn.Forte@Sun.COM }
1024*7836SJohn.Forte@Sun.COM 
1025*7836SJohn.Forte@Sun.COM static uint32_t
get_ds_id(matrix_t * matrix,uint32_t m_id,uint32_t curr_id)1026*7836SJohn.Forte@Sun.COM get_ds_id(
1027*7836SJohn.Forte@Sun.COM 	matrix_t *matrix,
1028*7836SJohn.Forte@Sun.COM 	uint32_t m_id,
1029*7836SJohn.Forte@Sun.COM 	uint32_t curr_id
1030*7836SJohn.Forte@Sun.COM )
1031*7836SJohn.Forte@Sun.COM {
1032*7836SJohn.Forte@Sun.COM 	bmp_t *bmp;
1033*7836SJohn.Forte@Sun.COM 	uint32_t primary = GET_PRIMARY(m_id);
1034*7836SJohn.Forte@Sun.COM 	uint32_t second = GET_SECOND(m_id);
1035*7836SJohn.Forte@Sun.COM 	uint32_t dd_id = 0;
1036*7836SJohn.Forte@Sun.COM 	uint32_t uid;
1037*7836SJohn.Forte@Sun.COM 	int i = 0;
1038*7836SJohn.Forte@Sun.COM 
1039*7836SJohn.Forte@Sun.COM 	if (matrix->x > primary) {
1040*7836SJohn.Forte@Sun.COM 		while (i < matrix->y) {
1041*7836SJohn.Forte@Sun.COM 			bmp = MATRIX_X_UNIT(matrix, i);
1042*7836SJohn.Forte@Sun.COM 			uid = MATRIX_X_INFO(bmp);
1043*7836SJohn.Forte@Sun.COM 			if (uid > curr_id &&
1044*7836SJohn.Forte@Sun.COM 			    TEST_MEMBERSHIP(bmp, primary, second) != 0) {
1045*7836SJohn.Forte@Sun.COM 				if (dd_id == 0 || uid < dd_id) {
1046*7836SJohn.Forte@Sun.COM 					dd_id = uid;
1047*7836SJohn.Forte@Sun.COM 				}
1048*7836SJohn.Forte@Sun.COM 			}
1049*7836SJohn.Forte@Sun.COM 			i ++;
1050*7836SJohn.Forte@Sun.COM 		}
1051*7836SJohn.Forte@Sun.COM 	}
1052*7836SJohn.Forte@Sun.COM 
1053*7836SJohn.Forte@Sun.COM 	return (dd_id);
1054*7836SJohn.Forte@Sun.COM }
1055*7836SJohn.Forte@Sun.COM 
1056*7836SJohn.Forte@Sun.COM uint32_t
get_common_dd(uint32_t m_id1,uint32_t m_id2,uint32_t curr_id)1057*7836SJohn.Forte@Sun.COM get_common_dd(
1058*7836SJohn.Forte@Sun.COM 	uint32_t m_id1,
1059*7836SJohn.Forte@Sun.COM 	uint32_t m_id2,
1060*7836SJohn.Forte@Sun.COM 	uint32_t curr_id
1061*7836SJohn.Forte@Sun.COM )
1062*7836SJohn.Forte@Sun.COM {
1063*7836SJohn.Forte@Sun.COM 	matrix_t *matrix;
1064*7836SJohn.Forte@Sun.COM 
1065*7836SJohn.Forte@Sun.COM 	bmp_t *bmp;
1066*7836SJohn.Forte@Sun.COM 	uint32_t primary1 = GET_PRIMARY(m_id1);
1067*7836SJohn.Forte@Sun.COM 	uint32_t second1 = GET_SECOND(m_id1);
1068*7836SJohn.Forte@Sun.COM 	uint32_t primary2 = GET_PRIMARY(m_id2);
1069*7836SJohn.Forte@Sun.COM 	uint32_t second2 = GET_SECOND(m_id2);
1070*7836SJohn.Forte@Sun.COM 	uint32_t dd_id = 0;
1071*7836SJohn.Forte@Sun.COM 	int i = 0;
1072*7836SJohn.Forte@Sun.COM 
1073*7836SJohn.Forte@Sun.COM 	matrix = cache_get_matrix(OBJ_DD);
1074*7836SJohn.Forte@Sun.COM 
1075*7836SJohn.Forte@Sun.COM 	if (matrix->x > primary1 && matrix->x > primary2) {
1076*7836SJohn.Forte@Sun.COM 		while (i < matrix->y) {
1077*7836SJohn.Forte@Sun.COM 			bmp = MATRIX_X_UNIT(matrix, i);
1078*7836SJohn.Forte@Sun.COM 			if (MATRIX_X_INFO(bmp) > curr_id &&
1079*7836SJohn.Forte@Sun.COM 			    TEST_MEMBERSHIP(bmp, primary1, second1) != 0 &&
1080*7836SJohn.Forte@Sun.COM 			    TEST_MEMBERSHIP(bmp, primary2, second2) != 0) {
1081*7836SJohn.Forte@Sun.COM 				dd_id = MATRIX_X_INFO(bmp);
1082*7836SJohn.Forte@Sun.COM 				break;
1083*7836SJohn.Forte@Sun.COM 			}
1084*7836SJohn.Forte@Sun.COM 			i ++;
1085*7836SJohn.Forte@Sun.COM 		}
1086*7836SJohn.Forte@Sun.COM 	}
1087*7836SJohn.Forte@Sun.COM 
1088*7836SJohn.Forte@Sun.COM 	return (dd_id);
1089*7836SJohn.Forte@Sun.COM }
1090*7836SJohn.Forte@Sun.COM 
1091*7836SJohn.Forte@Sun.COM uint32_t
get_dd_id(uint32_t m_id,uint32_t curr_id)1092*7836SJohn.Forte@Sun.COM get_dd_id(
1093*7836SJohn.Forte@Sun.COM 	uint32_t m_id,
1094*7836SJohn.Forte@Sun.COM 	uint32_t curr_id
1095*7836SJohn.Forte@Sun.COM )
1096*7836SJohn.Forte@Sun.COM {
1097*7836SJohn.Forte@Sun.COM 	matrix_t *matrix = cache_get_matrix(OBJ_DD);
1098*7836SJohn.Forte@Sun.COM 
1099*7836SJohn.Forte@Sun.COM 	return (get_ds_id(matrix, m_id, curr_id));
1100*7836SJohn.Forte@Sun.COM }
1101*7836SJohn.Forte@Sun.COM 
1102*7836SJohn.Forte@Sun.COM uint32_t
get_dds_id(uint32_t m_id,uint32_t curr_id)1103*7836SJohn.Forte@Sun.COM get_dds_id(
1104*7836SJohn.Forte@Sun.COM 	uint32_t m_id,
1105*7836SJohn.Forte@Sun.COM 	uint32_t curr_id
1106*7836SJohn.Forte@Sun.COM )
1107*7836SJohn.Forte@Sun.COM {
1108*7836SJohn.Forte@Sun.COM 	matrix_t *matrix = cache_get_matrix(OBJ_DDS);
1109*7836SJohn.Forte@Sun.COM 
1110*7836SJohn.Forte@Sun.COM 	return (get_ds_id(matrix, m_id, curr_id));
1111*7836SJohn.Forte@Sun.COM }
1112*7836SJohn.Forte@Sun.COM 
1113*7836SJohn.Forte@Sun.COM static int
create_ds_object(isns_type_t type,isns_obj_t ** ds_p,isns_attr_t * name_attr,isns_attr_t * uid_attr,isns_attr_t * status_attr)1114*7836SJohn.Forte@Sun.COM create_ds_object(
1115*7836SJohn.Forte@Sun.COM 	isns_type_t type,
1116*7836SJohn.Forte@Sun.COM 	isns_obj_t **ds_p,
1117*7836SJohn.Forte@Sun.COM 	isns_attr_t *name_attr,
1118*7836SJohn.Forte@Sun.COM 	isns_attr_t *uid_attr,
1119*7836SJohn.Forte@Sun.COM 	isns_attr_t *status_attr
1120*7836SJohn.Forte@Sun.COM )
1121*7836SJohn.Forte@Sun.COM {
1122*7836SJohn.Forte@Sun.COM 	int ec = 0;
1123*7836SJohn.Forte@Sun.COM 
1124*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
1125*7836SJohn.Forte@Sun.COM 	int id1, id2, id3;
1126*7836SJohn.Forte@Sun.COM 
1127*7836SJohn.Forte@Sun.COM 	if (type == OBJ_DD) {
1128*7836SJohn.Forte@Sun.COM 		id1 = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
1129*7836SJohn.Forte@Sun.COM 		id2 = ATTR_INDEX_DD(ISNS_DD_ID_ATTR_ID);
1130*7836SJohn.Forte@Sun.COM 		id3 = ATTR_INDEX_DD(ISNS_DD_FEATURES_ATTR_ID);
1131*7836SJohn.Forte@Sun.COM 	} else {
1132*7836SJohn.Forte@Sun.COM 		ASSERT(type == OBJ_DDS);
1133*7836SJohn.Forte@Sun.COM 		id1 = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
1134*7836SJohn.Forte@Sun.COM 		id2 = ATTR_INDEX_DDS(ISNS_DD_SET_ID_ATTR_ID);
1135*7836SJohn.Forte@Sun.COM 		id3 = ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID);
1136*7836SJohn.Forte@Sun.COM 	}
1137*7836SJohn.Forte@Sun.COM 
1138*7836SJohn.Forte@Sun.COM 	obj = obj_calloc(type);
1139*7836SJohn.Forte@Sun.COM 	if (obj != NULL &&
1140*7836SJohn.Forte@Sun.COM 	    (name_attr != NULL && name_attr->tag != 0 &&
1141*7836SJohn.Forte@Sun.COM 	    assign_attr(&obj->attrs[id1], name_attr) == 0) &&
1142*7836SJohn.Forte@Sun.COM 	    (uid_attr == NULL || uid_attr->value.ui == 0 ||
1143*7836SJohn.Forte@Sun.COM 	    assign_attr(&obj->attrs[id2], uid_attr) == 0) &&
1144*7836SJohn.Forte@Sun.COM 	    (status_attr == NULL || status_attr->value.ui == 0 ||
1145*7836SJohn.Forte@Sun.COM 	    assign_attr(&obj->attrs[id3], status_attr) == 0)) {
1146*7836SJohn.Forte@Sun.COM 		*ds_p = obj;
1147*7836SJohn.Forte@Sun.COM 	} else {
1148*7836SJohn.Forte@Sun.COM 		/* no memory */
1149*7836SJohn.Forte@Sun.COM 		free_object(obj);
1150*7836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
1151*7836SJohn.Forte@Sun.COM 	}
1152*7836SJohn.Forte@Sun.COM 
1153*7836SJohn.Forte@Sun.COM 	return (ec);
1154*7836SJohn.Forte@Sun.COM }
1155*7836SJohn.Forte@Sun.COM 
1156*7836SJohn.Forte@Sun.COM int
create_dd_object(isns_tlv_t * op,uint16_t op_len,isns_obj_t ** dd_p)1157*7836SJohn.Forte@Sun.COM create_dd_object(
1158*7836SJohn.Forte@Sun.COM 	isns_tlv_t *op,
1159*7836SJohn.Forte@Sun.COM 	uint16_t op_len,
1160*7836SJohn.Forte@Sun.COM 	isns_obj_t **dd_p
1161*7836SJohn.Forte@Sun.COM )
1162*7836SJohn.Forte@Sun.COM {
1163*7836SJohn.Forte@Sun.COM 	int ec = 0;
1164*7836SJohn.Forte@Sun.COM 	uint8_t *value;
1165*7836SJohn.Forte@Sun.COM 	isns_attr_t name = { 0 };
1166*7836SJohn.Forte@Sun.COM 	isns_attr_t dd_id = { 0 }, features = { 0 };
1167*7836SJohn.Forte@Sun.COM 
1168*7836SJohn.Forte@Sun.COM 	name.tag = ISNS_DD_NAME_ATTR_ID;
1169*7836SJohn.Forte@Sun.COM 
1170*7836SJohn.Forte@Sun.COM 	while (op_len > 8 && ec == 0) {
1171*7836SJohn.Forte@Sun.COM 		value = &op->attr_value[0];
1172*7836SJohn.Forte@Sun.COM 		switch (op->attr_id) {
1173*7836SJohn.Forte@Sun.COM 		case ISNS_DD_ID_ATTR_ID:
1174*7836SJohn.Forte@Sun.COM 			if (op->attr_len == 4) {
1175*7836SJohn.Forte@Sun.COM 				dd_id.tag = ISNS_DD_ID_ATTR_ID;
1176*7836SJohn.Forte@Sun.COM 				dd_id.len = 4;
1177*7836SJohn.Forte@Sun.COM 				dd_id.value.ui = ntohl(*(uint32_t *)value);
1178*7836SJohn.Forte@Sun.COM 			} else if (op->attr_len != 0) {
1179*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
1180*7836SJohn.Forte@Sun.COM 			}
1181*7836SJohn.Forte@Sun.COM 			break;
1182*7836SJohn.Forte@Sun.COM 		case ISNS_DD_NAME_ATTR_ID:
1183*7836SJohn.Forte@Sun.COM 			if (op->attr_len > 0 &&
1184*7836SJohn.Forte@Sun.COM 			    op->attr_len <= 256) {
1185*7836SJohn.Forte@Sun.COM 				name.len = op->attr_len;
1186*7836SJohn.Forte@Sun.COM 				name.value.ptr = (uchar_t *)value;
1187*7836SJohn.Forte@Sun.COM 			} else if (op->attr_len != 0) {
1188*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
1189*7836SJohn.Forte@Sun.COM 			}
1190*7836SJohn.Forte@Sun.COM 			break;
1191*7836SJohn.Forte@Sun.COM 		case ISNS_DD_ISCSI_INDEX_ATTR_ID:
1192*7836SJohn.Forte@Sun.COM 		case ISNS_DD_ISCSI_NAME_ATTR_ID:
1193*7836SJohn.Forte@Sun.COM 			break;
1194*7836SJohn.Forte@Sun.COM 		case ISNS_DD_FC_PORT_NAME_ATTR_ID:
1195*7836SJohn.Forte@Sun.COM 		case ISNS_DD_PORTAL_INDEX_ATTR_ID:
1196*7836SJohn.Forte@Sun.COM 		case ISNS_DD_PORTAL_IP_ADDR_ATTR_ID:
1197*7836SJohn.Forte@Sun.COM 		case ISNS_DD_PORTAL_PORT_ATTR_ID:
1198*7836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_REGIS_NOT_SUPPORTED;
1199*7836SJohn.Forte@Sun.COM 			break;
1200*7836SJohn.Forte@Sun.COM 		case ISNS_DD_FEATURES_ATTR_ID:
1201*7836SJohn.Forte@Sun.COM 			if (op->attr_len == 4) {
1202*7836SJohn.Forte@Sun.COM 				features.tag = ISNS_DD_FEATURES_ATTR_ID;
1203*7836SJohn.Forte@Sun.COM 				features.len = op->attr_len;
1204*7836SJohn.Forte@Sun.COM 				features.value.ui = ntohl(*(uint32_t *)value);
1205*7836SJohn.Forte@Sun.COM 			} else if (op->attr_len != 0) {
1206*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
1207*7836SJohn.Forte@Sun.COM 			}
1208*7836SJohn.Forte@Sun.COM 			break;
1209*7836SJohn.Forte@Sun.COM 		default:
1210*7836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INVALID_REGIS;
1211*7836SJohn.Forte@Sun.COM 			break;
1212*7836SJohn.Forte@Sun.COM 		}
1213*7836SJohn.Forte@Sun.COM 		NEXT_TLV(op, op_len);
1214*7836SJohn.Forte@Sun.COM 	}
1215*7836SJohn.Forte@Sun.COM 
1216*7836SJohn.Forte@Sun.COM 	if (ec == 0) {
1217*7836SJohn.Forte@Sun.COM 		ec = create_ds_object(OBJ_DD, dd_p,
1218*7836SJohn.Forte@Sun.COM 		    &name, &dd_id, &features);
1219*7836SJohn.Forte@Sun.COM 	}
1220*7836SJohn.Forte@Sun.COM 
1221*7836SJohn.Forte@Sun.COM 	return (ec);
1222*7836SJohn.Forte@Sun.COM }
1223*7836SJohn.Forte@Sun.COM 
1224*7836SJohn.Forte@Sun.COM int
create_dds_object(isns_tlv_t * op,uint16_t op_len,isns_obj_t ** dds_p)1225*7836SJohn.Forte@Sun.COM create_dds_object(
1226*7836SJohn.Forte@Sun.COM 	isns_tlv_t *op,
1227*7836SJohn.Forte@Sun.COM 	uint16_t op_len,
1228*7836SJohn.Forte@Sun.COM 	isns_obj_t **dds_p
1229*7836SJohn.Forte@Sun.COM )
1230*7836SJohn.Forte@Sun.COM {
1231*7836SJohn.Forte@Sun.COM 	int ec = 0;
1232*7836SJohn.Forte@Sun.COM 	uint8_t *value;
1233*7836SJohn.Forte@Sun.COM 	isns_attr_t name = { 0 };
1234*7836SJohn.Forte@Sun.COM 	isns_attr_t dds_id = { 0 }, code = { 0 };
1235*7836SJohn.Forte@Sun.COM 
1236*7836SJohn.Forte@Sun.COM 	name.tag = ISNS_DD_SET_NAME_ATTR_ID;
1237*7836SJohn.Forte@Sun.COM 
1238*7836SJohn.Forte@Sun.COM 	while (op_len > 8 && ec == 0) {
1239*7836SJohn.Forte@Sun.COM 		value = &op->attr_value[0];
1240*7836SJohn.Forte@Sun.COM 		switch (op->attr_id) {
1241*7836SJohn.Forte@Sun.COM 		case ISNS_DD_SET_ID_ATTR_ID:
1242*7836SJohn.Forte@Sun.COM 			if (op->attr_len == 4) {
1243*7836SJohn.Forte@Sun.COM 				dds_id.tag = ISNS_DD_ID_ATTR_ID;
1244*7836SJohn.Forte@Sun.COM 				dds_id.len = 4;
1245*7836SJohn.Forte@Sun.COM 				dds_id.value.ui = ntohl(*(uint32_t *)value);
1246*7836SJohn.Forte@Sun.COM 			} else if (op->attr_len != 0) {
1247*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
1248*7836SJohn.Forte@Sun.COM 			}
1249*7836SJohn.Forte@Sun.COM 			break;
1250*7836SJohn.Forte@Sun.COM 		case ISNS_DD_SET_NAME_ATTR_ID:
1251*7836SJohn.Forte@Sun.COM 			if (op->attr_len > 0 &&
1252*7836SJohn.Forte@Sun.COM 			    op->attr_len <= 256) {
1253*7836SJohn.Forte@Sun.COM 				name.len = op->attr_len;
1254*7836SJohn.Forte@Sun.COM 				name.value.ptr = (uchar_t *)value;
1255*7836SJohn.Forte@Sun.COM 			} else if (op->attr_len != 0) {
1256*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
1257*7836SJohn.Forte@Sun.COM 			}
1258*7836SJohn.Forte@Sun.COM 			break;
1259*7836SJohn.Forte@Sun.COM 		case ISNS_DD_SET_STATUS_ATTR_ID:
1260*7836SJohn.Forte@Sun.COM 			if (op->attr_len == 4) {
1261*7836SJohn.Forte@Sun.COM 				code.tag = ISNS_DD_SET_STATUS_ATTR_ID;
1262*7836SJohn.Forte@Sun.COM 				code.len = op->attr_len;
1263*7836SJohn.Forte@Sun.COM 				code.value.ui = ntohl(*(uint32_t *)value);
1264*7836SJohn.Forte@Sun.COM 			} else if (op->attr_len != 0) {
1265*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
1266*7836SJohn.Forte@Sun.COM 			}
1267*7836SJohn.Forte@Sun.COM 			break;
1268*7836SJohn.Forte@Sun.COM 		case ISNS_DD_ID_ATTR_ID:
1269*7836SJohn.Forte@Sun.COM 			break;
1270*7836SJohn.Forte@Sun.COM 		default:
1271*7836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INVALID_REGIS;
1272*7836SJohn.Forte@Sun.COM 			break;
1273*7836SJohn.Forte@Sun.COM 		}
1274*7836SJohn.Forte@Sun.COM 		NEXT_TLV(op, op_len);
1275*7836SJohn.Forte@Sun.COM 	}
1276*7836SJohn.Forte@Sun.COM 
1277*7836SJohn.Forte@Sun.COM 	if (ec == 0) {
1278*7836SJohn.Forte@Sun.COM 		ec = create_ds_object(OBJ_DDS, dds_p,
1279*7836SJohn.Forte@Sun.COM 		    &name, &dds_id, &code);
1280*7836SJohn.Forte@Sun.COM 	}
1281*7836SJohn.Forte@Sun.COM 
1282*7836SJohn.Forte@Sun.COM 	return (ec);
1283*7836SJohn.Forte@Sun.COM }
1284*7836SJohn.Forte@Sun.COM 
1285*7836SJohn.Forte@Sun.COM int
adm_create_dd(isns_obj_t ** dd_p,uchar_t * name,uint32_t uid,uint32_t features)1286*7836SJohn.Forte@Sun.COM adm_create_dd(
1287*7836SJohn.Forte@Sun.COM 	isns_obj_t **dd_p,
1288*7836SJohn.Forte@Sun.COM 	uchar_t *name,
1289*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1290*7836SJohn.Forte@Sun.COM 	uint32_t features
1291*7836SJohn.Forte@Sun.COM )
1292*7836SJohn.Forte@Sun.COM {
1293*7836SJohn.Forte@Sun.COM 	uint32_t len;
1294*7836SJohn.Forte@Sun.COM 	isns_attr_t name_attr = { 0 };
1295*7836SJohn.Forte@Sun.COM 	isns_attr_t uid_attr = { 0 };
1296*7836SJohn.Forte@Sun.COM 	isns_attr_t features_attr = { 0 };
1297*7836SJohn.Forte@Sun.COM 
1298*7836SJohn.Forte@Sun.COM 	name_attr.tag = ISNS_DD_NAME_ATTR_ID;
1299*7836SJohn.Forte@Sun.COM 	if (name != NULL) {
1300*7836SJohn.Forte@Sun.COM 		/* need to include the null terminator */
1301*7836SJohn.Forte@Sun.COM 		/* and be on 4 bytes aligned */
1302*7836SJohn.Forte@Sun.COM 		len = strlen((char *)name) + 1;
1303*7836SJohn.Forte@Sun.COM 		len += 4 - (len % 4);
1304*7836SJohn.Forte@Sun.COM 		name_attr.len = len;
1305*7836SJohn.Forte@Sun.COM 		name_attr.value.ptr = name;
1306*7836SJohn.Forte@Sun.COM 	}
1307*7836SJohn.Forte@Sun.COM 
1308*7836SJohn.Forte@Sun.COM 	uid_attr.tag = ISNS_DD_ID_ATTR_ID;
1309*7836SJohn.Forte@Sun.COM 	uid_attr.len = 4;
1310*7836SJohn.Forte@Sun.COM 	uid_attr.value.ui = uid;
1311*7836SJohn.Forte@Sun.COM 
1312*7836SJohn.Forte@Sun.COM 	features_attr.tag = ISNS_DD_FEATURES_ATTR_ID;
1313*7836SJohn.Forte@Sun.COM 	features_attr.len = 4;
1314*7836SJohn.Forte@Sun.COM 	features_attr.value.ui = features;
1315*7836SJohn.Forte@Sun.COM 
1316*7836SJohn.Forte@Sun.COM 	return (create_ds_object(OBJ_DD, dd_p,
1317*7836SJohn.Forte@Sun.COM 	    &name_attr, &uid_attr, &features_attr));
1318*7836SJohn.Forte@Sun.COM }
1319*7836SJohn.Forte@Sun.COM 
1320*7836SJohn.Forte@Sun.COM int
adm_create_dds(isns_obj_t ** dds_p,uchar_t * name,uint32_t uid,uint32_t code)1321*7836SJohn.Forte@Sun.COM adm_create_dds(
1322*7836SJohn.Forte@Sun.COM 	isns_obj_t **dds_p,
1323*7836SJohn.Forte@Sun.COM 	uchar_t *name,
1324*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1325*7836SJohn.Forte@Sun.COM 	uint32_t code
1326*7836SJohn.Forte@Sun.COM )
1327*7836SJohn.Forte@Sun.COM {
1328*7836SJohn.Forte@Sun.COM 	uint32_t len;
1329*7836SJohn.Forte@Sun.COM 	isns_attr_t name_attr = { 0 };
1330*7836SJohn.Forte@Sun.COM 	isns_attr_t uid_attr = { 0 };
1331*7836SJohn.Forte@Sun.COM 	isns_attr_t code_attr = { 0 };
1332*7836SJohn.Forte@Sun.COM 
1333*7836SJohn.Forte@Sun.COM 	name_attr.tag = ISNS_DD_SET_NAME_ATTR_ID;
1334*7836SJohn.Forte@Sun.COM 	if (name != NULL) {
1335*7836SJohn.Forte@Sun.COM 		/* need to include the null terminator */
1336*7836SJohn.Forte@Sun.COM 		/* and be on 4 bytes aligned */
1337*7836SJohn.Forte@Sun.COM 		len = strlen((char *)name) + 1;
1338*7836SJohn.Forte@Sun.COM 		len += 4 - (len % 4);
1339*7836SJohn.Forte@Sun.COM 		name_attr.len = len;
1340*7836SJohn.Forte@Sun.COM 		name_attr.value.ptr = name;
1341*7836SJohn.Forte@Sun.COM 	}
1342*7836SJohn.Forte@Sun.COM 
1343*7836SJohn.Forte@Sun.COM 	uid_attr.tag = ISNS_DD_SET_ID_ATTR_ID;
1344*7836SJohn.Forte@Sun.COM 	uid_attr.len = 4;
1345*7836SJohn.Forte@Sun.COM 	uid_attr.value.ui = uid;
1346*7836SJohn.Forte@Sun.COM 
1347*7836SJohn.Forte@Sun.COM 	code_attr.tag = ISNS_DD_SET_STATUS_ATTR_ID;
1348*7836SJohn.Forte@Sun.COM 	code_attr.len = 4;
1349*7836SJohn.Forte@Sun.COM 	code_attr.value.ui = code;
1350*7836SJohn.Forte@Sun.COM 
1351*7836SJohn.Forte@Sun.COM 	return (create_ds_object(OBJ_DDS, dds_p,
1352*7836SJohn.Forte@Sun.COM 	    &name_attr, &uid_attr, &code_attr));
1353*7836SJohn.Forte@Sun.COM }
1354*7836SJohn.Forte@Sun.COM 
1355*7836SJohn.Forte@Sun.COM static int
update_ds_name(isns_type_t type,uint32_t uid,uint32_t tag,uint32_t len,uchar_t * name)1356*7836SJohn.Forte@Sun.COM update_ds_name(
1357*7836SJohn.Forte@Sun.COM 	isns_type_t type,
1358*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1359*7836SJohn.Forte@Sun.COM 	uint32_t tag,
1360*7836SJohn.Forte@Sun.COM 	uint32_t len,
1361*7836SJohn.Forte@Sun.COM 	uchar_t *name
1362*7836SJohn.Forte@Sun.COM )
1363*7836SJohn.Forte@Sun.COM {
1364*7836SJohn.Forte@Sun.COM 	int ec = 0;
1365*7836SJohn.Forte@Sun.COM 
1366*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1367*7836SJohn.Forte@Sun.COM 
1368*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, type, uid);
1369*7836SJohn.Forte@Sun.COM 
1370*7836SJohn.Forte@Sun.COM 	lc.id[1] = tag;
1371*7836SJohn.Forte@Sun.COM 	lc.data[1].ui = len;
1372*7836SJohn.Forte@Sun.COM 	lc.data[2].ptr = name;
1373*7836SJohn.Forte@Sun.COM 
1374*7836SJohn.Forte@Sun.COM 	ec = cache_rekey(&lc, &uid, cb_update_ds_attr);
1375*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
1376*7836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INVALID_REGIS;
1377*7836SJohn.Forte@Sun.COM 	}
1378*7836SJohn.Forte@Sun.COM 
1379*7836SJohn.Forte@Sun.COM 	return (ec);
1380*7836SJohn.Forte@Sun.COM }
1381*7836SJohn.Forte@Sun.COM 
1382*7836SJohn.Forte@Sun.COM int
update_dd_name(uint32_t uid,uint32_t len,uchar_t * name)1383*7836SJohn.Forte@Sun.COM update_dd_name(
1384*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1385*7836SJohn.Forte@Sun.COM 	uint32_t len,
1386*7836SJohn.Forte@Sun.COM 	uchar_t *name
1387*7836SJohn.Forte@Sun.COM )
1388*7836SJohn.Forte@Sun.COM {
1389*7836SJohn.Forte@Sun.COM 	/*
1390*7836SJohn.Forte@Sun.COM 	 * We do now allow changing the default DD and DD-set name.
1391*7836SJohn.Forte@Sun.COM 	 */
1392*7836SJohn.Forte@Sun.COM 	if (uid == ISNS_DEFAULT_DD_ID) {
1393*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1394*7836SJohn.Forte@Sun.COM 	}
1395*7836SJohn.Forte@Sun.COM 
1396*7836SJohn.Forte@Sun.COM 	return (update_ds_name(OBJ_DD, uid, ISNS_DD_NAME_ATTR_ID, len, name));
1397*7836SJohn.Forte@Sun.COM }
1398*7836SJohn.Forte@Sun.COM 
1399*7836SJohn.Forte@Sun.COM int
update_dds_name(uint32_t uid,uint32_t len,uchar_t * name)1400*7836SJohn.Forte@Sun.COM update_dds_name(
1401*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1402*7836SJohn.Forte@Sun.COM 	uint32_t len,
1403*7836SJohn.Forte@Sun.COM 	uchar_t *name
1404*7836SJohn.Forte@Sun.COM )
1405*7836SJohn.Forte@Sun.COM {
1406*7836SJohn.Forte@Sun.COM 	/*
1407*7836SJohn.Forte@Sun.COM 	 * We do now allow changing the default DD and DD-set name.
1408*7836SJohn.Forte@Sun.COM 	 */
1409*7836SJohn.Forte@Sun.COM 	if (uid == ISNS_DEFAULT_DD_ID) {
1410*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1411*7836SJohn.Forte@Sun.COM 	}
1412*7836SJohn.Forte@Sun.COM 
1413*7836SJohn.Forte@Sun.COM 	return (update_ds_name(OBJ_DDS, uid,
1414*7836SJohn.Forte@Sun.COM 	    ISNS_DD_SET_NAME_ATTR_ID, len, name));
1415*7836SJohn.Forte@Sun.COM }
1416*7836SJohn.Forte@Sun.COM 
1417*7836SJohn.Forte@Sun.COM static int
update_ds_uint32(isns_type_t type,uint32_t uid,uint32_t tag,uint32_t value)1418*7836SJohn.Forte@Sun.COM update_ds_uint32(
1419*7836SJohn.Forte@Sun.COM 	isns_type_t type,
1420*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1421*7836SJohn.Forte@Sun.COM 	uint32_t tag,
1422*7836SJohn.Forte@Sun.COM 	uint32_t value
1423*7836SJohn.Forte@Sun.COM )
1424*7836SJohn.Forte@Sun.COM {
1425*7836SJohn.Forte@Sun.COM 	int ec = 0;
1426*7836SJohn.Forte@Sun.COM 
1427*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1428*7836SJohn.Forte@Sun.COM 
1429*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, type, uid);
1430*7836SJohn.Forte@Sun.COM 
1431*7836SJohn.Forte@Sun.COM 	lc.id[1] = tag;
1432*7836SJohn.Forte@Sun.COM 	lc.data[1].ui = value;
1433*7836SJohn.Forte@Sun.COM 
1434*7836SJohn.Forte@Sun.COM 	ec = cache_lookup(&lc, &uid, cb_update_ds_attr);
1435*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
1436*7836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INVALID_REGIS;
1437*7836SJohn.Forte@Sun.COM 	}
1438*7836SJohn.Forte@Sun.COM 
1439*7836SJohn.Forte@Sun.COM 	return (ec);
1440*7836SJohn.Forte@Sun.COM }
1441*7836SJohn.Forte@Sun.COM 
1442*7836SJohn.Forte@Sun.COM int
update_dd_features(uint32_t uid,uint32_t features)1443*7836SJohn.Forte@Sun.COM update_dd_features(
1444*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1445*7836SJohn.Forte@Sun.COM 	uint32_t features
1446*7836SJohn.Forte@Sun.COM )
1447*7836SJohn.Forte@Sun.COM {
1448*7836SJohn.Forte@Sun.COM 	return (update_ds_uint32(OBJ_DD, uid,
1449*7836SJohn.Forte@Sun.COM 	    ISNS_DD_FEATURES_ATTR_ID, features));
1450*7836SJohn.Forte@Sun.COM }
1451*7836SJohn.Forte@Sun.COM 
1452*7836SJohn.Forte@Sun.COM int
update_dds_status(uint32_t uid,uint32_t enabled)1453*7836SJohn.Forte@Sun.COM update_dds_status(
1454*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1455*7836SJohn.Forte@Sun.COM 	uint32_t enabled
1456*7836SJohn.Forte@Sun.COM )
1457*7836SJohn.Forte@Sun.COM {
1458*7836SJohn.Forte@Sun.COM 	return (update_ds_uint32(OBJ_DDS, uid,
1459*7836SJohn.Forte@Sun.COM 	    ISNS_DD_SET_STATUS_ATTR_ID, enabled));
1460*7836SJohn.Forte@Sun.COM }
1461*7836SJohn.Forte@Sun.COM 
1462*7836SJohn.Forte@Sun.COM int
add_dd_member(isns_obj_t * assoc)1463*7836SJohn.Forte@Sun.COM add_dd_member(
1464*7836SJohn.Forte@Sun.COM 	isns_obj_t *assoc
1465*7836SJohn.Forte@Sun.COM )
1466*7836SJohn.Forte@Sun.COM {
1467*7836SJohn.Forte@Sun.COM 	int ec = 0;
1468*7836SJohn.Forte@Sun.COM 
1469*7836SJohn.Forte@Sun.COM 	uint32_t dd_id;
1470*7836SJohn.Forte@Sun.COM 	uint32_t m_id, m_type;
1471*7836SJohn.Forte@Sun.COM 
1472*7836SJohn.Forte@Sun.COM 	dd_id = get_parent_uid(assoc);
1473*7836SJohn.Forte@Sun.COM 	/*
1474*7836SJohn.Forte@Sun.COM 	 * We do now allow placing any node to the default DD explicitly.
1475*7836SJohn.Forte@Sun.COM 	 */
1476*7836SJohn.Forte@Sun.COM 	if (dd_id == ISNS_DEFAULT_DD_ID) {
1477*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1478*7836SJohn.Forte@Sun.COM 	}
1479*7836SJohn.Forte@Sun.COM 
1480*7836SJohn.Forte@Sun.COM 	ec = get_member_info(assoc, &m_type, &m_id, 1);
1481*7836SJohn.Forte@Sun.COM 	if (ec == 0) {
1482*7836SJohn.Forte@Sun.COM 		ec = update_dd_matrix(
1483*7836SJohn.Forte@Sun.COM 		    '+', /* add member */
1484*7836SJohn.Forte@Sun.COM 		    dd_id,
1485*7836SJohn.Forte@Sun.COM 		    m_type,
1486*7836SJohn.Forte@Sun.COM 		    m_id);
1487*7836SJohn.Forte@Sun.COM 	}
1488*7836SJohn.Forte@Sun.COM 
1489*7836SJohn.Forte@Sun.COM 	if (ec == 0) {
1490*7836SJohn.Forte@Sun.COM 		if (sys_q != NULL) {
1491*7836SJohn.Forte@Sun.COM 			/* add the membership to data store */
1492*7836SJohn.Forte@Sun.COM 			ec = write_data(DATA_ADD, assoc);
1493*7836SJohn.Forte@Sun.COM 		}
1494*7836SJohn.Forte@Sun.COM 
1495*7836SJohn.Forte@Sun.COM 		/* trigger a management scn */
1496*7836SJohn.Forte@Sun.COM 		if (ec == 0 && scn_q != NULL) {
1497*7836SJohn.Forte@Sun.COM 			(void) make_scn(ISNS_MEMBER_ADDED, assoc);
1498*7836SJohn.Forte@Sun.COM 		}
1499*7836SJohn.Forte@Sun.COM 	}
1500*7836SJohn.Forte@Sun.COM 
1501*7836SJohn.Forte@Sun.COM 	return (ec);
1502*7836SJohn.Forte@Sun.COM }
1503*7836SJohn.Forte@Sun.COM 
1504*7836SJohn.Forte@Sun.COM int
add_dds_member(isns_obj_t * assoc)1505*7836SJohn.Forte@Sun.COM add_dds_member(
1506*7836SJohn.Forte@Sun.COM 	isns_obj_t *assoc
1507*7836SJohn.Forte@Sun.COM )
1508*7836SJohn.Forte@Sun.COM {
1509*7836SJohn.Forte@Sun.COM 	int ec = 0;
1510*7836SJohn.Forte@Sun.COM 
1511*7836SJohn.Forte@Sun.COM 	uint32_t m_id = assoc->attrs[ATTR_INDEX_ASSOC_DD(
1512*7836SJohn.Forte@Sun.COM 	    ISNS_DD_ID_ATTR_ID)].value.ui;
1513*7836SJohn.Forte@Sun.COM 	uint32_t dds_id;
1514*7836SJohn.Forte@Sun.COM 
1515*7836SJohn.Forte@Sun.COM 	dds_id = get_parent_uid(assoc);
1516*7836SJohn.Forte@Sun.COM 	/*
1517*7836SJohn.Forte@Sun.COM 	 * We do now allow changing the membership of the default DD
1518*7836SJohn.Forte@Sun.COM 	 * and DD-set.
1519*7836SJohn.Forte@Sun.COM 	 */
1520*7836SJohn.Forte@Sun.COM 	if (dds_id == ISNS_DEFAULT_DD_SET_ID ||
1521*7836SJohn.Forte@Sun.COM 	    m_id == ISNS_DEFAULT_DD_ID) {
1522*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1523*7836SJohn.Forte@Sun.COM 	}
1524*7836SJohn.Forte@Sun.COM 
1525*7836SJohn.Forte@Sun.COM 	ec = get_dds_member_info(m_id);
1526*7836SJohn.Forte@Sun.COM 	if (ec == 0) {
1527*7836SJohn.Forte@Sun.COM 		ec = update_dds_matrix(
1528*7836SJohn.Forte@Sun.COM 		    '+', /* add member */
1529*7836SJohn.Forte@Sun.COM 		    dds_id,
1530*7836SJohn.Forte@Sun.COM 		    m_id);
1531*7836SJohn.Forte@Sun.COM 	}
1532*7836SJohn.Forte@Sun.COM 
1533*7836SJohn.Forte@Sun.COM 	if (ec == 0) {
1534*7836SJohn.Forte@Sun.COM 		if (sys_q != NULL) {
1535*7836SJohn.Forte@Sun.COM 			/* add the membership to data store */
1536*7836SJohn.Forte@Sun.COM 			ec = write_data(DATA_ADD, assoc);
1537*7836SJohn.Forte@Sun.COM 		}
1538*7836SJohn.Forte@Sun.COM 
1539*7836SJohn.Forte@Sun.COM 		/* trigger a management scn */
1540*7836SJohn.Forte@Sun.COM 		if (ec == 0 && scn_q != NULL) {
1541*7836SJohn.Forte@Sun.COM 			(void) make_scn(ISNS_MEMBER_ADDED, assoc);
1542*7836SJohn.Forte@Sun.COM 		}
1543*7836SJohn.Forte@Sun.COM 	}
1544*7836SJohn.Forte@Sun.COM 
1545*7836SJohn.Forte@Sun.COM 	return (ec);
1546*7836SJohn.Forte@Sun.COM }
1547*7836SJohn.Forte@Sun.COM 
1548*7836SJohn.Forte@Sun.COM int
remove_dd_member(isns_obj_t * assoc)1549*7836SJohn.Forte@Sun.COM remove_dd_member(
1550*7836SJohn.Forte@Sun.COM 	isns_obj_t *assoc
1551*7836SJohn.Forte@Sun.COM )
1552*7836SJohn.Forte@Sun.COM {
1553*7836SJohn.Forte@Sun.COM 	int ec = 0;
1554*7836SJohn.Forte@Sun.COM 
1555*7836SJohn.Forte@Sun.COM 	uint32_t dd_id;
1556*7836SJohn.Forte@Sun.COM 	uint32_t m_type;
1557*7836SJohn.Forte@Sun.COM 	uint32_t m_id;
1558*7836SJohn.Forte@Sun.COM 
1559*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1560*7836SJohn.Forte@Sun.COM 
1561*7836SJohn.Forte@Sun.COM 	dd_id = get_parent_uid(assoc);
1562*7836SJohn.Forte@Sun.COM 	/*
1563*7836SJohn.Forte@Sun.COM 	 * We do now allow removing the member from default DD explicitly.
1564*7836SJohn.Forte@Sun.COM 	 */
1565*7836SJohn.Forte@Sun.COM 	if (dd_id == ISNS_DEFAULT_DD_ID) {
1566*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1567*7836SJohn.Forte@Sun.COM 	}
1568*7836SJohn.Forte@Sun.COM 
1569*7836SJohn.Forte@Sun.COM 	ec = get_member_info(assoc, &m_type, &m_id, 0);
1570*7836SJohn.Forte@Sun.COM 	if (ec == 0) {
1571*7836SJohn.Forte@Sun.COM 		ec = update_dd_matrix(
1572*7836SJohn.Forte@Sun.COM 		    '-', /* remove member */
1573*7836SJohn.Forte@Sun.COM 		    dd_id,
1574*7836SJohn.Forte@Sun.COM 		    m_type,
1575*7836SJohn.Forte@Sun.COM 		    m_id);
1576*7836SJohn.Forte@Sun.COM 		if (ec == 0) {
1577*7836SJohn.Forte@Sun.COM 			/* update data store */
1578*7836SJohn.Forte@Sun.COM 			if (sys_q != NULL) {
1579*7836SJohn.Forte@Sun.COM 				/* remove it from data store */
1580*7836SJohn.Forte@Sun.COM 				ec = write_data(
1581*7836SJohn.Forte@Sun.COM 				    DATA_DELETE_ASSOC, assoc);
1582*7836SJohn.Forte@Sun.COM 			}
1583*7836SJohn.Forte@Sun.COM 
1584*7836SJohn.Forte@Sun.COM 			/* trigger a management scn */
1585*7836SJohn.Forte@Sun.COM 			if (ec == 0 && scn_q != NULL) {
1586*7836SJohn.Forte@Sun.COM 				(void) make_scn(ISNS_MEMBER_REMOVED, assoc);
1587*7836SJohn.Forte@Sun.COM 			}
1588*7836SJohn.Forte@Sun.COM 
1589*7836SJohn.Forte@Sun.COM 			/* remove it from object container if */
1590*7836SJohn.Forte@Sun.COM 			/* it is not a registered object */
1591*7836SJohn.Forte@Sun.COM 			if (ec == 0) {
1592*7836SJohn.Forte@Sun.COM 				SET_UID_LCP(&lc, m_type, m_id);
1593*7836SJohn.Forte@Sun.COM 				ec = dereg_assoc(&lc);
1594*7836SJohn.Forte@Sun.COM 			}
1595*7836SJohn.Forte@Sun.COM 		}
1596*7836SJohn.Forte@Sun.COM 	}
1597*7836SJohn.Forte@Sun.COM 
1598*7836SJohn.Forte@Sun.COM 	return (ec);
1599*7836SJohn.Forte@Sun.COM }
1600*7836SJohn.Forte@Sun.COM 
1601*7836SJohn.Forte@Sun.COM int
remove_dds_member(uint32_t dds_id,uint32_t m_id)1602*7836SJohn.Forte@Sun.COM remove_dds_member(
1603*7836SJohn.Forte@Sun.COM 	uint32_t dds_id,
1604*7836SJohn.Forte@Sun.COM 	uint32_t m_id
1605*7836SJohn.Forte@Sun.COM )
1606*7836SJohn.Forte@Sun.COM {
1607*7836SJohn.Forte@Sun.COM 	int ec = 0;
1608*7836SJohn.Forte@Sun.COM 
1609*7836SJohn.Forte@Sun.COM 	isns_obj_t *clone;
1610*7836SJohn.Forte@Sun.COM 
1611*7836SJohn.Forte@Sun.COM 	/*
1612*7836SJohn.Forte@Sun.COM 	 * We do now allow removing the member from default DD-set.
1613*7836SJohn.Forte@Sun.COM 	 */
1614*7836SJohn.Forte@Sun.COM 	if (dds_id == ISNS_DEFAULT_DD_SET_ID) {
1615*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1616*7836SJohn.Forte@Sun.COM 	}
1617*7836SJohn.Forte@Sun.COM 
1618*7836SJohn.Forte@Sun.COM 	if (m_id != 0) {
1619*7836SJohn.Forte@Sun.COM 		ec = update_dds_matrix(
1620*7836SJohn.Forte@Sun.COM 		    '-', /* remove member */
1621*7836SJohn.Forte@Sun.COM 		    dds_id,
1622*7836SJohn.Forte@Sun.COM 		    m_id);
1623*7836SJohn.Forte@Sun.COM 		if (ec == 0) {
1624*7836SJohn.Forte@Sun.COM 			clone = obj_calloc(OBJ_ASSOC_DD);
1625*7836SJohn.Forte@Sun.COM 			if (clone != NULL) {
1626*7836SJohn.Forte@Sun.COM 				(void) set_obj_uid((void *)clone, m_id);
1627*7836SJohn.Forte@Sun.COM 				(void) set_parent_obj(clone, dds_id);
1628*7836SJohn.Forte@Sun.COM 			}
1629*7836SJohn.Forte@Sun.COM 			/* update data store */
1630*7836SJohn.Forte@Sun.COM 			if (sys_q != NULL) {
1631*7836SJohn.Forte@Sun.COM 				if (clone != NULL) {
1632*7836SJohn.Forte@Sun.COM 					/* remove it from data store */
1633*7836SJohn.Forte@Sun.COM 					ec = write_data(
1634*7836SJohn.Forte@Sun.COM 					    DATA_DELETE_ASSOC, clone);
1635*7836SJohn.Forte@Sun.COM 				} else {
1636*7836SJohn.Forte@Sun.COM 					ec = ISNS_RSP_INTERNAL_ERROR;
1637*7836SJohn.Forte@Sun.COM 				}
1638*7836SJohn.Forte@Sun.COM 			}
1639*7836SJohn.Forte@Sun.COM 
1640*7836SJohn.Forte@Sun.COM 			/* trigger a management scn */
1641*7836SJohn.Forte@Sun.COM 			if (ec == 0 &&
1642*7836SJohn.Forte@Sun.COM 			    scn_q != NULL &&
1643*7836SJohn.Forte@Sun.COM 			    clone != NULL) {
1644*7836SJohn.Forte@Sun.COM 				(void) make_scn(ISNS_MEMBER_REMOVED, clone);
1645*7836SJohn.Forte@Sun.COM 			}
1646*7836SJohn.Forte@Sun.COM 			free_object(clone);
1647*7836SJohn.Forte@Sun.COM 		}
1648*7836SJohn.Forte@Sun.COM 	}
1649*7836SJohn.Forte@Sun.COM 
1650*7836SJohn.Forte@Sun.COM 	return (ec);
1651*7836SJohn.Forte@Sun.COM }
1652*7836SJohn.Forte@Sun.COM 
1653*7836SJohn.Forte@Sun.COM static int
remove_member_wildchar(matrix_t * matrix,uint32_t m_id)1654*7836SJohn.Forte@Sun.COM remove_member_wildchar(
1655*7836SJohn.Forte@Sun.COM 	matrix_t *matrix,
1656*7836SJohn.Forte@Sun.COM 	uint32_t m_id
1657*7836SJohn.Forte@Sun.COM )
1658*7836SJohn.Forte@Sun.COM {
1659*7836SJohn.Forte@Sun.COM 	int ec = 0;
1660*7836SJohn.Forte@Sun.COM 
1661*7836SJohn.Forte@Sun.COM 	bmp_t *bmp;
1662*7836SJohn.Forte@Sun.COM 	uint32_t x_info;
1663*7836SJohn.Forte@Sun.COM 	int i;
1664*7836SJohn.Forte@Sun.COM 
1665*7836SJohn.Forte@Sun.COM 	uint32_t primary = GET_PRIMARY(m_id);
1666*7836SJohn.Forte@Sun.COM 	uint32_t second = GET_SECOND(m_id);
1667*7836SJohn.Forte@Sun.COM 
1668*7836SJohn.Forte@Sun.COM 	isns_obj_t *clone;
1669*7836SJohn.Forte@Sun.COM 
1670*7836SJohn.Forte@Sun.COM 	if (primary >= matrix->x) {
1671*7836SJohn.Forte@Sun.COM 		return (ec);
1672*7836SJohn.Forte@Sun.COM 	}
1673*7836SJohn.Forte@Sun.COM 
1674*7836SJohn.Forte@Sun.COM 	i = 0;
1675*7836SJohn.Forte@Sun.COM 	while (ec == 0 && i < matrix->y) {
1676*7836SJohn.Forte@Sun.COM 		bmp = MATRIX_X_UNIT(matrix, i);
1677*7836SJohn.Forte@Sun.COM 		x_info = MATRIX_X_INFO(bmp);
1678*7836SJohn.Forte@Sun.COM 		if (x_info != 0 &&
1679*7836SJohn.Forte@Sun.COM 		    TEST_MEMBERSHIP(bmp, primary, second) != 0) {
1680*7836SJohn.Forte@Sun.COM 			/* clean the membership */
1681*7836SJohn.Forte@Sun.COM 			CLEAR_MEMBERSHIP(bmp, primary, second);
1682*7836SJohn.Forte@Sun.COM 			/* update data store */
1683*7836SJohn.Forte@Sun.COM 			if (sys_q != NULL) {
1684*7836SJohn.Forte@Sun.COM 				clone = obj_calloc(OBJ_ASSOC_DD);
1685*7836SJohn.Forte@Sun.COM 				if (clone != NULL) {
1686*7836SJohn.Forte@Sun.COM 					(void) set_obj_uid((void *)clone, m_id);
1687*7836SJohn.Forte@Sun.COM 					(void) set_parent_obj(clone, x_info);
1688*7836SJohn.Forte@Sun.COM 					/* remove it from data store */
1689*7836SJohn.Forte@Sun.COM 					ec = write_data(
1690*7836SJohn.Forte@Sun.COM 					    DATA_DELETE_ASSOC, clone);
1691*7836SJohn.Forte@Sun.COM 					free_object(clone);
1692*7836SJohn.Forte@Sun.COM 				} else {
1693*7836SJohn.Forte@Sun.COM 					ec = ISNS_RSP_INTERNAL_ERROR;
1694*7836SJohn.Forte@Sun.COM 				}
1695*7836SJohn.Forte@Sun.COM 			}
1696*7836SJohn.Forte@Sun.COM 		}
1697*7836SJohn.Forte@Sun.COM 		i ++;
1698*7836SJohn.Forte@Sun.COM 	}
1699*7836SJohn.Forte@Sun.COM 
1700*7836SJohn.Forte@Sun.COM 	return (ec);
1701*7836SJohn.Forte@Sun.COM }
1702*7836SJohn.Forte@Sun.COM 
1703*7836SJohn.Forte@Sun.COM int
remove_dd_object(uint32_t dd_id)1704*7836SJohn.Forte@Sun.COM remove_dd_object(
1705*7836SJohn.Forte@Sun.COM 	uint32_t dd_id
1706*7836SJohn.Forte@Sun.COM )
1707*7836SJohn.Forte@Sun.COM {
1708*7836SJohn.Forte@Sun.COM 	matrix_t *dds_matrix;
1709*7836SJohn.Forte@Sun.COM 
1710*7836SJohn.Forte@Sun.COM 	bmp_t *p;
1711*7836SJohn.Forte@Sun.COM 	uint32_t n;
1712*7836SJohn.Forte@Sun.COM 	int ec;
1713*7836SJohn.Forte@Sun.COM 
1714*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1715*7836SJohn.Forte@Sun.COM 	uint32_t uid;
1716*7836SJohn.Forte@Sun.COM 
1717*7836SJohn.Forte@Sun.COM 	/*
1718*7836SJohn.Forte@Sun.COM 	 * We do now allow removing the default DD.
1719*7836SJohn.Forte@Sun.COM 	 */
1720*7836SJohn.Forte@Sun.COM 	if (dd_id == ISNS_DEFAULT_DD_ID) {
1721*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1722*7836SJohn.Forte@Sun.COM 	}
1723*7836SJohn.Forte@Sun.COM 
1724*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_DD, dd_id);
1725*7836SJohn.Forte@Sun.COM 
1726*7836SJohn.Forte@Sun.COM 	/* de-register the object at first */
1727*7836SJohn.Forte@Sun.COM 	ec = dereg_object(&lc, 0);
1728*7836SJohn.Forte@Sun.COM 
1729*7836SJohn.Forte@Sun.COM 	/* clear it from all of dd-set */
1730*7836SJohn.Forte@Sun.COM 	dds_matrix = cache_get_matrix(OBJ_DDS);
1731*7836SJohn.Forte@Sun.COM 	(void) remove_member_wildchar(dds_matrix, dd_id);
1732*7836SJohn.Forte@Sun.COM 
1733*7836SJohn.Forte@Sun.COM 	/* clear its member bitmap */
1734*7836SJohn.Forte@Sun.COM 	(void) clear_dd_matrix(dd_id, &p, &n);
1735*7836SJohn.Forte@Sun.COM 
1736*7836SJohn.Forte@Sun.COM 	/* deregister the member nodes which are not-registered node */
1737*7836SJohn.Forte@Sun.COM 	/* and have no longer membership in other DD(s). */
1738*7836SJohn.Forte@Sun.COM 	if (p != NULL) {
1739*7836SJohn.Forte@Sun.COM 		SET_UID_LCP(&lc, OBJ_ISCSI, 0);
1740*7836SJohn.Forte@Sun.COM 		FOR_EACH_MEMBER(p, n, uid, {
1741*7836SJohn.Forte@Sun.COM 			lc.data[0].ui = uid;
1742*7836SJohn.Forte@Sun.COM 			(void) dereg_assoc(&lc);
1743*7836SJohn.Forte@Sun.COM 		});
1744*7836SJohn.Forte@Sun.COM 		free(p);
1745*7836SJohn.Forte@Sun.COM 	}
1746*7836SJohn.Forte@Sun.COM 
1747*7836SJohn.Forte@Sun.COM 	return (ec);
1748*7836SJohn.Forte@Sun.COM }
1749*7836SJohn.Forte@Sun.COM 
1750*7836SJohn.Forte@Sun.COM int
remove_dds_object(uint32_t dds_id)1751*7836SJohn.Forte@Sun.COM remove_dds_object(
1752*7836SJohn.Forte@Sun.COM 	uint32_t dds_id
1753*7836SJohn.Forte@Sun.COM )
1754*7836SJohn.Forte@Sun.COM {
1755*7836SJohn.Forte@Sun.COM 	int ec;
1756*7836SJohn.Forte@Sun.COM 
1757*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1758*7836SJohn.Forte@Sun.COM 
1759*7836SJohn.Forte@Sun.COM 	/*
1760*7836SJohn.Forte@Sun.COM 	 * We do now allow removing the default DD-set.
1761*7836SJohn.Forte@Sun.COM 	 */
1762*7836SJohn.Forte@Sun.COM 	if (dds_id == ISNS_DEFAULT_DD_SET_ID) {
1763*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1764*7836SJohn.Forte@Sun.COM 	}
1765*7836SJohn.Forte@Sun.COM 
1766*7836SJohn.Forte@Sun.COM 	(void) clear_dds_matrix(dds_id);
1767*7836SJohn.Forte@Sun.COM 
1768*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_DDS, dds_id);
1769*7836SJohn.Forte@Sun.COM 
1770*7836SJohn.Forte@Sun.COM 	ec = dereg_object(&lc, 0);
1771*7836SJohn.Forte@Sun.COM 
1772*7836SJohn.Forte@Sun.COM 	return (ec);
1773*7836SJohn.Forte@Sun.COM }
1774*7836SJohn.Forte@Sun.COM 
1775*7836SJohn.Forte@Sun.COM int
update_ddd(void * p,const uchar_t op)1776*7836SJohn.Forte@Sun.COM update_ddd(
1777*7836SJohn.Forte@Sun.COM 	void *p,
1778*7836SJohn.Forte@Sun.COM 	const uchar_t op
1779*7836SJohn.Forte@Sun.COM )
1780*7836SJohn.Forte@Sun.COM {
1781*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
1782*7836SJohn.Forte@Sun.COM 	uint32_t uid;
1783*7836SJohn.Forte@Sun.COM 
1784*7836SJohn.Forte@Sun.COM 	matrix_t *matrix;
1785*7836SJohn.Forte@Sun.COM 
1786*7836SJohn.Forte@Sun.COM 	obj = (isns_obj_t *)p;
1787*7836SJohn.Forte@Sun.COM 	if (obj->type != OBJ_ISCSI) {
1788*7836SJohn.Forte@Sun.COM 		return (0);
1789*7836SJohn.Forte@Sun.COM 	}
1790*7836SJohn.Forte@Sun.COM 
1791*7836SJohn.Forte@Sun.COM 	matrix = cache_get_matrix(OBJ_DD);
1792*7836SJohn.Forte@Sun.COM 	uid = get_obj_uid(obj);
1793*7836SJohn.Forte@Sun.COM 
1794*7836SJohn.Forte@Sun.COM 	return (update_matrix(matrix, op, ISNS_DEFAULT_DD_ID, uid, 0));
1795*7836SJohn.Forte@Sun.COM }
1796*7836SJohn.Forte@Sun.COM 
1797*7836SJohn.Forte@Sun.COM int
verify_ddd()1798*7836SJohn.Forte@Sun.COM verify_ddd(
1799*7836SJohn.Forte@Sun.COM )
1800*7836SJohn.Forte@Sun.COM {
1801*7836SJohn.Forte@Sun.COM 	int ec = 0;
1802*7836SJohn.Forte@Sun.COM 
1803*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1804*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj;
1805*7836SJohn.Forte@Sun.COM 
1806*7836SJohn.Forte@Sun.COM 	uchar_t *name;
1807*7836SJohn.Forte@Sun.COM 	uint32_t uid;
1808*7836SJohn.Forte@Sun.COM 	uint32_t features;
1809*7836SJohn.Forte@Sun.COM 	uint32_t code;
1810*7836SJohn.Forte@Sun.COM 
1811*7836SJohn.Forte@Sun.COM 	/* Ensure the Default DD is registered. */
1812*7836SJohn.Forte@Sun.COM 	uid = ISNS_DEFAULT_DD_ID;
1813*7836SJohn.Forte@Sun.COM 
1814*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_DD, uid);
1815*7836SJohn.Forte@Sun.COM 
1816*7836SJohn.Forte@Sun.COM 	(void) cache_lock_write();
1817*7836SJohn.Forte@Sun.COM 
1818*7836SJohn.Forte@Sun.COM 	if (is_obj_there(&lc) == 0) {
1819*7836SJohn.Forte@Sun.COM 		name = (uchar_t *)DEFAULT_DD_NAME;
1820*7836SJohn.Forte@Sun.COM 		features = DEFAULT_DD_FEATURES;
1821*7836SJohn.Forte@Sun.COM 		ec = adm_create_dd(&obj, name, uid, features);
1822*7836SJohn.Forte@Sun.COM 		if (ec == 0) {
1823*7836SJohn.Forte@Sun.COM 			ec = register_object(obj, NULL, NULL);
1824*7836SJohn.Forte@Sun.COM 			if (ec != 0) {
1825*7836SJohn.Forte@Sun.COM 				free_object(obj);
1826*7836SJohn.Forte@Sun.COM 				goto verify_done;
1827*7836SJohn.Forte@Sun.COM 			}
1828*7836SJohn.Forte@Sun.COM 		} else {
1829*7836SJohn.Forte@Sun.COM 			goto verify_done;
1830*7836SJohn.Forte@Sun.COM 		}
1831*7836SJohn.Forte@Sun.COM 	}
1832*7836SJohn.Forte@Sun.COM 
1833*7836SJohn.Forte@Sun.COM 	/* Ensure the Default DD-set is registered. */
1834*7836SJohn.Forte@Sun.COM 	uid = ISNS_DEFAULT_DD_SET_ID;
1835*7836SJohn.Forte@Sun.COM 
1836*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_DDS, uid);
1837*7836SJohn.Forte@Sun.COM 
1838*7836SJohn.Forte@Sun.COM 	if (is_obj_there(&lc) == 0) {
1839*7836SJohn.Forte@Sun.COM 		name = (uchar_t *)DEFAULT_DD_SET_NAME;
1840*7836SJohn.Forte@Sun.COM 		code = DEFAULT_DD_SET_STATUS;
1841*7836SJohn.Forte@Sun.COM 		ec = adm_create_dds(&obj, name, uid, code);
1842*7836SJohn.Forte@Sun.COM 		if (ec == 0) {
1843*7836SJohn.Forte@Sun.COM 			ec = register_object(obj, NULL, NULL);
1844*7836SJohn.Forte@Sun.COM 			if (ec != 0) {
1845*7836SJohn.Forte@Sun.COM 				free_object(obj);
1846*7836SJohn.Forte@Sun.COM 			}
1847*7836SJohn.Forte@Sun.COM 		}
1848*7836SJohn.Forte@Sun.COM 	}
1849*7836SJohn.Forte@Sun.COM 
1850*7836SJohn.Forte@Sun.COM verify_done:
1851*7836SJohn.Forte@Sun.COM 
1852*7836SJohn.Forte@Sun.COM 	ec = cache_unlock_sync(ec);
1853*7836SJohn.Forte@Sun.COM 
1854*7836SJohn.Forte@Sun.COM 	return (ec);
1855*7836SJohn.Forte@Sun.COM }
1856