xref: /onnv-gate/usr/src/cmd/isns/isnsd/scn.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 #include <unistd.h>
31*7836SJohn.Forte@Sun.COM 
32*7836SJohn.Forte@Sun.COM #include "isns_server.h"
33*7836SJohn.Forte@Sun.COM #include "isns_msgq.h"
34*7836SJohn.Forte@Sun.COM #include "isns_cache.h"
35*7836SJohn.Forte@Sun.COM #include "isns_cfg.h"
36*7836SJohn.Forte@Sun.COM #include "isns_obj.h"
37*7836SJohn.Forte@Sun.COM #include "isns_dseng.h"
38*7836SJohn.Forte@Sun.COM #include "isns_log.h"
39*7836SJohn.Forte@Sun.COM #include "isns_scn.h"
40*7836SJohn.Forte@Sun.COM #include "isns_pdu.h"
41*7836SJohn.Forte@Sun.COM 
42*7836SJohn.Forte@Sun.COM /*
43*7836SJohn.Forte@Sun.COM  * global variables.
44*7836SJohn.Forte@Sun.COM  */
45*7836SJohn.Forte@Sun.COM 
46*7836SJohn.Forte@Sun.COM /*
47*7836SJohn.Forte@Sun.COM  * local variables.
48*7836SJohn.Forte@Sun.COM  */
49*7836SJohn.Forte@Sun.COM static scn_registry_t *scn_registry = NULL;
50*7836SJohn.Forte@Sun.COM static int scn_dispatched = 0;
51*7836SJohn.Forte@Sun.COM 
52*7836SJohn.Forte@Sun.COM /*
53*7836SJohn.Forte@Sun.COM  * external variables.
54*7836SJohn.Forte@Sun.COM  */
55*7836SJohn.Forte@Sun.COM extern uint8_t mgmt_scn;
56*7836SJohn.Forte@Sun.COM extern msg_queue_t *sys_q;
57*7836SJohn.Forte@Sun.COM extern msg_queue_t *scn_q;
58*7836SJohn.Forte@Sun.COM extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
59*7836SJohn.Forte@Sun.COM 
60*7836SJohn.Forte@Sun.COM #ifdef DEBUG
61*7836SJohn.Forte@Sun.COM extern void dump_pdu1(isns_pdu_t *);
62*7836SJohn.Forte@Sun.COM #endif
63*7836SJohn.Forte@Sun.COM 
64*7836SJohn.Forte@Sun.COM static int sf_gen(scn_raw_t *);
65*7836SJohn.Forte@Sun.COM static int sf_error(scn_raw_t *);
66*7836SJohn.Forte@Sun.COM 
67*7836SJohn.Forte@Sun.COM static scn_raw_t *make_raw_entity(isns_obj_t *);
68*7836SJohn.Forte@Sun.COM static scn_raw_t *make_raw_iscsi(isns_obj_t *);
69*7836SJohn.Forte@Sun.COM static scn_raw_t *make_raw_portal(isns_obj_t *);
70*7836SJohn.Forte@Sun.COM static scn_raw_t *make_raw_assoc_iscsi(isns_obj_t *);
71*7836SJohn.Forte@Sun.COM static scn_raw_t *make_raw_assoc_dd(isns_obj_t *);
72*7836SJohn.Forte@Sun.COM static scn_raw_t *(*const make_raw[MAX_OBJ_TYPE_FOR_SIZE])(isns_obj_t *) = {
73*7836SJohn.Forte@Sun.COM 	NULL,
74*7836SJohn.Forte@Sun.COM 	&make_raw_entity,
75*7836SJohn.Forte@Sun.COM 	&make_raw_iscsi,
76*7836SJohn.Forte@Sun.COM 	&make_raw_portal,
77*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_PG */
78*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DD */
79*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DDS */
80*7836SJohn.Forte@Sun.COM 	NULL,			/* MAX_OBJ_TYPE */
81*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DUMMY1 */
82*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DUMMY2 */
83*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DUMMY3 */
84*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DUMMY4 */
85*7836SJohn.Forte@Sun.COM 	&make_raw_assoc_iscsi,
86*7836SJohn.Forte@Sun.COM 	&make_raw_assoc_dd
87*7836SJohn.Forte@Sun.COM };
88*7836SJohn.Forte@Sun.COM 
89*7836SJohn.Forte@Sun.COM static scn_text_t *scn_gen_entity(scn_raw_t *);
90*7836SJohn.Forte@Sun.COM static scn_text_t *scn_gen_iscsi(scn_raw_t *);
91*7836SJohn.Forte@Sun.COM static scn_text_t *scn_gen_portal(scn_raw_t *);
92*7836SJohn.Forte@Sun.COM static scn_text_t *scn_gen_assoc_dd(scn_raw_t *);
93*7836SJohn.Forte@Sun.COM static scn_text_t *(*const scn_gen[MAX_OBJ_TYPE_FOR_SIZE])(scn_raw_t *) = {
94*7836SJohn.Forte@Sun.COM 	NULL,
95*7836SJohn.Forte@Sun.COM 	&scn_gen_entity,
96*7836SJohn.Forte@Sun.COM 	&scn_gen_iscsi,
97*7836SJohn.Forte@Sun.COM 	&scn_gen_portal,
98*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_PG */
99*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DD */
100*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DDS */
101*7836SJohn.Forte@Sun.COM 	NULL,			/* MAX_OBJ_TYPE */
102*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DUMMY1 */
103*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DUMMY2 */
104*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DUMMY3 */
105*7836SJohn.Forte@Sun.COM 	NULL,			/* OBJ_DUMMY4 */
106*7836SJohn.Forte@Sun.COM 	&scn_gen_iscsi,
107*7836SJohn.Forte@Sun.COM 	&scn_gen_assoc_dd
108*7836SJohn.Forte@Sun.COM };
109*7836SJohn.Forte@Sun.COM 
110*7836SJohn.Forte@Sun.COM #define	SCN_TEST(E, BITMAP, UID1, UID2, NT) \
111*7836SJohn.Forte@Sun.COM 	(((E) & (BITMAP)) && \
112*7836SJohn.Forte@Sun.COM 	(!((BITMAP) & (ISNS_INIT_SELF_INFO_ONLY | \
113*7836SJohn.Forte@Sun.COM 			ISNS_TARGET_SELF_INFO_ONLY)) || \
114*7836SJohn.Forte@Sun.COM 		((UID1) == (UID2)) || \
115*7836SJohn.Forte@Sun.COM 		(((BITMAP) & ISNS_INIT_SELF_INFO_ONLY) && \
116*7836SJohn.Forte@Sun.COM 			((NT) & ISNS_INITIATOR_NODE_TYPE)) || \
117*7836SJohn.Forte@Sun.COM 		(((BITMAP) & ISNS_TARGET_SELF_INFO_ONLY) && \
118*7836SJohn.Forte@Sun.COM 			((NT) & ISNS_TARGET_NODE_TYPE))))
119*7836SJohn.Forte@Sun.COM 
120*7836SJohn.Forte@Sun.COM /*
121*7836SJohn.Forte@Sun.COM  * local functions.
122*7836SJohn.Forte@Sun.COM  */
123*7836SJohn.Forte@Sun.COM 
124*7836SJohn.Forte@Sun.COM /*
125*7836SJohn.Forte@Sun.COM  * ****************************************************************************
126*7836SJohn.Forte@Sun.COM  *
127*7836SJohn.Forte@Sun.COM  * free_portal_1:
128*7836SJohn.Forte@Sun.COM  *	Free one SCN portal or decrease the reference count if the portal
129*7836SJohn.Forte@Sun.COM  *	is referenced by other SCN entry(s).
130*7836SJohn.Forte@Sun.COM  *
131*7836SJohn.Forte@Sun.COM  * p	- the portal.
132*7836SJohn.Forte@Sun.COM  *
133*7836SJohn.Forte@Sun.COM  * ****************************************************************************
134*7836SJohn.Forte@Sun.COM  */
135*7836SJohn.Forte@Sun.COM static void
free_portal_1(scn_portal_t * p)136*7836SJohn.Forte@Sun.COM free_portal_1(
137*7836SJohn.Forte@Sun.COM 	scn_portal_t *p
138*7836SJohn.Forte@Sun.COM )
139*7836SJohn.Forte@Sun.COM {
140*7836SJohn.Forte@Sun.COM 	if (p->ref <= 1) {
141*7836SJohn.Forte@Sun.COM 		if (p->sz == sizeof (in6_addr_t)) {
142*7836SJohn.Forte@Sun.COM 			free(p->ip.in6);
143*7836SJohn.Forte@Sun.COM 		}
144*7836SJohn.Forte@Sun.COM 		free(p);
145*7836SJohn.Forte@Sun.COM 	} else {
146*7836SJohn.Forte@Sun.COM 		p->ref --;
147*7836SJohn.Forte@Sun.COM 	}
148*7836SJohn.Forte@Sun.COM }
149*7836SJohn.Forte@Sun.COM 
150*7836SJohn.Forte@Sun.COM /*
151*7836SJohn.Forte@Sun.COM  * ****************************************************************************
152*7836SJohn.Forte@Sun.COM  *
153*7836SJohn.Forte@Sun.COM  * free_portal:
154*7836SJohn.Forte@Sun.COM  *	Free the unused portals, which are extracted for new SCN entry,
155*7836SJohn.Forte@Sun.COM  *	after the new SCN entry is added.
156*7836SJohn.Forte@Sun.COM  *
157*7836SJohn.Forte@Sun.COM  * p	- the portal.
158*7836SJohn.Forte@Sun.COM  *
159*7836SJohn.Forte@Sun.COM  * ****************************************************************************
160*7836SJohn.Forte@Sun.COM  */
161*7836SJohn.Forte@Sun.COM static void
free_portal(scn_portal_t * p)162*7836SJohn.Forte@Sun.COM free_portal(
163*7836SJohn.Forte@Sun.COM 	scn_portal_t *p
164*7836SJohn.Forte@Sun.COM )
165*7836SJohn.Forte@Sun.COM {
166*7836SJohn.Forte@Sun.COM 	scn_portal_t *n;
167*7836SJohn.Forte@Sun.COM 
168*7836SJohn.Forte@Sun.COM 	while (p != NULL) {
169*7836SJohn.Forte@Sun.COM 		n = p->next;
170*7836SJohn.Forte@Sun.COM 		free_portal_1(p);
171*7836SJohn.Forte@Sun.COM 		p = n;
172*7836SJohn.Forte@Sun.COM 	}
173*7836SJohn.Forte@Sun.COM }
174*7836SJohn.Forte@Sun.COM 
175*7836SJohn.Forte@Sun.COM /*
176*7836SJohn.Forte@Sun.COM  * ****************************************************************************
177*7836SJohn.Forte@Sun.COM  *
178*7836SJohn.Forte@Sun.COM  * free_portal_list:
179*7836SJohn.Forte@Sun.COM  *	Free the list of portals while a SCN entry is being destroyed.
180*7836SJohn.Forte@Sun.COM  *
181*7836SJohn.Forte@Sun.COM  * l	- the portal list.
182*7836SJohn.Forte@Sun.COM  *
183*7836SJohn.Forte@Sun.COM  * ****************************************************************************
184*7836SJohn.Forte@Sun.COM  */
185*7836SJohn.Forte@Sun.COM static void
free_portal_list(scn_list_t * l)186*7836SJohn.Forte@Sun.COM free_portal_list(
187*7836SJohn.Forte@Sun.COM 	scn_list_t *l
188*7836SJohn.Forte@Sun.COM )
189*7836SJohn.Forte@Sun.COM {
190*7836SJohn.Forte@Sun.COM 	scn_list_t *n;
191*7836SJohn.Forte@Sun.COM 	scn_portal_t *p;
192*7836SJohn.Forte@Sun.COM 
193*7836SJohn.Forte@Sun.COM 	while (l != NULL) {
194*7836SJohn.Forte@Sun.COM 		n = l->next;
195*7836SJohn.Forte@Sun.COM 		p = l->data.portal;
196*7836SJohn.Forte@Sun.COM 		free_portal_1(p);
197*7836SJohn.Forte@Sun.COM 		free(l);
198*7836SJohn.Forte@Sun.COM 		l = n;
199*7836SJohn.Forte@Sun.COM 	}
200*7836SJohn.Forte@Sun.COM }
201*7836SJohn.Forte@Sun.COM 
202*7836SJohn.Forte@Sun.COM /*
203*7836SJohn.Forte@Sun.COM  * ****************************************************************************
204*7836SJohn.Forte@Sun.COM  *
205*7836SJohn.Forte@Sun.COM  * free_scn_text:
206*7836SJohn.Forte@Sun.COM  *	Free one SCN or decrease the ref count after the SCN is emitted.
207*7836SJohn.Forte@Sun.COM  *
208*7836SJohn.Forte@Sun.COM  * text	- the SCN.
209*7836SJohn.Forte@Sun.COM  *
210*7836SJohn.Forte@Sun.COM  * ****************************************************************************
211*7836SJohn.Forte@Sun.COM  */
212*7836SJohn.Forte@Sun.COM static void
free_scn_text(scn_text_t * text)213*7836SJohn.Forte@Sun.COM free_scn_text(
214*7836SJohn.Forte@Sun.COM 	scn_text_t *text
215*7836SJohn.Forte@Sun.COM )
216*7836SJohn.Forte@Sun.COM {
217*7836SJohn.Forte@Sun.COM 	if (text->ref <= 1) {
218*7836SJohn.Forte@Sun.COM 		free(text->iscsi);
219*7836SJohn.Forte@Sun.COM 		free(text);
220*7836SJohn.Forte@Sun.COM 	} else {
221*7836SJohn.Forte@Sun.COM 		text->ref --;
222*7836SJohn.Forte@Sun.COM 	}
223*7836SJohn.Forte@Sun.COM }
224*7836SJohn.Forte@Sun.COM 
225*7836SJohn.Forte@Sun.COM /*
226*7836SJohn.Forte@Sun.COM  * ****************************************************************************
227*7836SJohn.Forte@Sun.COM  *
228*7836SJohn.Forte@Sun.COM  * free_scn_list:
229*7836SJohn.Forte@Sun.COM  *	Free the the list of SCN.
230*7836SJohn.Forte@Sun.COM  *
231*7836SJohn.Forte@Sun.COM  * scn	- the list.
232*7836SJohn.Forte@Sun.COM  *
233*7836SJohn.Forte@Sun.COM  * ****************************************************************************
234*7836SJohn.Forte@Sun.COM  */
235*7836SJohn.Forte@Sun.COM static void
free_scn_list(scn_t * scn)236*7836SJohn.Forte@Sun.COM free_scn_list(
237*7836SJohn.Forte@Sun.COM 	scn_t *scn
238*7836SJohn.Forte@Sun.COM )
239*7836SJohn.Forte@Sun.COM {
240*7836SJohn.Forte@Sun.COM 	scn_t *next_scn;
241*7836SJohn.Forte@Sun.COM 	scn_list_t *list;
242*7836SJohn.Forte@Sun.COM 	scn_list_t *next_list;
243*7836SJohn.Forte@Sun.COM 
244*7836SJohn.Forte@Sun.COM 	while (scn != NULL) {
245*7836SJohn.Forte@Sun.COM 		next_scn = scn->next;
246*7836SJohn.Forte@Sun.COM 		list = scn->data.list;
247*7836SJohn.Forte@Sun.COM 		while (list != NULL) {
248*7836SJohn.Forte@Sun.COM 			next_list = list->next;
249*7836SJohn.Forte@Sun.COM 			free_scn_text(list->data.text);
250*7836SJohn.Forte@Sun.COM 			free(list);
251*7836SJohn.Forte@Sun.COM 			list = next_list;
252*7836SJohn.Forte@Sun.COM 		}
253*7836SJohn.Forte@Sun.COM 		free(scn);
254*7836SJohn.Forte@Sun.COM 		scn = next_scn;
255*7836SJohn.Forte@Sun.COM 	}
256*7836SJohn.Forte@Sun.COM }
257*7836SJohn.Forte@Sun.COM 
258*7836SJohn.Forte@Sun.COM /*
259*7836SJohn.Forte@Sun.COM  * ****************************************************************************
260*7836SJohn.Forte@Sun.COM  *
261*7836SJohn.Forte@Sun.COM  * free_scn:
262*7836SJohn.Forte@Sun.COM  *	Free all of SCNs which are dispatched to every entry.
263*7836SJohn.Forte@Sun.COM  *
264*7836SJohn.Forte@Sun.COM  * ****************************************************************************
265*7836SJohn.Forte@Sun.COM  */
266*7836SJohn.Forte@Sun.COM static void
free_scn()267*7836SJohn.Forte@Sun.COM free_scn(
268*7836SJohn.Forte@Sun.COM )
269*7836SJohn.Forte@Sun.COM {
270*7836SJohn.Forte@Sun.COM 	scn_registry_t *p;
271*7836SJohn.Forte@Sun.COM 
272*7836SJohn.Forte@Sun.COM 	p = scn_registry;
273*7836SJohn.Forte@Sun.COM 
274*7836SJohn.Forte@Sun.COM 	while (p != NULL) {
275*7836SJohn.Forte@Sun.COM 		free_scn_list(p->scn);
276*7836SJohn.Forte@Sun.COM 		p->scn = NULL;
277*7836SJohn.Forte@Sun.COM 		p = p->next;
278*7836SJohn.Forte@Sun.COM 	}
279*7836SJohn.Forte@Sun.COM }
280*7836SJohn.Forte@Sun.COM 
281*7836SJohn.Forte@Sun.COM /*
282*7836SJohn.Forte@Sun.COM  * ****************************************************************************
283*7836SJohn.Forte@Sun.COM  *
284*7836SJohn.Forte@Sun.COM  * free_entry:
285*7836SJohn.Forte@Sun.COM  *	Free one SCN entry.
286*7836SJohn.Forte@Sun.COM  *
287*7836SJohn.Forte@Sun.COM  * e	- the SCN entry.
288*7836SJohn.Forte@Sun.COM  *
289*7836SJohn.Forte@Sun.COM  * ****************************************************************************
290*7836SJohn.Forte@Sun.COM  */
291*7836SJohn.Forte@Sun.COM static void
free_entry(scn_registry_t * e)292*7836SJohn.Forte@Sun.COM free_entry(
293*7836SJohn.Forte@Sun.COM 	scn_registry_t *e
294*7836SJohn.Forte@Sun.COM )
295*7836SJohn.Forte@Sun.COM {
296*7836SJohn.Forte@Sun.COM 	free_scn_list(e->scn);
297*7836SJohn.Forte@Sun.COM 	free_portal_list(e->portal.l);
298*7836SJohn.Forte@Sun.COM 	free(e->name);
299*7836SJohn.Forte@Sun.COM 	free(e);
300*7836SJohn.Forte@Sun.COM }
301*7836SJohn.Forte@Sun.COM 
302*7836SJohn.Forte@Sun.COM /*
303*7836SJohn.Forte@Sun.COM  * ****************************************************************************
304*7836SJohn.Forte@Sun.COM  *
305*7836SJohn.Forte@Sun.COM  * free_raw:
306*7836SJohn.Forte@Sun.COM  *	Free the raw data after the SCN is generated from it.
307*7836SJohn.Forte@Sun.COM  *
308*7836SJohn.Forte@Sun.COM  * raw	- the raw SCN data.
309*7836SJohn.Forte@Sun.COM  *
310*7836SJohn.Forte@Sun.COM  * ****************************************************************************
311*7836SJohn.Forte@Sun.COM  */
312*7836SJohn.Forte@Sun.COM static void
free_raw(scn_raw_t * raw)313*7836SJohn.Forte@Sun.COM free_raw(
314*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw
315*7836SJohn.Forte@Sun.COM )
316*7836SJohn.Forte@Sun.COM {
317*7836SJohn.Forte@Sun.COM 	if (raw->ref == 0) {
318*7836SJohn.Forte@Sun.COM 		free(raw->iscsi);
319*7836SJohn.Forte@Sun.COM 	}
320*7836SJohn.Forte@Sun.COM 	if (raw->ip != NULL) {
321*7836SJohn.Forte@Sun.COM 		free(raw->ip);
322*7836SJohn.Forte@Sun.COM 	}
323*7836SJohn.Forte@Sun.COM 	free(raw);
324*7836SJohn.Forte@Sun.COM }
325*7836SJohn.Forte@Sun.COM 
326*7836SJohn.Forte@Sun.COM /*
327*7836SJohn.Forte@Sun.COM  * ****************************************************************************
328*7836SJohn.Forte@Sun.COM  *
329*7836SJohn.Forte@Sun.COM  * scn_add_portal:
330*7836SJohn.Forte@Sun.COM  *	Add portals to the portal list of a SCN entry.
331*7836SJohn.Forte@Sun.COM  *
332*7836SJohn.Forte@Sun.COM  * e	- the SCN entry.
333*7836SJohn.Forte@Sun.COM  * p	- the portals.
334*7836SJohn.Forte@Sun.COM  * return - 0: successful, otherwise failed.
335*7836SJohn.Forte@Sun.COM  *
336*7836SJohn.Forte@Sun.COM  * ****************************************************************************
337*7836SJohn.Forte@Sun.COM  */
338*7836SJohn.Forte@Sun.COM static int
scn_add_portal(scn_registry_t * e,scn_portal_t * p)339*7836SJohn.Forte@Sun.COM scn_add_portal(
340*7836SJohn.Forte@Sun.COM 	scn_registry_t *e,
341*7836SJohn.Forte@Sun.COM 	scn_portal_t *p
342*7836SJohn.Forte@Sun.COM )
343*7836SJohn.Forte@Sun.COM {
344*7836SJohn.Forte@Sun.COM 	scn_portal_t *x;
345*7836SJohn.Forte@Sun.COM 	scn_list_t *l, *m;
346*7836SJohn.Forte@Sun.COM 
347*7836SJohn.Forte@Sun.COM 	scn_list_t **lp;
348*7836SJohn.Forte@Sun.COM 
349*7836SJohn.Forte@Sun.COM 	int found_it;
350*7836SJohn.Forte@Sun.COM 
351*7836SJohn.Forte@Sun.COM 	lp = &e->portal.l;
352*7836SJohn.Forte@Sun.COM 	while (p != NULL) {
353*7836SJohn.Forte@Sun.COM 		m = (scn_list_t *)malloc(sizeof (scn_list_t));
354*7836SJohn.Forte@Sun.COM 		if (m == NULL) {
355*7836SJohn.Forte@Sun.COM 			return (1);
356*7836SJohn.Forte@Sun.COM 		}
357*7836SJohn.Forte@Sun.COM 		found_it = 0;
358*7836SJohn.Forte@Sun.COM 		e = scn_registry;
359*7836SJohn.Forte@Sun.COM 		while (e && !found_it) {
360*7836SJohn.Forte@Sun.COM 			l = e->portal.l;
361*7836SJohn.Forte@Sun.COM 			while (l && !found_it) {
362*7836SJohn.Forte@Sun.COM 				x = l->data.portal;
363*7836SJohn.Forte@Sun.COM 				if (x->uid == p->uid) {
364*7836SJohn.Forte@Sun.COM 					found_it = 1;
365*7836SJohn.Forte@Sun.COM 				}
366*7836SJohn.Forte@Sun.COM 				l = l->next;
367*7836SJohn.Forte@Sun.COM 			}
368*7836SJohn.Forte@Sun.COM 			e = e->next;
369*7836SJohn.Forte@Sun.COM 		}
370*7836SJohn.Forte@Sun.COM 
371*7836SJohn.Forte@Sun.COM 		if (!found_it) {
372*7836SJohn.Forte@Sun.COM 			x = p;
373*7836SJohn.Forte@Sun.COM 		}
374*7836SJohn.Forte@Sun.COM 		m->data.portal = x;
375*7836SJohn.Forte@Sun.COM 		x->ref ++;
376*7836SJohn.Forte@Sun.COM 		m->next = *lp;
377*7836SJohn.Forte@Sun.COM 		*lp = m;
378*7836SJohn.Forte@Sun.COM 
379*7836SJohn.Forte@Sun.COM 		p = p->next;
380*7836SJohn.Forte@Sun.COM 	}
381*7836SJohn.Forte@Sun.COM 
382*7836SJohn.Forte@Sun.COM 	return (0);
383*7836SJohn.Forte@Sun.COM }
384*7836SJohn.Forte@Sun.COM 
385*7836SJohn.Forte@Sun.COM /*
386*7836SJohn.Forte@Sun.COM  * ****************************************************************************
387*7836SJohn.Forte@Sun.COM  *
388*7836SJohn.Forte@Sun.COM  * scn_remove_portal:
389*7836SJohn.Forte@Sun.COM  *	Remove a portal from the portal list of every SCN entry.
390*7836SJohn.Forte@Sun.COM  *
391*7836SJohn.Forte@Sun.COM  * uid	- the portal object uid.
392*7836SJohn.Forte@Sun.COM  * return - always successful (0).
393*7836SJohn.Forte@Sun.COM  *
394*7836SJohn.Forte@Sun.COM  * ****************************************************************************
395*7836SJohn.Forte@Sun.COM  */
396*7836SJohn.Forte@Sun.COM static int
scn_remove_portal(uint32_t uid)397*7836SJohn.Forte@Sun.COM scn_remove_portal(
398*7836SJohn.Forte@Sun.COM 	uint32_t uid
399*7836SJohn.Forte@Sun.COM )
400*7836SJohn.Forte@Sun.COM {
401*7836SJohn.Forte@Sun.COM 	scn_registry_t **ep, *e;
402*7836SJohn.Forte@Sun.COM 
403*7836SJohn.Forte@Sun.COM 	scn_portal_t *x;
404*7836SJohn.Forte@Sun.COM 	scn_list_t **lp, *l;
405*7836SJohn.Forte@Sun.COM 
406*7836SJohn.Forte@Sun.COM 	ep = &scn_registry;
407*7836SJohn.Forte@Sun.COM 	e = *ep;
408*7836SJohn.Forte@Sun.COM 
409*7836SJohn.Forte@Sun.COM 	while (e != NULL) {
410*7836SJohn.Forte@Sun.COM 		lp = &e->portal.l;
411*7836SJohn.Forte@Sun.COM 		l = *lp;
412*7836SJohn.Forte@Sun.COM 		while (l != NULL) {
413*7836SJohn.Forte@Sun.COM 			x = l->data.portal;
414*7836SJohn.Forte@Sun.COM 			if (x->uid == uid) {
415*7836SJohn.Forte@Sun.COM 				/* remove it */
416*7836SJohn.Forte@Sun.COM 				*lp = l->next;
417*7836SJohn.Forte@Sun.COM 				free_portal_1(x);
418*7836SJohn.Forte@Sun.COM 				free(l);
419*7836SJohn.Forte@Sun.COM 			} else {
420*7836SJohn.Forte@Sun.COM 				lp = &l->next;
421*7836SJohn.Forte@Sun.COM 			}
422*7836SJohn.Forte@Sun.COM 			l = *lp;
423*7836SJohn.Forte@Sun.COM 		}
424*7836SJohn.Forte@Sun.COM 
425*7836SJohn.Forte@Sun.COM 		if (e->portal.l == NULL) {
426*7836SJohn.Forte@Sun.COM 			/* no portal for this entry, destroy it */
427*7836SJohn.Forte@Sun.COM 			*ep = e->next;
428*7836SJohn.Forte@Sun.COM 			free_entry(e);
429*7836SJohn.Forte@Sun.COM 		} else {
430*7836SJohn.Forte@Sun.COM 			ep = &e->next;
431*7836SJohn.Forte@Sun.COM 		}
432*7836SJohn.Forte@Sun.COM 		e = *ep;
433*7836SJohn.Forte@Sun.COM 	}
434*7836SJohn.Forte@Sun.COM 
435*7836SJohn.Forte@Sun.COM 	return (0);
436*7836SJohn.Forte@Sun.COM }
437*7836SJohn.Forte@Sun.COM 
438*7836SJohn.Forte@Sun.COM /*
439*7836SJohn.Forte@Sun.COM  * ****************************************************************************
440*7836SJohn.Forte@Sun.COM  *
441*7836SJohn.Forte@Sun.COM  * scn_list_add:
442*7836SJohn.Forte@Sun.COM  *	Add one SCN entry to the SCN entry list.
443*7836SJohn.Forte@Sun.COM  *
444*7836SJohn.Forte@Sun.COM  * e	- the SCN entry.
445*7836SJohn.Forte@Sun.COM  * return - always successful (0).
446*7836SJohn.Forte@Sun.COM  *
447*7836SJohn.Forte@Sun.COM  * ****************************************************************************
448*7836SJohn.Forte@Sun.COM  */
449*7836SJohn.Forte@Sun.COM static int
scn_list_add(scn_registry_t * e)450*7836SJohn.Forte@Sun.COM scn_list_add(
451*7836SJohn.Forte@Sun.COM 	scn_registry_t *e
452*7836SJohn.Forte@Sun.COM )
453*7836SJohn.Forte@Sun.COM {
454*7836SJohn.Forte@Sun.COM 	scn_registry_t **pp;
455*7836SJohn.Forte@Sun.COM 	scn_portal_t *p;
456*7836SJohn.Forte@Sun.COM 
457*7836SJohn.Forte@Sun.COM 	p = e->portal.p;
458*7836SJohn.Forte@Sun.COM 	e->portal.l = NULL;
459*7836SJohn.Forte@Sun.COM 
460*7836SJohn.Forte@Sun.COM 	pp = &scn_registry;
461*7836SJohn.Forte@Sun.COM 	while (*pp) {
462*7836SJohn.Forte@Sun.COM 		if ((*pp)->uid == e->uid) {
463*7836SJohn.Forte@Sun.COM 			/* replace the bitmap */
464*7836SJohn.Forte@Sun.COM 			(*pp)->bitmap = e->bitmap;
465*7836SJohn.Forte@Sun.COM 			free_portal(p);
466*7836SJohn.Forte@Sun.COM 			free_entry(e);
467*7836SJohn.Forte@Sun.COM 			return (0);
468*7836SJohn.Forte@Sun.COM 		} else if ((*pp)->uid < e->uid) {
469*7836SJohn.Forte@Sun.COM 			break;
470*7836SJohn.Forte@Sun.COM 		}
471*7836SJohn.Forte@Sun.COM 		pp = &(*pp)->next;
472*7836SJohn.Forte@Sun.COM 	}
473*7836SJohn.Forte@Sun.COM 
474*7836SJohn.Forte@Sun.COM 	(void) scn_add_portal(e, p);
475*7836SJohn.Forte@Sun.COM 
476*7836SJohn.Forte@Sun.COM 	if (e->portal.l != NULL || sys_q == NULL) {
477*7836SJohn.Forte@Sun.COM 		/* insert it to the list */
478*7836SJohn.Forte@Sun.COM 		e->next = *pp;
479*7836SJohn.Forte@Sun.COM 		*pp = e;
480*7836SJohn.Forte@Sun.COM 	} else {
481*7836SJohn.Forte@Sun.COM 		/* no portal, ignore it */
482*7836SJohn.Forte@Sun.COM 		free_entry(e);
483*7836SJohn.Forte@Sun.COM 	}
484*7836SJohn.Forte@Sun.COM 
485*7836SJohn.Forte@Sun.COM 	/* free the unused portal(s) */
486*7836SJohn.Forte@Sun.COM 	free_portal(p);
487*7836SJohn.Forte@Sun.COM 
488*7836SJohn.Forte@Sun.COM 	return (0);
489*7836SJohn.Forte@Sun.COM }
490*7836SJohn.Forte@Sun.COM 
491*7836SJohn.Forte@Sun.COM /*
492*7836SJohn.Forte@Sun.COM  * ****************************************************************************
493*7836SJohn.Forte@Sun.COM  *
494*7836SJohn.Forte@Sun.COM  * scn_list_remove:
495*7836SJohn.Forte@Sun.COM  *	Remove one SCN entry from the SCN entry list.
496*7836SJohn.Forte@Sun.COM  *
497*7836SJohn.Forte@Sun.COM  * uid	- the SCN entry unique ID.
498*7836SJohn.Forte@Sun.COM  * return - always successful (0).
499*7836SJohn.Forte@Sun.COM  *
500*7836SJohn.Forte@Sun.COM  * ****************************************************************************
501*7836SJohn.Forte@Sun.COM  */
502*7836SJohn.Forte@Sun.COM static int
scn_list_remove(uint32_t uid)503*7836SJohn.Forte@Sun.COM scn_list_remove(
504*7836SJohn.Forte@Sun.COM 	uint32_t uid
505*7836SJohn.Forte@Sun.COM )
506*7836SJohn.Forte@Sun.COM {
507*7836SJohn.Forte@Sun.COM 	scn_registry_t **ep, *e;
508*7836SJohn.Forte@Sun.COM 
509*7836SJohn.Forte@Sun.COM 	ep = &scn_registry;
510*7836SJohn.Forte@Sun.COM 	e = *ep;
511*7836SJohn.Forte@Sun.COM 	while (e) {
512*7836SJohn.Forte@Sun.COM 		if (e->uid == uid) {
513*7836SJohn.Forte@Sun.COM 			/* destroy it */
514*7836SJohn.Forte@Sun.COM 			*ep = e->next;
515*7836SJohn.Forte@Sun.COM 			free_entry(e);
516*7836SJohn.Forte@Sun.COM 			break;
517*7836SJohn.Forte@Sun.COM 		} else if (e->uid < uid) {
518*7836SJohn.Forte@Sun.COM 			break;
519*7836SJohn.Forte@Sun.COM 		}
520*7836SJohn.Forte@Sun.COM 		ep = &e->next;
521*7836SJohn.Forte@Sun.COM 		e = *ep;
522*7836SJohn.Forte@Sun.COM 	}
523*7836SJohn.Forte@Sun.COM 
524*7836SJohn.Forte@Sun.COM 	return (0);
525*7836SJohn.Forte@Sun.COM }
526*7836SJohn.Forte@Sun.COM 
527*7836SJohn.Forte@Sun.COM /*
528*7836SJohn.Forte@Sun.COM  * ****************************************************************************
529*7836SJohn.Forte@Sun.COM  *
530*7836SJohn.Forte@Sun.COM  * cb_get_scn_port:
531*7836SJohn.Forte@Sun.COM  *	The callback function which returns the SCN port of a portal object.
532*7836SJohn.Forte@Sun.COM  *
533*7836SJohn.Forte@Sun.COM  * p1	- the portal object.
534*7836SJohn.Forte@Sun.COM  * p2	- the lookup control data.
535*7836SJohn.Forte@Sun.COM  * return - the SCN port number.
536*7836SJohn.Forte@Sun.COM  *
537*7836SJohn.Forte@Sun.COM  * ****************************************************************************
538*7836SJohn.Forte@Sun.COM  */
539*7836SJohn.Forte@Sun.COM static int
cb_get_scn_port(void * p1,void * p2)540*7836SJohn.Forte@Sun.COM cb_get_scn_port(
541*7836SJohn.Forte@Sun.COM 	void *p1,
542*7836SJohn.Forte@Sun.COM 	/*ARGSUSED*/
543*7836SJohn.Forte@Sun.COM 	void *p2
544*7836SJohn.Forte@Sun.COM )
545*7836SJohn.Forte@Sun.COM {
546*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
547*7836SJohn.Forte@Sun.COM 
548*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr = &obj->attrs[
549*7836SJohn.Forte@Sun.COM 	    ATTR_INDEX_PORTAL(ISNS_SCN_PORT_ATTR_ID)];
550*7836SJohn.Forte@Sun.COM 
551*7836SJohn.Forte@Sun.COM 	int port = 0;
552*7836SJohn.Forte@Sun.COM 
553*7836SJohn.Forte@Sun.COM 	if (attr->tag != 0 && attr->value.ui != 0) {
554*7836SJohn.Forte@Sun.COM 		port = (int)attr->value.ui;
555*7836SJohn.Forte@Sun.COM 	}
556*7836SJohn.Forte@Sun.COM 
557*7836SJohn.Forte@Sun.COM 	return (port);
558*7836SJohn.Forte@Sun.COM }
559*7836SJohn.Forte@Sun.COM 
560*7836SJohn.Forte@Sun.COM /*
561*7836SJohn.Forte@Sun.COM  * ****************************************************************************
562*7836SJohn.Forte@Sun.COM  *
563*7836SJohn.Forte@Sun.COM  * new_scn_portal:
564*7836SJohn.Forte@Sun.COM  *	Make a new SCN portal.
565*7836SJohn.Forte@Sun.COM  *
566*7836SJohn.Forte@Sun.COM  * ref	- the ref count.
567*7836SJohn.Forte@Sun.COM  * uid	- the portal object UID.
568*7836SJohn.Forte@Sun.COM  * ip	- the ip address.
569*7836SJohn.Forte@Sun.COM  * port	- the port number.
570*7836SJohn.Forte@Sun.COM  * return - the SCN portal.
571*7836SJohn.Forte@Sun.COM  *
572*7836SJohn.Forte@Sun.COM  * ****************************************************************************
573*7836SJohn.Forte@Sun.COM  */
574*7836SJohn.Forte@Sun.COM static scn_portal_t *
new_scn_portal(uint32_t ref,uint32_t uid,in6_addr_t * ip,uint32_t port)575*7836SJohn.Forte@Sun.COM new_scn_portal(
576*7836SJohn.Forte@Sun.COM 	uint32_t ref,
577*7836SJohn.Forte@Sun.COM 	uint32_t uid,
578*7836SJohn.Forte@Sun.COM 	in6_addr_t *ip,
579*7836SJohn.Forte@Sun.COM 	uint32_t port
580*7836SJohn.Forte@Sun.COM )
581*7836SJohn.Forte@Sun.COM {
582*7836SJohn.Forte@Sun.COM 	scn_portal_t *p;
583*7836SJohn.Forte@Sun.COM 
584*7836SJohn.Forte@Sun.COM 	p = (scn_portal_t *)malloc(sizeof (scn_portal_t));
585*7836SJohn.Forte@Sun.COM 	if (p != NULL) {
586*7836SJohn.Forte@Sun.COM 		p->uid = uid;
587*7836SJohn.Forte@Sun.COM 		/* convert the ipv6 to ipv4 */
588*7836SJohn.Forte@Sun.COM 		if (((int *)ip)[0] == 0x00 &&
589*7836SJohn.Forte@Sun.COM 		    ((int *)ip)[1] == 0x00 &&
590*7836SJohn.Forte@Sun.COM 		    ((uchar_t *)ip)[8] == 0x00 &&
591*7836SJohn.Forte@Sun.COM 		    ((uchar_t *)ip)[9] == 0x00 &&
592*7836SJohn.Forte@Sun.COM 		    ((uchar_t *)ip)[10] == 0xFF &&
593*7836SJohn.Forte@Sun.COM 		    ((uchar_t *)ip)[11] == 0xFF) {
594*7836SJohn.Forte@Sun.COM 			p->sz = sizeof (in_addr_t);
595*7836SJohn.Forte@Sun.COM 			p->ip.in = ((uint32_t *)ip)[3];
596*7836SJohn.Forte@Sun.COM 			free(ip);
597*7836SJohn.Forte@Sun.COM 		} else {
598*7836SJohn.Forte@Sun.COM 			p->sz = sizeof (in6_addr_t);
599*7836SJohn.Forte@Sun.COM 			p->ip.in6 = ip;
600*7836SJohn.Forte@Sun.COM 		}
601*7836SJohn.Forte@Sun.COM 		p->port = port;
602*7836SJohn.Forte@Sun.COM 		p->ref = ref;
603*7836SJohn.Forte@Sun.COM 		p->so = 0;
604*7836SJohn.Forte@Sun.COM 		p->next = NULL;
605*7836SJohn.Forte@Sun.COM 	}
606*7836SJohn.Forte@Sun.COM 
607*7836SJohn.Forte@Sun.COM 	return (p);
608*7836SJohn.Forte@Sun.COM }
609*7836SJohn.Forte@Sun.COM 
610*7836SJohn.Forte@Sun.COM /*
611*7836SJohn.Forte@Sun.COM  * ****************************************************************************
612*7836SJohn.Forte@Sun.COM  *
613*7836SJohn.Forte@Sun.COM  * extract scn_portal:
614*7836SJohn.Forte@Sun.COM  *	Extract the SCN portal(s) for a storage node.
615*7836SJohn.Forte@Sun.COM  *
616*7836SJohn.Forte@Sun.COM  * name	- the storage node name.
617*7836SJohn.Forte@Sun.COM  * return - the SCN portal list.
618*7836SJohn.Forte@Sun.COM  *
619*7836SJohn.Forte@Sun.COM  * ****************************************************************************
620*7836SJohn.Forte@Sun.COM  */
621*7836SJohn.Forte@Sun.COM static scn_portal_t *
extract_scn_portal(uchar_t * name)622*7836SJohn.Forte@Sun.COM extract_scn_portal(
623*7836SJohn.Forte@Sun.COM 	uchar_t *name
624*7836SJohn.Forte@Sun.COM )
625*7836SJohn.Forte@Sun.COM {
626*7836SJohn.Forte@Sun.COM 	scn_portal_t *list = NULL;
627*7836SJohn.Forte@Sun.COM 	scn_portal_t *p;
628*7836SJohn.Forte@Sun.COM 
629*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc_pg, lc_p;
630*7836SJohn.Forte@Sun.COM 	uint32_t pg_uid, uid;
631*7836SJohn.Forte@Sun.COM 
632*7836SJohn.Forte@Sun.COM 	in6_addr_t *ip;
633*7836SJohn.Forte@Sun.COM 	uint32_t port;
634*7836SJohn.Forte@Sun.COM 
635*7836SJohn.Forte@Sun.COM 	lc_pg.type = OBJ_PG;
636*7836SJohn.Forte@Sun.COM 	lc_pg.curr_uid = 0;
637*7836SJohn.Forte@Sun.COM 	lc_pg.id[0] = ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID);
638*7836SJohn.Forte@Sun.COM 	lc_pg.op[0] = OP_STRING;
639*7836SJohn.Forte@Sun.COM 	lc_pg.data[0].ptr = name;
640*7836SJohn.Forte@Sun.COM 	lc_pg.op[1] = 0;
641*7836SJohn.Forte@Sun.COM 
642*7836SJohn.Forte@Sun.COM 	lc_pg.id[1] = ISNS_PG_PORTAL_IP_ADDR_ATTR_ID;
643*7836SJohn.Forte@Sun.COM 	lc_pg.id[2] = ISNS_PG_PORTAL_PORT_ATTR_ID;
644*7836SJohn.Forte@Sun.COM 
645*7836SJohn.Forte@Sun.COM 	lc_p.type = OBJ_PORTAL;
646*7836SJohn.Forte@Sun.COM 	lc_p.curr_uid = 0;
647*7836SJohn.Forte@Sun.COM 	lc_p.id[0] = ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID);
648*7836SJohn.Forte@Sun.COM 	lc_p.op[0] = OP_MEMORY_IP6;
649*7836SJohn.Forte@Sun.COM 	lc_p.id[1] = ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID);
650*7836SJohn.Forte@Sun.COM 	lc_p.op[1] = OP_INTEGER;
651*7836SJohn.Forte@Sun.COM 	lc_p.op[2] = 0;
652*7836SJohn.Forte@Sun.COM 
653*7836SJohn.Forte@Sun.COM 	while (cache_lookup(&lc_pg, &pg_uid, cb_clone_attrs) == 0 &&
654*7836SJohn.Forte@Sun.COM 	    pg_uid != 0) {
655*7836SJohn.Forte@Sun.COM 		ip = lc_pg.data[1].ip;
656*7836SJohn.Forte@Sun.COM 		port = lc_pg.data[2].ui;
657*7836SJohn.Forte@Sun.COM 		if (ip != NULL) {
658*7836SJohn.Forte@Sun.COM 			lc_p.data[0].ip = ip;
659*7836SJohn.Forte@Sun.COM 			lc_p.data[1].ui = port;
660*7836SJohn.Forte@Sun.COM 			port = cache_lookup(&lc_p, &uid, cb_get_scn_port);
661*7836SJohn.Forte@Sun.COM 			if (port != 0 && uid != 0) {
662*7836SJohn.Forte@Sun.COM 				/* ref starts from 1 */
663*7836SJohn.Forte@Sun.COM 				p = new_scn_portal(1, uid, ip, port);
664*7836SJohn.Forte@Sun.COM 				if (p != NULL) {
665*7836SJohn.Forte@Sun.COM 					p->next = list;
666*7836SJohn.Forte@Sun.COM 					list = p;
667*7836SJohn.Forte@Sun.COM 				} else {
668*7836SJohn.Forte@Sun.COM 					free(ip);
669*7836SJohn.Forte@Sun.COM 					free(p);
670*7836SJohn.Forte@Sun.COM 				}
671*7836SJohn.Forte@Sun.COM 			} else {
672*7836SJohn.Forte@Sun.COM 				/* portal not registered or no scn port */
673*7836SJohn.Forte@Sun.COM 				free(ip);
674*7836SJohn.Forte@Sun.COM 			}
675*7836SJohn.Forte@Sun.COM 		}
676*7836SJohn.Forte@Sun.COM 		lc_pg.curr_uid = pg_uid;
677*7836SJohn.Forte@Sun.COM 	}
678*7836SJohn.Forte@Sun.COM 
679*7836SJohn.Forte@Sun.COM 	return (list);
680*7836SJohn.Forte@Sun.COM }
681*7836SJohn.Forte@Sun.COM 
682*7836SJohn.Forte@Sun.COM /*
683*7836SJohn.Forte@Sun.COM  * ****************************************************************************
684*7836SJohn.Forte@Sun.COM  *
685*7836SJohn.Forte@Sun.COM  * cb_update_scn_bitmap:
686*7836SJohn.Forte@Sun.COM  *	The callback function which updates the SCN Bitmap attribute of
687*7836SJohn.Forte@Sun.COM  *	a storage node object.
688*7836SJohn.Forte@Sun.COM  *
689*7836SJohn.Forte@Sun.COM  * p1	- the storage node object.
690*7836SJohn.Forte@Sun.COM  * p2	- the lookup control data.
691*7836SJohn.Forte@Sun.COM  * return - error code.
692*7836SJohn.Forte@Sun.COM  *
693*7836SJohn.Forte@Sun.COM  * ****************************************************************************
694*7836SJohn.Forte@Sun.COM  */
695*7836SJohn.Forte@Sun.COM static int
cb_update_scn_bitmap(void * p1,void * p2)696*7836SJohn.Forte@Sun.COM cb_update_scn_bitmap(
697*7836SJohn.Forte@Sun.COM 	void *p1,
698*7836SJohn.Forte@Sun.COM 	void *p2
699*7836SJohn.Forte@Sun.COM )
700*7836SJohn.Forte@Sun.COM {
701*7836SJohn.Forte@Sun.COM 	int ec = 0;
702*7836SJohn.Forte@Sun.COM 
703*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
704*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
705*7836SJohn.Forte@Sun.COM 
706*7836SJohn.Forte@Sun.COM 	int id = ATTR_INDEX_ISCSI(ISNS_ISCSI_SCN_BITMAP_ATTR_ID);
707*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr = &obj->attrs[id];
708*7836SJohn.Forte@Sun.COM 
709*7836SJohn.Forte@Sun.COM 	uint32_t bitmap = lcp->data[2].ui;
710*7836SJohn.Forte@Sun.COM 
711*7836SJohn.Forte@Sun.COM 	if (bitmap != 0) {
712*7836SJohn.Forte@Sun.COM 		attr->tag = ISNS_ISCSI_SCN_BITMAP_ATTR_ID;
713*7836SJohn.Forte@Sun.COM 		attr->len = 4;
714*7836SJohn.Forte@Sun.COM 	} else if (attr->tag == 0) {
715*7836SJohn.Forte@Sun.COM 		return (ec);
716*7836SJohn.Forte@Sun.COM 	} else {
717*7836SJohn.Forte@Sun.COM 		attr->tag = 0;
718*7836SJohn.Forte@Sun.COM 		attr->len = 0;
719*7836SJohn.Forte@Sun.COM 	}
720*7836SJohn.Forte@Sun.COM 	attr->value.ui = bitmap;
721*7836SJohn.Forte@Sun.COM 
722*7836SJohn.Forte@Sun.COM 	if (sys_q != NULL) {
723*7836SJohn.Forte@Sun.COM 		ec = write_data(DATA_UPDATE, obj);
724*7836SJohn.Forte@Sun.COM 	}
725*7836SJohn.Forte@Sun.COM 
726*7836SJohn.Forte@Sun.COM 	return (ec);
727*7836SJohn.Forte@Sun.COM }
728*7836SJohn.Forte@Sun.COM 
729*7836SJohn.Forte@Sun.COM /*
730*7836SJohn.Forte@Sun.COM  * ****************************************************************************
731*7836SJohn.Forte@Sun.COM  *
732*7836SJohn.Forte@Sun.COM  * cb_get_node_type:
733*7836SJohn.Forte@Sun.COM  *	The callback function which returns the node type attribute of
734*7836SJohn.Forte@Sun.COM  *	a storage node object.
735*7836SJohn.Forte@Sun.COM  *
736*7836SJohn.Forte@Sun.COM  * p1	- the storage node object.
737*7836SJohn.Forte@Sun.COM  * p2	- the lookup control data.
738*7836SJohn.Forte@Sun.COM  * return - error code.
739*7836SJohn.Forte@Sun.COM  *
740*7836SJohn.Forte@Sun.COM  * ****************************************************************************
741*7836SJohn.Forte@Sun.COM  */
742*7836SJohn.Forte@Sun.COM static int
cb_get_node_type(void * p1,void * p2)743*7836SJohn.Forte@Sun.COM cb_get_node_type(
744*7836SJohn.Forte@Sun.COM 	void *p1,
745*7836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
746*7836SJohn.Forte@Sun.COM 	void *p2
747*7836SJohn.Forte@Sun.COM )
748*7836SJohn.Forte@Sun.COM {
749*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj = (isns_obj_t *)p1;
750*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr = &obj->attrs[
751*7836SJohn.Forte@Sun.COM 	    ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_TYPE_ATTR_ID)];
752*7836SJohn.Forte@Sun.COM 	int nt = (int)attr->value.ui;
753*7836SJohn.Forte@Sun.COM 
754*7836SJohn.Forte@Sun.COM 	return (nt);
755*7836SJohn.Forte@Sun.COM }
756*7836SJohn.Forte@Sun.COM 
757*7836SJohn.Forte@Sun.COM /*
758*7836SJohn.Forte@Sun.COM  * ****************************************************************************
759*7836SJohn.Forte@Sun.COM  *
760*7836SJohn.Forte@Sun.COM  * cb_get_node_type:
761*7836SJohn.Forte@Sun.COM  *	The callback function which returns the storage node object UID
762*7836SJohn.Forte@Sun.COM  *	from a portal group object.
763*7836SJohn.Forte@Sun.COM  *
764*7836SJohn.Forte@Sun.COM  * p1	- the pg object.
765*7836SJohn.Forte@Sun.COM  * p2	- the lookup control data.
766*7836SJohn.Forte@Sun.COM  * return - the storage node object UID.
767*7836SJohn.Forte@Sun.COM  *
768*7836SJohn.Forte@Sun.COM  * ****************************************************************************
769*7836SJohn.Forte@Sun.COM  */
770*7836SJohn.Forte@Sun.COM static int
cb_pg_node(void * p1,void * p2)771*7836SJohn.Forte@Sun.COM cb_pg_node(
772*7836SJohn.Forte@Sun.COM 	void *p1,
773*7836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
774*7836SJohn.Forte@Sun.COM 	void *p2
775*7836SJohn.Forte@Sun.COM )
776*7836SJohn.Forte@Sun.COM {
777*7836SJohn.Forte@Sun.COM 	uint32_t ref;
778*7836SJohn.Forte@Sun.COM 
779*7836SJohn.Forte@Sun.COM 	ref = get_ref_t(p1, OBJ_ISCSI);
780*7836SJohn.Forte@Sun.COM 
781*7836SJohn.Forte@Sun.COM 	return ((int)ref);
782*7836SJohn.Forte@Sun.COM }
783*7836SJohn.Forte@Sun.COM 
784*7836SJohn.Forte@Sun.COM /*
785*7836SJohn.Forte@Sun.COM  * ****************************************************************************
786*7836SJohn.Forte@Sun.COM  *
787*7836SJohn.Forte@Sun.COM  * make_raw_entity:
788*7836SJohn.Forte@Sun.COM  *	Make raw SCN data with a Network Entity object.
789*7836SJohn.Forte@Sun.COM  *
790*7836SJohn.Forte@Sun.COM  * obj	- the network entity object.
791*7836SJohn.Forte@Sun.COM  * return - the raw SCN data.
792*7836SJohn.Forte@Sun.COM  *
793*7836SJohn.Forte@Sun.COM  * ****************************************************************************
794*7836SJohn.Forte@Sun.COM  */
795*7836SJohn.Forte@Sun.COM static scn_raw_t *
make_raw_entity(isns_obj_t * obj)796*7836SJohn.Forte@Sun.COM make_raw_entity(
797*7836SJohn.Forte@Sun.COM 	/*ARGSUSED*/
798*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj
799*7836SJohn.Forte@Sun.COM )
800*7836SJohn.Forte@Sun.COM {
801*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw;
802*7836SJohn.Forte@Sun.COM 
803*7836SJohn.Forte@Sun.COM 	raw = (scn_raw_t *)malloc(sizeof (scn_raw_t));
804*7836SJohn.Forte@Sun.COM 	if (raw != NULL) {
805*7836SJohn.Forte@Sun.COM 		raw->type = obj->type;
806*7836SJohn.Forte@Sun.COM 		raw->uid = get_obj_uid(obj);
807*7836SJohn.Forte@Sun.COM 		raw->iscsi = NULL;
808*7836SJohn.Forte@Sun.COM 		raw->ref = 0;
809*7836SJohn.Forte@Sun.COM 		raw->ilen = 0;
810*7836SJohn.Forte@Sun.COM 		raw->nt = 0;
811*7836SJohn.Forte@Sun.COM 		raw->ip = NULL;
812*7836SJohn.Forte@Sun.COM 		raw->dd_id = 0;
813*7836SJohn.Forte@Sun.COM 		raw->dds_id = 0;
814*7836SJohn.Forte@Sun.COM 	} else {
815*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "make_raw_entity", "malloc failed.");
816*7836SJohn.Forte@Sun.COM 	}
817*7836SJohn.Forte@Sun.COM 
818*7836SJohn.Forte@Sun.COM 	return (raw);
819*7836SJohn.Forte@Sun.COM }
820*7836SJohn.Forte@Sun.COM 
821*7836SJohn.Forte@Sun.COM /*
822*7836SJohn.Forte@Sun.COM  * ****************************************************************************
823*7836SJohn.Forte@Sun.COM  *
824*7836SJohn.Forte@Sun.COM  * make_raw_iscsi:
825*7836SJohn.Forte@Sun.COM  *	Make raw SCN data with a Storage Node object.
826*7836SJohn.Forte@Sun.COM  *
827*7836SJohn.Forte@Sun.COM  * obj	- the storage node object.
828*7836SJohn.Forte@Sun.COM  * return - the raw SCN data.
829*7836SJohn.Forte@Sun.COM  *
830*7836SJohn.Forte@Sun.COM  * ****************************************************************************
831*7836SJohn.Forte@Sun.COM  */
832*7836SJohn.Forte@Sun.COM static scn_raw_t *
make_raw_iscsi(isns_obj_t * obj)833*7836SJohn.Forte@Sun.COM make_raw_iscsi(
834*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj
835*7836SJohn.Forte@Sun.COM )
836*7836SJohn.Forte@Sun.COM {
837*7836SJohn.Forte@Sun.COM 	uint32_t uid;
838*7836SJohn.Forte@Sun.COM 	uint32_t nt;
839*7836SJohn.Forte@Sun.COM 	uchar_t *iscsi;
840*7836SJohn.Forte@Sun.COM 	uint32_t ilen;
841*7836SJohn.Forte@Sun.COM 
842*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
843*7836SJohn.Forte@Sun.COM 
844*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw;
845*7836SJohn.Forte@Sun.COM 
846*7836SJohn.Forte@Sun.COM 	uid = get_obj_uid(obj);
847*7836SJohn.Forte@Sun.COM 	attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_TYPE_ATTR_ID)];
848*7836SJohn.Forte@Sun.COM 	nt = attr->value.ui;
849*7836SJohn.Forte@Sun.COM 	attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
850*7836SJohn.Forte@Sun.COM 
851*7836SJohn.Forte@Sun.COM 	raw = (scn_raw_t *)malloc(sizeof (scn_raw_t));
852*7836SJohn.Forte@Sun.COM 	ilen = attr->len;
853*7836SJohn.Forte@Sun.COM 	iscsi = (uchar_t *)malloc(ilen);
854*7836SJohn.Forte@Sun.COM 	if (raw != NULL && iscsi != NULL) {
855*7836SJohn.Forte@Sun.COM 		/* copy the iscsi storage node name */
856*7836SJohn.Forte@Sun.COM 		(void) strcpy((char *)iscsi, (char *)attr->value.ptr);
857*7836SJohn.Forte@Sun.COM 
858*7836SJohn.Forte@Sun.COM 		raw->type = obj->type;
859*7836SJohn.Forte@Sun.COM 		raw->uid = uid;
860*7836SJohn.Forte@Sun.COM 		raw->iscsi = iscsi;
861*7836SJohn.Forte@Sun.COM 		raw->ref = 0;
862*7836SJohn.Forte@Sun.COM 		raw->ilen = ilen;
863*7836SJohn.Forte@Sun.COM 		raw->nt = nt;
864*7836SJohn.Forte@Sun.COM 		raw->ip = NULL;
865*7836SJohn.Forte@Sun.COM 		raw->dd_id = 0;
866*7836SJohn.Forte@Sun.COM 		raw->dds_id = 0;
867*7836SJohn.Forte@Sun.COM 	} else {
868*7836SJohn.Forte@Sun.COM 		free(raw);
869*7836SJohn.Forte@Sun.COM 		free(iscsi);
870*7836SJohn.Forte@Sun.COM 		raw = NULL;
871*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "make_raw_iscsi", "malloc failed.");
872*7836SJohn.Forte@Sun.COM 	}
873*7836SJohn.Forte@Sun.COM 
874*7836SJohn.Forte@Sun.COM 	return (raw);
875*7836SJohn.Forte@Sun.COM }
876*7836SJohn.Forte@Sun.COM 
877*7836SJohn.Forte@Sun.COM /*
878*7836SJohn.Forte@Sun.COM  * ****************************************************************************
879*7836SJohn.Forte@Sun.COM  *
880*7836SJohn.Forte@Sun.COM  * make_raw_portal:
881*7836SJohn.Forte@Sun.COM  *	Make raw SCN data with a Portal object.
882*7836SJohn.Forte@Sun.COM  *
883*7836SJohn.Forte@Sun.COM  * obj	- the portal object.
884*7836SJohn.Forte@Sun.COM  * return - the raw SCN data.
885*7836SJohn.Forte@Sun.COM  *
886*7836SJohn.Forte@Sun.COM  * ****************************************************************************
887*7836SJohn.Forte@Sun.COM  */
888*7836SJohn.Forte@Sun.COM static scn_raw_t *
make_raw_portal(isns_obj_t * obj)889*7836SJohn.Forte@Sun.COM make_raw_portal(
890*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj
891*7836SJohn.Forte@Sun.COM )
892*7836SJohn.Forte@Sun.COM {
893*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
894*7836SJohn.Forte@Sun.COM 	in6_addr_t *ip;
895*7836SJohn.Forte@Sun.COM 	uint32_t port;
896*7836SJohn.Forte@Sun.COM 
897*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw;
898*7836SJohn.Forte@Sun.COM 
899*7836SJohn.Forte@Sun.COM 	raw = (scn_raw_t *)malloc(sizeof (scn_raw_t));
900*7836SJohn.Forte@Sun.COM 	ip = (in6_addr_t *)malloc(sizeof (in6_addr_t));
901*7836SJohn.Forte@Sun.COM 	if (raw != NULL && ip != NULL) {
902*7836SJohn.Forte@Sun.COM 		attr = &obj->attrs[
903*7836SJohn.Forte@Sun.COM 		    ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID)];
904*7836SJohn.Forte@Sun.COM 		(void) memcpy(ip, attr->value.ip, sizeof (in6_addr_t));
905*7836SJohn.Forte@Sun.COM 		attr = &obj->attrs[
906*7836SJohn.Forte@Sun.COM 		    ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID)];
907*7836SJohn.Forte@Sun.COM 		port = attr->value.ui;
908*7836SJohn.Forte@Sun.COM 
909*7836SJohn.Forte@Sun.COM 		raw->type = obj->type;
910*7836SJohn.Forte@Sun.COM 		raw->uid = 0;
911*7836SJohn.Forte@Sun.COM 		raw->iscsi = NULL;
912*7836SJohn.Forte@Sun.COM 		raw->ref = 0;
913*7836SJohn.Forte@Sun.COM 		raw->ilen = 0;
914*7836SJohn.Forte@Sun.COM 		raw->nt = 0;
915*7836SJohn.Forte@Sun.COM 		raw->ip = ip;
916*7836SJohn.Forte@Sun.COM 		raw->port = port;
917*7836SJohn.Forte@Sun.COM 		raw->dd_id = 0;
918*7836SJohn.Forte@Sun.COM 		raw->dds_id = 0;
919*7836SJohn.Forte@Sun.COM 	} else {
920*7836SJohn.Forte@Sun.COM 		free(ip);
921*7836SJohn.Forte@Sun.COM 		free(raw);
922*7836SJohn.Forte@Sun.COM 		raw = NULL;
923*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "make_raw_portal", "malloc failed.");
924*7836SJohn.Forte@Sun.COM 	}
925*7836SJohn.Forte@Sun.COM 
926*7836SJohn.Forte@Sun.COM 	return (raw);
927*7836SJohn.Forte@Sun.COM }
928*7836SJohn.Forte@Sun.COM 
929*7836SJohn.Forte@Sun.COM /*
930*7836SJohn.Forte@Sun.COM  * ****************************************************************************
931*7836SJohn.Forte@Sun.COM  *
932*7836SJohn.Forte@Sun.COM  * make_raw_assoc_iscsi:
933*7836SJohn.Forte@Sun.COM  *	Make raw SCN data with a Discovery Domain member association.
934*7836SJohn.Forte@Sun.COM  *
935*7836SJohn.Forte@Sun.COM  * obj	- the member association object.
936*7836SJohn.Forte@Sun.COM  * return - the raw SCN data.
937*7836SJohn.Forte@Sun.COM  *
938*7836SJohn.Forte@Sun.COM  * ****************************************************************************
939*7836SJohn.Forte@Sun.COM  */
940*7836SJohn.Forte@Sun.COM static scn_raw_t *
make_raw_assoc_iscsi(isns_obj_t * obj)941*7836SJohn.Forte@Sun.COM make_raw_assoc_iscsi(
942*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj
943*7836SJohn.Forte@Sun.COM )
944*7836SJohn.Forte@Sun.COM {
945*7836SJohn.Forte@Sun.COM 	uint32_t uid;
946*7836SJohn.Forte@Sun.COM 	uint32_t dd_id;
947*7836SJohn.Forte@Sun.COM 	uint32_t nt;
948*7836SJohn.Forte@Sun.COM 
949*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
950*7836SJohn.Forte@Sun.COM 	isns_attr_t *attr;
951*7836SJohn.Forte@Sun.COM 
952*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw;
953*7836SJohn.Forte@Sun.COM 	uchar_t *iscsi;
954*7836SJohn.Forte@Sun.COM 	uint32_t ilen;
955*7836SJohn.Forte@Sun.COM 
956*7836SJohn.Forte@Sun.COM 	uid = get_obj_uid(obj);
957*7836SJohn.Forte@Sun.COM 	dd_id = get_parent_uid(obj);
958*7836SJohn.Forte@Sun.COM 
959*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_ISCSI, uid);
960*7836SJohn.Forte@Sun.COM 
961*7836SJohn.Forte@Sun.COM 	nt = cache_lookup(&lc, NULL, cb_get_node_type);
962*7836SJohn.Forte@Sun.COM 
963*7836SJohn.Forte@Sun.COM 	attr = &obj->attrs[ATTR_INDEX_ASSOC_ISCSI(ISNS_DD_ISCSI_NAME_ATTR_ID)];
964*7836SJohn.Forte@Sun.COM 
965*7836SJohn.Forte@Sun.COM 	raw = (scn_raw_t *)malloc(sizeof (scn_raw_t));
966*7836SJohn.Forte@Sun.COM 	ilen = attr->len;
967*7836SJohn.Forte@Sun.COM 	iscsi = (uchar_t *)malloc(ilen);
968*7836SJohn.Forte@Sun.COM 	if (raw != NULL && iscsi != NULL) {
969*7836SJohn.Forte@Sun.COM 		/* copy the iscsi storage node name */
970*7836SJohn.Forte@Sun.COM 		(void) strcpy((char *)iscsi, (char *)attr->value.ptr);
971*7836SJohn.Forte@Sun.COM 
972*7836SJohn.Forte@Sun.COM 		raw->type = obj->type;
973*7836SJohn.Forte@Sun.COM 		raw->uid = uid;
974*7836SJohn.Forte@Sun.COM 		raw->iscsi = iscsi;
975*7836SJohn.Forte@Sun.COM 		raw->ref = 0;
976*7836SJohn.Forte@Sun.COM 		raw->ilen = ilen;
977*7836SJohn.Forte@Sun.COM 		raw->nt = nt;
978*7836SJohn.Forte@Sun.COM 		raw->ip = NULL;
979*7836SJohn.Forte@Sun.COM 		raw->dd_id = dd_id;
980*7836SJohn.Forte@Sun.COM 		raw->dds_id = 0;
981*7836SJohn.Forte@Sun.COM 	} else {
982*7836SJohn.Forte@Sun.COM 		free(raw);
983*7836SJohn.Forte@Sun.COM 		free(iscsi);
984*7836SJohn.Forte@Sun.COM 		raw = NULL;
985*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "make_raw_assoc_iscsi", "malloc failed.");
986*7836SJohn.Forte@Sun.COM 	}
987*7836SJohn.Forte@Sun.COM 
988*7836SJohn.Forte@Sun.COM 	return (raw);
989*7836SJohn.Forte@Sun.COM }
990*7836SJohn.Forte@Sun.COM 
991*7836SJohn.Forte@Sun.COM /*
992*7836SJohn.Forte@Sun.COM  * ****************************************************************************
993*7836SJohn.Forte@Sun.COM  *
994*7836SJohn.Forte@Sun.COM  * make_raw_assoc_dd:
995*7836SJohn.Forte@Sun.COM  *	Make raw SCN data with a Discovery Domain Set member association.
996*7836SJohn.Forte@Sun.COM  *
997*7836SJohn.Forte@Sun.COM  * obj	- the member association object.
998*7836SJohn.Forte@Sun.COM  * return - the raw SCN data.
999*7836SJohn.Forte@Sun.COM  *
1000*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1001*7836SJohn.Forte@Sun.COM  */
1002*7836SJohn.Forte@Sun.COM static scn_raw_t *
make_raw_assoc_dd(isns_obj_t * obj)1003*7836SJohn.Forte@Sun.COM make_raw_assoc_dd(
1004*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj
1005*7836SJohn.Forte@Sun.COM )
1006*7836SJohn.Forte@Sun.COM {
1007*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw;
1008*7836SJohn.Forte@Sun.COM 
1009*7836SJohn.Forte@Sun.COM 	raw = (scn_raw_t *)malloc(sizeof (scn_raw_t));
1010*7836SJohn.Forte@Sun.COM 	if (raw != NULL) {
1011*7836SJohn.Forte@Sun.COM 		raw->type = obj->type;
1012*7836SJohn.Forte@Sun.COM 		raw->uid = 0;
1013*7836SJohn.Forte@Sun.COM 		raw->iscsi = NULL;
1014*7836SJohn.Forte@Sun.COM 		raw->ref = 0;
1015*7836SJohn.Forte@Sun.COM 		raw->ilen = 0;
1016*7836SJohn.Forte@Sun.COM 		raw->nt = 0;
1017*7836SJohn.Forte@Sun.COM 		raw->ip = NULL;
1018*7836SJohn.Forte@Sun.COM 		raw->dd_id = get_obj_uid(obj);
1019*7836SJohn.Forte@Sun.COM 		raw->dds_id = get_parent_uid(obj);
1020*7836SJohn.Forte@Sun.COM 	} else {
1021*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "make_raw_assoc_dd", "malloc failed.");
1022*7836SJohn.Forte@Sun.COM 	}
1023*7836SJohn.Forte@Sun.COM 
1024*7836SJohn.Forte@Sun.COM 	return (raw);
1025*7836SJohn.Forte@Sun.COM }
1026*7836SJohn.Forte@Sun.COM 
1027*7836SJohn.Forte@Sun.COM /*
1028*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1029*7836SJohn.Forte@Sun.COM  *
1030*7836SJohn.Forte@Sun.COM  * scn_gen_entity:
1031*7836SJohn.Forte@Sun.COM  *	Generate SCN with the raw SCN data from a Network Entity object.
1032*7836SJohn.Forte@Sun.COM  *
1033*7836SJohn.Forte@Sun.COM  * raw	- the raw SCN data.
1034*7836SJohn.Forte@Sun.COM  * return - the SCN.
1035*7836SJohn.Forte@Sun.COM  *
1036*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1037*7836SJohn.Forte@Sun.COM  */
1038*7836SJohn.Forte@Sun.COM static scn_text_t *
scn_gen_entity(scn_raw_t * raw)1039*7836SJohn.Forte@Sun.COM scn_gen_entity(
1040*7836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
1041*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw
1042*7836SJohn.Forte@Sun.COM )
1043*7836SJohn.Forte@Sun.COM {
1044*7836SJohn.Forte@Sun.COM 	return (NULL);
1045*7836SJohn.Forte@Sun.COM }
1046*7836SJohn.Forte@Sun.COM 
1047*7836SJohn.Forte@Sun.COM /*
1048*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1049*7836SJohn.Forte@Sun.COM  *
1050*7836SJohn.Forte@Sun.COM  * scn_gen_iscsi:
1051*7836SJohn.Forte@Sun.COM  *	Generate SCN with the raw SCN data from a Storage Node object.
1052*7836SJohn.Forte@Sun.COM  *
1053*7836SJohn.Forte@Sun.COM  * raw	- the raw SCN data.
1054*7836SJohn.Forte@Sun.COM  * return - the SCN.
1055*7836SJohn.Forte@Sun.COM  *
1056*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1057*7836SJohn.Forte@Sun.COM  */
1058*7836SJohn.Forte@Sun.COM static scn_text_t *
scn_gen_iscsi(scn_raw_t * raw)1059*7836SJohn.Forte@Sun.COM scn_gen_iscsi(
1060*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw
1061*7836SJohn.Forte@Sun.COM )
1062*7836SJohn.Forte@Sun.COM {
1063*7836SJohn.Forte@Sun.COM 	scn_text_t *text;
1064*7836SJohn.Forte@Sun.COM 
1065*7836SJohn.Forte@Sun.COM 	text = (scn_text_t *)malloc(sizeof (scn_text_t));
1066*7836SJohn.Forte@Sun.COM 	if (text != NULL) {
1067*7836SJohn.Forte@Sun.COM 		text->flag = 0;
1068*7836SJohn.Forte@Sun.COM 		text->ref = 1; /* start with 1 */
1069*7836SJohn.Forte@Sun.COM 		text->uid = raw->uid;
1070*7836SJohn.Forte@Sun.COM 		text->iscsi = raw->iscsi;
1071*7836SJohn.Forte@Sun.COM 		raw->ref ++;
1072*7836SJohn.Forte@Sun.COM 		text->ilen = raw->ilen;
1073*7836SJohn.Forte@Sun.COM 		text->nt = raw->nt;
1074*7836SJohn.Forte@Sun.COM 		text->dd_id = raw->dd_id;
1075*7836SJohn.Forte@Sun.COM 		text->dds_id = raw->dds_id;
1076*7836SJohn.Forte@Sun.COM 		text->next = NULL;
1077*7836SJohn.Forte@Sun.COM 	} else {
1078*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "scn_gen_iscsi", "malloc failed.");
1079*7836SJohn.Forte@Sun.COM 	}
1080*7836SJohn.Forte@Sun.COM 	return (text);
1081*7836SJohn.Forte@Sun.COM }
1082*7836SJohn.Forte@Sun.COM 
1083*7836SJohn.Forte@Sun.COM /*
1084*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1085*7836SJohn.Forte@Sun.COM  *
1086*7836SJohn.Forte@Sun.COM  * scn_gen_portal:
1087*7836SJohn.Forte@Sun.COM  *	Generate SCN with the raw SCN data from a Portal object.
1088*7836SJohn.Forte@Sun.COM  *
1089*7836SJohn.Forte@Sun.COM  * raw	- the raw SCN data.
1090*7836SJohn.Forte@Sun.COM  * return - the SCN.
1091*7836SJohn.Forte@Sun.COM  *
1092*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1093*7836SJohn.Forte@Sun.COM  */
1094*7836SJohn.Forte@Sun.COM static scn_text_t *
scn_gen_portal(scn_raw_t * raw)1095*7836SJohn.Forte@Sun.COM scn_gen_portal(
1096*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw
1097*7836SJohn.Forte@Sun.COM )
1098*7836SJohn.Forte@Sun.COM {
1099*7836SJohn.Forte@Sun.COM 	in6_addr_t *ip;
1100*7836SJohn.Forte@Sun.COM 	uint32_t port;
1101*7836SJohn.Forte@Sun.COM 
1102*7836SJohn.Forte@Sun.COM 	uint32_t pg_uid, uid;
1103*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t pg_lc, lc;
1104*7836SJohn.Forte@Sun.COM 
1105*7836SJohn.Forte@Sun.COM 	uint32_t nt;
1106*7836SJohn.Forte@Sun.COM 	uchar_t *name;
1107*7836SJohn.Forte@Sun.COM 	int ilen;
1108*7836SJohn.Forte@Sun.COM 
1109*7836SJohn.Forte@Sun.COM 	scn_text_t *text, *l = NULL;
1110*7836SJohn.Forte@Sun.COM 
1111*7836SJohn.Forte@Sun.COM 	ip = raw->ip;
1112*7836SJohn.Forte@Sun.COM 	port = raw->port;
1113*7836SJohn.Forte@Sun.COM 
1114*7836SJohn.Forte@Sun.COM 	pg_lc.curr_uid = 0;
1115*7836SJohn.Forte@Sun.COM 	pg_lc.type = OBJ_PG;
1116*7836SJohn.Forte@Sun.COM 	pg_lc.id[0] = ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID);
1117*7836SJohn.Forte@Sun.COM 	pg_lc.op[0] = OP_MEMORY_IP6;
1118*7836SJohn.Forte@Sun.COM 	pg_lc.data[0].ip = ip;
1119*7836SJohn.Forte@Sun.COM 	pg_lc.id[1] = ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID);
1120*7836SJohn.Forte@Sun.COM 	pg_lc.op[1] = OP_INTEGER;
1121*7836SJohn.Forte@Sun.COM 	pg_lc.data[1].ui = port;
1122*7836SJohn.Forte@Sun.COM 	pg_lc.op[2] = 0;
1123*7836SJohn.Forte@Sun.COM 
1124*7836SJohn.Forte@Sun.COM 	SET_UID_LCP(&lc, OBJ_ISCSI, 0);
1125*7836SJohn.Forte@Sun.COM 
1126*7836SJohn.Forte@Sun.COM 	lc.id[1] = ISNS_ISCSI_NAME_ATTR_ID;
1127*7836SJohn.Forte@Sun.COM 	lc.id[2] = ISNS_ISCSI_NODE_TYPE_ATTR_ID;
1128*7836SJohn.Forte@Sun.COM 	lc.data[1].ptr = NULL;
1129*7836SJohn.Forte@Sun.COM 
1130*7836SJohn.Forte@Sun.COM 	/* get a pg which is associated to the portal */
1131*7836SJohn.Forte@Sun.COM 	uid = cache_lookup(&pg_lc, &pg_uid, cb_pg_node);
1132*7836SJohn.Forte@Sun.COM 	while (pg_uid != 0) {
1133*7836SJohn.Forte@Sun.COM 		if (uid != 0) {
1134*7836SJohn.Forte@Sun.COM 			lc.data[0].ui = uid;
1135*7836SJohn.Forte@Sun.COM 			(void) cache_lookup(&lc, NULL, cb_clone_attrs);
1136*7836SJohn.Forte@Sun.COM 			name = lc.data[1].ptr;
1137*7836SJohn.Forte@Sun.COM 			if (name != NULL) {
1138*7836SJohn.Forte@Sun.COM 				nt = lc.data[2].ui;
1139*7836SJohn.Forte@Sun.COM 				text = (scn_text_t *)malloc(
1140*7836SJohn.Forte@Sun.COM 				    sizeof (scn_text_t));
1141*7836SJohn.Forte@Sun.COM 				if (text != NULL) {
1142*7836SJohn.Forte@Sun.COM 					text->flag = 0;
1143*7836SJohn.Forte@Sun.COM 					text->ref = 1; /* start with 1 */
1144*7836SJohn.Forte@Sun.COM 					text->uid = uid;
1145*7836SJohn.Forte@Sun.COM 					text->iscsi = name;
1146*7836SJohn.Forte@Sun.COM 					ilen = strlen((char *)name);
1147*7836SJohn.Forte@Sun.COM 					ilen += 4 - (ilen % 4);
1148*7836SJohn.Forte@Sun.COM 					text->ilen = ilen;
1149*7836SJohn.Forte@Sun.COM 					text->nt = nt;
1150*7836SJohn.Forte@Sun.COM 					text->dd_id = 0;
1151*7836SJohn.Forte@Sun.COM 					text->dds_id = 0;
1152*7836SJohn.Forte@Sun.COM 					text->next = l;
1153*7836SJohn.Forte@Sun.COM 					l = text;
1154*7836SJohn.Forte@Sun.COM 				} else {
1155*7836SJohn.Forte@Sun.COM 					free(name);
1156*7836SJohn.Forte@Sun.COM 					isnslog(LOG_DEBUG, "scn_gen_portal",
1157*7836SJohn.Forte@Sun.COM 					    "malloc failed.");
1158*7836SJohn.Forte@Sun.COM 				}
1159*7836SJohn.Forte@Sun.COM 				lc.data[1].ptr = NULL;
1160*7836SJohn.Forte@Sun.COM 			} else {
1161*7836SJohn.Forte@Sun.COM 				isnslog(LOG_WARNING, "scn_gen_portal",
1162*7836SJohn.Forte@Sun.COM 				    "cannot get node name.");
1163*7836SJohn.Forte@Sun.COM 			}
1164*7836SJohn.Forte@Sun.COM 		}
1165*7836SJohn.Forte@Sun.COM 
1166*7836SJohn.Forte@Sun.COM 		/* get the next pg */
1167*7836SJohn.Forte@Sun.COM 		pg_lc.curr_uid = pg_uid;
1168*7836SJohn.Forte@Sun.COM 		uid = cache_lookup(&pg_lc, &pg_uid, cb_pg_node);
1169*7836SJohn.Forte@Sun.COM 	}
1170*7836SJohn.Forte@Sun.COM 
1171*7836SJohn.Forte@Sun.COM 	/* update the iscsi storage node object */
1172*7836SJohn.Forte@Sun.COM 	raw->event = ISNS_OBJECT_UPDATED;
1173*7836SJohn.Forte@Sun.COM 
1174*7836SJohn.Forte@Sun.COM 	return (l);
1175*7836SJohn.Forte@Sun.COM }
1176*7836SJohn.Forte@Sun.COM 
1177*7836SJohn.Forte@Sun.COM /*
1178*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1179*7836SJohn.Forte@Sun.COM  *
1180*7836SJohn.Forte@Sun.COM  * scn_gen_assoc_dd:
1181*7836SJohn.Forte@Sun.COM  *	Generate SCN with the raw SCN data from a DD membership object.
1182*7836SJohn.Forte@Sun.COM  *
1183*7836SJohn.Forte@Sun.COM  * raw	- the raw SCN data.
1184*7836SJohn.Forte@Sun.COM  * return - the SCN.
1185*7836SJohn.Forte@Sun.COM  *
1186*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1187*7836SJohn.Forte@Sun.COM  */
1188*7836SJohn.Forte@Sun.COM static scn_text_t *
scn_gen_assoc_dd(scn_raw_t * raw)1189*7836SJohn.Forte@Sun.COM scn_gen_assoc_dd(
1190*7836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
1191*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw
1192*7836SJohn.Forte@Sun.COM )
1193*7836SJohn.Forte@Sun.COM {
1194*7836SJohn.Forte@Sun.COM 	return (NULL);
1195*7836SJohn.Forte@Sun.COM }
1196*7836SJohn.Forte@Sun.COM 
1197*7836SJohn.Forte@Sun.COM /*
1198*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1199*7836SJohn.Forte@Sun.COM  *
1200*7836SJohn.Forte@Sun.COM  * make_scn:
1201*7836SJohn.Forte@Sun.COM  *	Make a SCN with an event and an object.
1202*7836SJohn.Forte@Sun.COM  *
1203*7836SJohn.Forte@Sun.COM  * event - the event.
1204*7836SJohn.Forte@Sun.COM  * obj	 - the object.
1205*7836SJohn.Forte@Sun.COM  * return - always successful (0).
1206*7836SJohn.Forte@Sun.COM  *
1207*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1208*7836SJohn.Forte@Sun.COM  */
1209*7836SJohn.Forte@Sun.COM int
make_scn(uint32_t event,isns_obj_t * obj)1210*7836SJohn.Forte@Sun.COM make_scn(
1211*7836SJohn.Forte@Sun.COM 	uint32_t event,
1212*7836SJohn.Forte@Sun.COM 	isns_obj_t *obj
1213*7836SJohn.Forte@Sun.COM )
1214*7836SJohn.Forte@Sun.COM {
1215*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw = NULL;
1216*7836SJohn.Forte@Sun.COM 
1217*7836SJohn.Forte@Sun.COM 	scn_raw_t *(*f)(isns_obj_t *) = make_raw[obj->type];
1218*7836SJohn.Forte@Sun.COM 
1219*7836SJohn.Forte@Sun.COM 	if (f != NULL) {
1220*7836SJohn.Forte@Sun.COM 		/* make raw scn data */
1221*7836SJohn.Forte@Sun.COM 		raw = f(obj);
1222*7836SJohn.Forte@Sun.COM 	}
1223*7836SJohn.Forte@Sun.COM 	if (raw != NULL) {
1224*7836SJohn.Forte@Sun.COM 		/* trigger an scn event */
1225*7836SJohn.Forte@Sun.COM 		raw->event = event;
1226*7836SJohn.Forte@Sun.COM 		(void) queue_msg_set(scn_q, SCN_SET, (void *)raw);
1227*7836SJohn.Forte@Sun.COM 	}
1228*7836SJohn.Forte@Sun.COM 
1229*7836SJohn.Forte@Sun.COM 	return (0);
1230*7836SJohn.Forte@Sun.COM }
1231*7836SJohn.Forte@Sun.COM 
1232*7836SJohn.Forte@Sun.COM /*
1233*7836SJohn.Forte@Sun.COM  * data structure of the SCN state transition table.
1234*7836SJohn.Forte@Sun.COM  */
1235*7836SJohn.Forte@Sun.COM typedef struct scn_tbl {
1236*7836SJohn.Forte@Sun.COM 	int state;
1237*7836SJohn.Forte@Sun.COM 	uint32_t event;
1238*7836SJohn.Forte@Sun.COM 	isns_type_t type;
1239*7836SJohn.Forte@Sun.COM 	int (*sf)(scn_raw_t *);
1240*7836SJohn.Forte@Sun.COM 	int next_state;
1241*7836SJohn.Forte@Sun.COM } scn_tbl_t;
1242*7836SJohn.Forte@Sun.COM 
1243*7836SJohn.Forte@Sun.COM /*
1244*7836SJohn.Forte@Sun.COM  * the SCN state transition table.
1245*7836SJohn.Forte@Sun.COM  */
1246*7836SJohn.Forte@Sun.COM static const scn_tbl_t stbl[] = {
1247*7836SJohn.Forte@Sun.COM 	{ -1, 0, OBJ_PG, NULL, 0 },
1248*7836SJohn.Forte@Sun.COM 	{ -1, 0, OBJ_DD, NULL, 0 },
1249*7836SJohn.Forte@Sun.COM 	{ -1, 0, OBJ_DDS, NULL, 0 },
1250*7836SJohn.Forte@Sun.COM 
1251*7836SJohn.Forte@Sun.COM 	{ 0, ISNS_OBJECT_ADDED, OBJ_ENTITY, NULL, 1 },
1252*7836SJohn.Forte@Sun.COM 	{ 1, ISNS_OBJECT_ADDED, OBJ_ISCSI, sf_gen, 1 },
1253*7836SJohn.Forte@Sun.COM 	{ 1, ISNS_OBJECT_ADDED, 0, NULL, 1 },
1254*7836SJohn.Forte@Sun.COM 
1255*7836SJohn.Forte@Sun.COM 	{ 0, ISNS_OBJECT_UPDATED, OBJ_ENTITY, sf_gen, 2 },
1256*7836SJohn.Forte@Sun.COM 	{ 2, ISNS_OBJECT_UPDATED, 0, NULL, 2 },
1257*7836SJohn.Forte@Sun.COM 	{ 2, ISNS_OBJECT_ADDED, OBJ_ISCSI, sf_gen, 2 },
1258*7836SJohn.Forte@Sun.COM 	{ 2, ISNS_OBJECT_ADDED, 0, NULL, 2 },
1259*7836SJohn.Forte@Sun.COM 
1260*7836SJohn.Forte@Sun.COM 	{ 0, ISNS_OBJECT_REMOVED, OBJ_ENTITY, NULL, 3 },
1261*7836SJohn.Forte@Sun.COM 	{ 0, ISNS_OBJECT_REMOVED, 0, sf_gen, 4 },
1262*7836SJohn.Forte@Sun.COM 	{ 3, ISNS_OBJECT_REMOVED, OBJ_ISCSI, sf_gen, 3 },
1263*7836SJohn.Forte@Sun.COM 	{ 3, ISNS_OBJECT_REMOVED, 0, NULL, 3 },
1264*7836SJohn.Forte@Sun.COM 	{ 4, ISNS_OBJECT_REMOVED, 0, sf_gen, 4 },
1265*7836SJohn.Forte@Sun.COM 
1266*7836SJohn.Forte@Sun.COM 	{ 0, ISNS_MEMBER_ADDED, OBJ_ASSOC_ISCSI, sf_gen, 5 },
1267*7836SJohn.Forte@Sun.COM 	{ 5, ISNS_MEMBER_ADDED, OBJ_ASSOC_ISCSI, sf_gen, 5 },
1268*7836SJohn.Forte@Sun.COM 
1269*7836SJohn.Forte@Sun.COM 	{ 0, ISNS_MEMBER_ADDED, OBJ_ASSOC_DD, sf_gen, 6 },
1270*7836SJohn.Forte@Sun.COM 	{ 6, ISNS_MEMBER_ADDED, OBJ_ASSOC_DD, sf_gen, 6 },
1271*7836SJohn.Forte@Sun.COM 
1272*7836SJohn.Forte@Sun.COM 	{ 0, ISNS_MEMBER_REMOVED, OBJ_ASSOC_ISCSI, sf_gen, 7 },
1273*7836SJohn.Forte@Sun.COM 	{ 7, ISNS_MEMBER_REMOVED, OBJ_ASSOC_ISCSI, sf_gen, 7 },
1274*7836SJohn.Forte@Sun.COM 
1275*7836SJohn.Forte@Sun.COM 	{ 0, ISNS_MEMBER_REMOVED, OBJ_ASSOC_DD, sf_gen, 8 },
1276*7836SJohn.Forte@Sun.COM 	{ 8, ISNS_MEMBER_REMOVED, OBJ_ASSOC_DD, sf_gen, 8 },
1277*7836SJohn.Forte@Sun.COM 
1278*7836SJohn.Forte@Sun.COM 	{ -1, 0, 0, sf_error, -1 }
1279*7836SJohn.Forte@Sun.COM };
1280*7836SJohn.Forte@Sun.COM 
1281*7836SJohn.Forte@Sun.COM /*
1282*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1283*7836SJohn.Forte@Sun.COM  *
1284*7836SJohn.Forte@Sun.COM  * scn_disp1:
1285*7836SJohn.Forte@Sun.COM  *	Dispatch one SCN to one SCN entry.
1286*7836SJohn.Forte@Sun.COM  *
1287*7836SJohn.Forte@Sun.COM  * event - the event.
1288*7836SJohn.Forte@Sun.COM  * p	 - the SCN entry.
1289*7836SJohn.Forte@Sun.COM  * t	 - the SCN.
1290*7836SJohn.Forte@Sun.COM  * return - always successful (0).
1291*7836SJohn.Forte@Sun.COM  *
1292*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1293*7836SJohn.Forte@Sun.COM  */
1294*7836SJohn.Forte@Sun.COM static int
scn_disp1(uint32_t event,scn_registry_t * p,scn_text_t * t)1295*7836SJohn.Forte@Sun.COM scn_disp1(
1296*7836SJohn.Forte@Sun.COM 	uint32_t event,
1297*7836SJohn.Forte@Sun.COM 	scn_registry_t *p,
1298*7836SJohn.Forte@Sun.COM 	scn_text_t *t
1299*7836SJohn.Forte@Sun.COM )
1300*7836SJohn.Forte@Sun.COM {
1301*7836SJohn.Forte@Sun.COM 	scn_t *s, *r = NULL;
1302*7836SJohn.Forte@Sun.COM 	scn_list_t *l, **lp;
1303*7836SJohn.Forte@Sun.COM 
1304*7836SJohn.Forte@Sun.COM 	s = p->scn;
1305*7836SJohn.Forte@Sun.COM 
1306*7836SJohn.Forte@Sun.COM 	while (s != NULL) {
1307*7836SJohn.Forte@Sun.COM 		if (s->event == event) {
1308*7836SJohn.Forte@Sun.COM 			l = s->data.list;
1309*7836SJohn.Forte@Sun.COM 			do {
1310*7836SJohn.Forte@Sun.COM 				if (l->data.text->uid == t->uid) {
1311*7836SJohn.Forte@Sun.COM 					/* duplicated */
1312*7836SJohn.Forte@Sun.COM 					return (0);
1313*7836SJohn.Forte@Sun.COM 				}
1314*7836SJohn.Forte@Sun.COM 				lp = &l->next;
1315*7836SJohn.Forte@Sun.COM 				l = *lp;
1316*7836SJohn.Forte@Sun.COM 			} while (l != NULL);
1317*7836SJohn.Forte@Sun.COM 			break;
1318*7836SJohn.Forte@Sun.COM 		}
1319*7836SJohn.Forte@Sun.COM 		r = s;
1320*7836SJohn.Forte@Sun.COM 		s = s->next;
1321*7836SJohn.Forte@Sun.COM 	}
1322*7836SJohn.Forte@Sun.COM 
1323*7836SJohn.Forte@Sun.COM 	l = (scn_list_t *)malloc(sizeof (scn_list_t));
1324*7836SJohn.Forte@Sun.COM 	if (l != NULL) {
1325*7836SJohn.Forte@Sun.COM 		if (s == NULL) {
1326*7836SJohn.Forte@Sun.COM 			s = (scn_t *)malloc(sizeof (scn_t));
1327*7836SJohn.Forte@Sun.COM 			if (s != NULL) {
1328*7836SJohn.Forte@Sun.COM 				s->event = event;
1329*7836SJohn.Forte@Sun.COM 				s->next = NULL;
1330*7836SJohn.Forte@Sun.COM 				if (r != NULL) {
1331*7836SJohn.Forte@Sun.COM 					r->next = s;
1332*7836SJohn.Forte@Sun.COM 				} else {
1333*7836SJohn.Forte@Sun.COM 					p->scn = s;
1334*7836SJohn.Forte@Sun.COM 				}
1335*7836SJohn.Forte@Sun.COM 				lp = &s->data.list;
1336*7836SJohn.Forte@Sun.COM 			} else {
1337*7836SJohn.Forte@Sun.COM 				free(l);
1338*7836SJohn.Forte@Sun.COM 				isnslog(LOG_DEBUG, "scn_disp1",
1339*7836SJohn.Forte@Sun.COM 				    "malloc scn failed.\n");
1340*7836SJohn.Forte@Sun.COM 				return (0);
1341*7836SJohn.Forte@Sun.COM 			}
1342*7836SJohn.Forte@Sun.COM 		}
1343*7836SJohn.Forte@Sun.COM 
1344*7836SJohn.Forte@Sun.COM 		t->ref ++;
1345*7836SJohn.Forte@Sun.COM 		l->data.text = t;
1346*7836SJohn.Forte@Sun.COM 		l->next = NULL;
1347*7836SJohn.Forte@Sun.COM 		*lp = l;
1348*7836SJohn.Forte@Sun.COM 	} else {
1349*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "scn_disp1",
1350*7836SJohn.Forte@Sun.COM 		    "malloc list failed.\n");
1351*7836SJohn.Forte@Sun.COM 	}
1352*7836SJohn.Forte@Sun.COM 
1353*7836SJohn.Forte@Sun.COM 	return (0);
1354*7836SJohn.Forte@Sun.COM }
1355*7836SJohn.Forte@Sun.COM 
1356*7836SJohn.Forte@Sun.COM /*
1357*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1358*7836SJohn.Forte@Sun.COM  *
1359*7836SJohn.Forte@Sun.COM  * scn_disp1:
1360*7836SJohn.Forte@Sun.COM  *	Dispatch one SCN to every SCN entry and update the dispatch status.
1361*7836SJohn.Forte@Sun.COM  *
1362*7836SJohn.Forte@Sun.COM  * event - the event.
1363*7836SJohn.Forte@Sun.COM  * text	 - the SCN.
1364*7836SJohn.Forte@Sun.COM  * return - always successful (0).
1365*7836SJohn.Forte@Sun.COM  *
1366*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1367*7836SJohn.Forte@Sun.COM  */
1368*7836SJohn.Forte@Sun.COM static int
scn_disp(uint32_t event,scn_text_t * text)1369*7836SJohn.Forte@Sun.COM scn_disp(
1370*7836SJohn.Forte@Sun.COM 	uint32_t event,
1371*7836SJohn.Forte@Sun.COM 	scn_text_t *text
1372*7836SJohn.Forte@Sun.COM )
1373*7836SJohn.Forte@Sun.COM {
1374*7836SJohn.Forte@Sun.COM 	scn_registry_t *registry, *p;
1375*7836SJohn.Forte@Sun.COM 	uint32_t dd_id = 0;
1376*7836SJohn.Forte@Sun.COM 
1377*7836SJohn.Forte@Sun.COM 	scn_text_t *t;
1378*7836SJohn.Forte@Sun.COM 
1379*7836SJohn.Forte@Sun.COM 	uint32_t e;
1380*7836SJohn.Forte@Sun.COM 
1381*7836SJohn.Forte@Sun.COM 	registry = scn_registry;
1382*7836SJohn.Forte@Sun.COM 
1383*7836SJohn.Forte@Sun.COM 	t = text;
1384*7836SJohn.Forte@Sun.COM 	while (t != NULL) {
1385*7836SJohn.Forte@Sun.COM 		e = event;
1386*7836SJohn.Forte@Sun.COM 		if (t->flag == 0) {
1387*7836SJohn.Forte@Sun.COM 			if (e & ISNS_MEMBER_ADDED) {
1388*7836SJohn.Forte@Sun.COM 				e |= ISNS_OBJECT_ADDED;
1389*7836SJohn.Forte@Sun.COM 			} else if (e & ISNS_MEMBER_REMOVED) {
1390*7836SJohn.Forte@Sun.COM 				e |= ISNS_OBJECT_REMOVED;
1391*7836SJohn.Forte@Sun.COM 			}
1392*7836SJohn.Forte@Sun.COM 		}
1393*7836SJohn.Forte@Sun.COM 		p = registry;
1394*7836SJohn.Forte@Sun.COM 		while (p != NULL) {
1395*7836SJohn.Forte@Sun.COM 			if (SCN_TEST(e, p->bitmap, p->uid, t->uid, t->nt)) {
1396*7836SJohn.Forte@Sun.COM 				if (p->bitmap & ISNS_MGMT_REG) {
1397*7836SJohn.Forte@Sun.COM 					/* management scn are not bound */
1398*7836SJohn.Forte@Sun.COM 					/* by discovery domain service. */
1399*7836SJohn.Forte@Sun.COM 					dd_id = 1;
1400*7836SJohn.Forte@Sun.COM 				} else {
1401*7836SJohn.Forte@Sun.COM 					dd_id = 0;
1402*7836SJohn.Forte@Sun.COM 					/* lock the cache for reading */
1403*7836SJohn.Forte@Sun.COM 					(void) cache_lock_read();
1404*7836SJohn.Forte@Sun.COM 					/* verify common dd */
1405*7836SJohn.Forte@Sun.COM 					do {
1406*7836SJohn.Forte@Sun.COM 						dd_id = get_common_dd(
1407*7836SJohn.Forte@Sun.COM 						    p->uid,
1408*7836SJohn.Forte@Sun.COM 						    t->uid,
1409*7836SJohn.Forte@Sun.COM 						    dd_id);
1410*7836SJohn.Forte@Sun.COM 					} while (dd_id > 0 &&
1411*7836SJohn.Forte@Sun.COM 					    is_dd_active(dd_id) == 0);
1412*7836SJohn.Forte@Sun.COM 					/* unlock the cache */
1413*7836SJohn.Forte@Sun.COM 					(void) cache_unlock_nosync();
1414*7836SJohn.Forte@Sun.COM 				}
1415*7836SJohn.Forte@Sun.COM 				if (dd_id != 0) {
1416*7836SJohn.Forte@Sun.COM 					(void) scn_disp1(e, p, t);
1417*7836SJohn.Forte@Sun.COM 				}
1418*7836SJohn.Forte@Sun.COM 			}
1419*7836SJohn.Forte@Sun.COM 			p = p->next;
1420*7836SJohn.Forte@Sun.COM 		}
1421*7836SJohn.Forte@Sun.COM 		t = t->next;
1422*7836SJohn.Forte@Sun.COM 	}
1423*7836SJohn.Forte@Sun.COM 
1424*7836SJohn.Forte@Sun.COM 	while (text != NULL) {
1425*7836SJohn.Forte@Sun.COM 		t = text->next;
1426*7836SJohn.Forte@Sun.COM 		/* clean up the scn text(s) which nobody cares about. */
1427*7836SJohn.Forte@Sun.COM 		free_scn_text(text);
1428*7836SJohn.Forte@Sun.COM 		text = t;
1429*7836SJohn.Forte@Sun.COM 	}
1430*7836SJohn.Forte@Sun.COM 
1431*7836SJohn.Forte@Sun.COM 	if (dd_id != 0) {
1432*7836SJohn.Forte@Sun.COM 		/* scn(s) are dispatched. */
1433*7836SJohn.Forte@Sun.COM 		scn_dispatched = 1;
1434*7836SJohn.Forte@Sun.COM 	}
1435*7836SJohn.Forte@Sun.COM 
1436*7836SJohn.Forte@Sun.COM 	return (0);
1437*7836SJohn.Forte@Sun.COM }
1438*7836SJohn.Forte@Sun.COM 
1439*7836SJohn.Forte@Sun.COM /*
1440*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1441*7836SJohn.Forte@Sun.COM  *
1442*7836SJohn.Forte@Sun.COM  * sf_gen:
1443*7836SJohn.Forte@Sun.COM  *	State transition function which generates and dispatches SCN(s).
1444*7836SJohn.Forte@Sun.COM  *
1445*7836SJohn.Forte@Sun.COM  * raw	- the raw SCN data.
1446*7836SJohn.Forte@Sun.COM  * return - always successful (0).
1447*7836SJohn.Forte@Sun.COM  *
1448*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1449*7836SJohn.Forte@Sun.COM  */
1450*7836SJohn.Forte@Sun.COM static int
sf_gen(scn_raw_t * raw)1451*7836SJohn.Forte@Sun.COM sf_gen(
1452*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw
1453*7836SJohn.Forte@Sun.COM )
1454*7836SJohn.Forte@Sun.COM {
1455*7836SJohn.Forte@Sun.COM 	uint32_t event;
1456*7836SJohn.Forte@Sun.COM 
1457*7836SJohn.Forte@Sun.COM 	scn_text_t *(*gen)(scn_raw_t *);
1458*7836SJohn.Forte@Sun.COM 	scn_text_t *text = NULL;
1459*7836SJohn.Forte@Sun.COM 
1460*7836SJohn.Forte@Sun.COM 	gen = scn_gen[raw->type];
1461*7836SJohn.Forte@Sun.COM 	if (gen != NULL) {
1462*7836SJohn.Forte@Sun.COM 		text = gen(raw);
1463*7836SJohn.Forte@Sun.COM 	}
1464*7836SJohn.Forte@Sun.COM 
1465*7836SJohn.Forte@Sun.COM 	event = raw->event;
1466*7836SJohn.Forte@Sun.COM 	if (text != NULL) {
1467*7836SJohn.Forte@Sun.COM 		(void) scn_disp(event, text);
1468*7836SJohn.Forte@Sun.COM 	}
1469*7836SJohn.Forte@Sun.COM 
1470*7836SJohn.Forte@Sun.COM 	return (0);
1471*7836SJohn.Forte@Sun.COM }
1472*7836SJohn.Forte@Sun.COM 
1473*7836SJohn.Forte@Sun.COM /*
1474*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1475*7836SJohn.Forte@Sun.COM  *
1476*7836SJohn.Forte@Sun.COM  * sf_error:
1477*7836SJohn.Forte@Sun.COM  *	State transition function for an error state. It free any SCN(s)
1478*7836SJohn.Forte@Sun.COM  *	which have been generated and dispatched previously.
1479*7836SJohn.Forte@Sun.COM  *
1480*7836SJohn.Forte@Sun.COM  * raw	- the raw SCN data.
1481*7836SJohn.Forte@Sun.COM  * return - always successful (0).
1482*7836SJohn.Forte@Sun.COM  *
1483*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1484*7836SJohn.Forte@Sun.COM  */
1485*7836SJohn.Forte@Sun.COM static int
sf_error(scn_raw_t * raw)1486*7836SJohn.Forte@Sun.COM sf_error(
1487*7836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
1488*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw
1489*7836SJohn.Forte@Sun.COM )
1490*7836SJohn.Forte@Sun.COM {
1491*7836SJohn.Forte@Sun.COM 	free_scn();
1492*7836SJohn.Forte@Sun.COM 
1493*7836SJohn.Forte@Sun.COM 	return (0);
1494*7836SJohn.Forte@Sun.COM }
1495*7836SJohn.Forte@Sun.COM 
1496*7836SJohn.Forte@Sun.COM /*
1497*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1498*7836SJohn.Forte@Sun.COM  *
1499*7836SJohn.Forte@Sun.COM  * scn_transition:
1500*7836SJohn.Forte@Sun.COM  *	Performs the state transition when a SCN event occurs.
1501*7836SJohn.Forte@Sun.COM  *
1502*7836SJohn.Forte@Sun.COM  * state - the previous state.
1503*7836SJohn.Forte@Sun.COM  * raw	 - the raw SCN data.
1504*7836SJohn.Forte@Sun.COM  * return - the next state.
1505*7836SJohn.Forte@Sun.COM  *
1506*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1507*7836SJohn.Forte@Sun.COM  */
1508*7836SJohn.Forte@Sun.COM static int
scn_transition(int state,scn_raw_t * raw)1509*7836SJohn.Forte@Sun.COM scn_transition(
1510*7836SJohn.Forte@Sun.COM 	int state,
1511*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw
1512*7836SJohn.Forte@Sun.COM )
1513*7836SJohn.Forte@Sun.COM {
1514*7836SJohn.Forte@Sun.COM 	uint32_t event = raw->event;
1515*7836SJohn.Forte@Sun.COM 	isns_type_t type = raw->type;
1516*7836SJohn.Forte@Sun.COM 
1517*7836SJohn.Forte@Sun.COM 	int new_state = state;
1518*7836SJohn.Forte@Sun.COM 
1519*7836SJohn.Forte@Sun.COM 	const scn_tbl_t *tbl;
1520*7836SJohn.Forte@Sun.COM 
1521*7836SJohn.Forte@Sun.COM 	tbl = &stbl[0];
1522*7836SJohn.Forte@Sun.COM 	for (;;) {
1523*7836SJohn.Forte@Sun.COM 		if ((tbl->state == -1 || tbl->state == state) &&
1524*7836SJohn.Forte@Sun.COM 		    (tbl->event == 0 || tbl->event == event) &&
1525*7836SJohn.Forte@Sun.COM 		    (tbl->type == 0 || tbl->type == type)) {
1526*7836SJohn.Forte@Sun.COM 			if (tbl->next_state != 0) {
1527*7836SJohn.Forte@Sun.COM 				new_state = tbl->next_state;
1528*7836SJohn.Forte@Sun.COM 			}
1529*7836SJohn.Forte@Sun.COM 			if (tbl->sf != NULL) {
1530*7836SJohn.Forte@Sun.COM 				tbl->sf(raw);
1531*7836SJohn.Forte@Sun.COM 			}
1532*7836SJohn.Forte@Sun.COM 			break;
1533*7836SJohn.Forte@Sun.COM 		}
1534*7836SJohn.Forte@Sun.COM 		tbl ++;
1535*7836SJohn.Forte@Sun.COM 	}
1536*7836SJohn.Forte@Sun.COM 
1537*7836SJohn.Forte@Sun.COM 	if (new_state == -1) {
1538*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "scn_transition",
1539*7836SJohn.Forte@Sun.COM 		    "prev state: %d new event: 0x%x new object: %d.\n",
1540*7836SJohn.Forte@Sun.COM 		    state, event, type);
1541*7836SJohn.Forte@Sun.COM 		new_state = 0;
1542*7836SJohn.Forte@Sun.COM 	}
1543*7836SJohn.Forte@Sun.COM 
1544*7836SJohn.Forte@Sun.COM 	state = new_state;
1545*7836SJohn.Forte@Sun.COM 
1546*7836SJohn.Forte@Sun.COM 	return (state);
1547*7836SJohn.Forte@Sun.COM }
1548*7836SJohn.Forte@Sun.COM 
1549*7836SJohn.Forte@Sun.COM /*
1550*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1551*7836SJohn.Forte@Sun.COM  *
1552*7836SJohn.Forte@Sun.COM  * connect_to:
1553*7836SJohn.Forte@Sun.COM  *	Create socket connection with peer network portal.
1554*7836SJohn.Forte@Sun.COM  *
1555*7836SJohn.Forte@Sun.COM  * sz	- the size of the ip addr.
1556*7836SJohn.Forte@Sun.COM  * in	- the ipv4 address.
1557*7836SJohn.Forte@Sun.COM  * in6	- the ipv6 address.
1558*7836SJohn.Forte@Sun.COM  * port2- the port info.
1559*7836SJohn.Forte@Sun.COM  * return - the socket descriptor.
1560*7836SJohn.Forte@Sun.COM  *
1561*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1562*7836SJohn.Forte@Sun.COM  */
1563*7836SJohn.Forte@Sun.COM int
connect_to(int sz,in_addr_t in,in6_addr_t * in6,uint32_t port2)1564*7836SJohn.Forte@Sun.COM connect_to(
1565*7836SJohn.Forte@Sun.COM 	int sz,
1566*7836SJohn.Forte@Sun.COM 	in_addr_t in,
1567*7836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
1568*7836SJohn.Forte@Sun.COM 	in6_addr_t *in6,
1569*7836SJohn.Forte@Sun.COM 	uint32_t port2
1570*7836SJohn.Forte@Sun.COM )
1571*7836SJohn.Forte@Sun.COM {
1572*7836SJohn.Forte@Sun.COM 	int so = -1;
1573*7836SJohn.Forte@Sun.COM 
1574*7836SJohn.Forte@Sun.COM 	union {
1575*7836SJohn.Forte@Sun.COM 		struct sockaddr sin;
1576*7836SJohn.Forte@Sun.COM 		struct sockaddr_in in;
1577*7836SJohn.Forte@Sun.COM 		struct sockaddr_in6 in6;
1578*7836SJohn.Forte@Sun.COM 	} ca = { 0 };
1579*7836SJohn.Forte@Sun.COM 
1580*7836SJohn.Forte@Sun.COM 	int tcp;
1581*7836SJohn.Forte@Sun.COM 	uint16_t port;
1582*7836SJohn.Forte@Sun.COM 
1583*7836SJohn.Forte@Sun.COM 	tcp = (port2 & 0x10000) == 0 ? 1 : 0;
1584*7836SJohn.Forte@Sun.COM 	port = (uint16_t)(port2 & 0xFFFF);
1585*7836SJohn.Forte@Sun.COM 	if (sz == sizeof (in_addr_t)) {
1586*7836SJohn.Forte@Sun.COM 		if (tcp != 0) {
1587*7836SJohn.Forte@Sun.COM 			so = socket(AF_INET, SOCK_STREAM, 0);
1588*7836SJohn.Forte@Sun.COM 			if (so != -1) {
1589*7836SJohn.Forte@Sun.COM 				ca.in.sin_family = AF_INET;
1590*7836SJohn.Forte@Sun.COM 				ca.in.sin_port = htons(port);
1591*7836SJohn.Forte@Sun.COM 				ca.in.sin_addr.s_addr = in;
1592*7836SJohn.Forte@Sun.COM 				if (connect(so, &ca.sin, sizeof (ca.in)) !=
1593*7836SJohn.Forte@Sun.COM 				    0) {
1594*7836SJohn.Forte@Sun.COM 					isnslog(LOG_DEBUG, "connect_to",
1595*7836SJohn.Forte@Sun.COM 					    "connect() failed %%m.");
1596*7836SJohn.Forte@Sun.COM 					(void) close(so);
1597*7836SJohn.Forte@Sun.COM 					so = -1;
1598*7836SJohn.Forte@Sun.COM 				}
1599*7836SJohn.Forte@Sun.COM 			} else {
1600*7836SJohn.Forte@Sun.COM 				isnslog(LOG_DEBUG, "connect_to",
1601*7836SJohn.Forte@Sun.COM 				    "socket() failed %%m.");
1602*7836SJohn.Forte@Sun.COM 			}
1603*7836SJohn.Forte@Sun.COM 		} else {
1604*7836SJohn.Forte@Sun.COM 			/* FIXME: UDP support */
1605*7836SJohn.Forte@Sun.COM 			isnslog(LOG_DEBUG, "connect_to", "No UDP support.");
1606*7836SJohn.Forte@Sun.COM 		}
1607*7836SJohn.Forte@Sun.COM 	} else {
1608*7836SJohn.Forte@Sun.COM 		/* FIXME: IPv6 support */
1609*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "connect_to", "No IPv6 support.");
1610*7836SJohn.Forte@Sun.COM 	}
1611*7836SJohn.Forte@Sun.COM 
1612*7836SJohn.Forte@Sun.COM 	return (so);
1613*7836SJohn.Forte@Sun.COM }
1614*7836SJohn.Forte@Sun.COM 
1615*7836SJohn.Forte@Sun.COM /*
1616*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1617*7836SJohn.Forte@Sun.COM  *
1618*7836SJohn.Forte@Sun.COM  * emit_scn:
1619*7836SJohn.Forte@Sun.COM  *	Emit the SCN to any portal of the peer storage node.
1620*7836SJohn.Forte@Sun.COM  *
1621*7836SJohn.Forte@Sun.COM  * list	- the list of portal.
1622*7836SJohn.Forte@Sun.COM  * pdu	- the SCN packet.
1623*7836SJohn.Forte@Sun.COM  * pl	- the SCN packet payload length.
1624*7836SJohn.Forte@Sun.COM  * return - always successful (0).
1625*7836SJohn.Forte@Sun.COM  *
1626*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1627*7836SJohn.Forte@Sun.COM  */
1628*7836SJohn.Forte@Sun.COM static int
emit_scn(scn_list_t * list,isns_pdu_t * pdu,size_t pl)1629*7836SJohn.Forte@Sun.COM emit_scn(
1630*7836SJohn.Forte@Sun.COM 	scn_list_t *list,
1631*7836SJohn.Forte@Sun.COM 	isns_pdu_t *pdu,
1632*7836SJohn.Forte@Sun.COM 	size_t pl
1633*7836SJohn.Forte@Sun.COM )
1634*7836SJohn.Forte@Sun.COM {
1635*7836SJohn.Forte@Sun.COM 	int so = 0;
1636*7836SJohn.Forte@Sun.COM 	scn_list_t *l;
1637*7836SJohn.Forte@Sun.COM 	scn_portal_t *p;
1638*7836SJohn.Forte@Sun.COM 
1639*7836SJohn.Forte@Sun.COM 	isns_pdu_t *rsp = NULL;
1640*7836SJohn.Forte@Sun.COM 	size_t rsp_sz;
1641*7836SJohn.Forte@Sun.COM 
1642*7836SJohn.Forte@Sun.COM 	pdu->version = htons((uint16_t)ISNSP_VERSION);
1643*7836SJohn.Forte@Sun.COM 	pdu->func_id = htons((uint16_t)ISNS_SCN);
1644*7836SJohn.Forte@Sun.COM 	pdu->xid = htons(get_server_xid());
1645*7836SJohn.Forte@Sun.COM 
1646*7836SJohn.Forte@Sun.COM 	l = list;
1647*7836SJohn.Forte@Sun.COM 	while (l != NULL) {
1648*7836SJohn.Forte@Sun.COM 		p = l->data.portal;
1649*7836SJohn.Forte@Sun.COM 		so = connect_to(p->sz, p->ip.in, p->ip.in6, p->port);
1650*7836SJohn.Forte@Sun.COM 		if (so != -1) {
1651*7836SJohn.Forte@Sun.COM 			if (isns_send_pdu(so, pdu, pl) == 0) {
1652*7836SJohn.Forte@Sun.COM 				/* This may help Solaris iSCSI Initiator */
1653*7836SJohn.Forte@Sun.COM 				/* not to panic frequently. */
1654*7836SJohn.Forte@Sun.COM 				(void) isns_rcv_pdu(so, &rsp, &rsp_sz,
1655*7836SJohn.Forte@Sun.COM 				    ISNS_RCV_SHORT_TIMEOUT);
1656*7836SJohn.Forte@Sun.COM 			} else {
1657*7836SJohn.Forte@Sun.COM 				isnslog(LOG_DEBUG, "emit_scn",
1658*7836SJohn.Forte@Sun.COM 				    "sending packet failed.");
1659*7836SJohn.Forte@Sun.COM 			}
1660*7836SJohn.Forte@Sun.COM 			(void) close(so);
1661*7836SJohn.Forte@Sun.COM 			/* p->so = so; */
1662*7836SJohn.Forte@Sun.COM 			break;
1663*7836SJohn.Forte@Sun.COM 		}
1664*7836SJohn.Forte@Sun.COM 		l = l->next;
1665*7836SJohn.Forte@Sun.COM 	}
1666*7836SJohn.Forte@Sun.COM 
1667*7836SJohn.Forte@Sun.COM 	if (rsp != NULL) {
1668*7836SJohn.Forte@Sun.COM #ifdef DEBUG
1669*7836SJohn.Forte@Sun.COM 		dump_pdu1(rsp);
1670*7836SJohn.Forte@Sun.COM #endif
1671*7836SJohn.Forte@Sun.COM 		free(rsp);
1672*7836SJohn.Forte@Sun.COM 	}
1673*7836SJohn.Forte@Sun.COM 
1674*7836SJohn.Forte@Sun.COM 	return (0);
1675*7836SJohn.Forte@Sun.COM }
1676*7836SJohn.Forte@Sun.COM 
1677*7836SJohn.Forte@Sun.COM /*
1678*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1679*7836SJohn.Forte@Sun.COM  *
1680*7836SJohn.Forte@Sun.COM  * scn_trigger1:
1681*7836SJohn.Forte@Sun.COM  *	Trigger one SCN for one SCN entry.
1682*7836SJohn.Forte@Sun.COM  *
1683*7836SJohn.Forte@Sun.COM  * t	- the time that SCN is being triggered.
1684*7836SJohn.Forte@Sun.COM  * p	- the SCN entry.
1685*7836SJohn.Forte@Sun.COM  * return - always successful (0).
1686*7836SJohn.Forte@Sun.COM  *
1687*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1688*7836SJohn.Forte@Sun.COM  */
1689*7836SJohn.Forte@Sun.COM static int
scn_trigger1(time_t t,scn_registry_t * p)1690*7836SJohn.Forte@Sun.COM scn_trigger1(
1691*7836SJohn.Forte@Sun.COM 	time_t t,
1692*7836SJohn.Forte@Sun.COM 	scn_registry_t *p
1693*7836SJohn.Forte@Sun.COM )
1694*7836SJohn.Forte@Sun.COM {
1695*7836SJohn.Forte@Sun.COM 	int ec;
1696*7836SJohn.Forte@Sun.COM 
1697*7836SJohn.Forte@Sun.COM 	isns_pdu_t *pdu = NULL;
1698*7836SJohn.Forte@Sun.COM 	size_t sz;
1699*7836SJohn.Forte@Sun.COM 	size_t pl;
1700*7836SJohn.Forte@Sun.COM 
1701*7836SJohn.Forte@Sun.COM 	scn_t *s;
1702*7836SJohn.Forte@Sun.COM 	scn_list_t *l;
1703*7836SJohn.Forte@Sun.COM 	scn_text_t *x;
1704*7836SJohn.Forte@Sun.COM 
1705*7836SJohn.Forte@Sun.COM 	union {
1706*7836SJohn.Forte@Sun.COM 		uint32_t i32;
1707*7836SJohn.Forte@Sun.COM 		uint64_t i64;
1708*7836SJohn.Forte@Sun.COM 	} u;
1709*7836SJohn.Forte@Sun.COM 
1710*7836SJohn.Forte@Sun.COM #ifdef DEBUG
1711*7836SJohn.Forte@Sun.COM 	char buff[1024] = { 0 };
1712*7836SJohn.Forte@Sun.COM 	char *logbuff = buff;
1713*7836SJohn.Forte@Sun.COM #endif
1714*7836SJohn.Forte@Sun.COM 
1715*7836SJohn.Forte@Sun.COM 	ec = pdu_reset_scn(&pdu, &pl, &sz);
1716*7836SJohn.Forte@Sun.COM 	if (pdu == NULL) {
1717*7836SJohn.Forte@Sun.COM 		goto scn_done;
1718*7836SJohn.Forte@Sun.COM 	}
1719*7836SJohn.Forte@Sun.COM 
1720*7836SJohn.Forte@Sun.COM 	/* add destination attribute */
1721*7836SJohn.Forte@Sun.COM 	ec = pdu_add_tlv(&pdu, &pl, &sz,
1722*7836SJohn.Forte@Sun.COM 	    ISNS_ISCSI_NAME_ATTR_ID,
1723*7836SJohn.Forte@Sun.COM 	    p->nlen,
1724*7836SJohn.Forte@Sun.COM 	    (void *)p->name, 0);
1725*7836SJohn.Forte@Sun.COM 	if (ec != 0) {
1726*7836SJohn.Forte@Sun.COM 		goto scn_done;
1727*7836SJohn.Forte@Sun.COM 	}
1728*7836SJohn.Forte@Sun.COM 
1729*7836SJohn.Forte@Sun.COM #ifdef DEBUG
1730*7836SJohn.Forte@Sun.COM 	sprintf(logbuff, "==>%s ", p->name);
1731*7836SJohn.Forte@Sun.COM 	logbuff += strlen(logbuff);
1732*7836SJohn.Forte@Sun.COM #endif
1733*7836SJohn.Forte@Sun.COM 
1734*7836SJohn.Forte@Sun.COM 	/* add timestamp */
1735*7836SJohn.Forte@Sun.COM 	u.i64 = BE_64((uint64_t)t);
1736*7836SJohn.Forte@Sun.COM 	ec = pdu_add_tlv(&pdu, &pl, &sz,
1737*7836SJohn.Forte@Sun.COM 	    ISNS_TIMESTAMP_ATTR_ID,
1738*7836SJohn.Forte@Sun.COM 	    8,
1739*7836SJohn.Forte@Sun.COM 	    (void *)&u.i64, 1);
1740*7836SJohn.Forte@Sun.COM 
1741*7836SJohn.Forte@Sun.COM 	s = p->scn;
1742*7836SJohn.Forte@Sun.COM 	while (s != NULL && ec == 0) {
1743*7836SJohn.Forte@Sun.COM 		u.i32 = htonl(s->event);
1744*7836SJohn.Forte@Sun.COM 		ec = pdu_add_tlv(&pdu, &pl, &sz,
1745*7836SJohn.Forte@Sun.COM 		    ISNS_ISCSI_SCN_BITMAP_ATTR_ID,
1746*7836SJohn.Forte@Sun.COM 		    4,
1747*7836SJohn.Forte@Sun.COM 		    (void *)&u.i32, 1);
1748*7836SJohn.Forte@Sun.COM #ifdef DEBUG
1749*7836SJohn.Forte@Sun.COM 		sprintf(logbuff, "EVENT [%d] ", s->event);
1750*7836SJohn.Forte@Sun.COM 		logbuff += strlen(logbuff);
1751*7836SJohn.Forte@Sun.COM #endif
1752*7836SJohn.Forte@Sun.COM 		l = s->data.list;
1753*7836SJohn.Forte@Sun.COM 		while (l != NULL && ec == 0) {
1754*7836SJohn.Forte@Sun.COM 			x = l->data.text;
1755*7836SJohn.Forte@Sun.COM 			if (x->flag == 0) {
1756*7836SJohn.Forte@Sun.COM 				ec = pdu_add_tlv(&pdu, &pl, &sz,
1757*7836SJohn.Forte@Sun.COM 				    ISNS_ISCSI_NAME_ATTR_ID,
1758*7836SJohn.Forte@Sun.COM 				    x->ilen, (void *)x->iscsi, 0);
1759*7836SJohn.Forte@Sun.COM #ifdef DEBUG
1760*7836SJohn.Forte@Sun.COM 				sprintf(logbuff, "FROM [%s] ", x->iscsi);
1761*7836SJohn.Forte@Sun.COM 				logbuff += strlen(logbuff);
1762*7836SJohn.Forte@Sun.COM #endif
1763*7836SJohn.Forte@Sun.COM 				if (ec == 0 &&
1764*7836SJohn.Forte@Sun.COM 				    (p->bitmap &
1765*7836SJohn.Forte@Sun.COM 				    (ISNS_MEMBER_ADDED |
1766*7836SJohn.Forte@Sun.COM 				    ISNS_MEMBER_REMOVED))) {
1767*7836SJohn.Forte@Sun.COM 					/* management SCN */
1768*7836SJohn.Forte@Sun.COM 					u.i32 = htonl(x->dd_id);
1769*7836SJohn.Forte@Sun.COM 					ec = pdu_add_tlv(&pdu, &pl, &sz,
1770*7836SJohn.Forte@Sun.COM 					    ISNS_DD_ID_ATTR_ID,
1771*7836SJohn.Forte@Sun.COM 					    4, (void *)&u.i32, 1);
1772*7836SJohn.Forte@Sun.COM #ifdef DEBUG
1773*7836SJohn.Forte@Sun.COM 					sprintf(logbuff, "IN DD [%d] ",
1774*7836SJohn.Forte@Sun.COM 					    x->dd_id);
1775*7836SJohn.Forte@Sun.COM 					logbuff += strlen(logbuff);
1776*7836SJohn.Forte@Sun.COM #endif
1777*7836SJohn.Forte@Sun.COM 				}
1778*7836SJohn.Forte@Sun.COM 			} else {
1779*7836SJohn.Forte@Sun.COM 				/* add(remove) dd to(from) dd-set */
1780*7836SJohn.Forte@Sun.COM 				u.i32 = htonl(x->dd_id);
1781*7836SJohn.Forte@Sun.COM 				ec = pdu_add_tlv(&pdu, &pl, &sz,
1782*7836SJohn.Forte@Sun.COM 				    ISNS_DD_ID_ATTR_ID,
1783*7836SJohn.Forte@Sun.COM 				    4, (void *)&u.i32, 1);
1784*7836SJohn.Forte@Sun.COM 				u.i32 = htonl(x->dds_id);
1785*7836SJohn.Forte@Sun.COM 				if (ec == 0) {
1786*7836SJohn.Forte@Sun.COM 					ec = pdu_add_tlv(&pdu, &pl, &sz,
1787*7836SJohn.Forte@Sun.COM 					    ISNS_DD_ID_ATTR_ID,
1788*7836SJohn.Forte@Sun.COM 					    4, (void *)&u.i32, 1);
1789*7836SJohn.Forte@Sun.COM 				}
1790*7836SJohn.Forte@Sun.COM #ifdef DEBUG
1791*7836SJohn.Forte@Sun.COM 				sprintf(logbuff, "FROM [%d] ", x->dd_id);
1792*7836SJohn.Forte@Sun.COM 				logbuff += strlen(logbuff);
1793*7836SJohn.Forte@Sun.COM 				sprintf(logbuff, "IN [%d] ", x->dds_id);
1794*7836SJohn.Forte@Sun.COM 				logbuff += strlen(logbuff);
1795*7836SJohn.Forte@Sun.COM #endif
1796*7836SJohn.Forte@Sun.COM 			}
1797*7836SJohn.Forte@Sun.COM 			l = l->next;
1798*7836SJohn.Forte@Sun.COM 		}
1799*7836SJohn.Forte@Sun.COM 		s = s->next;
1800*7836SJohn.Forte@Sun.COM 	}
1801*7836SJohn.Forte@Sun.COM 
1802*7836SJohn.Forte@Sun.COM scn_done:
1803*7836SJohn.Forte@Sun.COM 	if (ec == 0) {
1804*7836SJohn.Forte@Sun.COM #ifdef DEBUG
1805*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "scn_trigger1", buff);
1806*7836SJohn.Forte@Sun.COM #endif
1807*7836SJohn.Forte@Sun.COM 		ec = emit_scn(p->portal.l, pdu, pl);
1808*7836SJohn.Forte@Sun.COM 	} else {
1809*7836SJohn.Forte@Sun.COM 		isnslog(LOG_DEBUG, "scn_trigger1", " failed.\n");
1810*7836SJohn.Forte@Sun.COM 	}
1811*7836SJohn.Forte@Sun.COM 
1812*7836SJohn.Forte@Sun.COM 	free(pdu);
1813*7836SJohn.Forte@Sun.COM 
1814*7836SJohn.Forte@Sun.COM 	return (0);
1815*7836SJohn.Forte@Sun.COM }
1816*7836SJohn.Forte@Sun.COM 
1817*7836SJohn.Forte@Sun.COM /*
1818*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1819*7836SJohn.Forte@Sun.COM  *
1820*7836SJohn.Forte@Sun.COM  * scn_trigger:
1821*7836SJohn.Forte@Sun.COM  *	Trigger one SCN for every SCN entry.
1822*7836SJohn.Forte@Sun.COM  *
1823*7836SJohn.Forte@Sun.COM  * return - always successful (0).
1824*7836SJohn.Forte@Sun.COM  *
1825*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1826*7836SJohn.Forte@Sun.COM  */
1827*7836SJohn.Forte@Sun.COM static int
scn_trigger()1828*7836SJohn.Forte@Sun.COM scn_trigger(
1829*7836SJohn.Forte@Sun.COM )
1830*7836SJohn.Forte@Sun.COM {
1831*7836SJohn.Forte@Sun.COM 	time_t t;
1832*7836SJohn.Forte@Sun.COM 	scn_registry_t *p;
1833*7836SJohn.Forte@Sun.COM 
1834*7836SJohn.Forte@Sun.COM 	t = time(NULL);
1835*7836SJohn.Forte@Sun.COM 
1836*7836SJohn.Forte@Sun.COM 	p = scn_registry;
1837*7836SJohn.Forte@Sun.COM 	while (p != NULL) {
1838*7836SJohn.Forte@Sun.COM 		if (p->scn != NULL) {
1839*7836SJohn.Forte@Sun.COM 			(void) scn_trigger1(t, p);
1840*7836SJohn.Forte@Sun.COM 		}
1841*7836SJohn.Forte@Sun.COM 		p = p->next;
1842*7836SJohn.Forte@Sun.COM 	}
1843*7836SJohn.Forte@Sun.COM 
1844*7836SJohn.Forte@Sun.COM 	return (0);
1845*7836SJohn.Forte@Sun.COM }
1846*7836SJohn.Forte@Sun.COM 
1847*7836SJohn.Forte@Sun.COM /*
1848*7836SJohn.Forte@Sun.COM  * global functions.
1849*7836SJohn.Forte@Sun.COM  */
1850*7836SJohn.Forte@Sun.COM 
1851*7836SJohn.Forte@Sun.COM /*
1852*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1853*7836SJohn.Forte@Sun.COM  *
1854*7836SJohn.Forte@Sun.COM  * scn_list_load:
1855*7836SJohn.Forte@Sun.COM  *	Load one SCN entry and add it to the SCN entry list.
1856*7836SJohn.Forte@Sun.COM  *
1857*7836SJohn.Forte@Sun.COM  * uid	- the Storage Node object UID.
1858*7836SJohn.Forte@Sun.COM  * node	- the Storage Node name.
1859*7836SJohn.Forte@Sun.COM  * nlen	- the length of the name.
1860*7836SJohn.Forte@Sun.COM  * bitmap - the SCN bitmap.
1861*7836SJohn.Forte@Sun.COM  * return - error code.
1862*7836SJohn.Forte@Sun.COM  *
1863*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1864*7836SJohn.Forte@Sun.COM  */
1865*7836SJohn.Forte@Sun.COM int
scn_list_load(uint32_t uid,uchar_t * node,uint32_t nlen,uint32_t bitmap)1866*7836SJohn.Forte@Sun.COM scn_list_load(
1867*7836SJohn.Forte@Sun.COM 	uint32_t uid,
1868*7836SJohn.Forte@Sun.COM 	uchar_t *node,
1869*7836SJohn.Forte@Sun.COM 	uint32_t nlen,
1870*7836SJohn.Forte@Sun.COM 	uint32_t bitmap
1871*7836SJohn.Forte@Sun.COM )
1872*7836SJohn.Forte@Sun.COM {
1873*7836SJohn.Forte@Sun.COM 	int ec = 0;
1874*7836SJohn.Forte@Sun.COM 
1875*7836SJohn.Forte@Sun.COM 	scn_registry_t *list;
1876*7836SJohn.Forte@Sun.COM 	uchar_t *name;
1877*7836SJohn.Forte@Sun.COM 
1878*7836SJohn.Forte@Sun.COM 	list = (scn_registry_t *)malloc(sizeof (scn_registry_t));
1879*7836SJohn.Forte@Sun.COM 	name = (uchar_t *)malloc(nlen);
1880*7836SJohn.Forte@Sun.COM 
1881*7836SJohn.Forte@Sun.COM 	if (list != NULL && name != NULL) {
1882*7836SJohn.Forte@Sun.COM 		list->uid = uid;
1883*7836SJohn.Forte@Sun.COM 		(void) strcpy((char *)name, (char *)node);
1884*7836SJohn.Forte@Sun.COM 		list->name = name;
1885*7836SJohn.Forte@Sun.COM 		list->nlen = nlen;
1886*7836SJohn.Forte@Sun.COM 		list->bitmap = bitmap;
1887*7836SJohn.Forte@Sun.COM 		list->portal.l = NULL;
1888*7836SJohn.Forte@Sun.COM 		list->scn = NULL;
1889*7836SJohn.Forte@Sun.COM 		list->next = NULL;
1890*7836SJohn.Forte@Sun.COM 		ASSERT(scn_q == NULL);
1891*7836SJohn.Forte@Sun.COM 		(void) scn_list_add(list);
1892*7836SJohn.Forte@Sun.COM 	} else {
1893*7836SJohn.Forte@Sun.COM 		free(list);
1894*7836SJohn.Forte@Sun.COM 		free(name);
1895*7836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
1896*7836SJohn.Forte@Sun.COM 	}
1897*7836SJohn.Forte@Sun.COM 
1898*7836SJohn.Forte@Sun.COM 	return (ec);
1899*7836SJohn.Forte@Sun.COM }
1900*7836SJohn.Forte@Sun.COM 
1901*7836SJohn.Forte@Sun.COM /*
1902*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1903*7836SJohn.Forte@Sun.COM  *
1904*7836SJohn.Forte@Sun.COM  * verify_scn_portal:
1905*7836SJohn.Forte@Sun.COM  *	Extract and verify portals for every SCN entry(s) after they are
1906*7836SJohn.Forte@Sun.COM  *	loaded from data store, for those which do not have a SCN portal,
1907*7836SJohn.Forte@Sun.COM  *	remove it from the SCN entry list.
1908*7836SJohn.Forte@Sun.COM  *
1909*7836SJohn.Forte@Sun.COM  * return - 1: error occurs, otherwise 0.
1910*7836SJohn.Forte@Sun.COM  *
1911*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1912*7836SJohn.Forte@Sun.COM  */
1913*7836SJohn.Forte@Sun.COM int
verify_scn_portal()1914*7836SJohn.Forte@Sun.COM verify_scn_portal(
1915*7836SJohn.Forte@Sun.COM )
1916*7836SJohn.Forte@Sun.COM {
1917*7836SJohn.Forte@Sun.COM 	scn_registry_t **pp, *e;
1918*7836SJohn.Forte@Sun.COM 	scn_portal_t *p;
1919*7836SJohn.Forte@Sun.COM 
1920*7836SJohn.Forte@Sun.COM 	pp = &scn_registry;
1921*7836SJohn.Forte@Sun.COM 	while (*pp != NULL) {
1922*7836SJohn.Forte@Sun.COM 		e = *pp;
1923*7836SJohn.Forte@Sun.COM 		p = extract_scn_portal(e->name);
1924*7836SJohn.Forte@Sun.COM 		if (p != NULL) {
1925*7836SJohn.Forte@Sun.COM 			if (scn_add_portal(e, p) != 0) {
1926*7836SJohn.Forte@Sun.COM 				return (1);
1927*7836SJohn.Forte@Sun.COM 			}
1928*7836SJohn.Forte@Sun.COM 		}
1929*7836SJohn.Forte@Sun.COM 		if (e->portal.l != NULL) {
1930*7836SJohn.Forte@Sun.COM 			pp = &e->next;
1931*7836SJohn.Forte@Sun.COM 		} else {
1932*7836SJohn.Forte@Sun.COM 			/* remove this entry */
1933*7836SJohn.Forte@Sun.COM 			*pp = e->next;
1934*7836SJohn.Forte@Sun.COM 			free_entry(e);
1935*7836SJohn.Forte@Sun.COM 		}
1936*7836SJohn.Forte@Sun.COM 		/* free the unused portal(s) */
1937*7836SJohn.Forte@Sun.COM 		free_portal(p);
1938*7836SJohn.Forte@Sun.COM 	}
1939*7836SJohn.Forte@Sun.COM 
1940*7836SJohn.Forte@Sun.COM 	return (0);
1941*7836SJohn.Forte@Sun.COM }
1942*7836SJohn.Forte@Sun.COM 
1943*7836SJohn.Forte@Sun.COM /*
1944*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1945*7836SJohn.Forte@Sun.COM  *
1946*7836SJohn.Forte@Sun.COM  * add_scn_entry:
1947*7836SJohn.Forte@Sun.COM  *	Add a SCN entry.
1948*7836SJohn.Forte@Sun.COM  *
1949*7836SJohn.Forte@Sun.COM  * node	- the Storage Node name.
1950*7836SJohn.Forte@Sun.COM  * nlen	- the length of the name.
1951*7836SJohn.Forte@Sun.COM  * bitmap - the SCN bitmap.
1952*7836SJohn.Forte@Sun.COM  * return - error code.
1953*7836SJohn.Forte@Sun.COM  *
1954*7836SJohn.Forte@Sun.COM  * ****************************************************************************
1955*7836SJohn.Forte@Sun.COM  */
1956*7836SJohn.Forte@Sun.COM int
add_scn_entry(uchar_t * node,uint32_t nlen,uint32_t bitmap)1957*7836SJohn.Forte@Sun.COM add_scn_entry(
1958*7836SJohn.Forte@Sun.COM 	uchar_t *node,
1959*7836SJohn.Forte@Sun.COM 	uint32_t nlen,
1960*7836SJohn.Forte@Sun.COM 	uint32_t bitmap
1961*7836SJohn.Forte@Sun.COM )
1962*7836SJohn.Forte@Sun.COM {
1963*7836SJohn.Forte@Sun.COM 	int ec = 0;
1964*7836SJohn.Forte@Sun.COM 
1965*7836SJohn.Forte@Sun.COM 	uint32_t mgmt;
1966*7836SJohn.Forte@Sun.COM 	scn_portal_t *p;
1967*7836SJohn.Forte@Sun.COM 
1968*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
1969*7836SJohn.Forte@Sun.COM 	uint32_t uid;
1970*7836SJohn.Forte@Sun.COM 	scn_registry_t *e;
1971*7836SJohn.Forte@Sun.COM 	uchar_t *name;
1972*7836SJohn.Forte@Sun.COM 
1973*7836SJohn.Forte@Sun.COM 	mgmt = bitmap & (
1974*7836SJohn.Forte@Sun.COM 	    ISNS_MGMT_REG |
1975*7836SJohn.Forte@Sun.COM 	    ISNS_MEMBER_REMOVED |
1976*7836SJohn.Forte@Sun.COM 	    ISNS_MEMBER_ADDED);
1977*7836SJohn.Forte@Sun.COM 
1978*7836SJohn.Forte@Sun.COM 	if ((mgmt > 0 &&
1979*7836SJohn.Forte@Sun.COM 	    (mgmt_scn == 0 ||
1980*7836SJohn.Forte@Sun.COM 	    mgmt < ISNS_MGMT_REG ||
1981*7836SJohn.Forte@Sun.COM 	    is_control_node(node) == 0)) ||
1982*7836SJohn.Forte@Sun.COM 	    (p = extract_scn_portal(node)) == NULL) {
1983*7836SJohn.Forte@Sun.COM 		return (ISNS_RSP_SCN_REGIS_REJECTED);
1984*7836SJohn.Forte@Sun.COM 	}
1985*7836SJohn.Forte@Sun.COM 
1986*7836SJohn.Forte@Sun.COM 	e = (scn_registry_t *)malloc(sizeof (scn_registry_t));
1987*7836SJohn.Forte@Sun.COM 	name = (uchar_t *)malloc(nlen);
1988*7836SJohn.Forte@Sun.COM 	if (e != NULL && name != NULL) {
1989*7836SJohn.Forte@Sun.COM 		lc.type = OBJ_ISCSI;
1990*7836SJohn.Forte@Sun.COM 		lc.curr_uid = 0;
1991*7836SJohn.Forte@Sun.COM 		lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
1992*7836SJohn.Forte@Sun.COM 		lc.data[0].ptr = node;
1993*7836SJohn.Forte@Sun.COM 		lc.op[0] = OP_STRING;
1994*7836SJohn.Forte@Sun.COM 		lc.op[1] = 0;
1995*7836SJohn.Forte@Sun.COM 		lc.data[2].ui = bitmap;
1996*7836SJohn.Forte@Sun.COM 		ec = cache_lookup(&lc, &uid, cb_update_scn_bitmap);
1997*7836SJohn.Forte@Sun.COM 		if (uid == 0) {
1998*7836SJohn.Forte@Sun.COM 			ec = ISNS_RSP_SCN_REGIS_REJECTED;
1999*7836SJohn.Forte@Sun.COM 		}
2000*7836SJohn.Forte@Sun.COM 		if (ec == 0) {
2001*7836SJohn.Forte@Sun.COM 			e->uid = uid;
2002*7836SJohn.Forte@Sun.COM 			(void) strcpy((char *)name, (char *)node);
2003*7836SJohn.Forte@Sun.COM 			e->name = name;
2004*7836SJohn.Forte@Sun.COM 			e->nlen = nlen;
2005*7836SJohn.Forte@Sun.COM 			e->bitmap = bitmap;
2006*7836SJohn.Forte@Sun.COM 			e->portal.p = p;
2007*7836SJohn.Forte@Sun.COM 			e->scn = NULL;
2008*7836SJohn.Forte@Sun.COM 			e->next = NULL;
2009*7836SJohn.Forte@Sun.COM 			(void) queue_msg_set(scn_q, SCN_ADD, (void *)e);
2010*7836SJohn.Forte@Sun.COM 		}
2011*7836SJohn.Forte@Sun.COM 	} else {
2012*7836SJohn.Forte@Sun.COM 		ec = ISNS_RSP_INTERNAL_ERROR;
2013*7836SJohn.Forte@Sun.COM 	}
2014*7836SJohn.Forte@Sun.COM 
2015*7836SJohn.Forte@Sun.COM 	if (ec != 0) {
2016*7836SJohn.Forte@Sun.COM 		free(e);
2017*7836SJohn.Forte@Sun.COM 		free(name);
2018*7836SJohn.Forte@Sun.COM 		free_portal(p);
2019*7836SJohn.Forte@Sun.COM 	}
2020*7836SJohn.Forte@Sun.COM 
2021*7836SJohn.Forte@Sun.COM 	return (ec);
2022*7836SJohn.Forte@Sun.COM }
2023*7836SJohn.Forte@Sun.COM 
2024*7836SJohn.Forte@Sun.COM /*
2025*7836SJohn.Forte@Sun.COM  * ****************************************************************************
2026*7836SJohn.Forte@Sun.COM  *
2027*7836SJohn.Forte@Sun.COM  * remove_scn_entry:
2028*7836SJohn.Forte@Sun.COM  *	Remove a SCN entry.
2029*7836SJohn.Forte@Sun.COM  *
2030*7836SJohn.Forte@Sun.COM  * node	- the Storage Node name.
2031*7836SJohn.Forte@Sun.COM  * return - error code.
2032*7836SJohn.Forte@Sun.COM  *
2033*7836SJohn.Forte@Sun.COM  * ****************************************************************************
2034*7836SJohn.Forte@Sun.COM  */
2035*7836SJohn.Forte@Sun.COM int
remove_scn_entry(uchar_t * node)2036*7836SJohn.Forte@Sun.COM remove_scn_entry(
2037*7836SJohn.Forte@Sun.COM 	uchar_t *node
2038*7836SJohn.Forte@Sun.COM )
2039*7836SJohn.Forte@Sun.COM {
2040*7836SJohn.Forte@Sun.COM 	int ec = 0;
2041*7836SJohn.Forte@Sun.COM 
2042*7836SJohn.Forte@Sun.COM 	lookup_ctrl_t lc;
2043*7836SJohn.Forte@Sun.COM 	uint32_t uid;
2044*7836SJohn.Forte@Sun.COM 
2045*7836SJohn.Forte@Sun.COM 	lc.type = OBJ_ISCSI;
2046*7836SJohn.Forte@Sun.COM 	lc.curr_uid = 0;
2047*7836SJohn.Forte@Sun.COM 	lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
2048*7836SJohn.Forte@Sun.COM 	lc.data[0].ptr = node;
2049*7836SJohn.Forte@Sun.COM 	lc.op[0] = OP_STRING;
2050*7836SJohn.Forte@Sun.COM 	lc.op[1] = 0;
2051*7836SJohn.Forte@Sun.COM 	lc.data[2].ui = 0;
2052*7836SJohn.Forte@Sun.COM 	ec = cache_lookup(&lc, &uid, cb_update_scn_bitmap);
2053*7836SJohn.Forte@Sun.COM 	if (ec == 0 && uid != 0) {
2054*7836SJohn.Forte@Sun.COM 		(void) queue_msg_set(scn_q, SCN_REMOVE, (void *)uid);
2055*7836SJohn.Forte@Sun.COM 	}
2056*7836SJohn.Forte@Sun.COM 
2057*7836SJohn.Forte@Sun.COM 	return (ec);
2058*7836SJohn.Forte@Sun.COM }
2059*7836SJohn.Forte@Sun.COM 
2060*7836SJohn.Forte@Sun.COM /*
2061*7836SJohn.Forte@Sun.COM  * ****************************************************************************
2062*7836SJohn.Forte@Sun.COM  *
2063*7836SJohn.Forte@Sun.COM  * remove_scn_portal:
2064*7836SJohn.Forte@Sun.COM  *	Remove a portal from every SCN entry.
2065*7836SJohn.Forte@Sun.COM  *
2066*7836SJohn.Forte@Sun.COM  * uid	- the Portal object UID.
2067*7836SJohn.Forte@Sun.COM  * return - alrays successful (0).
2068*7836SJohn.Forte@Sun.COM  *
2069*7836SJohn.Forte@Sun.COM  * ****************************************************************************
2070*7836SJohn.Forte@Sun.COM  */
2071*7836SJohn.Forte@Sun.COM int
remove_scn_portal(uint32_t uid)2072*7836SJohn.Forte@Sun.COM remove_scn_portal(
2073*7836SJohn.Forte@Sun.COM 	uint32_t uid
2074*7836SJohn.Forte@Sun.COM )
2075*7836SJohn.Forte@Sun.COM {
2076*7836SJohn.Forte@Sun.COM 	(void) queue_msg_set(scn_q, SCN_REMOVE_P, (void *)uid);
2077*7836SJohn.Forte@Sun.COM 
2078*7836SJohn.Forte@Sun.COM 	return (0);
2079*7836SJohn.Forte@Sun.COM }
2080*7836SJohn.Forte@Sun.COM 
2081*7836SJohn.Forte@Sun.COM /*
2082*7836SJohn.Forte@Sun.COM  * ****************************************************************************
2083*7836SJohn.Forte@Sun.COM  *
2084*7836SJohn.Forte@Sun.COM  * scn_proc:
2085*7836SJohn.Forte@Sun.COM  *	The entry point of the SCN thread. It listens on the SCN message
2086*7836SJohn.Forte@Sun.COM  *	queue and process every SCN related stuff.
2087*7836SJohn.Forte@Sun.COM  *
2088*7836SJohn.Forte@Sun.COM  * arg	- nothing.
2089*7836SJohn.Forte@Sun.COM  * return - NULL.
2090*7836SJohn.Forte@Sun.COM  *
2091*7836SJohn.Forte@Sun.COM  * ****************************************************************************
2092*7836SJohn.Forte@Sun.COM  */
2093*7836SJohn.Forte@Sun.COM void *
scn_proc(void * arg)2094*7836SJohn.Forte@Sun.COM scn_proc(
2095*7836SJohn.Forte@Sun.COM 	/* LINTED E_FUNC_ARG_UNUSED */
2096*7836SJohn.Forte@Sun.COM 	void *arg
2097*7836SJohn.Forte@Sun.COM )
2098*7836SJohn.Forte@Sun.COM {
2099*7836SJohn.Forte@Sun.COM 	int state = 0;
2100*7836SJohn.Forte@Sun.COM 
2101*7836SJohn.Forte@Sun.COM 	scn_raw_t *raw;
2102*7836SJohn.Forte@Sun.COM 	msg_text_t *msg;
2103*7836SJohn.Forte@Sun.COM 
2104*7836SJohn.Forte@Sun.COM 	for (;;) {
2105*7836SJohn.Forte@Sun.COM 		msg = queue_msg_get(scn_q);
2106*7836SJohn.Forte@Sun.COM 		switch (msg->id) {
2107*7836SJohn.Forte@Sun.COM 		case SCN_ADD:
2108*7836SJohn.Forte@Sun.COM 			(void) scn_list_add((scn_registry_t *)msg->data);
2109*7836SJohn.Forte@Sun.COM 			break;
2110*7836SJohn.Forte@Sun.COM 		case SCN_REMOVE:
2111*7836SJohn.Forte@Sun.COM 			(void) scn_list_remove((uint32_t)msg->data);
2112*7836SJohn.Forte@Sun.COM 			break;
2113*7836SJohn.Forte@Sun.COM 		case SCN_REMOVE_P:
2114*7836SJohn.Forte@Sun.COM 			(void) scn_remove_portal((uint32_t)msg->data);
2115*7836SJohn.Forte@Sun.COM 			break;
2116*7836SJohn.Forte@Sun.COM 		case SCN_SET:
2117*7836SJohn.Forte@Sun.COM 			raw = (scn_raw_t *)msg->data;
2118*7836SJohn.Forte@Sun.COM 			state = scn_transition(state, raw);
2119*7836SJohn.Forte@Sun.COM 			/* free the raw data */
2120*7836SJohn.Forte@Sun.COM 			free_raw(raw);
2121*7836SJohn.Forte@Sun.COM 			break;
2122*7836SJohn.Forte@Sun.COM 		case SCN_TRIGGER:
2123*7836SJohn.Forte@Sun.COM 			if (scn_dispatched != 0) {
2124*7836SJohn.Forte@Sun.COM 				(void) scn_trigger();
2125*7836SJohn.Forte@Sun.COM 			}
2126*7836SJohn.Forte@Sun.COM 		case SCN_IGNORE:
2127*7836SJohn.Forte@Sun.COM 			/* clean the scn(s) */
2128*7836SJohn.Forte@Sun.COM 			free_scn();
2129*7836SJohn.Forte@Sun.COM 			/* reset the state */
2130*7836SJohn.Forte@Sun.COM 			state = 0;
2131*7836SJohn.Forte@Sun.COM 			/* reset the scn_dispatched flag */
2132*7836SJohn.Forte@Sun.COM 			scn_dispatched = 0;
2133*7836SJohn.Forte@Sun.COM 			break;
2134*7836SJohn.Forte@Sun.COM 		case SCN_STOP:
2135*7836SJohn.Forte@Sun.COM 			queue_msg_free(msg);
2136*7836SJohn.Forte@Sun.COM 			return (NULL);
2137*7836SJohn.Forte@Sun.COM 		default:
2138*7836SJohn.Forte@Sun.COM 			break;
2139*7836SJohn.Forte@Sun.COM 		}
2140*7836SJohn.Forte@Sun.COM 		queue_msg_free(msg);
2141*7836SJohn.Forte@Sun.COM 	}
2142*7836SJohn.Forte@Sun.COM }
2143