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