4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
32 #include "isns_server.h"
33 #include "isns_msgq.h"
34 #include "isns_cache.h"
37 #include "isns_dseng.h"
49 static scn_registry_t
*scn_registry
= NULL
;
50 static int scn_dispatched
= 0;
55 extern uint8_t mgmt_scn
;
56 extern msg_queue_t
*sys_q
;
57 extern msg_queue_t
*scn_q
;
58 extern const int UID_ATTR_INDEX
[MAX_OBJ_TYPE_FOR_SIZE
];
61 extern void dump_pdu1(isns_pdu_t
*);
64 static int sf_gen(scn_raw_t
*);
65 static int sf_error(scn_raw_t
*);
67 static scn_raw_t
*make_raw_entity(isns_obj_t
*);
68 static scn_raw_t
*make_raw_iscsi(isns_obj_t
*);
69 static scn_raw_t
*make_raw_portal(isns_obj_t
*);
70 static scn_raw_t
*make_raw_assoc_iscsi(isns_obj_t
*);
71 static scn_raw_t
*make_raw_assoc_dd(isns_obj_t
*);
72 static scn_raw_t
*(*const make_raw
[MAX_OBJ_TYPE_FOR_SIZE
])(isns_obj_t
*) = {
80 NULL
, /* MAX_OBJ_TYPE */
81 NULL
, /* OBJ_DUMMY1 */
82 NULL
, /* OBJ_DUMMY2 */
83 NULL
, /* OBJ_DUMMY3 */
84 NULL
, /* OBJ_DUMMY4 */
85 &make_raw_assoc_iscsi
,
89 static scn_text_t
*scn_gen_entity(scn_raw_t
*);
90 static scn_text_t
*scn_gen_iscsi(scn_raw_t
*);
91 static scn_text_t
*scn_gen_portal(scn_raw_t
*);
92 static scn_text_t
*scn_gen_assoc_dd(scn_raw_t
*);
93 static scn_text_t
*(*const scn_gen
[MAX_OBJ_TYPE_FOR_SIZE
])(scn_raw_t
*) = {
101 NULL
, /* MAX_OBJ_TYPE */
102 NULL
, /* OBJ_DUMMY1 */
103 NULL
, /* OBJ_DUMMY2 */
104 NULL
, /* OBJ_DUMMY3 */
105 NULL
, /* OBJ_DUMMY4 */
110 #define SCN_TEST(E, BITMAP, UID1, UID2, NT) \
111 (((E) & (BITMAP)) && \
112 (!((BITMAP) & (ISNS_INIT_SELF_INFO_ONLY | \
113 ISNS_TARGET_SELF_INFO_ONLY)) || \
114 ((UID1) == (UID2)) || \
115 (((BITMAP) & ISNS_INIT_SELF_INFO_ONLY) && \
116 ((NT) & ISNS_INITIATOR_NODE_TYPE)) || \
117 (((BITMAP) & ISNS_TARGET_SELF_INFO_ONLY) && \
118 ((NT) & ISNS_TARGET_NODE_TYPE))))
125 * ****************************************************************************
128 * Free one SCN portal or decrease the reference count if the portal
129 * is referenced by other SCN entry(s).
133 * ****************************************************************************
141 if (p
->sz
== sizeof (in6_addr_t
)) {
151 * ****************************************************************************
154 * Free the unused portals, which are extracted for new SCN entry,
155 * after the new SCN entry is added.
159 * ****************************************************************************
176 * ****************************************************************************
179 * Free the list of portals while a SCN entry is being destroyed.
181 * l - the portal list.
183 * ****************************************************************************
203 * ****************************************************************************
206 * Free one SCN or decrease the ref count after the SCN is emitted.
210 * ****************************************************************************
217 if (text
->ref
<= 1) {
226 * ****************************************************************************
229 * Free the the list of SCN.
233 * ****************************************************************************
242 scn_list_t
*next_list
;
244 while (scn
!= NULL
) {
245 next_scn
= scn
->next
;
246 list
= scn
->data
.list
;
247 while (list
!= NULL
) {
248 next_list
= list
->next
;
249 free_scn_text(list
->data
.text
);
259 * ****************************************************************************
262 * Free all of SCNs which are dispatched to every entry.
264 * ****************************************************************************
275 free_scn_list(p
->scn
);
282 * ****************************************************************************
285 * Free one SCN entry.
289 * ****************************************************************************
296 free_scn_list(e
->scn
);
297 free_portal_list(e
->portal
.l
);
303 * ****************************************************************************
306 * Free the raw data after the SCN is generated from it.
308 * raw - the raw SCN data.
310 * ****************************************************************************
320 if (raw
->ip
!= NULL
) {
327 * ****************************************************************************
330 * Add portals to the portal list of a SCN entry.
334 * return - 0: successful, otherwise failed.
336 * ****************************************************************************
353 m
= (scn_list_t
*)malloc(sizeof (scn_list_t
));
359 while (e
&& !found_it
) {
361 while (l
&& !found_it
) {
363 if (x
->uid
== p
->uid
) {
386 * ****************************************************************************
389 * Remove a portal from the portal list of every SCN entry.
391 * uid - the portal object uid.
392 * return - always successful (0).
394 * ****************************************************************************
401 scn_registry_t
**ep
, *e
;
425 if (e
->portal
.l
== NULL
) {
426 /* no portal for this entry, destroy it */
439 * ****************************************************************************
442 * Add one SCN entry to the SCN entry list.
445 * return - always successful (0).
447 * ****************************************************************************
462 if ((*pp
)->uid
== e
->uid
) {
463 /* replace the bitmap */
464 (*pp
)->bitmap
= e
->bitmap
;
468 } else if ((*pp
)->uid
< e
->uid
) {
474 (void) scn_add_portal(e
, p
);
476 if (e
->portal
.l
!= NULL
|| sys_q
== NULL
) {
477 /* insert it to the list */
481 /* no portal, ignore it */
485 /* free the unused portal(s) */
492 * ****************************************************************************
495 * Remove one SCN entry from the SCN entry list.
497 * uid - the SCN entry unique ID.
498 * return - always successful (0).
500 * ****************************************************************************
507 scn_registry_t
**ep
, *e
;
517 } else if (e
->uid
< uid
) {
528 * ****************************************************************************
531 * The callback function which returns the SCN port of a portal object.
533 * p1 - the portal object.
534 * p2 - the lookup control data.
535 * return - the SCN port number.
537 * ****************************************************************************
546 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
548 isns_attr_t
*attr
= &obj
->attrs
[
549 ATTR_INDEX_PORTAL(ISNS_SCN_PORT_ATTR_ID
)];
553 if (attr
->tag
!= 0 && attr
->value
.ui
!= 0) {
554 port
= (int)attr
->value
.ui
;
561 * ****************************************************************************
564 * Make a new SCN portal.
566 * ref - the ref count.
567 * uid - the portal object UID.
568 * ip - the ip address.
569 * port - the port number.
570 * return - the SCN portal.
572 * ****************************************************************************
574 static scn_portal_t
*
584 p
= (scn_portal_t
*)malloc(sizeof (scn_portal_t
));
587 /* convert the ipv6 to ipv4 */
588 if (((int *)ip
)[0] == 0x00 &&
589 ((int *)ip
)[1] == 0x00 &&
590 ((uchar_t
*)ip
)[8] == 0x00 &&
591 ((uchar_t
*)ip
)[9] == 0x00 &&
592 ((uchar_t
*)ip
)[10] == 0xFF &&
593 ((uchar_t
*)ip
)[11] == 0xFF) {
594 p
->sz
= sizeof (in_addr_t
);
595 p
->ip
.in
= ((uint32_t *)ip
)[3];
598 p
->sz
= sizeof (in6_addr_t
);
611 * ****************************************************************************
613 * extract scn_portal:
614 * Extract the SCN portal(s) for a storage node.
616 * name - the storage node name.
617 * return - the SCN portal list.
619 * ****************************************************************************
621 static scn_portal_t
*
626 scn_portal_t
*list
= NULL
;
629 lookup_ctrl_t lc_pg
, lc_p
;
630 uint32_t pg_uid
, uid
;
637 lc_pg
.id
[0] = ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID
);
638 lc_pg
.op
[0] = OP_STRING
;
639 lc_pg
.data
[0].ptr
= name
;
642 lc_pg
.id
[1] = ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
;
643 lc_pg
.id
[2] = ISNS_PG_PORTAL_PORT_ATTR_ID
;
645 lc_p
.type
= OBJ_PORTAL
;
647 lc_p
.id
[0] = ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID
);
648 lc_p
.op
[0] = OP_MEMORY_IP6
;
649 lc_p
.id
[1] = ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID
);
650 lc_p
.op
[1] = OP_INTEGER
;
653 while (cache_lookup(&lc_pg
, &pg_uid
, cb_clone_attrs
) == 0 &&
655 ip
= lc_pg
.data
[1].ip
;
656 port
= lc_pg
.data
[2].ui
;
658 lc_p
.data
[0].ip
= ip
;
659 lc_p
.data
[1].ui
= port
;
660 port
= cache_lookup(&lc_p
, &uid
, cb_get_scn_port
);
661 if (port
!= 0 && uid
!= 0) {
662 /* ref starts from 1 */
663 p
= new_scn_portal(1, uid
, ip
, port
);
672 /* portal not registered or no scn port */
676 lc_pg
.curr_uid
= pg_uid
;
683 * ****************************************************************************
685 * cb_update_scn_bitmap:
686 * The callback function which updates the SCN Bitmap attribute of
687 * a storage node object.
689 * p1 - the storage node object.
690 * p2 - the lookup control data.
691 * return - error code.
693 * ****************************************************************************
696 cb_update_scn_bitmap(
703 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
704 lookup_ctrl_t
*lcp
= (lookup_ctrl_t
*)p2
;
706 int id
= ATTR_INDEX_ISCSI(ISNS_ISCSI_SCN_BITMAP_ATTR_ID
);
707 isns_attr_t
*attr
= &obj
->attrs
[id
];
709 uint32_t bitmap
= lcp
->data
[2].ui
;
712 attr
->tag
= ISNS_ISCSI_SCN_BITMAP_ATTR_ID
;
714 } else if (attr
->tag
== 0) {
720 attr
->value
.ui
= bitmap
;
723 ec
= write_data(DATA_UPDATE
, obj
);
730 * ****************************************************************************
733 * The callback function which returns the node type attribute of
734 * a storage node object.
736 * p1 - the storage node object.
737 * p2 - the lookup control data.
738 * return - error code.
740 * ****************************************************************************
745 /* LINTED E_FUNC_ARG_UNUSED */
749 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
750 isns_attr_t
*attr
= &obj
->attrs
[
751 ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_TYPE_ATTR_ID
)];
752 int nt
= (int)attr
->value
.ui
;
758 * ****************************************************************************
761 * The callback function which returns the storage node object UID
762 * from a portal group object.
764 * p1 - the pg object.
765 * p2 - the lookup control data.
766 * return - the storage node object UID.
768 * ****************************************************************************
773 /* LINTED E_FUNC_ARG_UNUSED */
779 ref
= get_ref_t(p1
, OBJ_ISCSI
);
785 * ****************************************************************************
788 * Make raw SCN data with a Network Entity object.
790 * obj - the network entity object.
791 * return - the raw SCN data.
793 * ****************************************************************************
803 raw
= (scn_raw_t
*)malloc(sizeof (scn_raw_t
));
805 raw
->type
= obj
->type
;
806 raw
->uid
= get_obj_uid(obj
);
815 isnslog(LOG_DEBUG
, "make_raw_entity", "malloc failed.");
822 * ****************************************************************************
825 * Make raw SCN data with a Storage Node object.
827 * obj - the storage node object.
828 * return - the raw SCN data.
830 * ****************************************************************************
846 uid
= get_obj_uid(obj
);
847 attr
= &obj
->attrs
[ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_TYPE_ATTR_ID
)];
849 attr
= &obj
->attrs
[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID
)];
851 raw
= (scn_raw_t
*)malloc(sizeof (scn_raw_t
));
853 iscsi
= (uchar_t
*)malloc(ilen
);
854 if (raw
!= NULL
&& iscsi
!= NULL
) {
855 /* copy the iscsi storage node name */
856 (void) strcpy((char *)iscsi
, (char *)attr
->value
.ptr
);
858 raw
->type
= obj
->type
;
871 isnslog(LOG_DEBUG
, "make_raw_iscsi", "malloc failed.");
878 * ****************************************************************************
881 * Make raw SCN data with a Portal object.
883 * obj - the portal object.
884 * return - the raw SCN data.
886 * ****************************************************************************
899 raw
= (scn_raw_t
*)malloc(sizeof (scn_raw_t
));
900 ip
= (in6_addr_t
*)malloc(sizeof (in6_addr_t
));
901 if (raw
!= NULL
&& ip
!= NULL
) {
903 ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID
)];
904 (void) memcpy(ip
, attr
->value
.ip
, sizeof (in6_addr_t
));
906 ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID
)];
907 port
= attr
->value
.ui
;
909 raw
->type
= obj
->type
;
923 isnslog(LOG_DEBUG
, "make_raw_portal", "malloc failed.");
930 * ****************************************************************************
932 * make_raw_assoc_iscsi:
933 * Make raw SCN data with a Discovery Domain member association.
935 * obj - the member association object.
936 * return - the raw SCN data.
938 * ****************************************************************************
941 make_raw_assoc_iscsi(
956 uid
= get_obj_uid(obj
);
957 dd_id
= get_parent_uid(obj
);
959 SET_UID_LCP(&lc
, OBJ_ISCSI
, uid
);
961 nt
= cache_lookup(&lc
, NULL
, cb_get_node_type
);
963 attr
= &obj
->attrs
[ATTR_INDEX_ASSOC_ISCSI(ISNS_DD_ISCSI_NAME_ATTR_ID
)];
965 raw
= (scn_raw_t
*)malloc(sizeof (scn_raw_t
));
967 iscsi
= (uchar_t
*)malloc(ilen
);
968 if (raw
!= NULL
&& iscsi
!= NULL
) {
969 /* copy the iscsi storage node name */
970 (void) strcpy((char *)iscsi
, (char *)attr
->value
.ptr
);
972 raw
->type
= obj
->type
;
985 isnslog(LOG_DEBUG
, "make_raw_assoc_iscsi", "malloc failed.");
992 * ****************************************************************************
995 * Make raw SCN data with a Discovery Domain Set member association.
997 * obj - the member association object.
998 * return - the raw SCN data.
1000 * ****************************************************************************
1009 raw
= (scn_raw_t
*)malloc(sizeof (scn_raw_t
));
1011 raw
->type
= obj
->type
;
1018 raw
->dd_id
= get_obj_uid(obj
);
1019 raw
->dds_id
= get_parent_uid(obj
);
1021 isnslog(LOG_DEBUG
, "make_raw_assoc_dd", "malloc failed.");
1028 * ****************************************************************************
1031 * Generate SCN with the raw SCN data from a Network Entity object.
1033 * raw - the raw SCN data.
1036 * ****************************************************************************
1040 /* LINTED E_FUNC_ARG_UNUSED */
1048 * ****************************************************************************
1051 * Generate SCN with the raw SCN data from a Storage Node object.
1053 * raw - the raw SCN data.
1056 * ****************************************************************************
1065 text
= (scn_text_t
*)malloc(sizeof (scn_text_t
));
1068 text
->ref
= 1; /* start with 1 */
1069 text
->uid
= raw
->uid
;
1070 text
->iscsi
= raw
->iscsi
;
1072 text
->ilen
= raw
->ilen
;
1074 text
->dd_id
= raw
->dd_id
;
1075 text
->dds_id
= raw
->dds_id
;
1078 isnslog(LOG_DEBUG
, "scn_gen_iscsi", "malloc failed.");
1084 * ****************************************************************************
1087 * Generate SCN with the raw SCN data from a Portal object.
1089 * raw - the raw SCN data.
1092 * ****************************************************************************
1102 uint32_t pg_uid
, uid
;
1103 lookup_ctrl_t pg_lc
, lc
;
1109 scn_text_t
*text
, *l
= NULL
;
1115 pg_lc
.type
= OBJ_PG
;
1116 pg_lc
.id
[0] = ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
);
1117 pg_lc
.op
[0] = OP_MEMORY_IP6
;
1118 pg_lc
.data
[0].ip
= ip
;
1119 pg_lc
.id
[1] = ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID
);
1120 pg_lc
.op
[1] = OP_INTEGER
;
1121 pg_lc
.data
[1].ui
= port
;
1124 SET_UID_LCP(&lc
, OBJ_ISCSI
, 0);
1126 lc
.id
[1] = ISNS_ISCSI_NAME_ATTR_ID
;
1127 lc
.id
[2] = ISNS_ISCSI_NODE_TYPE_ATTR_ID
;
1128 lc
.data
[1].ptr
= NULL
;
1130 /* get a pg which is associated to the portal */
1131 uid
= cache_lookup(&pg_lc
, &pg_uid
, cb_pg_node
);
1132 while (pg_uid
!= 0) {
1134 lc
.data
[0].ui
= uid
;
1135 (void) cache_lookup(&lc
, NULL
, cb_clone_attrs
);
1136 name
= lc
.data
[1].ptr
;
1139 text
= (scn_text_t
*)malloc(
1140 sizeof (scn_text_t
));
1143 text
->ref
= 1; /* start with 1 */
1146 ilen
= strlen((char *)name
);
1147 ilen
+= 4 - (ilen
% 4);
1156 isnslog(LOG_DEBUG
, "scn_gen_portal",
1159 lc
.data
[1].ptr
= NULL
;
1161 isnslog(LOG_WARNING
, "scn_gen_portal",
1162 "cannot get node name.");
1166 /* get the next pg */
1167 pg_lc
.curr_uid
= pg_uid
;
1168 uid
= cache_lookup(&pg_lc
, &pg_uid
, cb_pg_node
);
1171 /* update the iscsi storage node object */
1172 raw
->event
= ISNS_OBJECT_UPDATED
;
1178 * ****************************************************************************
1181 * Generate SCN with the raw SCN data from a DD membership object.
1183 * raw - the raw SCN data.
1186 * ****************************************************************************
1190 /* LINTED E_FUNC_ARG_UNUSED */
1198 * ****************************************************************************
1201 * Make a SCN with an event and an object.
1203 * event - the event.
1205 * return - always successful (0).
1207 * ****************************************************************************
1215 scn_raw_t
*raw
= NULL
;
1217 scn_raw_t
*(*f
)(isns_obj_t
*) = make_raw
[obj
->type
];
1220 /* make raw scn data */
1224 /* trigger an scn event */
1226 (void) queue_msg_set(scn_q
, SCN_SET
, (void *)raw
);
1233 * data structure of the SCN state transition table.
1235 typedef struct scn_tbl
{
1239 int (*sf
)(scn_raw_t
*);
1244 * the SCN state transition table.
1246 static const scn_tbl_t stbl
[] = {
1247 { -1, 0, OBJ_PG
, NULL
, 0 },
1248 { -1, 0, OBJ_DD
, NULL
, 0 },
1249 { -1, 0, OBJ_DDS
, NULL
, 0 },
1251 { 0, ISNS_OBJECT_ADDED
, OBJ_ENTITY
, NULL
, 1 },
1252 { 1, ISNS_OBJECT_ADDED
, OBJ_ISCSI
, sf_gen
, 1 },
1253 { 1, ISNS_OBJECT_ADDED
, 0, NULL
, 1 },
1255 { 0, ISNS_OBJECT_UPDATED
, OBJ_ENTITY
, sf_gen
, 2 },
1256 { 2, ISNS_OBJECT_UPDATED
, 0, NULL
, 2 },
1257 { 2, ISNS_OBJECT_ADDED
, OBJ_ISCSI
, sf_gen
, 2 },
1258 { 2, ISNS_OBJECT_ADDED
, 0, NULL
, 2 },
1260 { 0, ISNS_OBJECT_REMOVED
, OBJ_ENTITY
, NULL
, 3 },
1261 { 0, ISNS_OBJECT_REMOVED
, 0, sf_gen
, 4 },
1262 { 3, ISNS_OBJECT_REMOVED
, OBJ_ISCSI
, sf_gen
, 3 },
1263 { 3, ISNS_OBJECT_REMOVED
, 0, NULL
, 3 },
1264 { 4, ISNS_OBJECT_REMOVED
, 0, sf_gen
, 4 },
1266 { 0, ISNS_MEMBER_ADDED
, OBJ_ASSOC_ISCSI
, sf_gen
, 5 },
1267 { 5, ISNS_MEMBER_ADDED
, OBJ_ASSOC_ISCSI
, sf_gen
, 5 },
1269 { 0, ISNS_MEMBER_ADDED
, OBJ_ASSOC_DD
, sf_gen
, 6 },
1270 { 6, ISNS_MEMBER_ADDED
, OBJ_ASSOC_DD
, sf_gen
, 6 },
1272 { 0, ISNS_MEMBER_REMOVED
, OBJ_ASSOC_ISCSI
, sf_gen
, 7 },
1273 { 7, ISNS_MEMBER_REMOVED
, OBJ_ASSOC_ISCSI
, sf_gen
, 7 },
1275 { 0, ISNS_MEMBER_REMOVED
, OBJ_ASSOC_DD
, sf_gen
, 8 },
1276 { 8, ISNS_MEMBER_REMOVED
, OBJ_ASSOC_DD
, sf_gen
, 8 },
1278 { -1, 0, 0, sf_error
, -1 }
1282 * ****************************************************************************
1285 * Dispatch one SCN to one SCN entry.
1287 * event - the event.
1288 * p - the SCN entry.
1290 * return - always successful (0).
1292 * ****************************************************************************
1301 scn_t
*s
, *r
= NULL
;
1302 scn_list_t
*l
, **lp
;
1307 if (s
->event
== event
) {
1310 if (l
->data
.text
->uid
== t
->uid
) {
1316 } while (l
!= NULL
);
1323 l
= (scn_list_t
*)malloc(sizeof (scn_list_t
));
1326 s
= (scn_t
*)malloc(sizeof (scn_t
));
1338 isnslog(LOG_DEBUG
, "scn_disp1",
1339 "malloc scn failed.\n");
1349 isnslog(LOG_DEBUG
, "scn_disp1",
1350 "malloc list failed.\n");
1357 * ****************************************************************************
1360 * Dispatch one SCN to every SCN entry and update the dispatch status.
1362 * event - the event.
1364 * return - always successful (0).
1366 * ****************************************************************************
1374 scn_registry_t
*registry
, *p
;
1381 registry
= scn_registry
;
1387 if (e
& ISNS_MEMBER_ADDED
) {
1388 e
|= ISNS_OBJECT_ADDED
;
1389 } else if (e
& ISNS_MEMBER_REMOVED
) {
1390 e
|= ISNS_OBJECT_REMOVED
;
1395 if (SCN_TEST(e
, p
->bitmap
, p
->uid
, t
->uid
, t
->nt
)) {
1396 if (p
->bitmap
& ISNS_MGMT_REG
) {
1397 /* management scn are not bound */
1398 /* by discovery domain service. */
1402 /* lock the cache for reading */
1403 (void) cache_lock_read();
1404 /* verify common dd */
1406 dd_id
= get_common_dd(
1410 } while (dd_id
> 0 &&
1411 is_dd_active(dd_id
) == 0);
1412 /* unlock the cache */
1413 (void) cache_unlock_nosync();
1416 (void) scn_disp1(e
, p
, t
);
1424 while (text
!= NULL
) {
1426 /* clean up the scn text(s) which nobody cares about. */
1427 free_scn_text(text
);
1432 /* scn(s) are dispatched. */
1440 * ****************************************************************************
1443 * State transition function which generates and dispatches SCN(s).
1445 * raw - the raw SCN data.
1446 * return - always successful (0).
1448 * ****************************************************************************
1457 scn_text_t
*(*gen
)(scn_raw_t
*);
1458 scn_text_t
*text
= NULL
;
1460 gen
= scn_gen
[raw
->type
];
1467 (void) scn_disp(event
, text
);
1474 * ****************************************************************************
1477 * State transition function for an error state. It free any SCN(s)
1478 * which have been generated and dispatched previously.
1480 * raw - the raw SCN data.
1481 * return - always successful (0).
1483 * ****************************************************************************
1487 /* LINTED E_FUNC_ARG_UNUSED */
1497 * ****************************************************************************
1500 * Performs the state transition when a SCN event occurs.
1502 * state - the previous state.
1503 * raw - the raw SCN data.
1504 * return - the next state.
1506 * ****************************************************************************
1514 uint32_t event
= raw
->event
;
1515 isns_type_t type
= raw
->type
;
1517 int new_state
= state
;
1519 const scn_tbl_t
*tbl
;
1523 if ((tbl
->state
== -1 || tbl
->state
== state
) &&
1524 (tbl
->event
== 0 || tbl
->event
== event
) &&
1525 (tbl
->type
== 0 || tbl
->type
== type
)) {
1526 if (tbl
->next_state
!= 0) {
1527 new_state
= tbl
->next_state
;
1529 if (tbl
->sf
!= NULL
) {
1537 if (new_state
== -1) {
1538 isnslog(LOG_DEBUG
, "scn_transition",
1539 "prev state: %d new event: 0x%x new object: %d.\n",
1540 state
, event
, type
);
1550 * ****************************************************************************
1553 * Create socket connection with peer network portal.
1555 * sz - the size of the ip addr.
1556 * in - the ipv4 address.
1557 * in6 - the ipv6 address.
1558 * port2- the port info.
1559 * return - the socket descriptor.
1561 * ****************************************************************************
1567 /* LINTED E_FUNC_ARG_UNUSED */
1575 struct sockaddr sin
;
1576 struct sockaddr_in in
;
1577 struct sockaddr_in6 in6
;
1583 tcp
= (port2
& 0x10000) == 0 ? 1 : 0;
1584 port
= (uint16_t)(port2
& 0xFFFF);
1585 if (sz
== sizeof (in_addr_t
)) {
1587 so
= socket(AF_INET
, SOCK_STREAM
, 0);
1589 ca
.in
.sin_family
= AF_INET
;
1590 ca
.in
.sin_port
= htons(port
);
1591 ca
.in
.sin_addr
.s_addr
= in
;
1592 if (connect(so
, &ca
.sin
, sizeof (ca
.in
)) !=
1594 isnslog(LOG_DEBUG
, "connect_to",
1595 "connect() failed %%m.");
1600 isnslog(LOG_DEBUG
, "connect_to",
1601 "socket() failed %%m.");
1604 /* FIXME: UDP support */
1605 isnslog(LOG_DEBUG
, "connect_to", "No UDP support.");
1608 /* FIXME: IPv6 support */
1609 isnslog(LOG_DEBUG
, "connect_to", "No IPv6 support.");
1616 * ****************************************************************************
1619 * Emit the SCN to any portal of the peer storage node.
1621 * list - the list of portal.
1622 * pdu - the SCN packet.
1623 * pl - the SCN packet payload length.
1624 * return - always successful (0).
1626 * ****************************************************************************
1639 isns_pdu_t
*rsp
= NULL
;
1642 pdu
->version
= htons((uint16_t)ISNSP_VERSION
);
1643 pdu
->func_id
= htons((uint16_t)ISNS_SCN
);
1644 pdu
->xid
= htons(get_server_xid());
1649 so
= connect_to(p
->sz
, p
->ip
.in
, p
->ip
.in6
, p
->port
);
1651 if (isns_send_pdu(so
, pdu
, pl
) == 0) {
1652 /* This may help Solaris iSCSI Initiator */
1653 /* not to panic frequently. */
1654 (void) isns_rcv_pdu(so
, &rsp
, &rsp_sz
,
1655 ISNS_RCV_SHORT_TIMEOUT
);
1657 isnslog(LOG_DEBUG
, "emit_scn",
1658 "sending packet failed.");
1678 * ****************************************************************************
1681 * Trigger one SCN for one SCN entry.
1683 * t - the time that SCN is being triggered.
1684 * p - the SCN entry.
1685 * return - always successful (0).
1687 * ****************************************************************************
1697 isns_pdu_t
*pdu
= NULL
;
1711 char buff
[1024] = { 0 };
1712 char *logbuff
= buff
;
1715 ec
= pdu_reset_scn(&pdu
, &pl
, &sz
);
1720 /* add destination attribute */
1721 ec
= pdu_add_tlv(&pdu
, &pl
, &sz
,
1722 ISNS_ISCSI_NAME_ATTR_ID
,
1724 (void *)p
->name
, 0);
1730 sprintf(logbuff
, "==>%s ", p
->name
);
1731 logbuff
+= strlen(logbuff
);
1735 u
.i64
= BE_64((uint64_t)t
);
1736 ec
= pdu_add_tlv(&pdu
, &pl
, &sz
,
1737 ISNS_TIMESTAMP_ATTR_ID
,
1742 while (s
!= NULL
&& ec
== 0) {
1743 u
.i32
= htonl(s
->event
);
1744 ec
= pdu_add_tlv(&pdu
, &pl
, &sz
,
1745 ISNS_ISCSI_SCN_BITMAP_ATTR_ID
,
1749 sprintf(logbuff
, "EVENT [%d] ", s
->event
);
1750 logbuff
+= strlen(logbuff
);
1753 while (l
!= NULL
&& ec
== 0) {
1756 ec
= pdu_add_tlv(&pdu
, &pl
, &sz
,
1757 ISNS_ISCSI_NAME_ATTR_ID
,
1758 x
->ilen
, (void *)x
->iscsi
, 0);
1760 sprintf(logbuff
, "FROM [%s] ", x
->iscsi
);
1761 logbuff
+= strlen(logbuff
);
1765 (ISNS_MEMBER_ADDED
|
1766 ISNS_MEMBER_REMOVED
))) {
1767 /* management SCN */
1768 u
.i32
= htonl(x
->dd_id
);
1769 ec
= pdu_add_tlv(&pdu
, &pl
, &sz
,
1771 4, (void *)&u
.i32
, 1);
1773 sprintf(logbuff
, "IN DD [%d] ",
1775 logbuff
+= strlen(logbuff
);
1779 /* add(remove) dd to(from) dd-set */
1780 u
.i32
= htonl(x
->dd_id
);
1781 ec
= pdu_add_tlv(&pdu
, &pl
, &sz
,
1783 4, (void *)&u
.i32
, 1);
1784 u
.i32
= htonl(x
->dds_id
);
1786 ec
= pdu_add_tlv(&pdu
, &pl
, &sz
,
1788 4, (void *)&u
.i32
, 1);
1791 sprintf(logbuff
, "FROM [%d] ", x
->dd_id
);
1792 logbuff
+= strlen(logbuff
);
1793 sprintf(logbuff
, "IN [%d] ", x
->dds_id
);
1794 logbuff
+= strlen(logbuff
);
1805 isnslog(LOG_DEBUG
, "scn_trigger1", buff
);
1807 ec
= emit_scn(p
->portal
.l
, pdu
, pl
);
1809 isnslog(LOG_DEBUG
, "scn_trigger1", " failed.\n");
1818 * ****************************************************************************
1821 * Trigger one SCN for every SCN entry.
1823 * return - always successful (0).
1825 * ****************************************************************************
1838 if (p
->scn
!= NULL
) {
1839 (void) scn_trigger1(t
, p
);
1852 * ****************************************************************************
1855 * Load one SCN entry and add it to the SCN entry list.
1857 * uid - the Storage Node object UID.
1858 * node - the Storage Node name.
1859 * nlen - the length of the name.
1860 * bitmap - the SCN bitmap.
1861 * return - error code.
1863 * ****************************************************************************
1875 scn_registry_t
*list
;
1878 list
= (scn_registry_t
*)malloc(sizeof (scn_registry_t
));
1879 name
= (uchar_t
*)malloc(nlen
);
1881 if (list
!= NULL
&& name
!= NULL
) {
1883 (void) strcpy((char *)name
, (char *)node
);
1886 list
->bitmap
= bitmap
;
1887 list
->portal
.l
= NULL
;
1890 ASSERT(scn_q
== NULL
);
1891 (void) scn_list_add(list
);
1895 ec
= ISNS_RSP_INTERNAL_ERROR
;
1902 * ****************************************************************************
1904 * verify_scn_portal:
1905 * Extract and verify portals for every SCN entry(s) after they are
1906 * loaded from data store, for those which do not have a SCN portal,
1907 * remove it from the SCN entry list.
1909 * return - 1: error occurs, otherwise 0.
1911 * ****************************************************************************
1917 scn_registry_t
**pp
, *e
;
1921 while (*pp
!= NULL
) {
1923 p
= extract_scn_portal(e
->name
);
1925 if (scn_add_portal(e
, p
) != 0) {
1929 if (e
->portal
.l
!= NULL
) {
1932 /* remove this entry */
1936 /* free the unused portal(s) */
1944 * ****************************************************************************
1949 * node - the Storage Node name.
1950 * nlen - the length of the name.
1951 * bitmap - the SCN bitmap.
1952 * return - error code.
1954 * ****************************************************************************
1975 ISNS_MEMBER_REMOVED
|
1980 mgmt
< ISNS_MGMT_REG
||
1981 is_control_node(node
) == 0)) ||
1982 (p
= extract_scn_portal(node
)) == NULL
) {
1983 return (ISNS_RSP_SCN_REGIS_REJECTED
);
1986 e
= (scn_registry_t
*)malloc(sizeof (scn_registry_t
));
1987 name
= (uchar_t
*)malloc(nlen
);
1988 if (e
!= NULL
&& name
!= NULL
) {
1989 lc
.type
= OBJ_ISCSI
;
1991 lc
.id
[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID
);
1992 lc
.data
[0].ptr
= node
;
1993 lc
.op
[0] = OP_STRING
;
1995 lc
.data
[2].ui
= bitmap
;
1996 ec
= cache_lookup(&lc
, &uid
, cb_update_scn_bitmap
);
1998 ec
= ISNS_RSP_SCN_REGIS_REJECTED
;
2002 (void) strcpy((char *)name
, (char *)node
);
2009 (void) queue_msg_set(scn_q
, SCN_ADD
, (void *)e
);
2012 ec
= ISNS_RSP_INTERNAL_ERROR
;
2025 * ****************************************************************************
2028 * Remove a SCN entry.
2030 * node - the Storage Node name.
2031 * return - error code.
2033 * ****************************************************************************
2045 lc
.type
= OBJ_ISCSI
;
2047 lc
.id
[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID
);
2048 lc
.data
[0].ptr
= node
;
2049 lc
.op
[0] = OP_STRING
;
2052 ec
= cache_lookup(&lc
, &uid
, cb_update_scn_bitmap
);
2053 if (ec
== 0 && uid
!= 0) {
2054 (void) queue_msg_set(scn_q
, SCN_REMOVE
, (void *)uid
);
2061 * ****************************************************************************
2063 * remove_scn_portal:
2064 * Remove a portal from every SCN entry.
2066 * uid - the Portal object UID.
2067 * return - alrays successful (0).
2069 * ****************************************************************************
2076 (void) queue_msg_set(scn_q
, SCN_REMOVE_P
, (void *)uid
);
2082 * ****************************************************************************
2085 * The entry point of the SCN thread. It listens on the SCN message
2086 * queue and process every SCN related stuff.
2091 * ****************************************************************************
2095 /* LINTED E_FUNC_ARG_UNUSED */
2105 msg
= queue_msg_get(scn_q
);
2108 (void) scn_list_add((scn_registry_t
*)msg
->data
);
2111 (void) scn_list_remove((uint32_t)msg
->data
);
2114 (void) scn_remove_portal((uint32_t)msg
->data
);
2117 raw
= (scn_raw_t
*)msg
->data
;
2118 state
= scn_transition(state
, raw
);
2119 /* free the raw data */
2123 if (scn_dispatched
!= 0) {
2124 (void) scn_trigger();
2127 /* clean the scn(s) */
2129 /* reset the state */
2131 /* reset the scn_dispatched flag */
2135 queue_msg_free(msg
);
2140 queue_msg_free(msg
);