xref: /onnv-gate/usr/src/cmd/isns/isnsd/qry.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_func.h"
33*7836SJohn.Forte@Sun.COM #include "isns_msgq.h"
34*7836SJohn.Forte@Sun.COM #include "isns_htab.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_dd.h"
38*7836SJohn.Forte@Sun.COM #include "isns_pdu.h"
39*7836SJohn.Forte@Sun.COM #include "isns_qry.h"
40*7836SJohn.Forte@Sun.COM 
41*7836SJohn.Forte@Sun.COM /*
42*7836SJohn.Forte@Sun.COM  * external variables
43*7836SJohn.Forte@Sun.COM  */
44*7836SJohn.Forte@Sun.COM extern const int NUM_OF_ATTRS[MAX_OBJ_TYPE_FOR_SIZE];
45*7836SJohn.Forte@Sun.COM extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
46*7836SJohn.Forte@Sun.COM extern const int NUM_OF_CHILD[MAX_OBJ_TYPE];
47*7836SJohn.Forte@Sun.COM extern const int TYPE_OF_CHILD[MAX_OBJ_TYPE][MAX_CHILD_TYPE];
48*7836SJohn.Forte@Sun.COM 
49*7836SJohn.Forte@Sun.COM /*
50*7836SJohn.Forte@Sun.COM  * global variables
51*7836SJohn.Forte@Sun.COM  */
52*7836SJohn.Forte@Sun.COM const int TAG_RANGE[MAX_OBJ_TYPE][3] = {
53*7836SJohn.Forte@Sun.COM 	{ 0, 0 },
54*7836SJohn.Forte@Sun.COM 	{ ENTITY_KEY, LAST_TAG_ENTITY, ENTITY_END },
55*7836SJohn.Forte@Sun.COM 	{ ISCSI_KEY, LAST_TAG_ISCSI, ISCSI_END },
56*7836SJohn.Forte@Sun.COM 	{ PORTAL_KEY1, LAST_TAG_PORTAL, PORTAL_END },
57*7836SJohn.Forte@Sun.COM 	{ PG_KEY1, LAST_TAG_PG, PG_END },
58*7836SJohn.Forte@Sun.COM 	{ DD_KEY, LAST_TAG_DD, DD_END },
59*7836SJohn.Forte@Sun.COM 	{ DDS_KEY, LAST_TAG_DDS, DDS_END }
60*7836SJohn.Forte@Sun.COM };
61*7836SJohn.Forte@Sun.COM 
62*7836SJohn.Forte@Sun.COM /*
63*7836SJohn.Forte@Sun.COM  * local variables
64*7836SJohn.Forte@Sun.COM  */
65*7836SJohn.Forte@Sun.COM typedef int (*qry_func_t)(lookup_ctrl_t *);
66*7836SJohn.Forte@Sun.COM 
67*7836SJohn.Forte@Sun.COM /* Edge functions of each adjacent object */
68*7836SJohn.Forte@Sun.COM static int qry_c2e(lookup_ctrl_t *);
69*7836SJohn.Forte@Sun.COM static int qry_ds2m(lookup_ctrl_t *);
70*7836SJohn.Forte@Sun.COM static int qry_slf(lookup_ctrl_t *);
71*7836SJohn.Forte@Sun.COM static int qry_e2i(lookup_ctrl_t *);
72*7836SJohn.Forte@Sun.COM static int qry_e2p(lookup_ctrl_t *);
73*7836SJohn.Forte@Sun.COM static int qry_e2g(lookup_ctrl_t *);
74*7836SJohn.Forte@Sun.COM static int qry_i2g(lookup_ctrl_t *);
75*7836SJohn.Forte@Sun.COM static int qry_i2d(lookup_ctrl_t *);
76*7836SJohn.Forte@Sun.COM static int qry_p2g(lookup_ctrl_t *);
77*7836SJohn.Forte@Sun.COM static int qry_g2i(lookup_ctrl_t *);
78*7836SJohn.Forte@Sun.COM static int qry_g2p(lookup_ctrl_t *);
79*7836SJohn.Forte@Sun.COM static int qry_d2s(lookup_ctrl_t *);
80*7836SJohn.Forte@Sun.COM 
81*7836SJohn.Forte@Sun.COM /* The directed cyclic graph of query procedure. */
82*7836SJohn.Forte@Sun.COM /* __|____e_________i_________p_________g_________d_________s____ */
83*7836SJohn.Forte@Sun.COM /* e | qry_slf...qry_e2i...qry_e2p...qry_e2g...NULL......NULL.... */
84*7836SJohn.Forte@Sun.COM /* i | qry_c2e...qry_slf...NULL......qry_i2g...qry_i2d...NULL.... */
85*7836SJohn.Forte@Sun.COM /* p | qry_c2e...NULL......qry_slf...qry_p2g...NULL......NULL.... */
86*7836SJohn.Forte@Sun.COM /* g | qry_c2e...qry_g2i...qry_g2p...qry_slf...NULL......NULL.... */
87*7836SJohn.Forte@Sun.COM /* d | NULL......qry_ds2m..NULL......NULL......qry_slf...qry_d2s. */
88*7836SJohn.Forte@Sun.COM /* s | NULL......NULL......NULL......NULL......qry_ds2m..qry_slf. */
89*7836SJohn.Forte@Sun.COM 
90*7836SJohn.Forte@Sun.COM /* The type of spanning tree of query graph. */
91*7836SJohn.Forte@Sun.COM typedef struct adjvex {
92*7836SJohn.Forte@Sun.COM 	qry_func_t f;
93*7836SJohn.Forte@Sun.COM 	isns_type_t t;
94*7836SJohn.Forte@Sun.COM 	struct adjvex const *v;
95*7836SJohn.Forte@Sun.COM } adjvex_t;
96*7836SJohn.Forte@Sun.COM 
97*7836SJohn.Forte@Sun.COM /* The solid edges in the spanning tree. */
98*7836SJohn.Forte@Sun.COM static const adjvex_t v_slf = { &qry_slf,  0,		NULL };
99*7836SJohn.Forte@Sun.COM static const adjvex_t v_c2e = { &qry_c2e,  OBJ_ENTITY,	NULL };
100*7836SJohn.Forte@Sun.COM static const adjvex_t v_e2i = { &qry_e2i,  OBJ_ISCSI,	NULL };
101*7836SJohn.Forte@Sun.COM static const adjvex_t v_e2p = { &qry_e2p,  OBJ_PORTAL,	NULL };
102*7836SJohn.Forte@Sun.COM static const adjvex_t v_e2g = { &qry_e2g,  OBJ_PG,	NULL };
103*7836SJohn.Forte@Sun.COM static const adjvex_t v_i2g = { &qry_i2g,  OBJ_PG,	NULL };
104*7836SJohn.Forte@Sun.COM static const adjvex_t v_i2d = { &qry_i2d,  OBJ_DD,	NULL };
105*7836SJohn.Forte@Sun.COM static const adjvex_t v_p2g = { &qry_p2g,  OBJ_PG,	NULL };
106*7836SJohn.Forte@Sun.COM static const adjvex_t v_g2i = { &qry_g2i,  OBJ_ISCSI,	NULL };
107*7836SJohn.Forte@Sun.COM static const adjvex_t v_g2p = { &qry_g2p,  OBJ_PORTAL,	NULL };
108*7836SJohn.Forte@Sun.COM static const adjvex_t v_d2s = { &qry_d2s,  OBJ_DDS,	NULL };
109*7836SJohn.Forte@Sun.COM static const adjvex_t v_d2i = { &qry_ds2m, OBJ_ISCSI,	NULL };
110*7836SJohn.Forte@Sun.COM static const adjvex_t v_s2d = { &qry_ds2m, OBJ_DD,	NULL };
111*7836SJohn.Forte@Sun.COM 
112*7836SJohn.Forte@Sun.COM /* The virtual edges in the spanning tree. */
113*7836SJohn.Forte@Sun.COM static const adjvex_t v_i2p = { &qry_i2g,  OBJ_PG,    &v_g2p };
114*7836SJohn.Forte@Sun.COM static const adjvex_t v_i2s = { &qry_i2d,  OBJ_DD,    &v_d2s };
115*7836SJohn.Forte@Sun.COM 
116*7836SJohn.Forte@Sun.COM static const adjvex_t v_g2d = { &qry_g2i,  OBJ_ISCSI, &v_i2d };
117*7836SJohn.Forte@Sun.COM static const adjvex_t v_g2s = { &qry_g2i,  OBJ_ISCSI, &v_i2s };
118*7836SJohn.Forte@Sun.COM 
119*7836SJohn.Forte@Sun.COM static const adjvex_t v_p2i = { &qry_p2g,  OBJ_PG,    &v_g2i };
120*7836SJohn.Forte@Sun.COM static const adjvex_t v_p2d = { &qry_p2g,  OBJ_PG,    &v_g2d };
121*7836SJohn.Forte@Sun.COM static const adjvex_t v_p2s = { &qry_p2g,  OBJ_PG,    &v_g2s };
122*7836SJohn.Forte@Sun.COM 
123*7836SJohn.Forte@Sun.COM static const adjvex_t v_e2d = { &qry_e2i,  OBJ_ISCSI, &v_i2d };
124*7836SJohn.Forte@Sun.COM static const adjvex_t v_e2s = { &qry_e2i,  OBJ_ISCSI, &v_i2s };
125*7836SJohn.Forte@Sun.COM 
126*7836SJohn.Forte@Sun.COM static const adjvex_t v_d2e = { &qry_ds2m, OBJ_ISCSI, &v_c2e };
127*7836SJohn.Forte@Sun.COM static const adjvex_t v_d2p = { &qry_ds2m, OBJ_ISCSI, &v_i2p };
128*7836SJohn.Forte@Sun.COM static const adjvex_t v_d2g = { &qry_ds2m, OBJ_ISCSI, &v_i2g };
129*7836SJohn.Forte@Sun.COM 
130*7836SJohn.Forte@Sun.COM static const adjvex_t v_s2e = { &qry_ds2m, OBJ_DD,    &v_d2e };
131*7836SJohn.Forte@Sun.COM static const adjvex_t v_s2i = { &qry_ds2m, OBJ_DD,    &v_d2i };
132*7836SJohn.Forte@Sun.COM static const adjvex_t v_s2p = { &qry_ds2m, OBJ_DD,    &v_d2p };
133*7836SJohn.Forte@Sun.COM static const adjvex_t v_s2g = { &qry_ds2m, OBJ_DD,    &v_d2g };
134*7836SJohn.Forte@Sun.COM 
135*7836SJohn.Forte@Sun.COM /* the vector of query graph */
136*7836SJohn.Forte@Sun.COM static const adjvex_t *qry_puzzle[MAX_OBJ_TYPE][MAX_OBJ_TYPE] = {
137*7836SJohn.Forte@Sun.COM { NULL },
138*7836SJohn.Forte@Sun.COM { NULL, &v_slf, &v_e2i, &v_e2p, &v_e2g, &v_e2d, &v_e2s },
139*7836SJohn.Forte@Sun.COM { NULL, &v_c2e, &v_slf, &v_i2p, &v_i2g, &v_i2d, &v_i2s },
140*7836SJohn.Forte@Sun.COM { NULL, &v_c2e, &v_p2i, &v_slf, &v_p2g, &v_p2d, &v_p2s },
141*7836SJohn.Forte@Sun.COM { NULL, &v_c2e, &v_g2i, &v_g2p, &v_slf, &v_g2d, &v_g2s },
142*7836SJohn.Forte@Sun.COM { NULL, &v_d2e, &v_d2i, &v_d2p, &v_d2g, &v_slf, &v_d2s },
143*7836SJohn.Forte@Sun.COM { NULL, &v_s2e, &v_s2i, &v_s2p, &v_s2g, &v_s2d, &v_slf }
144*7836SJohn.Forte@Sun.COM };
145*7836SJohn.Forte@Sun.COM 
146*7836SJohn.Forte@Sun.COM static int
cb_qry_parent_uid(void * p1,void * p2)147*7836SJohn.Forte@Sun.COM cb_qry_parent_uid(
148*7836SJohn.Forte@Sun.COM 	void *p1,
149*7836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
150*7836SJohn.Forte@Sun.COM 	void *p2
151*7836SJohn.Forte@Sun.COM )
152*7836SJohn.Forte@Sun.COM {
153*7836SJohn.Forte@Sun.COM 	uint32_t puid = get_parent_uid((isns_obj_t *)p1);
154*7836SJohn.Forte@Sun.COM 	return ((int)puid);
155*7836SJohn.Forte@Sun.COM }
156*7836SJohn.Forte@Sun.COM 
157*7836SJohn.Forte@Sun.COM static int
cb_qry_child_uids(void * p1,void * p2)158*7836SJohn.Forte@Sun.COM cb_qry_child_uids(
159*7836SJohn.Forte@Sun.COM 	void *p1,
160*7836SJohn.Forte@Sun.COM 	void *p2
161*7836SJohn.Forte@Sun.COM )
162*7836SJohn.Forte@Sun.COM {
163*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
164*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
165*7836SJohn.Forte@Sun.COM 	isns_type_t type = lcp->data[1].ui;
166*7836SJohn.Forte@Sun.COM 	uint32_t *uidp = get_child_t(obj, type);
167*7836SJohn.Forte@Sun.COM 	uint32_t num = 0;
168*7836SJohn.Forte@Sun.COM 	uint32_t *p;
169*7836SJohn.Forte@Sun.COM 
170*7836SJohn.Forte@Sun.COM 	if (uidp != NULL && *uidp > 0) {
171*7836SJohn.Forte@Sun.COM 		num = *uidp;
172*7836SJohn.Forte@Sun.COM 		p = malloc(num * sizeof (*p));
173*7836SJohn.Forte@Sun.COM 		if (p != NULL) {
174*7836SJohn.Forte@Sun.COM 			uidp ++;
175*7836SJohn.Forte@Sun.COM 			(void) memcpy(p, uidp, num * sizeof (*p));
176*7836SJohn.Forte@Sun.COM 			lcp->id[2] = num;
177*7836SJohn.Forte@Sun.COM 			lcp->data[2].ptr = (uchar_t *)p;
178*7836SJohn.Forte@Sun.COM 		} else {
179*7836SJohn.Forte@Sun.COM 			return (ISNS_RSP_INTERNAL_ERROR);
180*7836SJohn.Forte@Sun.COM 		}
181*7836SJohn.Forte@Sun.COM 	}
182*7836SJohn.Forte@Sun.COM 
183*7836SJohn.Forte@Sun.COM 	return (0);
184*7836SJohn.Forte@Sun.COM }
185*7836SJohn.Forte@Sun.COM 
186*7836SJohn.Forte@Sun.COM static int
e2c(lookup_ctrl_t * lcp,isns_type_t type)187*7836SJohn.Forte@Sun.COM e2c(
188*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp,
189*7836SJohn.Forte@Sun.COM 	isns_type_t type
190*7836SJohn.Forte@Sun.COM )
191*7836SJohn.Forte@Sun.COM {
192*7836SJohn.Forte@Sun.COM 	int ec = 0;
193*7836SJohn.Forte@Sun.COM 
194*7836SJohn.Forte@Sun.COM 	uint32_t uid = lcp->curr_uid; /* last child */
195*7836SJohn.Forte@Sun.COM 	uint32_t num_of_child;
196*7836SJohn.Forte@Sun.COM 	uint32_t *uids;
197*7836SJohn.Forte@Sun.COM 
198*7836SJohn.Forte@Sun.COM 	uint32_t tmp_uid = 0;
199*7836SJohn.Forte@Sun.COM 
200*7836SJohn.Forte@Sun.COM 	/* the first times of query */
201*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
202*7836SJohn.Forte@Sun.COM 		lcp->data[1].ui = type;
203*7836SJohn.Forte@Sun.COM 		ec = cache_lookup(lcp, NULL, cb_qry_child_uids);
204*7836SJohn.Forte@Sun.COM 	}
205*7836SJohn.Forte@Sun.COM 
206*7836SJohn.Forte@Sun.COM 	num_of_child = lcp->id[2];
207*7836SJohn.Forte@Sun.COM 	uids = (uint32_t *)lcp->data[2].ptr;
208*7836SJohn.Forte@Sun.COM 
209*7836SJohn.Forte@Sun.COM 	while (num_of_child > 0) {
210*7836SJohn.Forte@Sun.COM 		if (*uids > uid) {
211*7836SJohn.Forte@Sun.COM 			tmp_uid = *uids;
212*7836SJohn.Forte@Sun.COM 			break;
213*7836SJohn.Forte@Sun.COM 		}
214*7836SJohn.Forte@Sun.COM 		uids ++;
215*7836SJohn.Forte@Sun.COM 		num_of_child --;
216*7836SJohn.Forte@Sun.COM 	}
217*7836SJohn.Forte@Sun.COM 
218*7836SJohn.Forte@Sun.COM 	uid = tmp_uid;
219*7836SJohn.Forte@Sun.COM 
220*7836SJohn.Forte@Sun.COM 	/* no more child, clean up memory */
221*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
222*7836SJohn.Forte@Sun.COM 		lcp->data[1].ui = 0;
223*7836SJohn.Forte@Sun.COM 		lcp->id[2] = 0;
224*7836SJohn.Forte@Sun.COM 		lcp->data[2].ptr = NULL;
225*7836SJohn.Forte@Sun.COM 
226*7836SJohn.Forte@Sun.COM 		/* free up the memory */
227*7836SJohn.Forte@Sun.COM 		free(uids);
228*7836SJohn.Forte@Sun.COM 	}
229*7836SJohn.Forte@Sun.COM 
230*7836SJohn.Forte@Sun.COM 	/* save it for returning and querying next uid */
231*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = uid;
232*7836SJohn.Forte@Sun.COM 
233*7836SJohn.Forte@Sun.COM 	return (ec);
234*7836SJohn.Forte@Sun.COM }
235*7836SJohn.Forte@Sun.COM 
236*7836SJohn.Forte@Sun.COM static int
qry_c2e(lookup_ctrl_t * lcp)237*7836SJohn.Forte@Sun.COM qry_c2e(
238*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
239*7836SJohn.Forte@Sun.COM )
240*7836SJohn.Forte@Sun.COM {
241*7836SJohn.Forte@Sun.COM 	uint32_t uid;
242*7836SJohn.Forte@Sun.COM 
243*7836SJohn.Forte@Sun.COM 	/* child object has only one parent */
244*7836SJohn.Forte@Sun.COM 	if (lcp->curr_uid == 0) {
245*7836SJohn.Forte@Sun.COM 		uid = (uint32_t)cache_lookup(lcp, NULL,
246*7836SJohn.Forte@Sun.COM 		    cb_qry_parent_uid);
247*7836SJohn.Forte@Sun.COM 	} else {
248*7836SJohn.Forte@Sun.COM 		uid = 0;
249*7836SJohn.Forte@Sun.COM 	}
250*7836SJohn.Forte@Sun.COM 
251*7836SJohn.Forte@Sun.COM 	/* save the result for returnning */
252*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = uid;
253*7836SJohn.Forte@Sun.COM 
254*7836SJohn.Forte@Sun.COM 	return (0);
255*7836SJohn.Forte@Sun.COM }
256*7836SJohn.Forte@Sun.COM 
257*7836SJohn.Forte@Sun.COM static int
qry_ds2m(lookup_ctrl_t * lcp)258*7836SJohn.Forte@Sun.COM qry_ds2m(
259*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
260*7836SJohn.Forte@Sun.COM )
261*7836SJohn.Forte@Sun.COM {
262*7836SJohn.Forte@Sun.COM 	int ec = 0;
263*7836SJohn.Forte@Sun.COM 
264*7836SJohn.Forte@Sun.COM 	uint32_t uid = lcp->curr_uid; /* last member */
265*7836SJohn.Forte@Sun.COM 	isns_type_t type = lcp->type;
266*7836SJohn.Forte@Sun.COM 	uint32_t ds_id = lcp->data[0].ui;
267*7836SJohn.Forte@Sun.COM 
268*7836SJohn.Forte@Sun.COM 	uint32_t tmp_uid;
269*7836SJohn.Forte@Sun.COM 
270*7836SJohn.Forte@Sun.COM 	uint32_t n;
271*7836SJohn.Forte@Sun.COM 	bmp_t *p;
272*7836SJohn.Forte@Sun.COM 
273*7836SJohn.Forte@Sun.COM 	/* the first times of query */
274*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
275*7836SJohn.Forte@Sun.COM 		ec = (type == OBJ_DD) ?
276*7836SJohn.Forte@Sun.COM 		    get_dd_matrix(ds_id, &p, &n) :
277*7836SJohn.Forte@Sun.COM 		    get_dds_matrix(ds_id, &p, &n);
278*7836SJohn.Forte@Sun.COM 		lcp->id[1] = n;
279*7836SJohn.Forte@Sun.COM 		lcp->data[1].ptr = (uchar_t *)p;
280*7836SJohn.Forte@Sun.COM 	} else {
281*7836SJohn.Forte@Sun.COM 		n = lcp->id[1];
282*7836SJohn.Forte@Sun.COM 		p = (bmp_t *)lcp->data[1].ptr;
283*7836SJohn.Forte@Sun.COM 	}
284*7836SJohn.Forte@Sun.COM 
285*7836SJohn.Forte@Sun.COM 	FOR_EACH_MEMBER(p, n, tmp_uid, {
286*7836SJohn.Forte@Sun.COM 		if (tmp_uid > uid) {
287*7836SJohn.Forte@Sun.COM 			lcp->curr_uid = tmp_uid;
288*7836SJohn.Forte@Sun.COM 			return (ec);
289*7836SJohn.Forte@Sun.COM 		}
290*7836SJohn.Forte@Sun.COM 	});
291*7836SJohn.Forte@Sun.COM 
292*7836SJohn.Forte@Sun.COM 	/* no more member, clean up memory */
293*7836SJohn.Forte@Sun.COM 	lcp->id[1] = 0;
294*7836SJohn.Forte@Sun.COM 	lcp->data[1].ptr = NULL;
295*7836SJohn.Forte@Sun.COM 
296*7836SJohn.Forte@Sun.COM 	/* free up the matrix */
297*7836SJohn.Forte@Sun.COM 	free(p);
298*7836SJohn.Forte@Sun.COM 
299*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = 0;
300*7836SJohn.Forte@Sun.COM 
301*7836SJohn.Forte@Sun.COM 	return (ec);
302*7836SJohn.Forte@Sun.COM }
303*7836SJohn.Forte@Sun.COM 
304*7836SJohn.Forte@Sun.COM static int
qry_slf(lookup_ctrl_t * lcp)305*7836SJohn.Forte@Sun.COM qry_slf(
306*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
307*7836SJohn.Forte@Sun.COM )
308*7836SJohn.Forte@Sun.COM {
309*7836SJohn.Forte@Sun.COM 	uint32_t uid;
310*7836SJohn.Forte@Sun.COM 
311*7836SJohn.Forte@Sun.COM 	if (lcp->curr_uid == 0) {
312*7836SJohn.Forte@Sun.COM 		uid = lcp->data[0].ui;
313*7836SJohn.Forte@Sun.COM 	} else {
314*7836SJohn.Forte@Sun.COM 		uid = 0;
315*7836SJohn.Forte@Sun.COM 	}
316*7836SJohn.Forte@Sun.COM 
317*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = uid;
318*7836SJohn.Forte@Sun.COM 
319*7836SJohn.Forte@Sun.COM 	return (0);
320*7836SJohn.Forte@Sun.COM }
321*7836SJohn.Forte@Sun.COM 
322*7836SJohn.Forte@Sun.COM static int
qry_e2i(lookup_ctrl_t * lcp)323*7836SJohn.Forte@Sun.COM qry_e2i(
324*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
325*7836SJohn.Forte@Sun.COM )
326*7836SJohn.Forte@Sun.COM {
327*7836SJohn.Forte@Sun.COM 	return (e2c(lcp, OBJ_ISCSI));
328*7836SJohn.Forte@Sun.COM }
329*7836SJohn.Forte@Sun.COM 
330*7836SJohn.Forte@Sun.COM static int
qry_e2p(lookup_ctrl_t * lcp)331*7836SJohn.Forte@Sun.COM qry_e2p(
332*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
333*7836SJohn.Forte@Sun.COM )
334*7836SJohn.Forte@Sun.COM {
335*7836SJohn.Forte@Sun.COM 	return (e2c(lcp, OBJ_PORTAL));
336*7836SJohn.Forte@Sun.COM }
337*7836SJohn.Forte@Sun.COM 
338*7836SJohn.Forte@Sun.COM static int
qry_e2g(lookup_ctrl_t * lcp)339*7836SJohn.Forte@Sun.COM qry_e2g(
340*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
341*7836SJohn.Forte@Sun.COM )
342*7836SJohn.Forte@Sun.COM {
343*7836SJohn.Forte@Sun.COM 	uint32_t uid = lcp->curr_uid; /* last pg */
344*7836SJohn.Forte@Sun.COM 
345*7836SJohn.Forte@Sun.COM 	htab_t *htab = cache_get_htab(OBJ_PG);
346*7836SJohn.Forte@Sun.COM 
347*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
348*7836SJohn.Forte@Sun.COM 	uint32_t puid;
349*7836SJohn.Forte@Sun.COM 
350*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_PG, 0);
351*7836SJohn.Forte@Sun.COM 
352*7836SJohn.Forte@Sun.COM 	/* this is a shortcut */
353*7836SJohn.Forte@Sun.COM 	FOR_EACH_ITEM(htab, uid, {
354*7836SJohn.Forte@Sun.COM 		lc.data[0].ui = uid;
355*7836SJohn.Forte@Sun.COM 		puid = (uint32_t)cache_lookup(&lc, NULL,
356*7836SJohn.Forte@Sun.COM 		    cb_qry_parent_uid);
357*7836SJohn.Forte@Sun.COM 		if (puid == lcp->data[0].ui) {
358*7836SJohn.Forte@Sun.COM 			/* keep the current uid */
359*7836SJohn.Forte@Sun.COM 			lcp->curr_uid = uid;
360*7836SJohn.Forte@Sun.COM 			return (0);
361*7836SJohn.Forte@Sun.COM 		}
362*7836SJohn.Forte@Sun.COM 	});
363*7836SJohn.Forte@Sun.COM 
364*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = 0;
365*7836SJohn.Forte@Sun.COM 
366*7836SJohn.Forte@Sun.COM 	return (0);
367*7836SJohn.Forte@Sun.COM }
368*7836SJohn.Forte@Sun.COM 
369*7836SJohn.Forte@Sun.COM static int
qry_i2g(lookup_ctrl_t * lcp)370*7836SJohn.Forte@Sun.COM qry_i2g(
371*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
372*7836SJohn.Forte@Sun.COM )
373*7836SJohn.Forte@Sun.COM {
374*7836SJohn.Forte@Sun.COM 	int ec = 0;
375*7836SJohn.Forte@Sun.COM 
376*7836SJohn.Forte@Sun.COM 	uint32_t uid = lcp->curr_uid; /* last pg */
377*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
378*7836SJohn.Forte@Sun.COM 
379*7836SJohn.Forte@Sun.COM 	/* the first times of query */
380*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
381*7836SJohn.Forte@Sun.COM 		lcp->id[1] = ISNS_ISCSI_NAME_ATTR_ID;
382*7836SJohn.Forte@Sun.COM 		ec = cache_lookup(lcp, NULL, cb_clone_attrs);
383*7836SJohn.Forte@Sun.COM 	}
384*7836SJohn.Forte@Sun.COM 
385*7836SJohn.Forte@Sun.COM 	if (lcp->data[1].ptr != NULL) {
386*7836SJohn.Forte@Sun.COM 		/* pg lookup */
387*7836SJohn.Forte@Sun.COM 		lc.curr_uid = uid;
388*7836SJohn.Forte@Sun.COM 		lc.type = OBJ_PG;
389*7836SJohn.Forte@Sun.COM 		lc.id[0] = ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID);
390*7836SJohn.Forte@Sun.COM 		lc.op[0] = OP_STRING;
391*7836SJohn.Forte@Sun.COM 		lc.data[0].ptr = lcp->data[1].ptr;
392*7836SJohn.Forte@Sun.COM 		lc.op[1] = 0;
393*7836SJohn.Forte@Sun.COM 
394*7836SJohn.Forte@Sun.COM 		uid = is_obj_there(&lc);
395*7836SJohn.Forte@Sun.COM 	} else {
396*7836SJohn.Forte@Sun.COM 		uid = 0;
397*7836SJohn.Forte@Sun.COM 	}
398*7836SJohn.Forte@Sun.COM 
399*7836SJohn.Forte@Sun.COM 	/* no more pg, update lcp with pg object */
400*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
401*7836SJohn.Forte@Sun.COM 		lcp->id[1] = 0;
402*7836SJohn.Forte@Sun.COM 
403*7836SJohn.Forte@Sun.COM 		/* clean up the memory */
404*7836SJohn.Forte@Sun.COM 		if (lcp->data[1].ptr != NULL) {
405*7836SJohn.Forte@Sun.COM 			free(lcp->data[1].ptr);
406*7836SJohn.Forte@Sun.COM 			/* reset it */
407*7836SJohn.Forte@Sun.COM 			lcp->data[1].ptr = NULL;
408*7836SJohn.Forte@Sun.COM 		}
409*7836SJohn.Forte@Sun.COM 	}
410*7836SJohn.Forte@Sun.COM 
411*7836SJohn.Forte@Sun.COM 	/* save it for returning and querying next pg */
412*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = uid;
413*7836SJohn.Forte@Sun.COM 
414*7836SJohn.Forte@Sun.COM 	return (ec);
415*7836SJohn.Forte@Sun.COM }
416*7836SJohn.Forte@Sun.COM 
417*7836SJohn.Forte@Sun.COM static int
qry_i2d(lookup_ctrl_t * lcp)418*7836SJohn.Forte@Sun.COM qry_i2d(
419*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
420*7836SJohn.Forte@Sun.COM )
421*7836SJohn.Forte@Sun.COM {
422*7836SJohn.Forte@Sun.COM 	uint32_t dd_id = lcp->curr_uid; /* last dd_id */
423*7836SJohn.Forte@Sun.COM 	uint32_t uid = lcp->data[0].ui;
424*7836SJohn.Forte@Sun.COM 
425*7836SJohn.Forte@Sun.COM 	dd_id = get_dd_id(uid, dd_id);
426*7836SJohn.Forte@Sun.COM 
427*7836SJohn.Forte@Sun.COM 	/* save it for returning and getting next dd */
428*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = dd_id;
429*7836SJohn.Forte@Sun.COM 
430*7836SJohn.Forte@Sun.COM 	return (0);
431*7836SJohn.Forte@Sun.COM }
432*7836SJohn.Forte@Sun.COM 
433*7836SJohn.Forte@Sun.COM static int
qry_p2g(lookup_ctrl_t * lcp)434*7836SJohn.Forte@Sun.COM qry_p2g(
435*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
436*7836SJohn.Forte@Sun.COM )
437*7836SJohn.Forte@Sun.COM {
438*7836SJohn.Forte@Sun.COM 	int ec = 0;
439*7836SJohn.Forte@Sun.COM 
440*7836SJohn.Forte@Sun.COM 	uint32_t uid = lcp->curr_uid; /* last pg */
441*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
442*7836SJohn.Forte@Sun.COM 
443*7836SJohn.Forte@Sun.COM 	/* the first time of query */
444*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
445*7836SJohn.Forte@Sun.COM 		/* use 1&2 for the portal ip address & port */
446*7836SJohn.Forte@Sun.COM 		lcp->id[1] = ISNS_PORTAL_IP_ADDR_ATTR_ID;
447*7836SJohn.Forte@Sun.COM 		lcp->id[2] = ISNS_PORTAL_PORT_ATTR_ID;
448*7836SJohn.Forte@Sun.COM 		ec = cache_lookup(lcp, NULL, cb_clone_attrs);
449*7836SJohn.Forte@Sun.COM 	}
450*7836SJohn.Forte@Sun.COM 
451*7836SJohn.Forte@Sun.COM 	if (lcp->data[1].ip != NULL) {
452*7836SJohn.Forte@Sun.COM 		/* pg lookup */
453*7836SJohn.Forte@Sun.COM 		lc.curr_uid = uid;
454*7836SJohn.Forte@Sun.COM 		lc.type = OBJ_PG;
455*7836SJohn.Forte@Sun.COM 		lc.id[0] = ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID);
456*7836SJohn.Forte@Sun.COM 		lc.op[0] = OP_MEMORY_IP6;
457*7836SJohn.Forte@Sun.COM 		lc.data[0].ip = lcp->data[1].ip;
458*7836SJohn.Forte@Sun.COM 		lc.id[1] = ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID);
459*7836SJohn.Forte@Sun.COM 		lc.op[1] = OP_INTEGER;
460*7836SJohn.Forte@Sun.COM 		lc.data[1].ui = lcp->data[2].ui;
461*7836SJohn.Forte@Sun.COM 		lc.op[2] = 0;
462*7836SJohn.Forte@Sun.COM 
463*7836SJohn.Forte@Sun.COM 		uid = is_obj_there(&lc);
464*7836SJohn.Forte@Sun.COM 	} else {
465*7836SJohn.Forte@Sun.COM 		uid = 0;
466*7836SJohn.Forte@Sun.COM 	}
467*7836SJohn.Forte@Sun.COM 
468*7836SJohn.Forte@Sun.COM 	/* no more pg, clean up memory */
469*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
470*7836SJohn.Forte@Sun.COM 		lcp->id[1] = 0;
471*7836SJohn.Forte@Sun.COM 		lcp->id[2] = 0;
472*7836SJohn.Forte@Sun.COM 
473*7836SJohn.Forte@Sun.COM 		/* clean up the memory */
474*7836SJohn.Forte@Sun.COM 		if (lcp->data[1].ip != NULL) {
475*7836SJohn.Forte@Sun.COM 			free(lcp->data[1].ip);
476*7836SJohn.Forte@Sun.COM 			/* reset it */
477*7836SJohn.Forte@Sun.COM 			lcp->data[1].ip = NULL;
478*7836SJohn.Forte@Sun.COM 		}
479*7836SJohn.Forte@Sun.COM 		lcp->data[2].ui = 0;
480*7836SJohn.Forte@Sun.COM 	}
481*7836SJohn.Forte@Sun.COM 
482*7836SJohn.Forte@Sun.COM 	/* save it for returning and next query */
483*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = uid;
484*7836SJohn.Forte@Sun.COM 
485*7836SJohn.Forte@Sun.COM 	return (ec);
486*7836SJohn.Forte@Sun.COM }
487*7836SJohn.Forte@Sun.COM 
488*7836SJohn.Forte@Sun.COM static int
qry_g2i(lookup_ctrl_t * lcp)489*7836SJohn.Forte@Sun.COM qry_g2i(
490*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
491*7836SJohn.Forte@Sun.COM )
492*7836SJohn.Forte@Sun.COM {
493*7836SJohn.Forte@Sun.COM 	int ec = 0;
494*7836SJohn.Forte@Sun.COM 
495*7836SJohn.Forte@Sun.COM 	uint32_t uid = lcp->curr_uid; /* last node */
496*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
497*7836SJohn.Forte@Sun.COM 
498*7836SJohn.Forte@Sun.COM 	/* the first time of query */
499*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
500*7836SJohn.Forte@Sun.COM 		/* use slot 1 for the storage node name */
501*7836SJohn.Forte@Sun.COM 		lcp->id[1] = ISNS_PG_ISCSI_NAME_ATTR_ID;
502*7836SJohn.Forte@Sun.COM 		ec = cache_lookup(lcp, NULL, cb_clone_attrs);
503*7836SJohn.Forte@Sun.COM 
504*7836SJohn.Forte@Sun.COM 		if (lcp->data[1].ptr != NULL) {
505*7836SJohn.Forte@Sun.COM 			/* iscsi node lookup */
506*7836SJohn.Forte@Sun.COM 			lc.curr_uid = uid;
507*7836SJohn.Forte@Sun.COM 			lc.type = OBJ_ISCSI;
508*7836SJohn.Forte@Sun.COM 			lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
509*7836SJohn.Forte@Sun.COM 			lc.op[0] = OP_STRING;
510*7836SJohn.Forte@Sun.COM 			lc.data[0].ptr = lcp->data[1].ptr;
511*7836SJohn.Forte@Sun.COM 			lc.op[1] = 0;
512*7836SJohn.Forte@Sun.COM 
513*7836SJohn.Forte@Sun.COM 			uid = is_obj_there(&lc);
514*7836SJohn.Forte@Sun.COM 
515*7836SJohn.Forte@Sun.COM 			/* no longer need it, clean it up */
516*7836SJohn.Forte@Sun.COM 			free(lcp->data[1].ptr);
517*7836SJohn.Forte@Sun.COM 			lcp->data[1].ptr = NULL;
518*7836SJohn.Forte@Sun.COM 		}
519*7836SJohn.Forte@Sun.COM 		/* no longer need it, reset it */
520*7836SJohn.Forte@Sun.COM 		lcp->id[1] = 0;
521*7836SJohn.Forte@Sun.COM 	} else {
522*7836SJohn.Forte@Sun.COM 		/* one pg has maximum number of one storage node */
523*7836SJohn.Forte@Sun.COM 		uid = 0;
524*7836SJohn.Forte@Sun.COM 	}
525*7836SJohn.Forte@Sun.COM 
526*7836SJohn.Forte@Sun.COM 	/* save it for returning and next query */
527*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = uid;
528*7836SJohn.Forte@Sun.COM 
529*7836SJohn.Forte@Sun.COM 	return (ec);
530*7836SJohn.Forte@Sun.COM }
531*7836SJohn.Forte@Sun.COM 
532*7836SJohn.Forte@Sun.COM static int
qry_g2p(lookup_ctrl_t * lcp)533*7836SJohn.Forte@Sun.COM qry_g2p(
534*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
535*7836SJohn.Forte@Sun.COM )
536*7836SJohn.Forte@Sun.COM {
537*7836SJohn.Forte@Sun.COM 	int ec = 0;
538*7836SJohn.Forte@Sun.COM 
539*7836SJohn.Forte@Sun.COM 	uint32_t uid = lcp->curr_uid; /* last portal */
540*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
541*7836SJohn.Forte@Sun.COM 
542*7836SJohn.Forte@Sun.COM 	/* the first times of query */
543*7836SJohn.Forte@Sun.COM 	if (uid == 0) {
544*7836SJohn.Forte@Sun.COM 		/* use 1&2 for the portal ip addr and port */
545*7836SJohn.Forte@Sun.COM 		lcp->id[1] = ISNS_PG_PORTAL_IP_ADDR_ATTR_ID;
546*7836SJohn.Forte@Sun.COM 		lcp->id[2] = ISNS_PG_PORTAL_PORT_ATTR_ID;
547*7836SJohn.Forte@Sun.COM 		ec = cache_lookup(lcp, NULL, cb_clone_attrs);
548*7836SJohn.Forte@Sun.COM 
549*7836SJohn.Forte@Sun.COM 		if (lcp->data[1].ip != NULL) {
550*7836SJohn.Forte@Sun.COM 			/* portal lookup */
551*7836SJohn.Forte@Sun.COM 			lc.curr_uid = uid;
552*7836SJohn.Forte@Sun.COM 			lc.type = OBJ_PORTAL;
553*7836SJohn.Forte@Sun.COM 			lc.id[0] = ATTR_INDEX_PORTAL(
554*7836SJohn.Forte@Sun.COM 			    ISNS_PORTAL_IP_ADDR_ATTR_ID);
555*7836SJohn.Forte@Sun.COM 			lc.op[0] = OP_MEMORY_IP6;
556*7836SJohn.Forte@Sun.COM 			lc.data[0].ip = lcp->data[1].ip;
557*7836SJohn.Forte@Sun.COM 			lc.id[1] = ATTR_INDEX_PORTAL(
558*7836SJohn.Forte@Sun.COM 			    ISNS_PORTAL_PORT_ATTR_ID);
559*7836SJohn.Forte@Sun.COM 			lc.op[1] = OP_INTEGER;
560*7836SJohn.Forte@Sun.COM 			lc.data[1].ui = lcp->data[2].ui;
561*7836SJohn.Forte@Sun.COM 			lc.op[2] = 0;
562*7836SJohn.Forte@Sun.COM 
563*7836SJohn.Forte@Sun.COM 			uid = is_obj_there(&lc);
564*7836SJohn.Forte@Sun.COM 
565*7836SJohn.Forte@Sun.COM 			/* no longer need it, reset it */
566*7836SJohn.Forte@Sun.COM 			free(lcp->data[1].ip);
567*7836SJohn.Forte@Sun.COM 			lcp->data[1].ip = NULL;
568*7836SJohn.Forte@Sun.COM 		}
569*7836SJohn.Forte@Sun.COM 		/* no longer need it, reset it */
570*7836SJohn.Forte@Sun.COM 		lcp->id[1] = 0;
571*7836SJohn.Forte@Sun.COM 		lcp->id[2] = 0;
572*7836SJohn.Forte@Sun.COM 		lcp->data[2].ui = 0;
573*7836SJohn.Forte@Sun.COM 	} else {
574*7836SJohn.Forte@Sun.COM 		/* one pg has maximum number of one portal */
575*7836SJohn.Forte@Sun.COM 		uid = 0;
576*7836SJohn.Forte@Sun.COM 	}
577*7836SJohn.Forte@Sun.COM 
578*7836SJohn.Forte@Sun.COM 	/* save it for returning and next query */
579*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = uid;
580*7836SJohn.Forte@Sun.COM 
581*7836SJohn.Forte@Sun.COM 	return (ec);
582*7836SJohn.Forte@Sun.COM }
583*7836SJohn.Forte@Sun.COM 
584*7836SJohn.Forte@Sun.COM static int
qry_d2s(lookup_ctrl_t * lcp)585*7836SJohn.Forte@Sun.COM qry_d2s(
586*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp
587*7836SJohn.Forte@Sun.COM )
588*7836SJohn.Forte@Sun.COM {
589*7836SJohn.Forte@Sun.COM 	uint32_t dds_id = lcp->curr_uid; /* last dds */
590*7836SJohn.Forte@Sun.COM 	uint32_t dd_id = lcp->data[0].ui;
591*7836SJohn.Forte@Sun.COM 
592*7836SJohn.Forte@Sun.COM 	dds_id = get_dds_id(dd_id, dds_id);
593*7836SJohn.Forte@Sun.COM 
594*7836SJohn.Forte@Sun.COM 	/* save it for returning and for getting next dds */
595*7836SJohn.Forte@Sun.COM 	lcp->curr_uid = dds_id;
596*7836SJohn.Forte@Sun.COM 
597*7836SJohn.Forte@Sun.COM 	return (0);
598*7836SJohn.Forte@Sun.COM }
599*7836SJohn.Forte@Sun.COM 
600*7836SJohn.Forte@Sun.COM int
validate_qry_key(isns_type_t type,isns_tlv_t * key,uint16_t key_len,isns_attr_t * attrs)601*7836SJohn.Forte@Sun.COM validate_qry_key(
602*7836SJohn.Forte@Sun.COM 	isns_type_t type,
603*7836SJohn.Forte@Sun.COM 	isns_tlv_t *key,
604*7836SJohn.Forte@Sun.COM 	uint16_t key_len,
605*7836SJohn.Forte@Sun.COM 	isns_attr_t *attrs
606*7836SJohn.Forte@Sun.COM )
607*7836SJohn.Forte@Sun.COM {
608*7836SJohn.Forte@Sun.COM 	int ec = 0;
609*7836SJohn.Forte@Sun.COM 
610*7836SJohn.Forte@Sun.COM 	uint32_t tag;
611*7836SJohn.Forte@Sun.COM 	uint32_t min_tag, max_tag;
612*7836SJohn.Forte@Sun.COM 
613*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
614*7836SJohn.Forte@Sun.COM 
615*7836SJohn.Forte@Sun.COM 	min_tag = TAG_RANGE[type][0];
616*7836SJohn.Forte@Sun.COM 	max_tag = TAG_RANGE[type][2];
617*7836SJohn.Forte@Sun.COM 
618*7836SJohn.Forte@Sun.COM 	while (key_len != 0 && ec == 0) {
619*7836SJohn.Forte@Sun.COM 		tag = key->attr_id;
620*7836SJohn.Forte@Sun.COM 		if (tag < min_tag || tag > max_tag) {
621*7836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_MSG_FORMAT_ERROR;
622*7836SJohn.Forte@Sun.COM 		} else if (key->attr_len > 0 && attrs != NULL) {
623*7836SJohn.Forte@Sun.COM 			attr = &attrs[tag - min_tag]; /* ATTR_INDEX_xxx */
624*7836SJohn.Forte@Sun.COM 			ec = extract_attr(attr, key, 0);
625*7836SJohn.Forte@Sun.COM 			if (ec == ISNS_RSP_INVALID_REGIS) {
626*7836SJohn.Forte@Sun.COM 				ec = ISNS_RSP_MSG_FORMAT_ERROR;
627*7836SJohn.Forte@Sun.COM 			}
628*7836SJohn.Forte@Sun.COM 		}
629*7836SJohn.Forte@Sun.COM 		NEXT_TLV(key, key_len);
630*7836SJohn.Forte@Sun.COM 	}
631*7836SJohn.Forte@Sun.COM 
632*7836SJohn.Forte@Sun.COM 	return (ec);
633*7836SJohn.Forte@Sun.COM }
634*7836SJohn.Forte@Sun.COM 
635*7836SJohn.Forte@Sun.COM static lookup_method_t
get_op_method(uint32_t tag)636*7836SJohn.Forte@Sun.COM get_op_method(
637*7836SJohn.Forte@Sun.COM 	uint32_t tag
638*7836SJohn.Forte@Sun.COM )
639*7836SJohn.Forte@Sun.COM {
640*7836SJohn.Forte@Sun.COM 	lookup_method_t method = 0;
641*7836SJohn.Forte@Sun.COM 
642*7836SJohn.Forte@Sun.COM 	switch (tag) {
643*7836SJohn.Forte@Sun.COM 	/* OP_STRING */
644*7836SJohn.Forte@Sun.COM 	case ISNS_EID_ATTR_ID:
645*7836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_NAME_ATTR_ID:
646*7836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_ALIAS_ATTR_ID:
647*7836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_NAME_ATTR_ID:
648*7836SJohn.Forte@Sun.COM 	case ISNS_DD_NAME_ATTR_ID:
649*7836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_NAME_ATTR_ID:
650*7836SJohn.Forte@Sun.COM 	case ISNS_PG_ISCSI_NAME_ATTR_ID:
651*7836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
652*7836SJohn.Forte@Sun.COM 		method = OP_STRING;
653*7836SJohn.Forte@Sun.COM 		break;
654*7836SJohn.Forte@Sun.COM 	/* OP_MEMORY_IP6 */
655*7836SJohn.Forte@Sun.COM 	case ISNS_MGMT_IP_ADDR_ATTR_ID:
656*7836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_IP_ADDR_ATTR_ID:
657*7836SJohn.Forte@Sun.COM 	case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
658*7836SJohn.Forte@Sun.COM 		method = OP_MEMORY_IP6;
659*7836SJohn.Forte@Sun.COM 		break;
660*7836SJohn.Forte@Sun.COM 	/* OP_INTEGER */
661*7836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_PROTOCOL_ATTR_ID:
662*7836SJohn.Forte@Sun.COM 	case ISNS_VERSION_RANGE_ATTR_ID:
663*7836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_REG_PERIOD_ATTR_ID:
664*7836SJohn.Forte@Sun.COM 	case ISNS_ENTITY_INDEX_ATTR_ID:
665*7836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_PORT_ATTR_ID:
666*7836SJohn.Forte@Sun.COM 	case ISNS_ESI_INTERVAL_ATTR_ID:
667*7836SJohn.Forte@Sun.COM 	case ISNS_ESI_PORT_ATTR_ID:
668*7836SJohn.Forte@Sun.COM 	case ISNS_PORTAL_INDEX_ATTR_ID:
669*7836SJohn.Forte@Sun.COM 	case ISNS_SCN_PORT_ATTR_ID:
670*7836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
671*7836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_SCN_BITMAP_ATTR_ID:
672*7836SJohn.Forte@Sun.COM 	case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
673*7836SJohn.Forte@Sun.COM 	case ISNS_PG_PORTAL_PORT_ATTR_ID:
674*7836SJohn.Forte@Sun.COM 	case ISNS_PG_TAG_ATTR_ID:
675*7836SJohn.Forte@Sun.COM 	case ISNS_PG_INDEX_ATTR_ID:
676*7836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_ID_ATTR_ID:
677*7836SJohn.Forte@Sun.COM 	case ISNS_DD_SET_STATUS_ATTR_ID:
678*7836SJohn.Forte@Sun.COM 	case ISNS_DD_ID_ATTR_ID:
679*7836SJohn.Forte@Sun.COM 	/* all other attrs */
680*7836SJohn.Forte@Sun.COM 	default:
681*7836SJohn.Forte@Sun.COM 		method = OP_INTEGER;
682*7836SJohn.Forte@Sun.COM 		break;
683*7836SJohn.Forte@Sun.COM 	}
684*7836SJohn.Forte@Sun.COM 
685*7836SJohn.Forte@Sun.COM 	return (method);
686*7836SJohn.Forte@Sun.COM }
687*7836SJohn.Forte@Sun.COM 
688*7836SJohn.Forte@Sun.COM static int
cb_attrs_match(void * p1,void * p2)689*7836SJohn.Forte@Sun.COM cb_attrs_match(
690*7836SJohn.Forte@Sun.COM 	void *p1,
691*7836SJohn.Forte@Sun.COM 	void *p2
692*7836SJohn.Forte@Sun.COM )
693*7836SJohn.Forte@Sun.COM {
694*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
695*7836SJohn.Forte@Sun.COM 	isns_attr_t *attrs = (isns_attr_t *)
696*7836SJohn.Forte@Sun.COM 	    ((lookup_ctrl_t *)p2)->data[1].ptr;
697*7836SJohn.Forte@Sun.COM 
698*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
699*7836SJohn.Forte@Sun.COM 	int match = 1; /* 0: not match, otherwise: match */
700*7836SJohn.Forte@Sun.COM 
701*7836SJohn.Forte@Sun.COM 	int i;
702*7836SJohn.Forte@Sun.COM 
703*7836SJohn.Forte@Sun.COM 	lc.op[1] = 0;
704*7836SJohn.Forte@Sun.COM 
705*7836SJohn.Forte@Sun.COM 	for (i = 0; match != 0 && i < NUM_OF_ATTRS[obj->type]; i++) {
706*7836SJohn.Forte@Sun.COM 		if (attrs->tag != 0 && attrs->len > 0) {
707*7836SJohn.Forte@Sun.COM 			lc.id[0] = i;
708*7836SJohn.Forte@Sun.COM 			lc.op[0] = get_op_method(attrs->tag);
709*7836SJohn.Forte@Sun.COM 			lc.data[0].ptr = attrs->value.ptr;
710*7836SJohn.Forte@Sun.COM 			match = key_cmp(&lc, obj) == 0 ? 1 : 0;
711*7836SJohn.Forte@Sun.COM 		}
712*7836SJohn.Forte@Sun.COM 		attrs ++;
713*7836SJohn.Forte@Sun.COM 	}
714*7836SJohn.Forte@Sun.COM 
715*7836SJohn.Forte@Sun.COM 	return (match);
716*7836SJohn.Forte@Sun.COM }
717*7836SJohn.Forte@Sun.COM 
718*7836SJohn.Forte@Sun.COM static int
attrs_match(isns_type_t type,uint32_t uid,isns_attr_t * attrs)719*7836SJohn.Forte@Sun.COM attrs_match(
720*7836SJohn.Forte@Sun.COM 	isns_type_t type,
721*7836SJohn.Forte@Sun.COM 	uint32_t uid,
722*7836SJohn.Forte@Sun.COM 	isns_attr_t *attrs
723*7836SJohn.Forte@Sun.COM )
724*7836SJohn.Forte@Sun.COM {
725*7836SJohn.Forte@Sun.COM 	int match; /* 0: not match, otherwise: match */
726*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
727*7836SJohn.Forte@Sun.COM 
728*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, type, uid);
729*7836SJohn.Forte@Sun.COM 
730*7836SJohn.Forte@Sun.COM 	lc.data[1].ptr = (uchar_t *)attrs;
731*7836SJohn.Forte@Sun.COM 
732*7836SJohn.Forte@Sun.COM 	match = cache_lookup(&lc, NULL, cb_attrs_match);
733*7836SJohn.Forte@Sun.COM 
734*7836SJohn.Forte@Sun.COM 	return (match);
735*7836SJohn.Forte@Sun.COM }
736*7836SJohn.Forte@Sun.COM 
737*7836SJohn.Forte@Sun.COM static int
insert_uid(uint32_t ** pp,uint32_t * np,uint32_t * sp,uint32_t uid)738*7836SJohn.Forte@Sun.COM insert_uid(
739*7836SJohn.Forte@Sun.COM 	uint32_t **pp,
740*7836SJohn.Forte@Sun.COM 	uint32_t *np,
741*7836SJohn.Forte@Sun.COM 	uint32_t *sp,
742*7836SJohn.Forte@Sun.COM 	uint32_t uid
743*7836SJohn.Forte@Sun.COM )
744*7836SJohn.Forte@Sun.COM {
745*7836SJohn.Forte@Sun.COM 	int ec = 0;
746*7836SJohn.Forte@Sun.COM 
747*7836SJohn.Forte@Sun.COM 	uint32_t *p = *pp;
748*7836SJohn.Forte@Sun.COM 	uint32_t n = *np;
749*7836SJohn.Forte@Sun.COM 	uint32_t s = *sp;
750*7836SJohn.Forte@Sun.COM 
751*7836SJohn.Forte@Sun.COM 	uint32_t u;
752*7836SJohn.Forte@Sun.COM 	uint32_t *t;
753*7836SJohn.Forte@Sun.COM 
754*7836SJohn.Forte@Sun.COM 	/* check for duplication */
755*7836SJohn.Forte@Sun.COM 	if (n > 0 && uid <= p[n - 1]) {
756*7836SJohn.Forte@Sun.COM 		while (n-- > 0) {
757*7836SJohn.Forte@Sun.COM 			if (p[n] == uid) {
758*7836SJohn.Forte@Sun.COM 				return (0);
759*7836SJohn.Forte@Sun.COM 			}
760*7836SJohn.Forte@Sun.COM 		}
761*7836SJohn.Forte@Sun.COM 		n = *np;
762*7836SJohn.Forte@Sun.COM 		u = p[n - 1];
763*7836SJohn.Forte@Sun.COM 		p[n - 1] = uid;
764*7836SJohn.Forte@Sun.COM 		uid = u;
765*7836SJohn.Forte@Sun.COM 	}
766*7836SJohn.Forte@Sun.COM 
767*7836SJohn.Forte@Sun.COM 
768*7836SJohn.Forte@Sun.COM 	if (s == n) {
769*7836SJohn.Forte@Sun.COM 		s = (s == 0) ? 8 : s * 2;
770*7836SJohn.Forte@Sun.COM 		t = (uint32_t *)realloc(p, s * sizeof (uint32_t));
771*7836SJohn.Forte@Sun.COM 		if (t != NULL) {
772*7836SJohn.Forte@Sun.COM 			p = t;
773*7836SJohn.Forte@Sun.COM 			*pp = p;
774*7836SJohn.Forte@Sun.COM 			*sp = s;
775*7836SJohn.Forte@Sun.COM 		} else {
776*7836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_INTERNAL_ERROR;
777*7836SJohn.Forte@Sun.COM 		}
778*7836SJohn.Forte@Sun.COM 	}
779*7836SJohn.Forte@Sun.COM 
780*7836SJohn.Forte@Sun.COM 	if (ec == 0) {
781*7836SJohn.Forte@Sun.COM 		p[n ++] = uid;
782*7836SJohn.Forte@Sun.COM 		*np = n;
783*7836SJohn.Forte@Sun.COM 	}
784*7836SJohn.Forte@Sun.COM 
785*7836SJohn.Forte@Sun.COM 	return (ec);
786*7836SJohn.Forte@Sun.COM }
787*7836SJohn.Forte@Sun.COM 
788*7836SJohn.Forte@Sun.COM static int
qry_and_match(uint32_t ** obj_uids,uint32_t * num_of_objs,uint32_t * size,isns_type_t type,uint32_t src_uid,isns_type_t src_type,isns_attr_t * attrs)789*7836SJohn.Forte@Sun.COM qry_and_match(
790*7836SJohn.Forte@Sun.COM 	uint32_t **obj_uids,
791*7836SJohn.Forte@Sun.COM 	uint32_t *num_of_objs,
792*7836SJohn.Forte@Sun.COM 	uint32_t *size,
793*7836SJohn.Forte@Sun.COM 	isns_type_t type,
794*7836SJohn.Forte@Sun.COM 	uint32_t src_uid,
795*7836SJohn.Forte@Sun.COM 	isns_type_t src_type,
796*7836SJohn.Forte@Sun.COM 	isns_attr_t *attrs
797*7836SJohn.Forte@Sun.COM )
798*7836SJohn.Forte@Sun.COM {
799*7836SJohn.Forte@Sun.COM 	int ec = 0;
800*7836SJohn.Forte@Sun.COM 
801*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc = { 0 }; /* !!! need to be empty */
802*7836SJohn.Forte@Sun.COM 	uint32_t uid;
803*7836SJohn.Forte@Sun.COM 
804*7836SJohn.Forte@Sun.COM 	const adjvex_t *vex;
805*7836SJohn.Forte@Sun.COM 
806*7836SJohn.Forte@Sun.COM 	/* circular list */
807*7836SJohn.Forte@Sun.COM 	uint32_t *p[2], n[2], s[2];
808*7836SJohn.Forte@Sun.COM 	int i, j;
809*7836SJohn.Forte@Sun.COM 
810*7836SJohn.Forte@Sun.COM 	uint32_t *p1, n1;
811*7836SJohn.Forte@Sun.COM 	uint32_t *p2, n2, s2;
812*7836SJohn.Forte@Sun.COM 	isns_type_t t;
813*7836SJohn.Forte@Sun.COM 
814*7836SJohn.Forte@Sun.COM 	/* initialize the circular list */
815*7836SJohn.Forte@Sun.COM 	i = 0;
816*7836SJohn.Forte@Sun.COM 	j = 1;
817*7836SJohn.Forte@Sun.COM 
818*7836SJohn.Forte@Sun.COM 	p[i] = *obj_uids;
819*7836SJohn.Forte@Sun.COM 	n[i] = *num_of_objs;
820*7836SJohn.Forte@Sun.COM 	s[i] = *size;
821*7836SJohn.Forte@Sun.COM 
822*7836SJohn.Forte@Sun.COM 	p[j] = malloc(8 * sizeof (uint32_t));
823*7836SJohn.Forte@Sun.COM 	p[j][0] = src_uid;
824*7836SJohn.Forte@Sun.COM 	n[j] = 1;
825*7836SJohn.Forte@Sun.COM 	s[j] = 8;
826*7836SJohn.Forte@Sun.COM 
827*7836SJohn.Forte@Sun.COM 	/* initial object type of being queried */
828*7836SJohn.Forte@Sun.COM 	t = src_type;
829*7836SJohn.Forte@Sun.COM 
830*7836SJohn.Forte@Sun.COM 	vex = qry_puzzle[src_type][type];
831*7836SJohn.Forte@Sun.COM 
832*7836SJohn.Forte@Sun.COM 	do {
833*7836SJohn.Forte@Sun.COM 		/* shift one on the circular list */
834*7836SJohn.Forte@Sun.COM 		i = (i + 1) & 1;
835*7836SJohn.Forte@Sun.COM 		j = (j + 1) & 1;
836*7836SJohn.Forte@Sun.COM 
837*7836SJohn.Forte@Sun.COM 		p1 = p[i]; n1 = n[i];
838*7836SJohn.Forte@Sun.COM 		p2 = p[j]; n2 = n[j]; s2 = s[j];
839*7836SJohn.Forte@Sun.COM 
840*7836SJohn.Forte@Sun.COM 		/* prepare lookup control */
841*7836SJohn.Forte@Sun.COM 		lc.type = t;
842*7836SJohn.Forte@Sun.COM 		lc.id[0] = UID_ATTR_INDEX[t];
843*7836SJohn.Forte@Sun.COM 		lc.op[0] = OP_INTEGER;
844*7836SJohn.Forte@Sun.COM 
845*7836SJohn.Forte@Sun.COM 		/* result object type */
846*7836SJohn.Forte@Sun.COM 		t = vex->t;
847*7836SJohn.Forte@Sun.COM 
848*7836SJohn.Forte@Sun.COM 		FOR_EACH_OBJS(p1, n1, uid, {
849*7836SJohn.Forte@Sun.COM 			/* start query */
850*7836SJohn.Forte@Sun.COM 			lc.data[0].ui = uid;
851*7836SJohn.Forte@Sun.COM 			ec = vex->f(&lc);
852*7836SJohn.Forte@Sun.COM 			uid = lc.curr_uid;
853*7836SJohn.Forte@Sun.COM 			while (ec == 0 && uid != 0) {
854*7836SJohn.Forte@Sun.COM 				if (attrs == NULL ||
855*7836SJohn.Forte@Sun.COM 				    attrs_match(type, uid, attrs) != 0) {
856*7836SJohn.Forte@Sun.COM 					ec = insert_uid(&p2, &n2, &s2, uid);
857*7836SJohn.Forte@Sun.COM 				}
858*7836SJohn.Forte@Sun.COM 				if (ec == 0) {
859*7836SJohn.Forte@Sun.COM 					ec = vex->f(&lc);
860*7836SJohn.Forte@Sun.COM 					uid = lc.curr_uid;
861*7836SJohn.Forte@Sun.COM 				} else {
862*7836SJohn.Forte@Sun.COM 					n1 = n2 = 0; /* force break */
863*7836SJohn.Forte@Sun.COM 				}
864*7836SJohn.Forte@Sun.COM 			}
865*7836SJohn.Forte@Sun.COM 		});
866*7836SJohn.Forte@Sun.COM 		if (ec == 0) {
867*7836SJohn.Forte@Sun.COM 			vex = vex->v;
868*7836SJohn.Forte@Sun.COM 		} else {
869*7836SJohn.Forte@Sun.COM 			vex = NULL; /* force break */
870*7836SJohn.Forte@Sun.COM 		}
871*7836SJohn.Forte@Sun.COM 		/* push back */
872*7836SJohn.Forte@Sun.COM 		p[j] = p2; n[j] = n2; s[j] = s2;
873*7836SJohn.Forte@Sun.COM 		/* reset the number of objects */
874*7836SJohn.Forte@Sun.COM 		n[i] = 0;
875*7836SJohn.Forte@Sun.COM 	} while (vex != NULL);
876*7836SJohn.Forte@Sun.COM 
877*7836SJohn.Forte@Sun.COM 	/* clean up the memory */
878*7836SJohn.Forte@Sun.COM 	free(p1);
879*7836SJohn.Forte@Sun.COM 	if (ec != 0) {
880*7836SJohn.Forte@Sun.COM 		free(p2);
881*7836SJohn.Forte@Sun.COM 		p2 = NULL;
882*7836SJohn.Forte@Sun.COM 		n2 = 0;
883*7836SJohn.Forte@Sun.COM 		s2 = 0;
884*7836SJohn.Forte@Sun.COM 	}
885*7836SJohn.Forte@Sun.COM 
886*7836SJohn.Forte@Sun.COM 	*obj_uids = p2;
887*7836SJohn.Forte@Sun.COM 	*num_of_objs = n2;
888*7836SJohn.Forte@Sun.COM 	*size = s2;
889*7836SJohn.Forte@Sun.COM 
890*7836SJohn.Forte@Sun.COM 	return (ec);
891*7836SJohn.Forte@Sun.COM }
892*7836SJohn.Forte@Sun.COM 
893*7836SJohn.Forte@Sun.COM int
get_qry_keys(bmp_t * nodes_bmp,uint32_t num_of_nodes,isns_type_t * type,isns_tlv_t * key,uint16_t key_len,uint32_t ** obj_uids,uint32_t * num_of_objs)894*7836SJohn.Forte@Sun.COM get_qry_keys(
895*7836SJohn.Forte@Sun.COM 	bmp_t *nodes_bmp,
896*7836SJohn.Forte@Sun.COM 	uint32_t num_of_nodes,
897*7836SJohn.Forte@Sun.COM 	isns_type_t *type,
898*7836SJohn.Forte@Sun.COM 	isns_tlv_t *key,
899*7836SJohn.Forte@Sun.COM 	uint16_t key_len,
900*7836SJohn.Forte@Sun.COM 	uint32_t **obj_uids,
901*7836SJohn.Forte@Sun.COM 	uint32_t *num_of_objs
902*7836SJohn.Forte@Sun.COM )
903*7836SJohn.Forte@Sun.COM {
904*7836SJohn.Forte@Sun.COM 	int ec = 0;
905*7836SJohn.Forte@Sun.COM 	union {
906*7836SJohn.Forte@Sun.COM 		isns_obj_t o;
907*7836SJohn.Forte@Sun.COM 		isns_entity_t e;
908*7836SJohn.Forte@Sun.COM 		isns_iscsi_t i;
909*7836SJohn.Forte@Sun.COM 		isns_portal_t p;
910*7836SJohn.Forte@Sun.COM 		isns_pg_t g;
911*7836SJohn.Forte@Sun.COM 		isns_dd_t d;
912*7836SJohn.Forte@Sun.COM 		isns_dds_t s;
913*7836SJohn.Forte@Sun.COM 	} an_obj = { 0 };
914*7836SJohn.Forte@Sun.COM 	isns_attr_t *attrs;
915*7836SJohn.Forte@Sun.COM 
916*7836SJohn.Forte@Sun.COM 	htab_t *htab;
917*7836SJohn.Forte@Sun.COM 	uint32_t node_uid;
918*7836SJohn.Forte@Sun.COM 
919*7836SJohn.Forte@Sun.COM 	uint32_t size;
920*7836SJohn.Forte@Sun.COM 
921*7836SJohn.Forte@Sun.COM 	*obj_uids = NULL;
922*7836SJohn.Forte@Sun.COM 	*num_of_objs = 0;
923*7836SJohn.Forte@Sun.COM 	size = 0;
924*7836SJohn.Forte@Sun.COM 
925*7836SJohn.Forte@Sun.COM 	/* get the object type identified by the key */
926*7836SJohn.Forte@Sun.COM 	*type = TLV2TYPE(key);
927*7836SJohn.Forte@Sun.COM 	if (*type == 0) {
928*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_INVALID_QRY);
929*7836SJohn.Forte@Sun.COM 	}
930*7836SJohn.Forte@Sun.COM 
931*7836SJohn.Forte@Sun.COM 	attrs = &an_obj.o.attrs[0];
932*7836SJohn.Forte@Sun.COM 	/* validate the Message Key */
933*7836SJohn.Forte@Sun.COM 	ec = validate_qry_key(*type, key, key_len, attrs);
934*7836SJohn.Forte@Sun.COM 	if (ec != 0) {
935*7836SJohn.Forte@Sun.COM 		return (ec);
936*7836SJohn.Forte@Sun.COM 	}
937*7836SJohn.Forte@Sun.COM 
938*7836SJohn.Forte@Sun.COM 	if (nodes_bmp != NULL) {
939*7836SJohn.Forte@Sun.COM 		FOR_EACH_MEMBER(nodes_bmp, num_of_nodes, node_uid, {
940*7836SJohn.Forte@Sun.COM 			ec = qry_and_match(
941*7836SJohn.Forte@Sun.COM 			    obj_uids, num_of_objs, &size, *type,
942*7836SJohn.Forte@Sun.COM 			    node_uid, OBJ_ISCSI, attrs);
943*7836SJohn.Forte@Sun.COM 			if (ec != 0) {
944*7836SJohn.Forte@Sun.COM 				return (ec);
945*7836SJohn.Forte@Sun.COM 			}
946*7836SJohn.Forte@Sun.COM 		});
947*7836SJohn.Forte@Sun.COM 	} else {
948*7836SJohn.Forte@Sun.COM 		node_uid = 0;
949*7836SJohn.Forte@Sun.COM 		htab = cache_get_htab(OBJ_ISCSI);
950*7836SJohn.Forte@Sun.COM 		FOR_EACH_ITEM(htab, node_uid, {
951*7836SJohn.Forte@Sun.COM 			ec = qry_and_match(
952*7836SJohn.Forte@Sun.COM 			    obj_uids, num_of_objs, &size, *type,
953*7836SJohn.Forte@Sun.COM 			    node_uid, OBJ_ISCSI, attrs);
954*7836SJohn.Forte@Sun.COM 			if (ec != 0) {
955*7836SJohn.Forte@Sun.COM 				return (ec);
956*7836SJohn.Forte@Sun.COM 			}
957*7836SJohn.Forte@Sun.COM 		});
958*7836SJohn.Forte@Sun.COM 	}
959*7836SJohn.Forte@Sun.COM 
960*7836SJohn.Forte@Sun.COM 	return (ec);
961*7836SJohn.Forte@Sun.COM }
962*7836SJohn.Forte@Sun.COM 
963*7836SJohn.Forte@Sun.COM int
get_qry_ops(uint32_t uid,isns_type_t src_type,isns_type_t op_type,uint32_t ** op_uids,uint32_t * num_of_ops,uint32_t * size)964*7836SJohn.Forte@Sun.COM get_qry_ops(
965*7836SJohn.Forte@Sun.COM 	uint32_t uid,
966*7836SJohn.Forte@Sun.COM 	isns_type_t src_type,
967*7836SJohn.Forte@Sun.COM 	isns_type_t op_type,
968*7836SJohn.Forte@Sun.COM 	uint32_t **op_uids,
969*7836SJohn.Forte@Sun.COM 	uint32_t *num_of_ops,
970*7836SJohn.Forte@Sun.COM 	uint32_t *size
971*7836SJohn.Forte@Sun.COM )
972*7836SJohn.Forte@Sun.COM {
973*7836SJohn.Forte@Sun.COM 	int ec = 0;
974*7836SJohn.Forte@Sun.COM 
975*7836SJohn.Forte@Sun.COM 	*num_of_ops = 0;
976*7836SJohn.Forte@Sun.COM 
977*7836SJohn.Forte@Sun.COM 	ec = qry_and_match(
978*7836SJohn.Forte@Sun.COM 	    op_uids, num_of_ops, size, op_type,
979*7836SJohn.Forte@Sun.COM 	    uid, src_type, NULL);
980*7836SJohn.Forte@Sun.COM 
981*7836SJohn.Forte@Sun.COM 	return (ec);
982*7836SJohn.Forte@Sun.COM }
983*7836SJohn.Forte@Sun.COM 
984*7836SJohn.Forte@Sun.COM int
get_qry_ops2(uint32_t * nodes_bmp,uint32_t num_of_nodes,isns_type_t op_type,uint32_t ** op_uids,uint32_t * num_of_ops,uint32_t * size)985*7836SJohn.Forte@Sun.COM get_qry_ops2(
986*7836SJohn.Forte@Sun.COM 	uint32_t *nodes_bmp,
987*7836SJohn.Forte@Sun.COM 	uint32_t num_of_nodes,
988*7836SJohn.Forte@Sun.COM 	isns_type_t op_type,
989*7836SJohn.Forte@Sun.COM 	uint32_t **op_uids,
990*7836SJohn.Forte@Sun.COM 	uint32_t *num_of_ops,
991*7836SJohn.Forte@Sun.COM 	uint32_t *size
992*7836SJohn.Forte@Sun.COM )
993*7836SJohn.Forte@Sun.COM {
994*7836SJohn.Forte@Sun.COM 	int ec = 0;
995*7836SJohn.Forte@Sun.COM 
996*7836SJohn.Forte@Sun.COM 	uint32_t node_uid;
997*7836SJohn.Forte@Sun.COM 
998*7836SJohn.Forte@Sun.COM 	htab_t *htab;
999*7836SJohn.Forte@Sun.COM 
1000*7836SJohn.Forte@Sun.COM 	*num_of_ops = 0;
1001*7836SJohn.Forte@Sun.COM 
1002*7836SJohn.Forte@Sun.COM 	if (nodes_bmp != NULL) {
1003*7836SJohn.Forte@Sun.COM 		FOR_EACH_MEMBER(nodes_bmp, num_of_nodes, node_uid, {
1004*7836SJohn.Forte@Sun.COM 			ec = qry_and_match(
1005*7836SJohn.Forte@Sun.COM 			    op_uids, num_of_ops, size, op_type,
1006*7836SJohn.Forte@Sun.COM 			    node_uid, OBJ_ISCSI, NULL);
1007*7836SJohn.Forte@Sun.COM 			if (ec != 0) {
1008*7836SJohn.Forte@Sun.COM 				return (ec);
1009*7836SJohn.Forte@Sun.COM 			}
1010*7836SJohn.Forte@Sun.COM 		});
1011*7836SJohn.Forte@Sun.COM 	} else {
1012*7836SJohn.Forte@Sun.COM 		node_uid = 0;
1013*7836SJohn.Forte@Sun.COM 		htab = cache_get_htab(OBJ_ISCSI);
1014*7836SJohn.Forte@Sun.COM 		FOR_EACH_ITEM(htab, node_uid, {
1015*7836SJohn.Forte@Sun.COM 			ec = qry_and_match(
1016*7836SJohn.Forte@Sun.COM 			    op_uids, num_of_ops, size, op_type,
1017*7836SJohn.Forte@Sun.COM 			    node_uid, OBJ_ISCSI, NULL);
1018*7836SJohn.Forte@Sun.COM 			if (ec != 0) {
1019*7836SJohn.Forte@Sun.COM 				return (ec);
1020*7836SJohn.Forte@Sun.COM 			}
1021*7836SJohn.Forte@Sun.COM 		});
1022*7836SJohn.Forte@Sun.COM 	}
1023*7836SJohn.Forte@Sun.COM 
1024*7836SJohn.Forte@Sun.COM 	return (ec);
1025*7836SJohn.Forte@Sun.COM }
1026*7836SJohn.Forte@Sun.COM 
1027*7836SJohn.Forte@Sun.COM uint32_t
get_next_obj(isns_tlv_t * tlv,uint32_t tlv_len,isns_type_t type,uint32_t * uids,uint32_t num)1028*7836SJohn.Forte@Sun.COM get_next_obj(
1029*7836SJohn.Forte@Sun.COM 	isns_tlv_t *tlv,
1030*7836SJohn.Forte@Sun.COM 	uint32_t tlv_len,
1031*7836SJohn.Forte@Sun.COM 	isns_type_t type,
1032*7836SJohn.Forte@Sun.COM 	uint32_t *uids,
1033*7836SJohn.Forte@Sun.COM 	uint32_t num
1034*7836SJohn.Forte@Sun.COM )
1035*7836SJohn.Forte@Sun.COM {
1036*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1037*7836SJohn.Forte@Sun.COM 
1038*7836SJohn.Forte@Sun.COM 	uint32_t tag;
1039*7836SJohn.Forte@Sun.COM 	uint8_t *value;
1040*7836SJohn.Forte@Sun.COM 
1041*7836SJohn.Forte@Sun.COM 	uint32_t old = 0;
1042*7836SJohn.Forte@Sun.COM 	uint32_t min = 0;
1043*7836SJohn.Forte@Sun.COM 	uint32_t uid, diff;
1044*7836SJohn.Forte@Sun.COM 	uint32_t pre_diff = 0xFFFFFFFF;
1045*7836SJohn.Forte@Sun.COM 
1046*7836SJohn.Forte@Sun.COM 	lc.curr_uid = 0;
1047*7836SJohn.Forte@Sun.COM 	lc.type = type;
1048*7836SJohn.Forte@Sun.COM 	lc.op[1] = 0;
1049*7836SJohn.Forte@Sun.COM 	lc.op[2] = 0;
1050*7836SJohn.Forte@Sun.COM 
1051*7836SJohn.Forte@Sun.COM 	if (tlv_len > 8) {
1052*7836SJohn.Forte@Sun.COM 		tag = tlv->attr_id;
1053*7836SJohn.Forte@Sun.COM 		value = tlv->attr_value;
1054*7836SJohn.Forte@Sun.COM 		switch (tag) {
1055*7836SJohn.Forte@Sun.COM 		case ISNS_EID_ATTR_ID:
1056*7836SJohn.Forte@Sun.COM 			lc.id[0] = ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID);
1057*7836SJohn.Forte@Sun.COM 			lc.op[0] = OP_STRING;
1058*7836SJohn.Forte@Sun.COM 			lc.data[0].ptr = (uchar_t *)value;
1059*7836SJohn.Forte@Sun.COM 			break;
1060*7836SJohn.Forte@Sun.COM 		case ISNS_ISCSI_NAME_ATTR_ID:
1061*7836SJohn.Forte@Sun.COM 			lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
1062*7836SJohn.Forte@Sun.COM 			lc.op[0] = OP_STRING;
1063*7836SJohn.Forte@Sun.COM 			lc.data[0].ptr = (uchar_t *)value;
1064*7836SJohn.Forte@Sun.COM 			break;
1065*7836SJohn.Forte@Sun.COM 		case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
1066*7836SJohn.Forte@Sun.COM 			lc.id[0] = ATTR_INDEX_ISCSI(
1067*7836SJohn.Forte@Sun.COM 			    ISNS_ISCSI_NODE_INDEX_ATTR_ID);
1068*7836SJohn.Forte@Sun.COM 			lc.op[0] = OP_INTEGER;
1069*7836SJohn.Forte@Sun.COM 			lc.data[0].ui = ntohl(*(uint32_t *)value);
1070*7836SJohn.Forte@Sun.COM 			break;
1071*7836SJohn.Forte@Sun.COM 		case ISNS_PORTAL_IP_ADDR_ATTR_ID:
1072*7836SJohn.Forte@Sun.COM 			lc.id[0] = ATTR_INDEX_PORTAL(
1073*7836SJohn.Forte@Sun.COM 			    ISNS_PORTAL_IP_ADDR_ATTR_ID);
1074*7836SJohn.Forte@Sun.COM 			lc.op[0] = OP_MEMORY_IP6;
1075*7836SJohn.Forte@Sun.COM 			lc.data[0].ip = (in6_addr_t *)value;
1076*7836SJohn.Forte@Sun.COM 			NEXT_TLV(tlv, tlv_len);
1077*7836SJohn.Forte@Sun.COM 			if (tlv_len > 8 &&
1078*7836SJohn.Forte@Sun.COM 			    ((tag = tlv->attr_id) ==
1079*7836SJohn.Forte@Sun.COM 			    ISNS_PORTAL_PORT_ATTR_ID)) {
1080*7836SJohn.Forte@Sun.COM 				value = tlv->attr_value;
1081*7836SJohn.Forte@Sun.COM 				lc.id[1] = ATTR_INDEX_PORTAL(
1082*7836SJohn.Forte@Sun.COM 				    ISNS_PORTAL_PORT_ATTR_ID);
1083*7836SJohn.Forte@Sun.COM 				lc.op[1] = OP_INTEGER;
1084*7836SJohn.Forte@Sun.COM 				lc.data[1].ui = ntohl(*(uint32_t *)value);
1085*7836SJohn.Forte@Sun.COM 			} else {
1086*7836SJohn.Forte@Sun.COM 				return (0);
1087*7836SJohn.Forte@Sun.COM 			}
1088*7836SJohn.Forte@Sun.COM 			break;
1089*7836SJohn.Forte@Sun.COM 		case ISNS_PORTAL_INDEX_ATTR_ID:
1090*7836SJohn.Forte@Sun.COM 			lc.id[0] = ATTR_INDEX_PORTAL(ISNS_PORTAL_INDEX_ATTR_ID);
1091*7836SJohn.Forte@Sun.COM 			lc.op[0] = OP_INTEGER;
1092*7836SJohn.Forte@Sun.COM 			lc.data[0].ui = ntohl(*(uint32_t *)value);
1093*7836SJohn.Forte@Sun.COM 			break;
1094*7836SJohn.Forte@Sun.COM 		case ISNS_PG_INDEX_ATTR_ID:
1095*7836SJohn.Forte@Sun.COM 			lc.id[0] = ATTR_INDEX_PG(ISNS_PG_INDEX_ATTR_ID);
1096*7836SJohn.Forte@Sun.COM 			lc.op[0] = OP_INTEGER;
1097*7836SJohn.Forte@Sun.COM 			lc.data[0].ui = ntohl(*(uint32_t *)value);
1098*7836SJohn.Forte@Sun.COM 			break;
1099*7836SJohn.Forte@Sun.COM 		default:
1100*7836SJohn.Forte@Sun.COM 			return (0);
1101*7836SJohn.Forte@Sun.COM 		}
1102*7836SJohn.Forte@Sun.COM 
1103*7836SJohn.Forte@Sun.COM 		old = is_obj_there(&lc);
1104*7836SJohn.Forte@Sun.COM 		if (old == 0) {
1105*7836SJohn.Forte@Sun.COM 			return (0);
1106*7836SJohn.Forte@Sun.COM 		}
1107*7836SJohn.Forte@Sun.COM 	}
1108*7836SJohn.Forte@Sun.COM 
1109*7836SJohn.Forte@Sun.COM 	while (num > 0) {
1110*7836SJohn.Forte@Sun.COM 		uid = uids[-- num];
1111*7836SJohn.Forte@Sun.COM 		if (uid > old) {
1112*7836SJohn.Forte@Sun.COM 			diff = uid - old;
1113*7836SJohn.Forte@Sun.COM 			if (diff < pre_diff) {
1114*7836SJohn.Forte@Sun.COM 				min = uid;
1115*7836SJohn.Forte@Sun.COM 				pre_diff = diff;
1116*7836SJohn.Forte@Sun.COM 			}
1117*7836SJohn.Forte@Sun.COM 		}
1118*7836SJohn.Forte@Sun.COM 	}
1119*7836SJohn.Forte@Sun.COM 
1120*7836SJohn.Forte@Sun.COM 	return (min);
1121*7836SJohn.Forte@Sun.COM }
1122*7836SJohn.Forte@Sun.COM 
1123*7836SJohn.Forte@Sun.COM static int
cb_qry_rsp(void * p1,void * p2)1124*7836SJohn.Forte@Sun.COM cb_qry_rsp(
1125*7836SJohn.Forte@Sun.COM 	void *p1,
1126*7836SJohn.Forte@Sun.COM 	void *p2
1127*7836SJohn.Forte@Sun.COM )
1128*7836SJohn.Forte@Sun.COM {
1129*7836SJohn.Forte@Sun.COM 	int ec = 0;
1130*7836SJohn.Forte@Sun.COM 
1131*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
1132*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
1133*7836SJohn.Forte@Sun.COM 
1134*7836SJohn.Forte@Sun.COM 	uint16_t tlv_len = lcp->id[1];
1135*7836SJohn.Forte@Sun.COM 	isns_tlv_t *tlv = (isns_tlv_t *)lcp->data[1].ptr;
1136*7836SJohn.Forte@Sun.COM 	conn_arg_t *conn = (conn_arg_t *)lcp->data[2].ptr;
1137*7836SJohn.Forte@Sun.COM 
1138*7836SJohn.Forte@Sun.COM 	isns_type_t type = obj->type;
1139*7836SJohn.Forte@Sun.COM 	uint32_t min_tag = TAG_RANGE[type][0];
1140*7836SJohn.Forte@Sun.COM 	uint32_t mid_tag = TAG_RANGE[type][1];
1141*7836SJohn.Forte@Sun.COM 	uint32_t max_tag = TAG_RANGE[type][2];
1142*7836SJohn.Forte@Sun.COM 
1143*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
1144*7836SJohn.Forte@Sun.COM 	uint32_t tag;
1145*7836SJohn.Forte@Sun.COM 	uint32_t id;
1146*7836SJohn.Forte@Sun.COM 	uint32_t len;
1147*7836SJohn.Forte@Sun.COM 	void *value;
1148*7836SJohn.Forte@Sun.COM 
1149*7836SJohn.Forte@Sun.COM 	isns_pdu_t *rsp = conn->out_packet.pdu;
1150*7836SJohn.Forte@Sun.COM 	size_t pl = conn->out_packet.pl;
1151*7836SJohn.Forte@Sun.COM 	size_t sz = conn->out_packet.sz;
1152*7836SJohn.Forte@Sun.COM 
1153*7836SJohn.Forte@Sun.COM 	do {
1154*7836SJohn.Forte@Sun.COM 		if (tlv->attr_len == 0) {
1155*7836SJohn.Forte@Sun.COM 			tag = tlv->attr_id;
1156*7836SJohn.Forte@Sun.COM 			if (tag <= mid_tag) {
1157*7836SJohn.Forte@Sun.COM 				id = ATTR_INDEX(tag, type);
1158*7836SJohn.Forte@Sun.COM 				attr = &obj->attrs[id];
1159*7836SJohn.Forte@Sun.COM 				len = attr->len;
1160*7836SJohn.Forte@Sun.COM 				value = (void *)attr->value.ptr;
1161*7836SJohn.Forte@Sun.COM 				ec = pdu_add_tlv(&rsp, &pl, &sz,
1162*7836SJohn.Forte@Sun.COM 				    tag, len, value, 0);
1163*7836SJohn.Forte@Sun.COM 			}
1164*7836SJohn.Forte@Sun.COM 		}
1165*7836SJohn.Forte@Sun.COM 		NEXT_TLV(tlv, tlv_len);
1166*7836SJohn.Forte@Sun.COM 	} while (ec == 0 &&
1167*7836SJohn.Forte@Sun.COM 	    tlv_len >= 8 &&
1168*7836SJohn.Forte@Sun.COM 	    tlv->attr_id >= min_tag &&
1169*7836SJohn.Forte@Sun.COM 	    tlv->attr_id <= max_tag);
1170*7836SJohn.Forte@Sun.COM 
1171*7836SJohn.Forte@Sun.COM 	conn->out_packet.pdu = rsp;
1172*7836SJohn.Forte@Sun.COM 	conn->out_packet.pl = pl;
1173*7836SJohn.Forte@Sun.COM 	conn->out_packet.sz = sz;
1174*7836SJohn.Forte@Sun.COM 
1175*7836SJohn.Forte@Sun.COM 	return (ec);
1176*7836SJohn.Forte@Sun.COM }
1177*7836SJohn.Forte@Sun.COM 
1178*7836SJohn.Forte@Sun.COM int
get_qry_attrs(uint32_t uid,isns_type_t type,isns_tlv_t * tlv,uint16_t tlv_len,conn_arg_t * conn)1179*7836SJohn.Forte@Sun.COM get_qry_attrs(
1180*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1181*7836SJohn.Forte@Sun.COM 	isns_type_t type,
1182*7836SJohn.Forte@Sun.COM 	isns_tlv_t *tlv,
1183*7836SJohn.Forte@Sun.COM 	uint16_t tlv_len,
1184*7836SJohn.Forte@Sun.COM 	conn_arg_t *conn
1185*7836SJohn.Forte@Sun.COM )
1186*7836SJohn.Forte@Sun.COM {
1187*7836SJohn.Forte@Sun.COM 	int ec = 0;
1188*7836SJohn.Forte@Sun.COM 
1189*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1190*7836SJohn.Forte@Sun.COM 
1191*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, type, uid);
1192*7836SJohn.Forte@Sun.COM 
1193*7836SJohn.Forte@Sun.COM 	lc.id[1] = tlv_len;
1194*7836SJohn.Forte@Sun.COM 	lc.data[1].ptr = (uchar_t *)tlv;
1195*7836SJohn.Forte@Sun.COM 	lc.data[2].ptr = (uchar_t *)conn;
1196*7836SJohn.Forte@Sun.COM 
1197*7836SJohn.Forte@Sun.COM 	ec = cache_lookup(&lc, NULL, cb_qry_rsp);
1198*7836SJohn.Forte@Sun.COM 
1199*7836SJohn.Forte@Sun.COM 	return (ec);
1200*7836SJohn.Forte@Sun.COM }
1201*7836SJohn.Forte@Sun.COM 
1202*7836SJohn.Forte@Sun.COM int
get_qry_attrs1(uint32_t uid,isns_type_t type,isns_tlv_t * tlv,uint16_t tlv_len,conn_arg_t * conn)1203*7836SJohn.Forte@Sun.COM get_qry_attrs1(
1204*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1205*7836SJohn.Forte@Sun.COM 	isns_type_t type,
1206*7836SJohn.Forte@Sun.COM 	isns_tlv_t *tlv,
1207*7836SJohn.Forte@Sun.COM 	uint16_t tlv_len,
1208*7836SJohn.Forte@Sun.COM 	conn_arg_t *conn
1209*7836SJohn.Forte@Sun.COM )
1210*7836SJohn.Forte@Sun.COM {
1211*7836SJohn.Forte@Sun.COM 	isns_tlv_t *tmp = tlv;
1212*7836SJohn.Forte@Sun.COM 	uint32_t tmp_len = tlv_len;
1213*7836SJohn.Forte@Sun.COM 
1214*7836SJohn.Forte@Sun.COM 	/* clear the length of all of tlv */
1215*7836SJohn.Forte@Sun.COM 	while (tmp_len > 8) {
1216*7836SJohn.Forte@Sun.COM 		tmp->attr_len = 0;
1217*7836SJohn.Forte@Sun.COM 		NEXT_TLV(tmp, tmp_len);
1218*7836SJohn.Forte@Sun.COM 	}
1219*7836SJohn.Forte@Sun.COM 
1220*7836SJohn.Forte@Sun.COM 	return (get_qry_attrs(uid, type, tlv, tlv_len, conn));
1221*7836SJohn.Forte@Sun.COM }
1222