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