xref: /illumos-gate/usr/src/cmd/isns/isnsd/dd.c (revision fcf3ce44)
1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte 
22*fcf3ce44SJohn Forte /*
23*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*fcf3ce44SJohn Forte  * Use is subject to license terms.
25*fcf3ce44SJohn Forte  */
26*fcf3ce44SJohn Forte 
27*fcf3ce44SJohn Forte #include <stdio.h>
28*fcf3ce44SJohn Forte #include <stdlib.h>
29*fcf3ce44SJohn Forte #include <string.h>
30*fcf3ce44SJohn Forte 
31*fcf3ce44SJohn Forte #include "isns_server.h"
32*fcf3ce44SJohn Forte #include "isns_msgq.h"
33*fcf3ce44SJohn Forte #include "isns_htab.h"
34*fcf3ce44SJohn Forte #include "isns_dd.h"
35*fcf3ce44SJohn Forte #include "isns_cache.h"
36*fcf3ce44SJohn Forte #include "isns_obj.h"
37*fcf3ce44SJohn Forte #include "isns_pdu.h"
38*fcf3ce44SJohn Forte #include "isns_dseng.h"
39*fcf3ce44SJohn Forte #include "isns_scn.h"
40*fcf3ce44SJohn Forte #include "isns_utils.h"
41*fcf3ce44SJohn Forte 
42*fcf3ce44SJohn Forte /*
43*fcf3ce44SJohn Forte  * extern global variables
44*fcf3ce44SJohn Forte  */
45*fcf3ce44SJohn Forte extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
46*fcf3ce44SJohn Forte 
47*fcf3ce44SJohn Forte extern msg_queue_t *sys_q;
48*fcf3ce44SJohn Forte extern msg_queue_t *scn_q;
49*fcf3ce44SJohn Forte 
50*fcf3ce44SJohn Forte extern int cache_flag;
51*fcf3ce44SJohn Forte 
52*fcf3ce44SJohn Forte /*
53*fcf3ce44SJohn Forte  * extern functions.
54*fcf3ce44SJohn Forte  */
55*fcf3ce44SJohn Forte 
56*fcf3ce44SJohn Forte /*
57*fcf3ce44SJohn Forte  * global variables
58*fcf3ce44SJohn Forte  */
59*fcf3ce44SJohn Forte 
60*fcf3ce44SJohn Forte /*
61*fcf3ce44SJohn Forte  * local variables
62*fcf3ce44SJohn Forte  */
63*fcf3ce44SJohn Forte 
64*fcf3ce44SJohn Forte /*
65*fcf3ce44SJohn Forte  * local functions.
66*fcf3ce44SJohn Forte  */
67*fcf3ce44SJohn Forte static matrix_t *new_matrix(uint32_t, uint32_t);
68*fcf3ce44SJohn Forte 
69*fcf3ce44SJohn Forte static int
cb_update_ds_attr(void * p1,void * p2)70*fcf3ce44SJohn Forte cb_update_ds_attr(
71*fcf3ce44SJohn Forte 	void *p1,
72*fcf3ce44SJohn Forte 	void *p2
73*fcf3ce44SJohn Forte )
74*fcf3ce44SJohn Forte {
75*fcf3ce44SJohn Forte 	int ec = 0;
76*fcf3ce44SJohn Forte 
77*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
78*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
79*fcf3ce44SJohn Forte 	uint32_t tag = lcp->id[1];
80*fcf3ce44SJohn Forte 	uint32_t which;
81*fcf3ce44SJohn Forte 	isns_attr_t *attr;
82*fcf3ce44SJohn Forte 
83*fcf3ce44SJohn Forte 	uint32_t len;
84*fcf3ce44SJohn Forte 	uchar_t *name;
85*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
86*fcf3ce44SJohn Forte 	uint32_t uid;
87*fcf3ce44SJohn Forte 
88*fcf3ce44SJohn Forte 	switch (tag) {
89*fcf3ce44SJohn Forte 	case ISNS_DD_NAME_ATTR_ID:
90*fcf3ce44SJohn Forte 		which = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
91*fcf3ce44SJohn Forte 		break;
92*fcf3ce44SJohn Forte 	case ISNS_DD_FEATURES_ATTR_ID:
93*fcf3ce44SJohn Forte 		which = ATTR_INDEX_DD(ISNS_DD_FEATURES_ATTR_ID);
94*fcf3ce44SJohn Forte 		break;
95*fcf3ce44SJohn Forte 	case ISNS_DD_SET_NAME_ATTR_ID:
96*fcf3ce44SJohn Forte 		which = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
97*fcf3ce44SJohn Forte 		break;
98*fcf3ce44SJohn Forte 	case ISNS_DD_SET_STATUS_ATTR_ID:
99*fcf3ce44SJohn Forte 		which = ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID);
100*fcf3ce44SJohn Forte 		break;
101*fcf3ce44SJohn Forte 	default:
102*fcf3ce44SJohn Forte 		ASSERT(0);
103*fcf3ce44SJohn Forte 		break;
104*fcf3ce44SJohn Forte 	}
105*fcf3ce44SJohn Forte 
106*fcf3ce44SJohn Forte 	attr = &obj->attrs[which];
107*fcf3ce44SJohn Forte 
108*fcf3ce44SJohn Forte 	switch (tag) {
109*fcf3ce44SJohn Forte 	case ISNS_DD_NAME_ATTR_ID:
110*fcf3ce44SJohn Forte 	case ISNS_DD_SET_NAME_ATTR_ID:
111*fcf3ce44SJohn Forte 		len = lcp->data[1].ui;
112*fcf3ce44SJohn Forte 		name = lcp->data[2].ptr;
113*fcf3ce44SJohn Forte 		lc.type = lcp->type;
114*fcf3ce44SJohn Forte 		lc.curr_uid = 0;
115*fcf3ce44SJohn Forte 		lc.id[0] = which;
116*fcf3ce44SJohn Forte 		lc.op[0] = OP_STRING;
117*fcf3ce44SJohn Forte 		lc.data[0].ptr = name;
118*fcf3ce44SJohn Forte 		lc.op[1] = 0;
119*fcf3ce44SJohn Forte 		/* check if the name is in use */
120*fcf3ce44SJohn Forte 		uid = is_obj_there(&lc);
121*fcf3ce44SJohn Forte 		if (uid != 0) {
122*fcf3ce44SJohn Forte 			if (uid != get_obj_uid(obj)) {
123*fcf3ce44SJohn Forte 				ec = ERR_NAME_IN_USE;
124*fcf3ce44SJohn Forte 			}
125*fcf3ce44SJohn Forte 			return (ec);
126*fcf3ce44SJohn Forte 		}
127*fcf3ce44SJohn Forte 		if (len > attr->len) {
128*fcf3ce44SJohn Forte 			uchar_t *tmp = (uchar_t *)malloc(len);
129*fcf3ce44SJohn Forte 			if (tmp != NULL) {
130*fcf3ce44SJohn Forte 				free(attr->value.ptr);
131*fcf3ce44SJohn Forte 				attr->value.ptr = tmp;
132*fcf3ce44SJohn Forte 			} else {
133*fcf3ce44SJohn Forte 				/* memory exhausted */
134*fcf3ce44SJohn Forte 				return (ISNS_RSP_INTERNAL_ERROR);
135*fcf3ce44SJohn Forte 			}
136*fcf3ce44SJohn Forte 		}
137*fcf3ce44SJohn Forte 		(void) strcpy((char *)attr->value.ptr, (char *)name);
138*fcf3ce44SJohn Forte 		attr->len = len;
139*fcf3ce44SJohn Forte 		break;
140*fcf3ce44SJohn Forte 	case ISNS_DD_FEATURES_ATTR_ID:
141*fcf3ce44SJohn Forte 	case ISNS_DD_SET_STATUS_ATTR_ID:
142*fcf3ce44SJohn Forte 		if (attr->tag != tag ||
143*fcf3ce44SJohn Forte 		    attr->value.ui != lcp->data[1].ui) {
144*fcf3ce44SJohn Forte 			attr->tag = tag;
145*fcf3ce44SJohn Forte 			attr->len = 4;
146*fcf3ce44SJohn Forte 			attr->value.ui = lcp->data[1].ui;
147*fcf3ce44SJohn Forte 		} else {
148*fcf3ce44SJohn Forte 			return (ec);
149*fcf3ce44SJohn Forte 		}
150*fcf3ce44SJohn Forte 		break;
151*fcf3ce44SJohn Forte 	}
152*fcf3ce44SJohn Forte 
153*fcf3ce44SJohn Forte 	/* cache has been updated, set the flag */
154*fcf3ce44SJohn Forte 	SET_CACHE_UPDATED();
155*fcf3ce44SJohn Forte 
156*fcf3ce44SJohn Forte 	/* update data store */
157*fcf3ce44SJohn Forte 	if (sys_q != NULL) {
158*fcf3ce44SJohn Forte 		ec = write_data(DATA_UPDATE, obj);
159*fcf3ce44SJohn Forte 	}
160*fcf3ce44SJohn Forte 
161*fcf3ce44SJohn Forte 	return (ec);
162*fcf3ce44SJohn Forte }
163*fcf3ce44SJohn Forte 
164*fcf3ce44SJohn Forte static isns_obj_t *
make_member_node(const uint32_t uid,isns_attr_t * attr1)165*fcf3ce44SJohn Forte make_member_node(
166*fcf3ce44SJohn Forte 	const uint32_t uid,
167*fcf3ce44SJohn Forte 	isns_attr_t *attr1
168*fcf3ce44SJohn Forte )
169*fcf3ce44SJohn Forte {
170*fcf3ce44SJohn Forte 	isns_obj_t *obj = NULL;
171*fcf3ce44SJohn Forte 	isns_attr_t *attr;
172*fcf3ce44SJohn Forte 	isns_attr_t tmp;
173*fcf3ce44SJohn Forte 
174*fcf3ce44SJohn Forte 	switch (attr1->tag) {
175*fcf3ce44SJohn Forte 	case ISNS_DD_ISCSI_NAME_ATTR_ID:
176*fcf3ce44SJohn Forte 		obj = obj_calloc(OBJ_ISCSI);
177*fcf3ce44SJohn Forte 		attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
178*fcf3ce44SJohn Forte 		tmp.tag = ISNS_ISCSI_NAME_ATTR_ID;
179*fcf3ce44SJohn Forte 		tmp.len = attr1->len;
180*fcf3ce44SJohn Forte 		tmp.value.ptr = attr1->value.ptr;
181*fcf3ce44SJohn Forte 		if (assign_attr(attr, &tmp) != 0) {
182*fcf3ce44SJohn Forte 			free_object(obj);
183*fcf3ce44SJohn Forte 			obj = NULL;
184*fcf3ce44SJohn Forte 		} else if (uid != 0) {
185*fcf3ce44SJohn Forte 			(void) set_obj_uid(obj, uid);
186*fcf3ce44SJohn Forte 		}
187*fcf3ce44SJohn Forte 		break;
188*fcf3ce44SJohn Forte 	default:
189*fcf3ce44SJohn Forte 		ASSERT(0);
190*fcf3ce44SJohn Forte 		break;
191*fcf3ce44SJohn Forte 	}
192*fcf3ce44SJohn Forte 
193*fcf3ce44SJohn Forte 	return (obj);
194*fcf3ce44SJohn Forte }
195*fcf3ce44SJohn Forte 
196*fcf3ce44SJohn Forte static isns_obj_t *
make_member_dd(const uint32_t uid)197*fcf3ce44SJohn Forte make_member_dd(
198*fcf3ce44SJohn Forte 	const uint32_t uid
199*fcf3ce44SJohn Forte )
200*fcf3ce44SJohn Forte {
201*fcf3ce44SJohn Forte 	isns_obj_t *obj = NULL;
202*fcf3ce44SJohn Forte 	isns_attr_t name = { 0 };
203*fcf3ce44SJohn Forte 
204*fcf3ce44SJohn Forte 	obj = obj_calloc(OBJ_DD);
205*fcf3ce44SJohn Forte 	if (obj != NULL) {
206*fcf3ce44SJohn Forte 		(void) set_obj_uid(obj, uid);
207*fcf3ce44SJohn Forte 		name.tag = ISNS_DD_NAME_ATTR_ID;
208*fcf3ce44SJohn Forte 		if (assign_attr(
209*fcf3ce44SJohn Forte 		    &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)],
210*fcf3ce44SJohn Forte 		    &name) != 0) {
211*fcf3ce44SJohn Forte 			free_object(obj);
212*fcf3ce44SJohn Forte 			obj = NULL;
213*fcf3ce44SJohn Forte 		}
214*fcf3ce44SJohn Forte 	}
215*fcf3ce44SJohn Forte 
216*fcf3ce44SJohn Forte 	return (obj);
217*fcf3ce44SJohn Forte }
218*fcf3ce44SJohn Forte 
219*fcf3ce44SJohn Forte static int
get_member_info(isns_obj_t * assoc,uint32_t * m_type,uint32_t * m_id,int flag)220*fcf3ce44SJohn Forte get_member_info(
221*fcf3ce44SJohn Forte 	isns_obj_t *assoc,
222*fcf3ce44SJohn Forte 	uint32_t *m_type,
223*fcf3ce44SJohn Forte 	uint32_t *m_id,
224*fcf3ce44SJohn Forte 	int flag
225*fcf3ce44SJohn Forte )
226*fcf3ce44SJohn Forte {
227*fcf3ce44SJohn Forte 	int ec = 0;
228*fcf3ce44SJohn Forte 	lookup_ctrl_t lc = { 0 };
229*fcf3ce44SJohn Forte 
230*fcf3ce44SJohn Forte 	isns_obj_t *obj;
231*fcf3ce44SJohn Forte 	isns_attr_t *attr1, *attr2;
232*fcf3ce44SJohn Forte 	uint32_t tmp_id = 0;
233*fcf3ce44SJohn Forte 	int i = 0;
234*fcf3ce44SJohn Forte 
235*fcf3ce44SJohn Forte 	*m_type = 0;
236*fcf3ce44SJohn Forte 	*m_id = 0;
237*fcf3ce44SJohn Forte 
238*fcf3ce44SJohn Forte 	attr1 = &assoc->attrs[ATTR_INDEX_ASSOC_ISCSI(
239*fcf3ce44SJohn Forte 	    ISNS_DD_ISCSI_INDEX_ATTR_ID)];
240*fcf3ce44SJohn Forte 	attr2 = &assoc->attrs[ATTR_INDEX_ASSOC_ISCSI(
241*fcf3ce44SJohn Forte 	    ISNS_DD_ISCSI_NAME_ATTR_ID)];
242*fcf3ce44SJohn Forte 
243*fcf3ce44SJohn Forte 	lc.type = OBJ_ISCSI;
244*fcf3ce44SJohn Forte 	if (attr1->tag != 0 && attr1->value.ui != 0) {
245*fcf3ce44SJohn Forte 		*m_id = attr1->value.ui;
246*fcf3ce44SJohn Forte 		lc.id[i] = UID_ATTR_INDEX[OBJ_ISCSI];
247*fcf3ce44SJohn Forte 		lc.op[i] = OP_INTEGER;
248*fcf3ce44SJohn Forte 		lc.data[i].ui = *m_id;
249*fcf3ce44SJohn Forte 		i ++;
250*fcf3ce44SJohn Forte 	}
251*fcf3ce44SJohn Forte 	if (attr2->tag != 0) {
252*fcf3ce44SJohn Forte 		lc.id[i] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
253*fcf3ce44SJohn Forte 		lc.op[i] = OP_STRING;
254*fcf3ce44SJohn Forte 		lc.data[i].ptr = attr2->value.ptr;
255*fcf3ce44SJohn Forte 		i ++;
256*fcf3ce44SJohn Forte 	} else if (scn_q != NULL || sys_q != NULL) {
257*fcf3ce44SJohn Forte 		lc.id[i] = ISNS_ISCSI_NAME_ATTR_ID;
258*fcf3ce44SJohn Forte 	}
259*fcf3ce44SJohn Forte 
260*fcf3ce44SJohn Forte 	/* a member id or member name is required */
261*fcf3ce44SJohn Forte 	if (i == 0) {
262*fcf3ce44SJohn Forte 		if (flag != 0) {
263*fcf3ce44SJohn Forte 			/* add member */
264*fcf3ce44SJohn Forte 			return (ISNS_RSP_INVALID_REGIS);
265*fcf3ce44SJohn Forte 		} else {
266*fcf3ce44SJohn Forte 			/* remove member (isnsp msg request only) */
267*fcf3ce44SJohn Forte 			return (0);
268*fcf3ce44SJohn Forte 		}
269*fcf3ce44SJohn Forte 	}
270*fcf3ce44SJohn Forte 
271*fcf3ce44SJohn Forte 	ec = cache_lookup(&lc, &tmp_id, cb_clone_attrs);
272*fcf3ce44SJohn Forte 
273*fcf3ce44SJohn Forte 	if (ec == 0 && tmp_id == 0) {
274*fcf3ce44SJohn Forte 		if (flag != 0) {
275*fcf3ce44SJohn Forte 			/* add member */
276*fcf3ce44SJohn Forte 			if (attr1->tag == 0 || sys_q == NULL) {
277*fcf3ce44SJohn Forte 				/* object does not exist, create one */
278*fcf3ce44SJohn Forte 				obj = make_member_node(*m_id, attr2);
279*fcf3ce44SJohn Forte 				if (obj == NULL) {
280*fcf3ce44SJohn Forte 					ec = ISNS_RSP_INTERNAL_ERROR;
281*fcf3ce44SJohn Forte 				} else {
282*fcf3ce44SJohn Forte 					ec = register_assoc(obj, &tmp_id);
283*fcf3ce44SJohn Forte 					if (ec != 0) {
284*fcf3ce44SJohn Forte 						free_object(obj);
285*fcf3ce44SJohn Forte 					}
286*fcf3ce44SJohn Forte 				}
287*fcf3ce44SJohn Forte 			} else {
288*fcf3ce44SJohn Forte 				/* don't create it if uid is specified */
289*fcf3ce44SJohn Forte 				ec = ISNS_RSP_NO_SUCH_ENTRY;
290*fcf3ce44SJohn Forte 			}
291*fcf3ce44SJohn Forte 		} else {
292*fcf3ce44SJohn Forte 			/* remove member */
293*fcf3ce44SJohn Forte 			ec = ERR_NO_SUCH_ASSOCIATION;
294*fcf3ce44SJohn Forte 		}
295*fcf3ce44SJohn Forte 	}
296*fcf3ce44SJohn Forte 
297*fcf3ce44SJohn Forte 	if (attr1->tag == 0) {
298*fcf3ce44SJohn Forte 		attr1->tag = ISNS_DD_ISCSI_INDEX_ATTR_ID;
299*fcf3ce44SJohn Forte 		attr1->len = 4;
300*fcf3ce44SJohn Forte 		attr1->value.ui = tmp_id;
301*fcf3ce44SJohn Forte 	} else if (attr2->tag == 0) {
302*fcf3ce44SJohn Forte 		attr2->tag = ISNS_DD_ISCSI_NAME_ATTR_ID;
303*fcf3ce44SJohn Forte 		attr2->len = strlen((char *)lc.data[1].ptr);
304*fcf3ce44SJohn Forte 		attr2->len += 4 - (attr2->len % 4);
305*fcf3ce44SJohn Forte 		attr2->value.ptr = lc.data[1].ptr;
306*fcf3ce44SJohn Forte 	}
307*fcf3ce44SJohn Forte 
308*fcf3ce44SJohn Forte 	*m_type = OBJ_ISCSI;
309*fcf3ce44SJohn Forte 	*m_id = tmp_id;
310*fcf3ce44SJohn Forte 
311*fcf3ce44SJohn Forte 	return (ec);
312*fcf3ce44SJohn Forte }
313*fcf3ce44SJohn Forte 
314*fcf3ce44SJohn Forte static int
get_dds_member_info(uint32_t m_id)315*fcf3ce44SJohn Forte get_dds_member_info(
316*fcf3ce44SJohn Forte 	uint32_t m_id
317*fcf3ce44SJohn Forte )
318*fcf3ce44SJohn Forte {
319*fcf3ce44SJohn Forte 	int ec = 0;
320*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
321*fcf3ce44SJohn Forte 
322*fcf3ce44SJohn Forte 	isns_obj_t *obj;
323*fcf3ce44SJohn Forte 	uint32_t tmp_id;
324*fcf3ce44SJohn Forte 
325*fcf3ce44SJohn Forte 	if (m_id != 0) {
326*fcf3ce44SJohn Forte 		SET_UID_LCP(&lc, OBJ_DD, m_id);
327*fcf3ce44SJohn Forte 	} else {
328*fcf3ce44SJohn Forte 		return (ISNS_RSP_INVALID_REGIS);
329*fcf3ce44SJohn Forte 	}
330*fcf3ce44SJohn Forte 
331*fcf3ce44SJohn Forte 	tmp_id = is_obj_there(&lc);
332*fcf3ce44SJohn Forte 
333*fcf3ce44SJohn Forte 	if (tmp_id == 0) {
334*fcf3ce44SJohn Forte 		/* object does not exist, create one */
335*fcf3ce44SJohn Forte 		obj = make_member_dd(m_id);
336*fcf3ce44SJohn Forte 		if (obj != NULL) {
337*fcf3ce44SJohn Forte 			ec = register_object(obj, NULL, NULL);
338*fcf3ce44SJohn Forte 		} else {
339*fcf3ce44SJohn Forte 			/* no memory */
340*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
341*fcf3ce44SJohn Forte 		}
342*fcf3ce44SJohn Forte 	}
343*fcf3ce44SJohn Forte 
344*fcf3ce44SJohn Forte 	return (ec);
345*fcf3ce44SJohn Forte }
346*fcf3ce44SJohn Forte 
347*fcf3ce44SJohn Forte static int
update_matrix(matrix_t * matrix,const uchar_t op,const uint32_t puid,const uint32_t m_id,int ddd_flag)348*fcf3ce44SJohn Forte update_matrix(
349*fcf3ce44SJohn Forte 	matrix_t *matrix,
350*fcf3ce44SJohn Forte 	const uchar_t op,
351*fcf3ce44SJohn Forte 	const uint32_t puid,
352*fcf3ce44SJohn Forte 	const uint32_t m_id,
353*fcf3ce44SJohn Forte 	int ddd_flag
354*fcf3ce44SJohn Forte )
355*fcf3ce44SJohn Forte {
356*fcf3ce44SJohn Forte 	int ec = 0;
357*fcf3ce44SJohn Forte 
358*fcf3ce44SJohn Forte 	uint32_t new_x = 0, new_y = 0;
359*fcf3ce44SJohn Forte 	matrix_t *tmp_matrix;
360*fcf3ce44SJohn Forte 
361*fcf3ce44SJohn Forte 	uint32_t i, j, k = 0;
362*fcf3ce44SJohn Forte 	uint32_t x_info;
363*fcf3ce44SJohn Forte 	bmp_t *bmp, *tmp_bmp;
364*fcf3ce44SJohn Forte 
365*fcf3ce44SJohn Forte 	uint32_t primary = GET_PRIMARY(m_id);
366*fcf3ce44SJohn Forte 	uint32_t second = GET_SECOND(m_id);
367*fcf3ce44SJohn Forte 
368*fcf3ce44SJohn Forte 	if (primary >= matrix->x) {
369*fcf3ce44SJohn Forte 		if (op == '-') {
370*fcf3ce44SJohn Forte 			ec = ERR_NO_SUCH_ASSOCIATION;
371*fcf3ce44SJohn Forte 			goto update_matrix_done;
372*fcf3ce44SJohn Forte 		}
373*fcf3ce44SJohn Forte 		/* enlarge the matrix on x axis */
374*fcf3ce44SJohn Forte 		if (primary >= matrix->x * 2) {
375*fcf3ce44SJohn Forte 			new_x = primary + 1;
376*fcf3ce44SJohn Forte 		} else {
377*fcf3ce44SJohn Forte 			new_x = matrix->x * 2;
378*fcf3ce44SJohn Forte 		}
379*fcf3ce44SJohn Forte 	}
380*fcf3ce44SJohn Forte 
381*fcf3ce44SJohn Forte 	i = 0;
382*fcf3ce44SJohn Forte 	while (i < matrix->y) {
383*fcf3ce44SJohn Forte 		bmp = MATRIX_X_UNIT(matrix, i);
384*fcf3ce44SJohn Forte 		x_info = MATRIX_X_INFO(bmp);
385*fcf3ce44SJohn Forte 		if (x_info == puid) {
386*fcf3ce44SJohn Forte 			break;
387*fcf3ce44SJohn Forte 		} else if (x_info == 0 && k == 0) {
388*fcf3ce44SJohn Forte 			/* the first available slot */
389*fcf3ce44SJohn Forte 			k = i;
390*fcf3ce44SJohn Forte 		}
391*fcf3ce44SJohn Forte 		i ++;
392*fcf3ce44SJohn Forte 	}
393*fcf3ce44SJohn Forte 	if (i == matrix->y) {
394*fcf3ce44SJohn Forte 		if (op == '-') {
395*fcf3ce44SJohn Forte 			ec = ERR_NO_SUCH_ASSOCIATION;
396*fcf3ce44SJohn Forte 			goto update_matrix_done;
397*fcf3ce44SJohn Forte 		} else if (k == 0) {
398*fcf3ce44SJohn Forte 			new_y = matrix->y * 2;
399*fcf3ce44SJohn Forte 		} else {
400*fcf3ce44SJohn Forte 			i = k;
401*fcf3ce44SJohn Forte 		}
402*fcf3ce44SJohn Forte 	}
403*fcf3ce44SJohn Forte 
404*fcf3ce44SJohn Forte 	/*
405*fcf3ce44SJohn Forte 	 * enlarge the matrix.
406*fcf3ce44SJohn Forte 	 */
407*fcf3ce44SJohn Forte 	if (new_x != 0 || new_y != 0) {
408*fcf3ce44SJohn Forte 		if (new_x == 0) {
409*fcf3ce44SJohn Forte 			new_x = matrix->x;
410*fcf3ce44SJohn Forte 		}
411*fcf3ce44SJohn Forte 		if (new_y == 0) {
412*fcf3ce44SJohn Forte 			new_y = matrix->y;
413*fcf3ce44SJohn Forte 		}
414*fcf3ce44SJohn Forte 		tmp_matrix = new_matrix(new_x, new_y);
415*fcf3ce44SJohn Forte 		if (tmp_matrix != NULL) {
416*fcf3ce44SJohn Forte 			j = 0;
417*fcf3ce44SJohn Forte 			while (j < matrix->y) {
418*fcf3ce44SJohn Forte 				bmp = MATRIX_X_UNIT(matrix, j);
419*fcf3ce44SJohn Forte 				x_info = MATRIX_X_INFO(bmp);
420*fcf3ce44SJohn Forte 				if (x_info != 0) {
421*fcf3ce44SJohn Forte 					tmp_bmp = MATRIX_X_UNIT(tmp_matrix, j);
422*fcf3ce44SJohn Forte 					(void) memcpy((void *)tmp_bmp,
423*fcf3ce44SJohn Forte 					    (void *)bmp, SIZEOF_X_UNIT(matrix));
424*fcf3ce44SJohn Forte 				}
425*fcf3ce44SJohn Forte 				j ++;
426*fcf3ce44SJohn Forte 			}
427*fcf3ce44SJohn Forte 			free(matrix->m);
428*fcf3ce44SJohn Forte 			matrix->x = tmp_matrix->x;
429*fcf3ce44SJohn Forte 			matrix->y = tmp_matrix->y;
430*fcf3ce44SJohn Forte 			matrix->m = tmp_matrix->m;
431*fcf3ce44SJohn Forte 			free(tmp_matrix);
432*fcf3ce44SJohn Forte 		} else {
433*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
434*fcf3ce44SJohn Forte 			goto update_matrix_done;
435*fcf3ce44SJohn Forte 		}
436*fcf3ce44SJohn Forte 	}
437*fcf3ce44SJohn Forte 
438*fcf3ce44SJohn Forte 	bmp = MATRIX_X_UNIT(matrix, i);
439*fcf3ce44SJohn Forte 
440*fcf3ce44SJohn Forte 	MATRIX_X_INFO(bmp) = puid;
441*fcf3ce44SJohn Forte 	if (op == '+') {
442*fcf3ce44SJohn Forte 		if (TEST_MEMBERSHIP(bmp, primary, second) == 0) {
443*fcf3ce44SJohn Forte 			SET_MEMBERSHIP(bmp, primary, second);
444*fcf3ce44SJohn Forte 			SET_CACHE_UPDATED();
445*fcf3ce44SJohn Forte 			if (ddd_flag != 0) {
446*fcf3ce44SJohn Forte 				bmp = MATRIX_X_UNIT(matrix, 0);
447*fcf3ce44SJohn Forte 				ASSERT(MATRIX_X_INFO(bmp) ==
448*fcf3ce44SJohn Forte 				    ISNS_DEFAULT_DD_ID);
449*fcf3ce44SJohn Forte 				CLEAR_MEMBERSHIP(bmp, primary, second);
450*fcf3ce44SJohn Forte 			}
451*fcf3ce44SJohn Forte 		} else {
452*fcf3ce44SJohn Forte 			ec = ERR_ALREADY_ASSOCIATED;
453*fcf3ce44SJohn Forte 		}
454*fcf3ce44SJohn Forte 	} else if (op == '-') {
455*fcf3ce44SJohn Forte 		if (TEST_MEMBERSHIP(bmp, primary, second) != 0) {
456*fcf3ce44SJohn Forte 			CLEAR_MEMBERSHIP(bmp, primary, second);
457*fcf3ce44SJohn Forte 			SET_CACHE_UPDATED();
458*fcf3ce44SJohn Forte 			if (ddd_flag != 0) {
459*fcf3ce44SJohn Forte 				i = 1;
460*fcf3ce44SJohn Forte 				while (i < matrix->y) {
461*fcf3ce44SJohn Forte 					bmp = MATRIX_X_UNIT(matrix, i);
462*fcf3ce44SJohn Forte 					x_info = MATRIX_X_INFO(bmp);
463*fcf3ce44SJohn Forte 					if (x_info != 0 &&
464*fcf3ce44SJohn Forte 					    TEST_MEMBERSHIP(bmp,
465*fcf3ce44SJohn Forte 					    primary, second) != 0) {
466*fcf3ce44SJohn Forte 						break;
467*fcf3ce44SJohn Forte 					}
468*fcf3ce44SJohn Forte 					i ++;
469*fcf3ce44SJohn Forte 				}
470*fcf3ce44SJohn Forte 				if (i == matrix->y) {
471*fcf3ce44SJohn Forte 					bmp = MATRIX_X_UNIT(matrix, 0);
472*fcf3ce44SJohn Forte 					ASSERT(MATRIX_X_INFO(bmp) ==
473*fcf3ce44SJohn Forte 					    ISNS_DEFAULT_DD_ID);
474*fcf3ce44SJohn Forte 					SET_MEMBERSHIP(bmp, primary, second);
475*fcf3ce44SJohn Forte 				}
476*fcf3ce44SJohn Forte 			}
477*fcf3ce44SJohn Forte 		} else {
478*fcf3ce44SJohn Forte 			ec = ERR_NO_SUCH_ASSOCIATION;
479*fcf3ce44SJohn Forte 		}
480*fcf3ce44SJohn Forte 	}
481*fcf3ce44SJohn Forte 
482*fcf3ce44SJohn Forte update_matrix_done:
483*fcf3ce44SJohn Forte 	return (ec);
484*fcf3ce44SJohn Forte }
485*fcf3ce44SJohn Forte 
486*fcf3ce44SJohn Forte /*ARGSUSED*/
487*fcf3ce44SJohn Forte 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*fcf3ce44SJohn Forte update_dd_matrix(
489*fcf3ce44SJohn Forte 	const uchar_t op,
490*fcf3ce44SJohn Forte 	const uint32_t dd_id,
491*fcf3ce44SJohn Forte 	const uint32_t m_type,
492*fcf3ce44SJohn Forte 	const uint32_t m_id
493*fcf3ce44SJohn Forte )
494*fcf3ce44SJohn Forte {
495*fcf3ce44SJohn Forte 	matrix_t *matrix;
496*fcf3ce44SJohn Forte 
497*fcf3ce44SJohn Forte 	ASSERT(m_type == OBJ_ISCSI);
498*fcf3ce44SJohn Forte 
499*fcf3ce44SJohn Forte 	matrix = cache_get_matrix(OBJ_DD);
500*fcf3ce44SJohn Forte 
501*fcf3ce44SJohn Forte 	return (update_matrix(matrix, op, dd_id, m_id, 1));
502*fcf3ce44SJohn Forte }
503*fcf3ce44SJohn Forte 
504*fcf3ce44SJohn Forte static int
update_dds_matrix(const uchar_t op,const uint32_t dds_id,const uint32_t m_id)505*fcf3ce44SJohn Forte update_dds_matrix(
506*fcf3ce44SJohn Forte 	const uchar_t op,
507*fcf3ce44SJohn Forte 	const uint32_t dds_id,
508*fcf3ce44SJohn Forte 	const uint32_t m_id
509*fcf3ce44SJohn Forte )
510*fcf3ce44SJohn Forte {
511*fcf3ce44SJohn Forte 	matrix_t *dds_matrix = cache_get_matrix(OBJ_DDS);
512*fcf3ce44SJohn Forte 
513*fcf3ce44SJohn Forte 	return (update_matrix(dds_matrix, op, dds_id, m_id, 0));
514*fcf3ce44SJohn Forte }
515*fcf3ce44SJohn Forte 
516*fcf3ce44SJohn Forte static int
clear_matrix(matrix_t * matrix,const uint32_t uid,bmp_t ** p,uint32_t * n,int ddd_flag)517*fcf3ce44SJohn Forte clear_matrix(
518*fcf3ce44SJohn Forte 	matrix_t *matrix,
519*fcf3ce44SJohn Forte 	const uint32_t uid,
520*fcf3ce44SJohn Forte 	bmp_t **p,
521*fcf3ce44SJohn Forte 	uint32_t *n,
522*fcf3ce44SJohn Forte 	int ddd_flag
523*fcf3ce44SJohn Forte )
524*fcf3ce44SJohn Forte {
525*fcf3ce44SJohn Forte 	int ec = 0;
526*fcf3ce44SJohn Forte 	bmp_t *bmp;
527*fcf3ce44SJohn Forte 	uint32_t x_info;
528*fcf3ce44SJohn Forte 	int i, j;
529*fcf3ce44SJohn Forte 
530*fcf3ce44SJohn Forte 	uint32_t primary;
531*fcf3ce44SJohn Forte 	uint32_t second;
532*fcf3ce44SJohn Forte 
533*fcf3ce44SJohn Forte 	if (p != NULL) {
534*fcf3ce44SJohn Forte 		*p = NULL;
535*fcf3ce44SJohn Forte 		*n = 0;
536*fcf3ce44SJohn Forte 	}
537*fcf3ce44SJohn Forte 
538*fcf3ce44SJohn Forte 	i = 0;
539*fcf3ce44SJohn Forte 	while (i < matrix->y) {
540*fcf3ce44SJohn Forte 		bmp = MATRIX_X_UNIT(matrix, i);
541*fcf3ce44SJohn Forte 		x_info = MATRIX_X_INFO(bmp);
542*fcf3ce44SJohn Forte 		if (x_info == uid) {
543*fcf3ce44SJohn Forte 			if (p != NULL) {
544*fcf3ce44SJohn Forte 				/* dup it for caller */
545*fcf3ce44SJohn Forte 				*n = matrix->x;
546*fcf3ce44SJohn Forte 				*p = (bmp_t *)malloc(*n * sizeof (bmp_t));
547*fcf3ce44SJohn Forte 				if (*p != NULL) {
548*fcf3ce44SJohn Forte 					(void) memcpy(*p, &bmp[MATRIX_X_HEADER],
549*fcf3ce44SJohn Forte 					    *n * sizeof (bmp_t));
550*fcf3ce44SJohn Forte 				} else {
551*fcf3ce44SJohn Forte 					ec = ISNS_RSP_INTERNAL_ERROR;
552*fcf3ce44SJohn Forte 				}
553*fcf3ce44SJohn Forte 			}
554*fcf3ce44SJohn Forte 			/* clean it */
555*fcf3ce44SJohn Forte 			(void) memset(bmp, 0, SIZEOF_X_UNIT(matrix));
556*fcf3ce44SJohn Forte 			break;
557*fcf3ce44SJohn Forte 		}
558*fcf3ce44SJohn Forte 		i ++;
559*fcf3ce44SJohn Forte 	}
560*fcf3ce44SJohn Forte 
561*fcf3ce44SJohn Forte 	if (ddd_flag != 0 && p != NULL) {
562*fcf3ce44SJohn Forte 		bmp = MATRIX_X_UNIT(matrix, 0);
563*fcf3ce44SJohn Forte 		ASSERT(MATRIX_X_INFO(bmp) == ISNS_DEFAULT_DD_ID);
564*fcf3ce44SJohn Forte 		/* Test the membership for each node which is a */
565*fcf3ce44SJohn Forte 		/* member in the dd that is being deleted. */
566*fcf3ce44SJohn Forte 		FOR_EACH_MEMBER(*p, *n, i, {
567*fcf3ce44SJohn Forte 			j = get_dd_id(i, 0);
568*fcf3ce44SJohn Forte 			if (j == 0) {
569*fcf3ce44SJohn Forte 				/* put it to the default dd */
570*fcf3ce44SJohn Forte 				primary = GET_PRIMARY(i);
571*fcf3ce44SJohn Forte 				second = GET_SECOND(i);
572*fcf3ce44SJohn Forte 				SET_MEMBERSHIP(bmp, primary, second);
573*fcf3ce44SJohn Forte 			}
574*fcf3ce44SJohn Forte 		});
575*fcf3ce44SJohn Forte 	}
576*fcf3ce44SJohn Forte 
577*fcf3ce44SJohn Forte 	return (ec);
578*fcf3ce44SJohn Forte }
579*fcf3ce44SJohn Forte 
580*fcf3ce44SJohn Forte static int
get_matrix(matrix_t * matrix,const uint32_t uid,bmp_t ** p,uint32_t * n)581*fcf3ce44SJohn Forte get_matrix(
582*fcf3ce44SJohn Forte 	matrix_t *matrix,
583*fcf3ce44SJohn Forte 	const uint32_t uid,
584*fcf3ce44SJohn Forte 	bmp_t **p,
585*fcf3ce44SJohn Forte 	uint32_t *n
586*fcf3ce44SJohn Forte )
587*fcf3ce44SJohn Forte {
588*fcf3ce44SJohn Forte 	int ec = 0;
589*fcf3ce44SJohn Forte 	bmp_t *bmp;
590*fcf3ce44SJohn Forte 	uint32_t x_info;
591*fcf3ce44SJohn Forte 	int i;
592*fcf3ce44SJohn Forte 
593*fcf3ce44SJohn Forte 	*n = 0;
594*fcf3ce44SJohn Forte 	*p = NULL;
595*fcf3ce44SJohn Forte 
596*fcf3ce44SJohn Forte 	i = 0;
597*fcf3ce44SJohn Forte 	while (i < matrix->y) {
598*fcf3ce44SJohn Forte 		bmp = MATRIX_X_UNIT(matrix, i);
599*fcf3ce44SJohn Forte 		x_info = MATRIX_X_INFO(bmp);
600*fcf3ce44SJohn Forte 		if (x_info == uid) {
601*fcf3ce44SJohn Forte 			/* dup it for caller */
602*fcf3ce44SJohn Forte 			*n = matrix->x;
603*fcf3ce44SJohn Forte 			*p = (bmp_t *)malloc(*n * sizeof (bmp_t));
604*fcf3ce44SJohn Forte 			if (*p != NULL) {
605*fcf3ce44SJohn Forte 				(void) memcpy(*p, &bmp[MATRIX_X_HEADER],
606*fcf3ce44SJohn Forte 				    *n * sizeof (bmp_t));
607*fcf3ce44SJohn Forte 			} else {
608*fcf3ce44SJohn Forte 				*n = 0;
609*fcf3ce44SJohn Forte 				ec = ISNS_RSP_INTERNAL_ERROR;
610*fcf3ce44SJohn Forte 			}
611*fcf3ce44SJohn Forte 			break;
612*fcf3ce44SJohn Forte 		}
613*fcf3ce44SJohn Forte 		i ++;
614*fcf3ce44SJohn Forte 	}
615*fcf3ce44SJohn Forte 
616*fcf3ce44SJohn Forte 	return (ec);
617*fcf3ce44SJohn Forte }
618*fcf3ce44SJohn Forte 
619*fcf3ce44SJohn Forte static int
clear_dd_matrix(const uint32_t dd_id,bmp_t ** p,uint32_t * n)620*fcf3ce44SJohn Forte clear_dd_matrix(
621*fcf3ce44SJohn Forte 	const uint32_t dd_id,
622*fcf3ce44SJohn Forte 	bmp_t **p,
623*fcf3ce44SJohn Forte 	uint32_t *n
624*fcf3ce44SJohn Forte )
625*fcf3ce44SJohn Forte {
626*fcf3ce44SJohn Forte 	matrix_t *matrix = cache_get_matrix(OBJ_DD);
627*fcf3ce44SJohn Forte 
628*fcf3ce44SJohn Forte 	return (clear_matrix(matrix, dd_id, p, n, 1));
629*fcf3ce44SJohn Forte }
630*fcf3ce44SJohn Forte 
631*fcf3ce44SJohn Forte static int
clear_dds_matrix(const uint32_t dds_id)632*fcf3ce44SJohn Forte clear_dds_matrix(
633*fcf3ce44SJohn Forte 	const uint32_t dds_id
634*fcf3ce44SJohn Forte )
635*fcf3ce44SJohn Forte {
636*fcf3ce44SJohn Forte 	matrix_t *matrix = cache_get_matrix(OBJ_DDS);
637*fcf3ce44SJohn Forte 
638*fcf3ce44SJohn Forte 	return (clear_matrix(matrix, dds_id, NULL, NULL, 0));
639*fcf3ce44SJohn Forte }
640*fcf3ce44SJohn Forte 
641*fcf3ce44SJohn Forte int
get_dd_matrix(const uint32_t dd_id,bmp_t ** p,uint32_t * n)642*fcf3ce44SJohn Forte get_dd_matrix(
643*fcf3ce44SJohn Forte 	const uint32_t dd_id,
644*fcf3ce44SJohn Forte 	bmp_t **p,
645*fcf3ce44SJohn Forte 	uint32_t *n
646*fcf3ce44SJohn Forte )
647*fcf3ce44SJohn Forte {
648*fcf3ce44SJohn Forte 	matrix_t *matrix = cache_get_matrix(OBJ_DD);
649*fcf3ce44SJohn Forte 
650*fcf3ce44SJohn Forte 	return (get_matrix(matrix, dd_id, p, n));
651*fcf3ce44SJohn Forte }
652*fcf3ce44SJohn Forte 
653*fcf3ce44SJohn Forte int
get_dds_matrix(const uint32_t dds_id,bmp_t ** p,uint32_t * n)654*fcf3ce44SJohn Forte get_dds_matrix(
655*fcf3ce44SJohn Forte 	const uint32_t dds_id,
656*fcf3ce44SJohn Forte 	bmp_t **p,
657*fcf3ce44SJohn Forte 	uint32_t *n
658*fcf3ce44SJohn Forte )
659*fcf3ce44SJohn Forte {
660*fcf3ce44SJohn Forte 	matrix_t *matrix = cache_get_matrix(OBJ_DDS);
661*fcf3ce44SJohn Forte 
662*fcf3ce44SJohn Forte 	return (get_matrix(matrix, dds_id, p, n));
663*fcf3ce44SJohn Forte }
664*fcf3ce44SJohn Forte 
665*fcf3ce44SJohn Forte /*ARGSUSED*/
666*fcf3ce44SJohn Forte static int
cb_get_dds_status(void * p1,void * p2)667*fcf3ce44SJohn Forte cb_get_dds_status(
668*fcf3ce44SJohn Forte 	void *p1,
669*fcf3ce44SJohn Forte 	void *p2
670*fcf3ce44SJohn Forte )
671*fcf3ce44SJohn Forte {
672*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
673*fcf3ce44SJohn Forte 
674*fcf3ce44SJohn Forte 	isns_attr_t *attr = &obj->attrs[
675*fcf3ce44SJohn Forte 	    ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID)];
676*fcf3ce44SJohn Forte 
677*fcf3ce44SJohn Forte 	return (DDS_ENABLED(attr->value.ui) ? 1 : 0);
678*fcf3ce44SJohn Forte }
679*fcf3ce44SJohn Forte 
680*fcf3ce44SJohn Forte static int
get_dds_status(uint32_t dds_id)681*fcf3ce44SJohn Forte get_dds_status(
682*fcf3ce44SJohn Forte 	uint32_t dds_id
683*fcf3ce44SJohn Forte )
684*fcf3ce44SJohn Forte {
685*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
686*fcf3ce44SJohn Forte 
687*fcf3ce44SJohn Forte 	if (dds_id == 0) {
688*fcf3ce44SJohn Forte 		return (0);
689*fcf3ce44SJohn Forte 	}
690*fcf3ce44SJohn Forte 
691*fcf3ce44SJohn Forte 	SET_UID_LCP(&lc, OBJ_DDS, dds_id);
692*fcf3ce44SJohn Forte 
693*fcf3ce44SJohn Forte 	return (cache_lookup(&lc, NULL, cb_get_dds_status));
694*fcf3ce44SJohn Forte }
695*fcf3ce44SJohn Forte 
696*fcf3ce44SJohn Forte int
is_dd_active(uint32_t dd_id)697*fcf3ce44SJohn Forte is_dd_active(
698*fcf3ce44SJohn Forte 	uint32_t dd_id
699*fcf3ce44SJohn Forte )
700*fcf3ce44SJohn Forte {
701*fcf3ce44SJohn Forte 	int active = 0;
702*fcf3ce44SJohn Forte 
703*fcf3ce44SJohn Forte 	matrix_t *dds_matrix;
704*fcf3ce44SJohn Forte 	uint32_t primary;
705*fcf3ce44SJohn Forte 	uint32_t second;
706*fcf3ce44SJohn Forte 	uint32_t x_info;
707*fcf3ce44SJohn Forte 	bmp_t *bmp;
708*fcf3ce44SJohn Forte 	int i;
709*fcf3ce44SJohn Forte 
710*fcf3ce44SJohn Forte 	if (dd_id == 0) {
711*fcf3ce44SJohn Forte 		return (active);
712*fcf3ce44SJohn Forte 	}
713*fcf3ce44SJohn Forte 
714*fcf3ce44SJohn Forte 	dds_matrix = cache_get_matrix(OBJ_DDS);
715*fcf3ce44SJohn Forte 	primary = GET_PRIMARY(dd_id);
716*fcf3ce44SJohn Forte 	second = GET_SECOND(dd_id);
717*fcf3ce44SJohn Forte 
718*fcf3ce44SJohn Forte 	if (primary < dds_matrix->x) {
719*fcf3ce44SJohn Forte 		i = 0;
720*fcf3ce44SJohn Forte 		while (i < dds_matrix->y) {
721*fcf3ce44SJohn Forte 			bmp = MATRIX_X_UNIT(dds_matrix, i);
722*fcf3ce44SJohn Forte 			x_info = MATRIX_X_INFO(bmp);
723*fcf3ce44SJohn Forte 			if (x_info != 0 &&
724*fcf3ce44SJohn Forte 			    TEST_MEMBERSHIP(bmp, primary, second) != 0) {
725*fcf3ce44SJohn Forte 				if (get_dds_status(x_info) != 0) {
726*fcf3ce44SJohn Forte 					active = 1;
727*fcf3ce44SJohn Forte 					break;
728*fcf3ce44SJohn Forte 				}
729*fcf3ce44SJohn Forte 			}
730*fcf3ce44SJohn Forte 			i ++;
731*fcf3ce44SJohn Forte 		}
732*fcf3ce44SJohn Forte 	}
733*fcf3ce44SJohn Forte 
734*fcf3ce44SJohn Forte 	return (active);
735*fcf3ce44SJohn Forte }
736*fcf3ce44SJohn Forte 
737*fcf3ce44SJohn Forte int
get_scope(uchar_t * node_name,bmp_t ** p,uint32_t * n)738*fcf3ce44SJohn Forte get_scope(
739*fcf3ce44SJohn Forte 	uchar_t *node_name,
740*fcf3ce44SJohn Forte 	bmp_t **p,
741*fcf3ce44SJohn Forte 	uint32_t *n
742*fcf3ce44SJohn Forte )
743*fcf3ce44SJohn Forte {
744*fcf3ce44SJohn Forte 	int ec = 0;
745*fcf3ce44SJohn Forte 
746*fcf3ce44SJohn Forte 	lookup_ctrl_t lc;
747*fcf3ce44SJohn Forte 	uint32_t uid;
748*fcf3ce44SJohn Forte 
749*fcf3ce44SJohn Forte 	matrix_t *dd_matrix;
750*fcf3ce44SJohn Forte 	uint32_t primary;
751*fcf3ce44SJohn Forte 	uint32_t second;
752*fcf3ce44SJohn Forte 	uint32_t x_info;
753*fcf3ce44SJohn Forte 	bmp_t *bmp;
754*fcf3ce44SJohn Forte 	int i, j;
755*fcf3ce44SJohn Forte 
756*fcf3ce44SJohn Forte 	bmp_t *tmp_p;
757*fcf3ce44SJohn Forte 	uint32_t tmp_n;
758*fcf3ce44SJohn Forte 
759*fcf3ce44SJohn Forte 	bmp_t *short_p;
760*fcf3ce44SJohn Forte 	uint32_t short_n;
761*fcf3ce44SJohn Forte 
762*fcf3ce44SJohn Forte 	/* clear it */
763*fcf3ce44SJohn Forte 	*p = NULL;
764*fcf3ce44SJohn Forte 	*n = 0;
765*fcf3ce44SJohn Forte 
766*fcf3ce44SJohn Forte 	/* get the source object uid */
767*fcf3ce44SJohn Forte 	lc.curr_uid = 0;
768*fcf3ce44SJohn Forte 	lc.type = OBJ_ISCSI;
769*fcf3ce44SJohn Forte 	lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
770*fcf3ce44SJohn Forte 	lc.op[0] = OP_STRING;
771*fcf3ce44SJohn Forte 	lc.data[0].ptr = node_name;
772*fcf3ce44SJohn Forte 	lc.op[1] = 0;
773*fcf3ce44SJohn Forte 
774*fcf3ce44SJohn Forte 	uid = is_obj_there(&lc);
775*fcf3ce44SJohn Forte 
776*fcf3ce44SJohn Forte 	/* no such object */
777*fcf3ce44SJohn Forte 	if (uid == 0) {
778*fcf3ce44SJohn Forte 		return (ec);
779*fcf3ce44SJohn Forte 	}
780*fcf3ce44SJohn Forte 
781*fcf3ce44SJohn Forte 	dd_matrix = cache_get_matrix(OBJ_DD);
782*fcf3ce44SJohn Forte 	primary = GET_PRIMARY(uid);
783*fcf3ce44SJohn Forte 	second = GET_SECOND(uid);
784*fcf3ce44SJohn Forte 
785*fcf3ce44SJohn Forte 	if (primary < dd_matrix->x) {
786*fcf3ce44SJohn Forte 		i = 0;
787*fcf3ce44SJohn Forte 		while (i < dd_matrix->y) {
788*fcf3ce44SJohn Forte 			bmp = MATRIX_X_UNIT(dd_matrix, i);
789*fcf3ce44SJohn Forte 			x_info = MATRIX_X_INFO(bmp);
790*fcf3ce44SJohn Forte 			if (ec == 0 && x_info != 0 &&
791*fcf3ce44SJohn Forte 			    TEST_MEMBERSHIP(bmp, primary, second) != 0) {
792*fcf3ce44SJohn Forte 				if (is_dd_active(x_info) != 0 &&
793*fcf3ce44SJohn Forte 				    (ec = get_dd_matrix(x_info,
794*fcf3ce44SJohn Forte 				    &tmp_p, &tmp_n)) == 0) {
795*fcf3ce44SJohn Forte 					if (*p == NULL) {
796*fcf3ce44SJohn Forte 						*p = tmp_p;
797*fcf3ce44SJohn Forte 						*n = tmp_n;
798*fcf3ce44SJohn Forte 					} else {
799*fcf3ce44SJohn Forte 						if (*n >= tmp_n) {
800*fcf3ce44SJohn Forte 							short_p = tmp_p;
801*fcf3ce44SJohn Forte 							short_n = tmp_n;
802*fcf3ce44SJohn Forte 						} else {
803*fcf3ce44SJohn Forte 							short_p = *p;
804*fcf3ce44SJohn Forte 							short_n = *n;
805*fcf3ce44SJohn Forte 							*p = tmp_p;
806*fcf3ce44SJohn Forte 							*n = tmp_n;
807*fcf3ce44SJohn Forte 						}
808*fcf3ce44SJohn Forte 						j = 0;
809*fcf3ce44SJohn Forte 						while (j < short_n) {
810*fcf3ce44SJohn Forte 							(*p)[j] |= short_p[j];
811*fcf3ce44SJohn Forte 							j ++;
812*fcf3ce44SJohn Forte 						}
813*fcf3ce44SJohn Forte 						free(short_p);
814*fcf3ce44SJohn Forte 					}
815*fcf3ce44SJohn Forte 				}
816*fcf3ce44SJohn Forte 			}
817*fcf3ce44SJohn Forte 			i ++;
818*fcf3ce44SJohn Forte 		}
819*fcf3ce44SJohn Forte 	}
820*fcf3ce44SJohn Forte 
821*fcf3ce44SJohn Forte 	primary ++;
822*fcf3ce44SJohn Forte 	if (ec == 0 && *p == NULL) {
823*fcf3ce44SJohn Forte 		*p = (bmp_t *)calloc(primary, sizeof (bmp_t));
824*fcf3ce44SJohn Forte 		if (*p != NULL) {
825*fcf3ce44SJohn Forte 			*n = primary;
826*fcf3ce44SJohn Forte 		} else {
827*fcf3ce44SJohn Forte 			*n = 0;
828*fcf3ce44SJohn Forte 			ec = ISNS_RSP_INTERNAL_ERROR;
829*fcf3ce44SJohn Forte 		}
830*fcf3ce44SJohn Forte 	}
831*fcf3ce44SJohn Forte 
832*fcf3ce44SJohn Forte 	if (*p != NULL) {
833*fcf3ce44SJohn Forte 		(*p)[primary - 1] |= (1 << second);
834*fcf3ce44SJohn Forte 	}
835*fcf3ce44SJohn Forte 
836*fcf3ce44SJohn Forte 	return (ec);
837*fcf3ce44SJohn Forte }
838*fcf3ce44SJohn Forte 
839*fcf3ce44SJohn Forte int
cb_clone_attrs(void * p1,void * p2)840*fcf3ce44SJohn Forte cb_clone_attrs(
841*fcf3ce44SJohn Forte 	void *p1,
842*fcf3ce44SJohn Forte 	void *p2
843*fcf3ce44SJohn Forte )
844*fcf3ce44SJohn Forte {
845*fcf3ce44SJohn Forte 	int ec = 0;
846*fcf3ce44SJohn Forte 
847*fcf3ce44SJohn Forte 	isns_obj_t *obj = (isns_obj_t *)p1;
848*fcf3ce44SJohn Forte 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
849*fcf3ce44SJohn Forte 
850*fcf3ce44SJohn Forte 	isns_attr_t *attr;
851*fcf3ce44SJohn Forte 
852*fcf3ce44SJohn Forte 	int i = 1;
853*fcf3ce44SJohn Forte 
854*fcf3ce44SJohn Forte 	while (i < MAX_LOOKUP_CTRL &&
855*fcf3ce44SJohn Forte 	    lcp->op[i] != 0) {
856*fcf3ce44SJohn Forte 		i ++;
857*fcf3ce44SJohn Forte 	}
858*fcf3ce44SJohn Forte 
859*fcf3ce44SJohn Forte 	while (ec == 0 &&
860*fcf3ce44SJohn Forte 	    i < MAX_LOOKUP_CTRL &&
861*fcf3ce44SJohn Forte 	    lcp->id[i] != 0) {
862*fcf3ce44SJohn Forte 		switch (lcp->id[i]) {
863*fcf3ce44SJohn Forte 		case ISNS_ISCSI_NAME_ATTR_ID:
864*fcf3ce44SJohn Forte 			attr = &obj->attrs[ATTR_INDEX_ISCSI(
865*fcf3ce44SJohn Forte 			    ISNS_ISCSI_NAME_ATTR_ID)];
866*fcf3ce44SJohn Forte 			lcp->data[i].ptr = (uchar_t *)malloc(attr->len);
867*fcf3ce44SJohn Forte 			if (lcp->data[i].ptr != NULL) {
868*fcf3ce44SJohn Forte 				(void) strcpy((char *)lcp->data[i].ptr,
869*fcf3ce44SJohn Forte 				    (char *)attr->value.ptr);
870*fcf3ce44SJohn Forte 			} else {
871*fcf3ce44SJohn Forte 				/* memory exhausted */
872*fcf3ce44SJohn Forte 				ec = ISNS_RSP_INTERNAL_ERROR;
873*fcf3ce44SJohn Forte 			}
874*fcf3ce44SJohn Forte 			break;
875*fcf3ce44SJohn Forte 		case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
876*fcf3ce44SJohn Forte 			attr = &obj->attrs[ATTR_INDEX_ISCSI(
877*fcf3ce44SJohn Forte 			    ISNS_ISCSI_NODE_TYPE_ATTR_ID)];
878*fcf3ce44SJohn Forte 			lcp->data[i].ui = attr->value.ui;
879*fcf3ce44SJohn Forte 			break;
880*fcf3ce44SJohn Forte 		case ISNS_PG_ISCSI_NAME_ATTR_ID:
881*fcf3ce44SJohn Forte 			attr = &obj->attrs[ATTR_INDEX_PG(
882*fcf3ce44SJohn Forte 			    ISNS_PG_ISCSI_NAME_ATTR_ID)];
883*fcf3ce44SJohn Forte 			lcp->data[i].ptr = (uchar_t *)malloc(attr->len);
884*fcf3ce44SJohn Forte 			if (lcp->data[i].ptr != NULL) {
885*fcf3ce44SJohn Forte 				(void) strcpy((char *)lcp->data[i].ptr,
886*fcf3ce44SJohn Forte 				    (char *)attr->value.ptr);
887*fcf3ce44SJohn Forte 			} else {
888*fcf3ce44SJohn Forte 				/* memory exhausted */
889*fcf3ce44SJohn Forte 				ec = ISNS_RSP_INTERNAL_ERROR;
890*fcf3ce44SJohn Forte 			}
891*fcf3ce44SJohn Forte 			break;
892*fcf3ce44SJohn Forte 		case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
893*fcf3ce44SJohn Forte 			attr = &obj->attrs[ATTR_INDEX_PG(
894*fcf3ce44SJohn Forte 			    ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)];
895*fcf3ce44SJohn Forte 			lcp->data[i].ip = (in6_addr_t *)malloc(attr->len);
896*fcf3ce44SJohn Forte 			if (lcp->data[i].ip != NULL) {
897*fcf3ce44SJohn Forte 				(void) memcpy(lcp->data[i].ip,
898*fcf3ce44SJohn Forte 				    attr->value.ip, attr->len);
899*fcf3ce44SJohn Forte 			} else {
900*fcf3ce44SJohn Forte 				/* memory exhausted */
901*fcf3ce44SJohn Forte 				ec = ISNS_RSP_INTERNAL_ERROR;
902*fcf3ce44SJohn Forte 			}
903*fcf3ce44SJohn Forte 			break;
904*fcf3ce44SJohn Forte 		case ISNS_PG_PORTAL_PORT_ATTR_ID:
905*fcf3ce44SJohn Forte 			attr = &obj->attrs[ATTR_INDEX_PG(
906*fcf3ce44SJohn Forte 			    ISNS_PG_PORTAL_PORT_ATTR_ID)];
907*fcf3ce44SJohn Forte 			lcp->data[i].ui = attr->value.ui;
908*fcf3ce44SJohn Forte 			break;
909*fcf3ce44SJohn Forte 		case ISNS_PORTAL_IP_ADDR_ATTR_ID:
910*fcf3ce44SJohn Forte 			attr = &obj->attrs[ATTR_INDEX_PORTAL(
911*fcf3ce44SJohn Forte 			    ISNS_PORTAL_IP_ADDR_ATTR_ID)];
912*fcf3ce44SJohn Forte 			lcp->data[i].ip = (in6_addr_t *)malloc(attr->len);
913*fcf3ce44SJohn Forte 			if (lcp->data[i].ip != NULL) {
914*fcf3ce44SJohn Forte 				(void) memcpy(lcp->data[i].ip,
915*fcf3ce44SJohn Forte 				    attr->value.ip, attr->len);
916*fcf3ce44SJohn Forte 			} else {
917*fcf3ce44SJohn Forte 				/* memory exhausted */
918*fcf3ce44SJohn Forte 				ec = ISNS_RSP_INTERNAL_ERROR;
919*fcf3ce44SJohn Forte 			}
920*fcf3ce44SJohn Forte 			break;
921*fcf3ce44SJohn Forte 		case ISNS_PORTAL_PORT_ATTR_ID:
922*fcf3ce44SJohn Forte 		case ISNS_ESI_PORT_ATTR_ID:
923*fcf3ce44SJohn Forte 			attr = &obj->attrs[ATTR_INDEX_PORTAL(lcp->id[i])];
924*fcf3ce44SJohn Forte 			if (attr->tag != 0 && attr->value.ui != 0) {
925*fcf3ce44SJohn Forte 				lcp->data[i].ui = attr->value.ui;
926*fcf3ce44SJohn Forte 			} else {
927*fcf3ce44SJohn Forte 				lcp->data[i].ui = 0;
928*fcf3ce44SJohn Forte 			}
929*fcf3ce44SJohn Forte 			break;
930*fcf3ce44SJohn Forte 		default:
931*fcf3ce44SJohn Forte 			ASSERT(0);
932*fcf3ce44SJohn Forte 			lcp->data[i].ui = 0;
933*fcf3ce44SJohn Forte 			break;
934*fcf3ce44SJohn Forte 		}
935*fcf3ce44SJohn Forte 		i ++;
936*fcf3ce44SJohn Forte 	}
937*fcf3ce44SJohn Forte 
938*fcf3ce44SJohn Forte 	return (ec);
939*fcf3ce44SJohn Forte }
940*fcf3ce44SJohn Forte 
941*fcf3ce44SJohn Forte static matrix_t *
new_matrix(uint32_t x,uint32_t y)942*fcf3ce44SJohn Forte new_matrix(
943*fcf3ce44SJohn Forte 	uint32_t x,
944*fcf3ce44SJohn Forte 	uint32_t y
945*fcf3ce44SJohn Forte )
946*fcf3ce44SJohn Forte {
947*fcf3ce44SJohn Forte 	matrix_t *matrix;
948*fcf3ce44SJohn Forte 
949*fcf3ce44SJohn Forte 	matrix = (matrix_t *)malloc(sizeof (matrix_t));
950*fcf3ce44SJohn Forte 	if (matrix != NULL) {
951*fcf3ce44SJohn Forte 		matrix->x = x;
952*fcf3ce44SJohn Forte 		matrix->y = y;
953*fcf3ce44SJohn Forte 		matrix->m = (bmp_t *)calloc(y, SIZEOF_X_UNIT(matrix));
954*fcf3ce44SJohn Forte 		if (matrix->m == NULL) {
955*fcf3ce44SJohn Forte 			free(matrix);
956*fcf3ce44SJohn Forte 			matrix = NULL;
957*fcf3ce44SJohn Forte 		}
958*fcf3ce44SJohn Forte 	}
959*fcf3ce44SJohn Forte 
960*fcf3ce44SJohn Forte 	return (matrix);
961*fcf3ce44SJohn Forte }
962*fcf3ce44SJohn Forte 
963*fcf3ce44SJohn Forte int
dd_matrix_init(struct cache * c)964*fcf3ce44SJohn Forte dd_matrix_init(
965*fcf3ce44SJohn Forte 	struct cache *c
966*fcf3ce44SJohn Forte )
967*fcf3ce44SJohn Forte {
968*fcf3ce44SJohn Forte 	matrix_t *x;
969*fcf3ce44SJohn Forte 	bmp_t *bmp;
970*fcf3ce44SJohn Forte 	uint32_t primary;
971*fcf3ce44SJohn Forte 	uint32_t second;
972*fcf3ce44SJohn Forte 
973*fcf3ce44SJohn Forte 	/*
974*fcf3ce44SJohn Forte 	 * allocate an array of pointer for dd and dd-set matrix.
975*fcf3ce44SJohn Forte 	 */
976*fcf3ce44SJohn Forte 	c->x = (matrix_t **)calloc(2, sizeof (matrix_t *));
977*fcf3ce44SJohn Forte 	if (c->x == NULL) {
978*fcf3ce44SJohn Forte 		return (1);
979*fcf3ce44SJohn Forte 	}
980*fcf3ce44SJohn Forte 
981*fcf3ce44SJohn Forte 	/*
982*fcf3ce44SJohn Forte 	 * create dd matrix.
983*fcf3ce44SJohn Forte 	 */
984*fcf3ce44SJohn Forte 	x = new_matrix(8, 64);
985*fcf3ce44SJohn Forte 	if (x != NULL) {
986*fcf3ce44SJohn Forte 		x->c = c;
987*fcf3ce44SJohn Forte 		c->x[0] = x;
988*fcf3ce44SJohn Forte 	} else {
989*fcf3ce44SJohn Forte 		return (1);
990*fcf3ce44SJohn Forte 	}
991*fcf3ce44SJohn Forte 
992*fcf3ce44SJohn Forte 	/*
993*fcf3ce44SJohn Forte 	 * Mark the first array on the y axis for Default DD.
994*fcf3ce44SJohn Forte 	 */
995*fcf3ce44SJohn Forte 	bmp = MATRIX_X_UNIT(x, 0);
996*fcf3ce44SJohn Forte 	MATRIX_X_INFO(bmp) = ISNS_DEFAULT_DD_ID;
997*fcf3ce44SJohn Forte 
998*fcf3ce44SJohn Forte 	/*
999*fcf3ce44SJohn Forte 	 * create dd set matrix.
1000*fcf3ce44SJohn Forte 	 */
1001*fcf3ce44SJohn Forte 	x = new_matrix(2, 16);
1002*fcf3ce44SJohn Forte 	if (x != NULL) {
1003*fcf3ce44SJohn Forte 		x->c = c;
1004*fcf3ce44SJohn Forte 		c->x[1] = x;
1005*fcf3ce44SJohn Forte 	} else {
1006*fcf3ce44SJohn Forte 		return (1);
1007*fcf3ce44SJohn Forte 	}
1008*fcf3ce44SJohn Forte 
1009*fcf3ce44SJohn Forte 	/*
1010*fcf3ce44SJohn Forte 	 * Mark the first array on the y axis for Default DD-set.
1011*fcf3ce44SJohn Forte 	 */
1012*fcf3ce44SJohn Forte 	bmp = MATRIX_X_UNIT(x, 0);
1013*fcf3ce44SJohn Forte 	MATRIX_X_INFO(bmp) = ISNS_DEFAULT_DD_SET_ID;
1014*fcf3ce44SJohn Forte 
1015*fcf3ce44SJohn Forte 	/*
1016*fcf3ce44SJohn Forte 	 * Add Default DD as a member of Default DD-set.
1017*fcf3ce44SJohn Forte 	 */
1018*fcf3ce44SJohn Forte 	primary = GET_PRIMARY(ISNS_DEFAULT_DD_ID);
1019*fcf3ce44SJohn Forte 	second = GET_SECOND(ISNS_DEFAULT_DD_ID);
1020*fcf3ce44SJohn Forte 	SET_MEMBERSHIP(bmp, primary, second);
1021*fcf3ce44SJohn Forte 
1022*fcf3ce44SJohn Forte 	return (0);
1023*fcf3ce44SJohn Forte }
1024*fcf3ce44SJohn Forte 
1025*fcf3ce44SJohn Forte static uint32_t
get_ds_id(matrix_t * matrix,uint32_t m_id,uint32_t curr_id)1026*fcf3ce44SJohn Forte get_ds_id(
1027*fcf3ce44SJohn Forte 	matrix_t *matrix,
1028*fcf3ce44SJohn Forte 	uint32_t m_id,
1029*fcf3ce44SJohn Forte 	uint32_t curr_id
1030*fcf3ce44SJohn Forte )
1031*fcf3ce44SJohn Forte {
1032*fcf3ce44SJohn Forte 	bmp_t *bmp;
1033*fcf3ce44SJohn Forte 	uint32_t primary = GET_PRIMARY(m_id);
1034*fcf3ce44SJohn Forte 	uint32_t second = GET_SECOND(m_id);
1035*fcf3ce44SJohn Forte 	uint32_t dd_id = 0;
1036*fcf3ce44SJohn Forte 	uint32_t uid;
1037*fcf3ce44SJohn Forte 	int i = 0;
1038*fcf3ce44SJohn Forte 
1039*fcf3ce44SJohn Forte 	if (matrix->x > primary) {
1040*fcf3ce44SJohn Forte 		while (i < matrix->y) {
1041*fcf3ce44SJohn Forte 			bmp = MATRIX_X_UNIT(matrix, i);
1042*fcf3ce44SJohn Forte 			uid = MATRIX_X_INFO(bmp);
1043*fcf3ce44SJohn Forte 			if (uid > curr_id &&
1044*fcf3ce44SJohn Forte 			    TEST_MEMBERSHIP(bmp, primary, second) != 0) {
1045*fcf3ce44SJohn Forte 				if (dd_id == 0 || uid < dd_id) {
1046*fcf3ce44SJohn Forte 					dd_id = uid;
1047*fcf3ce44SJohn Forte 				}
1048*fcf3ce44SJohn Forte 			}
1049*fcf3ce44SJohn Forte 			i ++;
1050*fcf3ce44SJohn Forte 		}
1051*fcf3ce44SJohn Forte 	}
1052*fcf3ce44SJohn Forte 
1053