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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
36 #include "isns_server.h"
37 #include "isns_msgq.h"
38 #include "isns_htab.h"
39 #include "isns_cache.h"
43 #include "isns_func.h"
44 #include "isns_dseng.h"
47 #include "isns_utils.h"
54 extern int verbose_mc
;
55 extern void print_object(char *, isns_obj_t
*);
58 extern msg_queue_t
*sys_q
;
59 extern msg_queue_t
*scn_q
;
61 extern pthread_mutex_t el_mtx
;
63 extern int cache_flag
;
72 /* type of parent object */
73 const int TYPE_OF_PARENT
[MAX_OBJ_TYPE_FOR_SIZE
] = {
86 ASSOC_ISCSI_PARENT_TYPE
,
90 /* number of children object type */
91 const int NUM_OF_CHILD
[MAX_OBJ_TYPE
] = {
101 /* type of a child object */
102 const int TYPE_OF_CHILD
[MAX_OBJ_TYPE
][MAX_CHILD_TYPE
] = {
104 { OBJ_ISCSI
, OBJ_PORTAL
},
112 /* number of attributes of certain type of object */
113 const int NUM_OF_ATTRS
[MAX_OBJ_TYPE_FOR_SIZE
] = {
121 0, /* MAX_OBJ_TYPE */
126 NUM_OF_ASSOC_ISCSI_ATTRS
,
127 NUM_OF_ASSOC_DD_ATTRS
130 /* the tag of UID of each type of object */
131 static const int UID_TAG
[MAX_OBJ_TYPE_FOR_SIZE
] = {
133 ISNS_ENTITY_INDEX_ATTR_ID
,
134 ISNS_ISCSI_NODE_INDEX_ATTR_ID
,
135 ISNS_PORTAL_INDEX_ATTR_ID
,
136 ISNS_PG_INDEX_ATTR_ID
,
138 ISNS_DD_SET_ID_ATTR_ID
,
139 0, /* MAX_OBJ_TYPE */
144 ISNS_DD_ISCSI_INDEX_ATTR_ID
,
148 /* the index of UID of each type of object */
149 const int UID_ATTR_INDEX
[MAX_OBJ_TYPE_FOR_SIZE
] = {
151 ATTR_INDEX_ENTITY(ISNS_ENTITY_INDEX_ATTR_ID
),
152 ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_INDEX_ATTR_ID
),
153 ATTR_INDEX_PORTAL(ISNS_PORTAL_INDEX_ATTR_ID
),
154 ATTR_INDEX_PG(ISNS_PG_INDEX_ATTR_ID
),
155 ATTR_INDEX_DD(ISNS_DD_ID_ATTR_ID
),
156 ATTR_INDEX_DDS(ISNS_DD_SET_ID_ATTR_ID
),
157 0, /* MAX_OBJ_TYPE */
162 ATTR_INDEX_ASSOC_ISCSI(ISNS_DD_ISCSI_INDEX_ATTR_ID
),
163 ATTR_INDEX_ASSOC_DD(ISNS_DD_ID_ATTR_ID
)
166 /* the index of the key attributes of each type of object */
167 static const int KEY_ATTR_INDEX
[MAX_OBJ_TYPE
][MAX_KEY_ATTRS
] = {
169 { ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID
), 0 },
170 { ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID
),
172 { ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID
),
173 ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID
),
175 { ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID
),
176 ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
),
177 ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID
) },
178 { ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID
), 0 },
179 { ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID
), 0 }
182 /* the operating methods for key attributes of each type of object */
183 static const int KEY_ATTR_OP
[MAX_OBJ_TYPE
][MAX_KEY_ATTRS
] = {
187 { OP_MEMORY_IP6
, OP_INTEGER
, 0 },
188 { OP_STRING
, OP_MEMORY_IP6
, OP_INTEGER
},
193 /* the size of each type of object */
194 static const int SIZEOF_OBJ
[MAX_OBJ_TYPE_FOR_SIZE
] = {
196 sizeof (isns_entity_t
),
197 sizeof (isns_iscsi_t
),
198 sizeof (isns_portal_t
),
207 sizeof (isns_assoc_iscsi_t
),
208 sizeof (isns_assoc_dd_t
)
212 const int NUM_OF_REF
[MAX_OBJ_TYPE_FOR_SIZE
] = {
214 static const int NUM_OF_REF
[MAX_OBJ_TYPE_FOR_SIZE
] = {
232 /* the type of the reference object */
233 static const int TYPE_OF_REF
[MAX_OBJ_TYPE
][MAX_REF_COUNT
+ 1] = {
236 { OBJ_PG
, OBJ_PORTAL
, 0 },
237 { OBJ_PG
, OBJ_ISCSI
, 0 },
238 { 0, OBJ_ISCSI
, OBJ_PORTAL
},
243 /* the operating method for match operation of the reference object */
244 #define MAX_REF_MATCH (2)
245 static const int REF_MATCH_OPS
[MAX_OBJ_TYPE
][MAX_REF_MATCH
] = {
249 { OP_MEMORY_IP6
, OP_INTEGER
},
255 /* the index of the attribute of being matched object */
256 static const int REF_MATCH_ID1
[MAX_OBJ_TYPE
][MAX_REF_MATCH
] = {
259 { ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID
), 0 },
260 { ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID
),
261 ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID
) },
267 /* the index of the attribute of matching object */
268 static const int REF_MATCH_ID2
[MAX_OBJ_TYPE
][MAX_REF_MATCH
] = {
271 { ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID
), 0 },
272 { ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
),
273 ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID
) },
282 static uint32_t get_reg_period();
283 static char *make_unique_name(int *, uint32_t);
284 static lookup_ctrl_t
*set_lookup_ctrl(lookup_ctrl_t
*, isns_obj_t
*);
285 static int setup_ref_lcp(lookup_ctrl_t
*,
286 const isns_obj_t
*, const isns_obj_t
*);
287 static int setup_deref_lcp(lookup_ctrl_t
*,
288 const isns_obj_t
*, isns_type_t
);
289 static int cb_get_parent(void *, void *);
290 static int cb_node_child(void *, void *);
291 static int cb_set_ref(void *, void *);
292 static int cb_clear_ref(void *, void *);
293 static int cb_add_child(void *, void *);
294 static int cb_remove_child(void *, void *);
295 static int cb_verify_ref(void *, void *);
296 static int cb_ref_new2old(void *, void *);
297 static int cb_new_ref(void *, void *);
298 static int ref_new2old(
299 lookup_ctrl_t
*, isns_type_t
, uint32_t, const isns_obj_t
*);
300 static int ref_new2new(
301 lookup_ctrl_t
*, const isns_obj_t
*, const isns_obj_t
*);
302 static int new_ref(const isns_obj_t
*, const isns_obj_t
*);
303 static uint32_t setup_parent_lcp(lookup_ctrl_t
*, isns_obj_t
*);
304 static int set_obj_offline(isns_obj_t
*);
305 static int copy_attrs(isns_obj_t
*, const isns_obj_t
*);
307 static isns_obj_t
*make_default_pg(const isns_obj_t
*, const isns_obj_t
*);
308 static isns_obj_t
*(*const make_ref
[MAX_OBJ_TYPE
])
309 (const isns_obj_t
*, const isns_obj_t
*) = {
319 static uint32_t entity_hval(void *, uint16_t, uint32_t *);
320 static uint32_t iscsi_hval(void *, uint16_t, uint32_t *);
321 static uint32_t portal_hval(void *, uint16_t, uint32_t *);
322 static uint32_t pg_hval(void *, uint16_t, uint32_t *);
323 static uint32_t dd_hval(void *, uint16_t, uint32_t *);
324 static uint32_t dds_hval(void *, uint16_t, uint32_t *);
325 static uint32_t (*const hval_func
[MAX_OBJ_TYPE
])
326 (void *, uint16_t, uint32_t *) = {
337 * ****************************************************************************
340 * caculate the hash value of a network entity object.
342 * p - the pointer pointers to network entity object or
343 * the lookup control data, both have the key attribute
344 * of a network entity object.
345 * chunk- which chunk of the hash table.
346 * flags- pointer to flags.
347 * return - the hash value.
349 * ****************************************************************************
354 /* LINTED E_FUNC_ARG_UNUSED */
363 if ((*flags
& FLAGS_CTRL_MASK
) == 0) {
364 /* p pointers to a network entity object */
365 obj
= (isns_obj_t
*)p
;
366 key
= obj
->attrs
[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID
)].
369 /* p is lookup control data */
370 lcp
= (lookup_ctrl_t
*)p
;
371 key
= lcp
->data
[0].ptr
;
374 return (htab_compute_hval(key
));
378 * ****************************************************************************
381 * caculate the hash value of an iscsi storage node object.
383 * p - the pointer pointers to iscsi storage node object or
384 * the lookup control data, both have the key attribute
385 * of an iscsi storage node object.
386 * chunk- which chunk of the hash table.
387 * flags- pointer to flags.
388 * return - the hash value.
390 * ****************************************************************************
395 /* LINTED E_FUNC_ARG_UNUSED */
404 if ((*flags
& FLAGS_CTRL_MASK
) == 0) {
405 /* p pointers to an iscsi storage node object */
406 obj
= (isns_obj_t
*)p
;
407 key
= obj
->attrs
[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID
)].
410 /* p is lookup control data */
411 lcp
= (lookup_ctrl_t
*)p
;
412 key
= lcp
->data
[0].ptr
;
415 return (htab_compute_hval(key
));
419 * ****************************************************************************
422 * caculate the hash value of a portal object.
424 * p - the pointer pointers to a portal object or the lookup control
425 * data, both have the key attributes of a portal object.
426 * chunk- which chunk of the hash table.
427 * flags- pointer to flags.
428 * return - the hash value.
430 * ****************************************************************************
435 /* LINTED E_FUNC_ARG_UNUSED */
440 char buff
[INET6_ADDRSTRLEN
+ 8] = { 0 };
441 char buff2
[8] = { 0 };
449 if ((*flags
& FLAGS_CTRL_MASK
) == 0) {
450 /* p pointers to a portal object */
451 obj
= (isns_obj_t
*)p
;
452 ip
= obj
->attrs
[ATTR_INDEX_PORTAL
453 (ISNS_PORTAL_IP_ADDR_ATTR_ID
)].value
.ip
;
454 port
= obj
->attrs
[ATTR_INDEX_PORTAL
455 (ISNS_PORTAL_PORT_ATTR_ID
)].value
.ui
;
457 /* p is lookup control data */
458 lcp
= (lookup_ctrl_t
*)p
;
459 ip
= lcp
->data
[0].ip
;
460 port
= lcp
->data
[1].ui
;
463 key
= (uchar_t
*)inet_ntop(AF_INET6
, (void *)ip
,
464 buff
, sizeof (buff
));
465 (void) snprintf(buff2
, sizeof (buff2
), "%d", port
);
466 (void) strcat((char *)key
, buff2
);
468 return (htab_compute_hval(key
));
472 * ****************************************************************************
475 * caculate the hash value of a portal group object.
477 * p - the pointer pointers to a portal group object or the lookup
478 * control data, both have the key attributes of a portal object.
479 * chunk- which chunk of the hash table.
480 * flags- pointer to flags.
481 * return - the hash value.
483 * ****************************************************************************
492 char buff
[INET6_ADDRSTRLEN
+ 8] = { 0 };
493 char buff2
[8] = { 0 };
498 in6_addr_t
*ip
= NULL
;
501 if ((*flags
& FLAGS_CTRL_MASK
) == 0) {
502 /* p is a portal group object */
503 obj
= (isns_obj_t
*)p
;
505 /* the first chunk */
506 key
= obj
->attrs
[ATTR_INDEX_PG
507 (ISNS_PG_ISCSI_NAME_ATTR_ID
)].value
.ptr
;
510 ip
= obj
->attrs
[ATTR_INDEX_PG
511 (ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
)].value
.ip
;
512 port
= obj
->attrs
[ATTR_INDEX_PG
513 (ISNS_PG_PORTAL_PORT_ATTR_ID
)].value
.ui
;
516 /* p is a lookup control data */
517 lcp
= (lookup_ctrl_t
*)p
;
518 /* clear the chunk flags */
519 *flags
&= ~FLAGS_CHUNK_MASK
;
520 if (lcp
->op
[0] == OP_STRING
) {
521 /* the first chunk */
522 key
= lcp
->data
[0].ptr
;
525 ip
= lcp
->data
[0].ip
;
526 port
= lcp
->data
[1].ui
;
532 key
= (uchar_t
*)inet_ntop(AF_INET6
, (void *)ip
,
533 buff
, sizeof (buff
));
534 (void) snprintf(buff2
, sizeof (buff2
), "%d", port
);
535 (void) strcat((char *)key
, buff2
);
538 return (htab_compute_hval(key
));
542 * ****************************************************************************
545 * caculate the hash value of a DD object.
547 * p - the pointer pointers to a DD object or the lookup control data,
548 * both have the key attributes of a DD object.
549 * chunk- which chunk of the hash table.
550 * flags- pointer to flags.
551 * return - the hash value.
553 * ****************************************************************************
558 /* LINTED E_FUNC_ARG_UNUSED */
567 if ((*flags
& FLAGS_CTRL_MASK
) == 0) {
568 /* p is a DD object */
569 obj
= (isns_obj_t
*)p
;
570 key
= obj
->attrs
[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID
)].
573 /* p is a lookup control data */
574 lcp
= (lookup_ctrl_t
*)p
;
575 key
= lcp
->data
[0].ptr
;
578 return (htab_compute_hval(key
));
582 * ****************************************************************************
585 * caculate the hash value of a DD-set object.
587 * p - the pointer pointers to a DD-set object or the lookup control data,
588 * both have the key attributes of a DD-set object.
589 * chunk- which chunk of the hash table.
590 * flags- pointer to flags.
591 * return - the hash value.
593 * ****************************************************************************
598 /* LINTED E_FUNC_ARG_UNUSED */
607 if ((*flags
& FLAGS_CTRL_MASK
) == 0) {
608 /* p is a DD-set object */
609 obj
= (isns_obj_t
*)p
;
610 key
= obj
->attrs
[ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID
)].
613 /* p is lookup control data */
614 lcp
= (lookup_ctrl_t
*)p
;
615 key
= lcp
->data
[0].ptr
;
618 return (htab_compute_hval(key
));
622 * ****************************************************************************
625 * caculate the hash value of an object.
627 * p - the pointer pointers to an object or lookup control data,
628 * both has the object type and the key attributes of an object.
629 * chunk- which chunk of the hash table.
630 * flags- pointer to flags.
631 * return - the hash value.
633 * ****************************************************************************
642 isns_type_t type
= ((isns_obj_t
*)p
)->type
;
644 return (hval_func
[type
](p
, chunk
, flags
));
648 * ****************************************************************************
651 * get the UID of an object.
653 * p - the pointer pointers to an object.
656 * ****************************************************************************
663 isns_obj_t
*obj
= (isns_obj_t
*)p
;
664 isns_attr_t
*attr
= &obj
->attrs
[UID_ATTR_INDEX
[obj
->type
]];
665 uint32_t uid
= attr
->value
.ui
;
670 * ****************************************************************************
673 * set the UID of an object.
675 * p - the pointer pointers to an object.
679 * ****************************************************************************
687 isns_obj_t
*obj
= (isns_obj_t
*)p
;
688 isns_attr_t
*attr
= &obj
->attrs
[UID_ATTR_INDEX
[obj
->type
]];
690 /* set the tag, len and value */
691 attr
->tag
= UID_TAG
[obj
->type
];
693 attr
->value
.ui
= uid
;
699 * ****************************************************************************
702 * compare between two objects or an object with a lookup control data.
704 * p1 - the pointer points to an object.
705 * p2 - the pointer points to an object or a lookup control data.
706 * flags- 0: p2 is an object; otherwise p2 is a lookup control data.
707 * return - the comparsion result.
709 * ****************************************************************************
718 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
719 lookup_ctrl_t buff
= { 0 };
724 lcp
= set_lookup_ctrl(&buff
, (isns_obj_t
*)p2
);
726 lcp
= (lookup_ctrl_t
*)p2
;
727 uid
= get_obj_uid(obj
);
728 /* the object are linked with decending order by */
729 /* the object UID, if the object UID is greater than */
730 /* or equal to the current UID, it needs to compare */
731 /* for the next one. */
732 if (lcp
->curr_uid
!= 0 && uid
>= lcp
->curr_uid
) {
737 return (key_cmp(lcp
, obj
));
741 * ****************************************************************************
744 * replace an existing object with the new one.
746 * p1 - the pointer points to an object being replaced.
747 * p2 - the pointer points to a new object.
748 * uid_p- points to uid for returning.
749 * flag - 0: do not free the source object, otherwise free it.
750 * return - error code.
752 * ****************************************************************************
764 #ifndef SKIP_SRC_AUTH
765 uint32_t *pp_dst
, *pp_src
, swap
;
769 isns_obj_t
*dst
= (isns_obj_t
*)p1
;
770 isns_obj_t
*src
= (isns_obj_t
*)p2
;
772 if (src
->type
== OBJ_DD
|| src
->type
== OBJ_DDS
) {
773 /* replace not allowed */
774 return (ERR_NAME_IN_USE
);
777 online
= is_obj_online(dst
);
779 /* set cache update flag */
782 /* update parent uid */
783 #ifndef SKIP_SRC_AUTH
784 pp_dst
= get_parent_p(dst
);
785 if (pp_dst
!= NULL
) {
786 pp_src
= get_parent_p(src
);
795 /* update all of attributes */
796 if (copy_attrs(dst
, src
) != 0) {
797 return (ISNS_RSP_INTERNAL_ERROR
);
800 /* free up the src object */
802 (void) free_object(src
);
803 } else if (online
== 0) {
804 (void) set_obj_uid(src
, get_obj_uid(dst
));
805 (void) set_obj_offline(src
);
808 /* update data store */
810 ec
= write_data(DATA_UPDATE
, dst
);
812 /* we should never have duplicated entry in data store */
813 ec
= ISNS_RSP_INTERNAL_ERROR
;
819 (void) make_scn((online
== 0) ?
825 *uid_p
= get_obj_uid(dst
);
833 * ****************************************************************************
836 * post function after adding a new object.
838 * p - object which has been added.
839 * return - error code.
841 * ****************************************************************************
850 isns_obj_t
*obj
= (isns_obj_t
*)p
;
852 /* add the new object to data store */
854 ec
= write_data(DATA_ADD
, obj
);
858 if (ec
== 0 && scn_q
!= NULL
) {
859 (void) make_scn(ISNS_OBJECT_ADDED
, obj
);
866 * ****************************************************************************
869 * initialize the object hash tables.
871 * c - points to the cache.
872 * return - error code.
874 * ****************************************************************************
886 * allocate an array of pointer for the object hash tables.
888 c
->t
= (struct htab
**)calloc(sizeof (struct htab
*), MAX_OBJ_TYPE
);
894 * hash table for network entity objects.
896 t
= htab_create(UID_FLAGS_SEQ
, 8, 1);
899 c
->t
[OBJ_ENTITY
] = t
;
905 * hash table for iscsi storage node objects.
907 t
= htab_create(UID_FLAGS_SEQ
, 8, 1);
916 * hash table for portal objects.
918 t
= htab_create(UID_FLAGS_SEQ
, 8, 1);
921 c
->t
[OBJ_PORTAL
] = t
;
927 * hash table for portal group objects.
929 t
= htab_create(UID_FLAGS_SEQ
, 8, 2);
938 * hash table for discovery domain objects.
940 t
= htab_create(0, 6, 1);
949 * hash table for discovery domain set objects.
951 t
= htab_create(0, 4, 1);
963 * ****************************************************************************
966 * get the ref pointer of the portal group object.
968 * obj - portal group object.
969 * return - ref pointer.
971 * ****************************************************************************
980 obj
->type
== OBJ_PG
? &((isns_pg_t
*)obj
)->ref
[n
] : NULL
;
995 return (*get_ref_np(obj
, n
));
1004 isns_type_t t
= obj
->type
;
1007 while (i
< NUM_OF_REF
[t
]) {
1008 if (rt
== TYPE_OF_REF
[t
][i
+ 1]) {
1009 return (get_ref_np(obj
, i
));
1023 uint32_t *refp
= get_ref_p(obj
, type
);
1027 /* LINTED E_NOP_ELSE_STMT */
1036 * ****************************************************************************
1039 * get the pointer of the parent object.
1042 * return - parent object pointer.
1044 * ****************************************************************************
1048 const isns_obj_t
*obj
1052 switch (obj
->type
) {
1054 pp
= &((isns_iscsi_t
*)obj
)->puid
;
1057 pp
= &((isns_portal_t
*)obj
)->puid
;
1060 pp
= &((isns_pg_t
*)obj
)->puid
;
1062 case OBJ_ASSOC_ISCSI
:
1063 pp
= &((isns_assoc_iscsi_t
*)obj
)->puid
;
1066 pp
= &((isns_assoc_dd_t
*)obj
)->puid
;
1078 const isns_obj_t
*obj
1081 uint32_t *pp
= get_parent_p(obj
);
1090 * ****************************************************************************
1093 * get the pointer of the UID array of the n'th child of an object.
1096 * n - the child index.
1097 * return - the pointer of the UID array.
1099 * ****************************************************************************
1108 obj
->type
== OBJ_ENTITY
? &((isns_entity_t
*)obj
)->cuid
[n
] : NULL
;
1114 * ****************************************************************************
1117 * get the UID array of the n'th child of an object.
1120 * n - the child index.
1121 * return - the UID array.
1123 * ****************************************************************************
1135 uint32_t **pp
= get_child_np(obj
, n
);
1146 * ****************************************************************************
1149 * get the pointer of the UID array of the child matching the type.
1152 * child_type - the child object type.
1153 * return - the pointer of the UID array.
1155 * ****************************************************************************
1163 uint32_t **pp
= NULL
;
1165 while (i
< NUM_OF_CHILD
[base
->type
]) {
1166 if (child_type
== TYPE_OF_CHILD
[base
->type
][i
]) {
1167 pp
= get_child_np(base
, i
);
1177 * ****************************************************************************
1180 * get the UID array of the child object matching the type.
1183 * child_type - the child object type.
1184 * return - the UID array.
1186 * ****************************************************************************
1194 uint32_t **pp
= get_child_p(base
, child_type
);
1204 * ****************************************************************************
1207 * compare the object against the lookup control data.
1209 * lcp - the lookup control data.
1211 * return - comparison result.
1213 * ****************************************************************************
1223 while (i
< MAX_LOOKUP_CTRL
&& lcp
->op
[i
] > 0 && match
) {
1224 isns_attr_t
*attr
= &obj
->attrs
[lcp
->id
[i
]];
1225 switch (lcp
->op
[i
]) {
1227 match
= (strcmp((const char *)lcp
->data
[i
].ptr
,
1228 (const char *)attr
->value
.ptr
) == 0);
1231 match
= (lcp
->data
[i
].ui
== attr
->value
.ui
);
1234 match
= !memcmp((void *)lcp
->data
[i
].ip
,
1235 (void *)attr
->value
.ip
,
1236 sizeof (in6_addr_t
));
1254 * ****************************************************************************
1257 * fill in the lookup control data for an object.
1259 * lcp - the lookup control data.
1261 * return - the lookup control data.
1263 * ****************************************************************************
1265 static lookup_ctrl_t
*
1271 isns_type_t type
= obj
->type
;
1276 while (i
< MAX_KEY_ATTRS
) {
1277 op
= KEY_ATTR_OP
[type
][i
];
1279 id
= KEY_ATTR_INDEX
[type
][i
];
1282 lcp
->data
[i
].ui
= obj
->attrs
[id
].value
.ui
;
1293 * ****************************************************************************
1296 * assign an attribute.
1298 * attr - the attribute being assigned.
1299 * tmp - the attribute.
1300 * return - error code.
1302 * ****************************************************************************
1307 const isns_attr_t
*tmp
1313 case ISNS_EID_ATTR_ID
:
1314 case ISNS_DD_SET_NAME_ATTR_ID
:
1315 case ISNS_DD_NAME_ATTR_ID
:
1316 if (tmp
->len
== 0 && attr
->len
== 0) {
1318 char *name
= make_unique_name(&len
, tmp
->tag
);
1320 attr
->value
.ptr
= (uchar_t
*)name
;
1321 attr
->tag
= tmp
->tag
;
1324 /* memory exhausted */
1329 case ISNS_PORTAL_NAME_ATTR_ID
:
1330 case ISNS_ISCSI_NAME_ATTR_ID
:
1331 case ISNS_ISCSI_ALIAS_ATTR_ID
:
1332 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID
:
1333 case ISNS_PG_ISCSI_NAME_ATTR_ID
:
1334 case ISNS_DD_ISCSI_NAME_ATTR_ID
:
1335 if (tmp
->len
== 0) {
1337 } else if (tmp
->len
>= attr
->len
) {
1338 attr
->value
.ptr
= realloc(
1339 attr
->value
.ptr
, tmp
->len
+ 1);
1341 if (attr
->value
.ptr
!= NULL
) {
1342 (void) strncpy((char *)attr
->value
.ptr
,
1343 (char *)tmp
->value
.ptr
, tmp
->len
);
1344 attr
->value
.ptr
[tmp
->len
] = 0;
1345 attr
->tag
= tmp
->tag
;
1346 attr
->len
= tmp
->len
;
1348 /* memory exhausted */
1352 case ISNS_MGMT_IP_ADDR_ATTR_ID
:
1353 case ISNS_PORTAL_IP_ADDR_ATTR_ID
:
1354 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
:
1355 if (attr
->value
.ip
== NULL
) {
1356 attr
->value
.ip
= (in6_addr_t
*)calloc(1, tmp
->len
);
1358 if (attr
->value
.ip
!= NULL
) {
1359 (void) memcpy((void *)attr
->value
.ip
,
1360 (void *)tmp
->value
.ip
, tmp
->len
);
1361 attr
->tag
= tmp
->tag
;
1362 attr
->len
= tmp
->len
;
1364 /* memory exhausted */
1368 case ISNS_ENTITY_INDEX_ATTR_ID
:
1369 case ISNS_PORTAL_INDEX_ATTR_ID
:
1370 case ISNS_ISCSI_NODE_INDEX_ATTR_ID
:
1371 case ISNS_PG_INDEX_ATTR_ID
:
1372 case ISNS_DD_SET_ID_ATTR_ID
:
1373 case ISNS_DD_ID_ATTR_ID
:
1374 if (attr
->value
.ui
!= 0) {
1378 case ISNS_ENTITY_PROTOCOL_ATTR_ID
:
1379 case ISNS_VERSION_RANGE_ATTR_ID
:
1381 case ISNS_PORTAL_PORT_ATTR_ID
:
1382 case ISNS_ESI_PORT_ATTR_ID
:
1383 case ISNS_SCN_PORT_ATTR_ID
:
1385 case ISNS_ISCSI_NODE_TYPE_ATTR_ID
:
1386 case ISNS_ISCSI_SCN_BITMAP_ATTR_ID
:
1388 case ISNS_PG_PORTAL_PORT_ATTR_ID
:
1389 case ISNS_PG_TAG_ATTR_ID
:
1391 case ISNS_DD_SET_STATUS_ATTR_ID
:
1392 case ISNS_DD_ISCSI_INDEX_ATTR_ID
:
1393 attr
->tag
= tmp
->tag
;
1394 attr
->len
= tmp
->len
;
1395 attr
->value
.ui
= tmp
->value
.ui
;
1397 case ISNS_ENTITY_REG_PERIOD_ATTR_ID
:
1398 attr
->tag
= tmp
->tag
;
1399 attr
->len
= tmp
->len
;
1400 attr
->value
.ui
= tmp
->value
.ui
;
1401 t
= get_reg_period();
1402 if (attr
->value
.ui
> t
) {
1404 } else if (attr
->value
.ui
< ONE_DAY
) {
1405 attr
->value
.ui
= ONE_DAY
;
1408 case ISNS_ESI_INTERVAL_ATTR_ID
:
1409 attr
->tag
= tmp
->tag
;
1410 attr
->len
= tmp
->len
;
1411 attr
->value
.ui
= tmp
->value
.ui
;
1412 if (attr
->value
.ui
> ONE_DAY
) {
1413 attr
->value
.ui
= ONE_DAY
;
1414 } else if (attr
->value
.ui
< MIN_ESI_INTVAL
) {
1415 attr
->value
.ui
= MIN_ESI_INTVAL
; /* 20 seconds */
1420 /* don't assign the attribute */
1427 * ****************************************************************************
1430 * copy all of attributes from one object to another.
1432 * dst - the destination object.
1433 * tmp - the source object.
1434 * return - error code.
1436 * ****************************************************************************
1441 const isns_obj_t
*src
1445 int n
= NUM_OF_ATTRS
[dst
->type
];
1447 isns_attr_t
*dst_attr
;
1448 const isns_attr_t
*src_attr
;
1451 src_attr
= &(src
->attrs
[i
]);
1452 if (src_attr
->tag
!= 0) {
1453 dst_attr
= &(dst
->attrs
[i
]);
1454 if (assign_attr(dst_attr
, src_attr
) != 0) {
1465 * ****************************************************************************
1468 * extract an attribute from a TLV format data.
1470 * attr - the attribute.
1471 * tlv - the TLV format data.
1472 * return - error code.
1474 * ****************************************************************************
1479 const isns_tlv_t
*tlv
,
1485 uint32_t min_len
= 4, max_len
= 224;
1487 switch (tlv
->attr_id
) {
1488 case ISNS_EID_ATTR_ID
:
1491 case ISNS_PORTAL_NAME_ATTR_ID
:
1492 case ISNS_ISCSI_ALIAS_ATTR_ID
:
1493 case ISNS_DD_SET_NAME_ATTR_ID
:
1494 case ISNS_DD_NAME_ATTR_ID
:
1497 case ISNS_ISCSI_NAME_ATTR_ID
:
1498 case ISNS_PG_ISCSI_NAME_ATTR_ID
:
1499 if (tlv
->attr_len
< min_len
|| tlv
->attr_len
> max_len
) {
1500 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
1502 attr
->tag
= tlv
->attr_id
;
1503 attr
->len
= tlv
->attr_len
;
1504 attr
->value
.ptr
= (uchar_t
*)&(tlv
->attr_value
[0]);
1507 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID
:
1508 attr
->tag
= tlv
->attr_id
;
1509 attr
->len
= tlv
->attr_len
;
1510 attr
->value
.ptr
= (uchar_t
*)&(tlv
->attr_value
[0]);
1512 case ISNS_MGMT_IP_ADDR_ATTR_ID
:
1513 case ISNS_PORTAL_IP_ADDR_ATTR_ID
:
1514 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
:
1515 if (tlv
->attr_len
!= 16) {
1516 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
1518 attr
->tag
= tlv
->attr_id
;
1519 attr
->len
= tlv
->attr_len
;
1520 attr
->value
.ip
= (void *)&(tlv
->attr_value
[0]);
1523 case ISNS_ENTITY_PROTOCOL_ATTR_ID
:
1524 case ISNS_VERSION_RANGE_ATTR_ID
:
1525 case ISNS_ENTITY_REG_PERIOD_ATTR_ID
:
1527 case ISNS_PORTAL_PORT_ATTR_ID
:
1528 case ISNS_ESI_INTERVAL_ATTR_ID
:
1529 case ISNS_ESI_PORT_ATTR_ID
:
1530 case ISNS_SCN_PORT_ATTR_ID
:
1532 case ISNS_ISCSI_NODE_TYPE_ATTR_ID
:
1534 case ISNS_PG_PORTAL_PORT_ATTR_ID
:
1536 case ISNS_DD_SET_ID_ATTR_ID
:
1537 case ISNS_DD_SET_STATUS_ATTR_ID
:
1539 case ISNS_DD_ID_ATTR_ID
:
1540 if (tlv
->attr_len
!= 4) {
1541 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
1545 case ISNS_PG_TAG_ATTR_ID
:
1546 attr
->tag
= tlv
->attr_id
;
1547 attr
->len
= tlv
->attr_len
;
1548 if (tlv
->attr_len
== 4) {
1549 attr
->value
.ui
= ntohl(*(uint32_t *)
1550 &(tlv
->attr_value
[0]));
1555 case ISNS_ISCSI_SCN_BITMAP_ATTR_ID
:
1556 /* ignore scn bitmap attribute during object registration, */
1557 /* it is registered by scn_reg message. */
1558 case ISNS_ENTITY_ISAKMP_P1_ATTR_ID
:
1559 case ISNS_ENTITY_CERT_ATTR_ID
:
1560 case ISNS_PORTAL_SEC_BMP_ATTR_ID
:
1561 case ISNS_PORTAL_ISAKMP_P1_ATTR_ID
:
1562 case ISNS_PORTAL_ISAKMP_P2_ATTR_ID
:
1563 case ISNS_PORTAL_CERT_ATTR_ID
:
1565 case ISNS_PORTAL_INDEX_ATTR_ID
:
1566 case ISNS_ISCSI_NODE_INDEX_ATTR_ID
:
1567 case ISNS_PG_INDEX_ATTR_ID
:
1569 if (tlv
->attr_len
!= 4) {
1570 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
1572 attr
->tag
= tlv
->attr_id
;
1573 attr
->len
= tlv
->attr_len
;
1574 attr
->value
.ui
= ntohl(*(uint32_t *)
1575 &(tlv
->attr_value
[0]));
1580 case ISNS_ENTITY_INDEX_ATTR_ID
:
1581 case ISNS_TIMESTAMP_ATTR_ID
:
1584 ec
= ISNS_RSP_INVALID_QRY
;
1586 ec
= ISNS_RSP_INVALID_REGIS
;
1595 * ****************************************************************************
1598 * copy an attribute from a TLV format data.
1600 * attr - the attribute.
1601 * tlv - the TLV format data.
1602 * return - error code.
1604 * ****************************************************************************
1609 const isns_tlv_t
*tlv
1614 isns_attr_t tmp
= { 0 };
1616 /* extract the attribute first */
1617 ec
= extract_attr(&tmp
, tlv
, 1);
1619 /* assign the attribute */
1620 if (ec
== 0 && tmp
.tag
!= 0) {
1621 if (assign_attr(attr
, &tmp
) != 0) {
1622 ec
= ISNS_RSP_INTERNAL_ERROR
;
1630 * ****************************************************************************
1633 * get current timestamp.
1635 * return - current timestamp.
1637 * ****************************************************************************
1646 /* block the scheduler */
1647 (void) pthread_mutex_lock(&el_mtx
);
1649 /* get most current time */
1650 if (sys_q
!= NULL
) {
1651 /* need to wakeup idle */
1656 t
= get_stopwatch(flag
);
1659 (void) pthread_mutex_unlock(&el_mtx
);
1665 * ****************************************************************************
1668 * get the longest registration period.
1670 * return - the longest registration period.
1672 * ****************************************************************************
1681 /* get most current time */
1682 t
= get_timestamp();
1684 /* just one second before the end of the world */
1685 period
= INFINITY
- t
- 1;
1691 * ****************************************************************************
1694 * allocate memory space for an object.
1696 * type - the object type.
1697 * return - pointer of the object being allocated.
1699 * ****************************************************************************
1706 isns_obj_t
*obj
= NULL
;
1708 obj
= (isns_obj_t
*)calloc(1, SIZEOF_OBJ
[type
]);
1713 printf("object(%d) allocated\n", type
);
1722 * ****************************************************************************
1724 * make_default_entity:
1725 * generate a default network entity object.
1727 * return - pointer of the default network entity object.
1729 * ****************************************************************************
1732 make_default_entity(
1737 isns_obj_t
*obj
= obj_calloc(OBJ_ENTITY
);
1741 char *eid
= make_unique_name(&len
, ISNS_EID_ATTR_ID
);
1746 attr
= &obj
->attrs
[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID
)];
1748 /* set default entity name */
1749 attr
->tag
= ISNS_EID_ATTR_ID
;
1751 attr
->value
.ptr
= (uchar_t
*)eid
;
1753 /* set default registration period */
1755 ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID
)];
1756 if (attr
->tag
== 0) {
1757 attr
->tag
= ISNS_ENTITY_REG_PERIOD_ATTR_ID
;
1759 t
= get_reg_period();
1768 * ****************************************************************************
1771 * generate a default portal group object.
1773 * iscsi - the iscsi storage node object.
1774 * portal - the portal object.
1775 * return - pointer of the default portal group object.
1777 * ****************************************************************************
1781 const isns_obj_t
*p1
,
1782 const isns_obj_t
*p2
1785 const isns_obj_t
*iscsi
, *portal
;
1786 const isns_attr_t
*name
, *addr
, *port
;
1790 in6_addr_t
*pg_addr
;
1796 if (p1
->type
== OBJ_ISCSI
) {
1803 name
= &iscsi
->attrs
[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID
)];
1804 addr
= &portal
->attrs
[ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID
)];
1805 port
= &portal
->attrs
[ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID
)];
1807 pg
= obj_calloc(OBJ_PG
);
1808 pg_name
= (uchar_t
*)malloc(name
->len
);
1809 pg_addr
= (in6_addr_t
*)malloc(addr
->len
);
1810 if (pg
!= NULL
&& pg_name
!= NULL
&& pg_addr
!= NULL
) {
1811 (void) strcpy((char *)pg_name
, (char *)name
->value
.ptr
);
1812 attr
= &pg
->attrs
[ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID
)];
1813 attr
->tag
= ISNS_PG_ISCSI_NAME_ATTR_ID
;
1814 attr
->len
= name
->len
;
1815 attr
->value
.ptr
= pg_name
;
1817 (void) memcpy((void *)pg_addr
,
1818 (void *)addr
->value
.ip
, addr
->len
);
1819 attr
= &pg
->attrs
[ATTR_INDEX_PG(
1820 ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
)];
1821 attr
->tag
= ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
;
1822 attr
->len
= addr
->len
;
1823 attr
->value
.ip
= pg_addr
;
1825 attr
= &pg
->attrs
[ATTR_INDEX_PG(
1826 ISNS_PG_PORTAL_PORT_ATTR_ID
)];
1827 attr
->tag
= ISNS_PG_PORTAL_PORT_ATTR_ID
;
1828 attr
->len
= port
->len
;
1829 attr
->value
.ui
= port
->value
.ui
;
1831 attr
= &pg
->attrs
[ATTR_INDEX_PG(
1832 ISNS_PG_TAG_ATTR_ID
)];
1833 attr
->tag
= ISNS_PG_TAG_ATTR_ID
;
1835 attr
->value
.ui
= ISNS_DEFAULT_PGT
;
1837 refp
= get_ref_p(pg
, OBJ_ISCSI
);
1838 *refp
= get_obj_uid(iscsi
);
1840 refp
= get_ref_p(pg
, OBJ_PORTAL
);
1841 *refp
= get_obj_uid(portal
);
1843 (void) set_parent_obj(pg
, get_parent_uid(iscsi
));
1855 * ****************************************************************************
1858 * parse the Operating Attributes of the DevAttrReg message and
1859 * create the Network Entity object if it has one.
1861 * p - the pointer of the object for returning.
1862 * op - the operating attributes.
1863 * op_len - the length of the operating attributes.
1864 * return - error code.
1866 * ****************************************************************************
1881 isns_obj_t
*entity
= NULL
;
1886 /* parse the entity object */
1887 if (tmp_len
>= 8 && IS_ENTITY_KEY(tmp
->attr_id
)) {
1888 entity
= obj_calloc(OBJ_ENTITY
);
1889 if (entity
!= NULL
) {
1891 attr
= &entity
->attrs
[
1892 ATTR_INDEX_ENTITY(tmp
->attr_id
)];
1893 ec
= copy_attr(attr
, tmp
);
1894 NEXT_TLV(tmp
, tmp_len
);
1897 IS_ENTITY_ATTR(tmp
->attr_id
));
1899 ec
= ISNS_RSP_INTERNAL_ERROR
;
1903 /* set default registration period */
1904 attr
= &entity
->attrs
[
1905 ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID
)];
1906 if (attr
->tag
== 0) {
1907 attr
->tag
= ISNS_ENTITY_REG_PERIOD_ATTR_ID
;
1909 attr
->value
.ui
= get_reg_period();
1911 } else if (entity
!= NULL
) {
1925 * ****************************************************************************
1928 * parse the Operating Attributes of the DevAttrReg message and
1929 * create an iSCSI Storage Node object.
1931 * p - the pointer of the object for returning.
1932 * pg_key1 - the pointer of iscsi storage node name for returning.
1933 * op - the operating attributes.
1934 * op_len - the length of the operating attributes.
1935 * return - error code.
1937 * ****************************************************************************
1942 isns_attr_t
*pg_key1
,
1953 isns_obj_t
*obj
= NULL
;
1958 /* keep the iscsi storage node name for */
1959 /* parsing a pg object which is immediately */
1960 /* followed with a PGT by the iscsi storage node */
1961 pg_key1
->tag
= PG_KEY1
;
1962 pg_key1
->len
= tmp
->attr_len
;
1963 pg_key1
->value
.ptr
= (uchar_t
*)&tmp
->attr_value
[0];
1965 /* parse one iscsi storage node object */
1966 obj
= obj_calloc(OBJ_ISCSI
);
1968 /* parse key & non-key attributes */
1971 ATTR_INDEX_ISCSI(tmp
->attr_id
)];
1972 ec
= copy_attr(attr
, tmp
);
1973 NEXT_TLV(tmp
, tmp_len
);
1976 IS_ISCSI_ATTR(tmp
->attr_id
));
1979 ec
= ISNS_RSP_INTERNAL_ERROR
;
1990 * ****************************************************************************
1993 * parse the Operating Attributes of the DevAttrReg message and
1994 * create a Portal object.
1996 * p - the pointer of the object for returning.
1997 * pg_key1 - the pointer of portal ip addr for returning.
1998 * pg_key2 - the pointer of portal port for returning.
1999 * op - the operating attributes.
2000 * op_len - the length of the operating attributes.
2001 * return - error code.
2003 * ****************************************************************************
2008 isns_attr_t
*pg_key1
,
2009 isns_attr_t
*pg_key2
,
2020 isns_obj_t
*obj
= NULL
;
2027 /* keep the portal ip addr */
2028 pg_key1
->tag
= PG_KEY2
;
2029 pg_key1
->len
= tmp
->attr_len
;
2030 pg_key1
->value
.ip
= (void *)&tmp
->attr_value
[0];
2033 NEXT_TLV(tmp
, tmp_len
);
2035 tmp
->attr_id
== PORTAL_KEY2
&&
2036 tmp
->attr_len
== 4) {
2037 /* keep the portal port */
2038 pg_key2
->tag
= PG_KEY3
;
2039 pg_key2
->len
= tmp
->attr_len
;
2040 pg_key2
->value
.ui
= ntohl(*(uint32_t *)&tmp
->attr_value
[0]);
2042 /* parse one portal object */
2043 obj
= obj_calloc(OBJ_PORTAL
);
2045 /* copy ip addr attribute */
2047 ATTR_INDEX_PORTAL(ip
->attr_id
)];
2048 ec
= copy_attr(attr
, ip
);
2049 /* copy port attribute */
2052 ATTR_INDEX_PORTAL(tmp
->attr_id
)];
2053 ec
= copy_attr(attr
, tmp
);
2055 /* parse non-key attributes */
2056 NEXT_TLV(tmp
, tmp_len
);
2059 IS_PORTAL_ATTR(tmp
->attr_id
)) {
2063 ec
= copy_attr(attr
, tmp
);
2064 NEXT_TLV(tmp
, tmp_len
);
2068 ec
= ISNS_RSP_INTERNAL_ERROR
;
2071 /* ip address is not followed by port */
2072 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
2083 * ****************************************************************************
2086 * parse the Operating Attributes of the DevAttrReg message and
2087 * create a Portal Group object.
2089 * p - the pointer of the object for returning.
2090 * op - the operating attributes.
2091 * op_len - the length of the operating attributes.
2092 * return - error code.
2094 * ****************************************************************************
2109 isns_obj_t
*obj
= NULL
;
2114 /* parse a complete pg object */
2115 obj
= obj_calloc(OBJ_PG
);
2117 /* parse attributes */
2120 ATTR_INDEX_PG(tmp
->attr_id
)];
2121 ec
= copy_attr(attr
, tmp
);
2122 NEXT_TLV(tmp
, tmp_len
);
2125 IS_PG_ATTR(tmp
->attr_id
));
2127 ec
= ISNS_RSP_INTERNAL_ERROR
;
2138 * ****************************************************************************
2141 * parse the Operating Attributes of the DevAttrReg message and
2142 * create a Portal Group object which is followed to a Portal object.
2144 * p - the pointer of the object for returning.
2145 * pgt - the size-3 array of pointers which have the pg portal ip addr, port
2146 * and the pg tag attributes.
2147 * op - the operating attributes.
2148 * op_len - the length of the operating attributes.
2149 * return - error code.
2151 * ****************************************************************************
2156 isns_attr_t
const *pgt
,
2167 isns_obj_t
*obj
= NULL
;
2173 if (pgt
[0].tag
== PG_KEY2
&&
2174 pgt
[1].tag
== PG_KEY3
) {
2175 /* the pg iscsi storage node name is */
2176 /* followed to a portal group tag */
2177 obj
= obj_calloc(OBJ_PG
);
2179 /* copy pg iscsi storage node name */
2181 ATTR_INDEX_PG(tmp
->attr_id
)];
2182 ec
= copy_attr(attr
, tmp
);
2183 /* copy pg ip addr, pg port & pgt */
2184 while (ec
== 0 && i
< 3) {
2186 ATTR_INDEX_PG(pgt
[i
].tag
)];
2187 ec
= assign_attr(attr
, &pgt
[i
]);
2190 NEXT_TLV(tmp
, tmp_len
);
2193 ec
= ISNS_RSP_INTERNAL_ERROR
;
2196 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
2207 * ****************************************************************************
2210 * parse the Operating Attributes of the DevAttrReg message and
2211 * create a Portal Group object which is followed to a iSCSI
2212 * Storage Node object.
2214 * p - the pointer of the object for returning.
2215 * pgt - the size-3 array of pointers which have the pg iscsi storage
2216 * node name and the pg tag attributes.
2217 * op - the operating attributes.
2218 * op_len - the length of the operating attributes.
2219 * return - error code.
2221 * ****************************************************************************
2226 isns_attr_t
const *pgt
,
2237 isns_obj_t
*obj
= NULL
;
2245 /* keep ip address */
2247 NEXT_TLV(tmp
, tmp_len
);
2250 /* expect pg portal port */
2251 tmp
->attr_id
== PG_KEY3
&&
2252 tmp
->attr_len
== 4 &&
2254 pgt
[2].tag
== PG_PGT
&&
2255 /* expect pg iscsi storage node name only */
2257 pgt
[0].tag
== PG_KEY1
) {
2258 /* the pg portal ip addr & port is followed */
2259 /* to a pg tag and we have the iscsi storage */
2260 /* node parsed previously */
2261 obj
= obj_calloc(OBJ_PG
);
2263 /* copy the pg ip addr */
2265 ATTR_INDEX_PG(ip
->attr_id
)];
2266 ec
= copy_attr(attr
, ip
);
2267 /* copy the pg port */
2270 ATTR_INDEX_PG(tmp
->attr_id
)];
2271 ec
= copy_attr(attr
, tmp
);
2273 /* copy pg iscsi storage node name & pgt */
2274 while (ec
== 0 && i
< 3) {
2276 ATTR_INDEX_PG(pgt
[i
].tag
)];
2277 ec
= assign_attr(attr
, &pgt
[i
]);
2280 NEXT_TLV(tmp
, tmp_len
);
2282 ec
= ISNS_RSP_INTERNAL_ERROR
;
2285 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
2296 * ****************************************************************************
2299 * parse and create one object from the rest of Operating Attributes
2300 * of the DevAttrReg message, the object can be iSCSI Storage Node,
2301 * Portal or Portal Group.
2303 * p - the pointer of the object for returning.
2304 * pgt - an attribute array with size 3, the elements are:
2305 * 0: the first pg key attribute, it is either the name of an
2306 * iscsi storage node object or the ip addr of a portal object.
2307 * 1: the second pg key attribute, i.e. the portal port.
2308 * 2: the portal group tag attribute.
2309 * op - the operating attributes.
2310 * op_len - the length of the operating attributes.
2311 * return - error code.
2313 * ****************************************************************************
2334 switch ((*op
)->attr_id
) {
2336 ec
= reg_get_iscsi(p
, &pgt
[0], op
, op_len
);
2341 ec
= reg_get_portal(p
, &pgt
[0], &pgt
[1], op
, op_len
);
2345 if (pgt
[2].tag
== PG_PGT
) {
2346 /* pg iscsi storage node name is */
2347 /* followed to a pgt */
2348 ec
= reg_get_pg1(p
, pgt
, op
, op_len
);
2350 /* a complete pg object */
2351 ec
= reg_get_pg(p
, op
, op_len
);
2358 /* pg portal ip addr is followed to a pgt */
2359 ec
= reg_get_pg2(p
, pgt
, op
, op_len
);
2362 switch (pgt
[0].tag
) {
2364 /* portal group tag does not follow */
2365 /* iscsi storage node or portal object */
2367 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
2371 pgt
[2].tag
= PG_PGT
;
2372 pgt
[2].len
= (*op
)->attr_len
;
2374 switch ((*op
)->attr_len
) {
2376 pg_tag
= ntohl(*(uint32_t *)
2377 &(*op
)->attr_value
[0]);
2380 pgt
[2].value
.ui
= pg_tag
;
2384 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
2389 NEXT_TLV(*op
, *op_len
);
2390 ec
= reg_get_obj(p
, pgt
, op
, op_len
);
2394 /* should never happen */
2397 ec
= ISNS_RSP_INTERNAL_ERROR
;
2403 ec
= ISNS_RSP_MSG_FORMAT_ERROR
;
2407 if (ec
== 0 && derefd
== 0) {
2408 ec
= update_deref_obj(*p
);
2411 if (ec
!= 0 && *p
!= NULL
) {
2412 free_one_object(*p
);
2420 * ****************************************************************************
2423 * Authorize the source attribute the DevAttrReg message.
2424 * The update can only performed by the node who has the owenership.
2426 * p - the pointer of the object for returning.
2427 * pgt - an attribute array with size 3, the elements are:
2428 * 0: the first pg key attribute, it is either the name of an
2429 * iscsi storage node object or the ip addr of a portal object.
2430 * 1: the second pg key attribute, i.e. the portal port.
2431 * 2: the portal group tag attribute.
2432 * op - the operating attributes.
2433 * op_len - the length of the operating attributes.
2434 * return - error code.
2436 * ****************************************************************************
2448 puid
= is_parent_there(src
);
2450 if (TYPE_OF_PARENT
[type
] != 0) {
2451 SET_UID_LCP(&lc
, type
, uid
);
2452 uid
= cache_lookup(&lc
, NULL
, cb_get_parent
);
2453 type
= TYPE_OF_PARENT
[type
];
2456 if (uid
!= 0 && puid
== 0) {
2457 SET_UID_LCP(&lc
, type
, uid
);
2458 uid
= cache_lookup(&lc
, NULL
, cb_node_child
);
2469 * ****************************************************************************
2472 * determine if the object is currently registered with the server.
2474 * obj - the object being checked.
2475 * return - 0: not registered, otherwise registered.
2477 * ****************************************************************************
2481 const isns_obj_t
*obj
2486 switch (obj
->type
) {
2488 online
= obj
->attrs
[ATTR_INDEX_ISCSI(
2489 ISNS_ISCSI_NODE_TYPE_ATTR_ID
)].value
.ui
== 0 ? 0 : 1;
2503 switch (obj
->type
) {
2505 obj
->attrs
[ATTR_INDEX_ISCSI(
2506 ISNS_ISCSI_NODE_TYPE_ATTR_ID
)].value
.ui
= 0;
2516 * ****************************************************************************
2519 * clone the association object.
2521 * p - the object being cloned.
2522 * clone_flag - 0: the object is being removed;
2523 * 1: only the association is being removed.
2524 * return - the clone object.
2526 * ****************************************************************************
2536 const isns_attr_t
*src_attr
;
2537 isns_attr_t
*dst_attr
;
2541 const isns_obj_t
*obj
;
2547 obj
= (isns_obj_t
*)p
;
2549 if (obj
->type
!= OBJ_ISCSI
) {
2553 dd_flag
= (get_dd_id(get_obj_uid(obj
), ISNS_DEFAULT_DD_ID
) == 0) ?
2555 online
= is_obj_online(obj
);
2557 state
= (clone_flag
<< 2) | (dd_flag
<< 1) | online
;
2559 /* clone_flag dd_flag online action */
2560 /* 0 0 0 ASSERT(0) */
2563 /* 0 1 1 clone it */
2586 clone
= obj_calloc(type
);
2588 if (clone
!= NULL
) {
2589 id
= UID_ATTR_INDEX
[type
];
2590 src_attr
= &(obj
->attrs
[id
]);
2591 dst_attr
= &(clone
->attrs
[id
]);
2592 if (assign_attr(dst_attr
, src_attr
) != 0) {
2593 free_one_object(clone
);
2597 while (i
< MAX_KEY_ATTRS
) {
2598 op
= KEY_ATTR_OP
[type
][i
];
2600 id
= KEY_ATTR_INDEX
[type
][i
];
2601 src_attr
= &(obj
->attrs
[id
]);
2602 dst_attr
= &(clone
->attrs
[id
]);
2603 if (assign_attr(dst_attr
, src_attr
) != 0) {
2604 free_one_object(clone
);
2614 return ((void *)clone
);
2618 * ****************************************************************************
2621 * free up one object.
2623 * obj - the object being freed.
2625 * ****************************************************************************
2637 for (i
= 0; i
< NUM_OF_ATTRS
[obj
->type
]; i
++) {
2638 isns_attr_t
*attr
= &obj
->attrs
[i
];
2639 switch (attr
->tag
) {
2640 case ISNS_EID_ATTR_ID
:
2641 case ISNS_ISCSI_NAME_ATTR_ID
:
2642 case ISNS_ISCSI_ALIAS_ATTR_ID
:
2643 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID
:
2644 case ISNS_PG_ISCSI_NAME_ATTR_ID
:
2645 case ISNS_PORTAL_IP_ADDR_ATTR_ID
:
2646 case ISNS_PORTAL_NAME_ATTR_ID
:
2647 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID
:
2648 case ISNS_DD_SET_NAME_ATTR_ID
:
2649 case ISNS_DD_NAME_ATTR_ID
:
2650 case ISNS_DD_ISCSI_NAME_ATTR_ID
:
2651 case ISNS_DD_FC_PORT_NAME_ATTR_ID
:
2652 case ISNS_DD_PORTAL_IP_ADDR_ATTR_ID
:
2655 printf("memory(%d) deallocated\n",
2659 free(attr
->value
.ptr
);
2660 attr
->value
.ptr
= NULL
;
2667 /* free child uids */
2669 while (i
< NUM_OF_CHILD
[obj
->type
]) {
2670 cuid
= get_child_n(obj
, i
);
2675 /* at last, free the object itself */
2678 printf("object(%d) deallocated\n", obj
->type
);
2685 * ****************************************************************************
2688 * free up one object.
2690 * obj - the object being freed.
2692 * ****************************************************************************
2699 free_one_object(obj
);
2703 * ****************************************************************************
2706 * set the parent object UID.
2708 * obj - the child object.
2709 * puid- the parent object UID.
2710 * return - error code.
2712 * ****************************************************************************
2720 uint32_t *const p
= get_parent_p(obj
);
2729 * ****************************************************************************
2732 * add a child object UID to the child object array.
2734 * obj - the parent object.
2735 * child_type - the type of the child object.
2736 * number - the number of the child object.
2737 * return - the length of the child object UID array.
2739 * ****************************************************************************
2743 const isns_type_t ptype
,
2744 const isns_type_t ctype
,
2752 void const ***pp
, **p
;
2753 uint32_t num
, new_num
;
2756 /* get the pointer of the array which the child belongs to */
2757 while (i
< NUM_OF_CHILD
[ptype
]) {
2758 if (TYPE_OF_CHILD
[ptype
][i
] == ctype
) {
2765 /* the child type is not applicable */
2771 /* get an empty slot from the uid array for this child */
2776 if (p
[++i
] == NULL
) {
2789 /* the array is full, enlarge the child uid array */
2790 p
= reallocarray(p
, new_num
+ 1, sizeof (void *));
2793 *p
= (void *)new_num
;
2796 ec
= ISNS_RSP_INTERNAL_ERROR
;
2803 * ****************************************************************************
2805 * update_child_object:
2806 * update the child object of a network entity object.
2808 * puid - the UID of the parent object, i.e. the network entity object.
2809 * child_type - the type of the child object.
2810 * child_uid - the uid of the child object.
2811 * return - error code.
2813 * ****************************************************************************
2817 const isns_type_t ptype
,
2818 const uint32_t puid
,
2819 void const ***child
,
2827 SET_UID_LCP(&lc
, ptype
, puid
);
2829 lc
.data
[1].ptr
= (uchar_t
*)child
;
2830 lc
.data
[2].ui
= child_flag
;
2832 ec
= cache_lookup(&lc
, NULL
, cb_add_child
);
2839 const isns_obj_t
*obj
2848 if (TYPE_OF_REF
[t
][0] != 0) {
2849 (void) setup_ref_lcp(&lc
, obj
, NULL
);
2852 lc
.data
[2].ui
= get_obj_uid(obj
);
2857 (void) cache_lookup(&lc
, &uid
, cb_set_ref
);
2865 * ****************************************************************************
2868 * update the reference bit of a portal group object.
2870 * obj - the object being ref'ed.
2871 * return - error code.
2873 * ****************************************************************************
2877 const isns_type_t ptype
,
2878 const uint32_t puid
,
2886 SET_UID_LCP(&lc
, ptype
, puid
);
2888 lc
.data
[1].ptr
= (uchar_t
*)child
;
2890 ec
= cache_lookup(&lc
, NULL
, cb_verify_ref
);
2906 uint32_t uid
, *refp
;
2910 while (i
< NUM_OF_REF
[t
]) {
2911 rt
= TYPE_OF_REF
[t
][i
+ 1];
2912 (void) setup_deref_lcp(&lc
, obj
, rt
);
2913 uid
= is_obj_there(&lc
);
2915 refp
= get_ref_p(obj
, lc
.type
);
2922 if (i
> 0 && ref_count
== 0) {
2923 ec
= ISNS_RSP_INVALID_REGIS
;
2930 * ****************************************************************************
2933 * add one object to the object container.
2935 * obj - the object being added.
2936 * uid_p- the pointer for returning object UID.
2937 * update_p- the pointer for returning flag which indicates if the object
2938 * is newly registered or updated with an existing one.
2939 * return - error code.
2941 * ****************************************************************************
2950 return (cache_add(obj
, 0, uid_p
, update_p
));
2954 * ****************************************************************************
2957 * add one association object to the object container, the association
2958 * object has only the information for discovery domain membership, i.e.
2959 * a name and UID only.
2961 * obj - the association object being added.
2962 * uid_p- the pointer for returning object UID.
2963 * return - error code.
2965 * ****************************************************************************
2973 return (cache_add(obj
, 1, uid_p
, NULL
));
2977 * ****************************************************************************
2980 * check if the object is registered or not.
2982 * lcp - the lookup control data.
2983 * return - the object UID.
2985 * ****************************************************************************
2994 (void) cache_lookup(lcp
, &uid
, NULL
);
3007 lc
.type
= OBJ_ISCSI
;
3008 lc
.id
[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID
);
3009 lc
.op
[0] = OP_STRING
;
3010 lc
.data
[0].ptr
= src
;
3013 return (cache_lookup(&lc
, NULL
, cb_get_parent
));
3017 * ****************************************************************************
3020 * prepare the lookup control data for looking up a portal group
3021 * object which references to a iscsi stroage node and/or a portal
3024 * lcp - the lookup control data.
3025 * iscsi- the ref'ed iscsi storage node object.
3026 * portal- the ref'ed portal object.
3027 * return - error code.
3029 * ****************************************************************************
3034 const isns_obj_t
*iscsi
,
3035 const isns_obj_t
*portal
3041 lcp
->type
= TYPE_OF_REF
[iscsi
->type
][0];
3043 /* extrace the matching attributes from iscsi storage node object */
3044 while (iscsi
!= NULL
&&
3045 i
< MAX_REF_MATCH
&&
3046 REF_MATCH_OPS
[iscsi
->type
][i
] > 0) {
3047 lcp
->id
[i
] = REF_MATCH_ID2
[iscsi
->type
][i
];
3048 lcp
->op
[i
] = REF_MATCH_OPS
[iscsi
->type
][i
];
3049 lcp
->data
[i
].ptr
= iscsi
->attrs
[
3050 REF_MATCH_ID1
[iscsi
->type
][i
]].value
.ptr
;
3054 /* extrace the matching attributes from portal object */
3055 while (portal
!= NULL
&&
3056 i
< MAX_LOOKUP_CTRL
&&
3057 j
< MAX_REF_MATCH
&&
3058 REF_MATCH_OPS
[portal
->type
][j
] > 0) {
3059 lcp
->id
[i
] = REF_MATCH_ID2
[portal
->type
][j
];
3060 lcp
->op
[i
] = REF_MATCH_OPS
[portal
->type
][j
];
3061 lcp
->data
[i
].ptr
= portal
->attrs
[
3062 REF_MATCH_ID1
[portal
->type
][j
]].value
.ptr
;
3067 if (i
< MAX_LOOKUP_CTRL
) {
3077 const isns_obj_t
*pg
,
3086 /* extrace the matching attributes from iscsi storage node object */
3087 while (i
< MAX_REF_MATCH
&&
3088 REF_MATCH_OPS
[t
][i
] > 0) {
3089 lcp
->id
[i
] = REF_MATCH_ID1
[t
][i
];
3090 lcp
->op
[i
] = REF_MATCH_OPS
[t
][i
];
3091 lcp
->data
[i
].ptr
= pg
->attrs
[
3092 REF_MATCH_ID2
[t
][i
]].value
.ptr
;
3096 if (i
< MAX_LOOKUP_CTRL
) {
3104 * ****************************************************************************
3107 * prepare the lookup control data for looking up parent object
3108 * with a child object.
3110 * lcp - the lookup control data.
3111 * obj - the child object.
3112 * return - parent object UID.
3114 * ****************************************************************************
3125 puid
= get_parent_uid(obj
);
3127 ptype
= TYPE_OF_PARENT
[obj
->type
];
3128 SET_UID_LCP(lcp
, ptype
, puid
);
3129 lcp
->data
[1].ui
= obj
->type
;
3130 lcp
->data
[2].ui
= get_obj_uid(obj
);
3139 /* LINTED E_FUNC_ARG_UNUSED */
3143 return (get_parent_uid(p1
));
3149 /* LINTED E_FUNC_ARG_UNUSED */
3153 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
3157 uint32_t *cuid
= get_child_t(obj
, OBJ_ISCSI
);
3177 * ****************************************************************************
3180 * callback function which sets the reference bit to 1 according to
3181 * the type of object.
3185 * return - error code.
3187 * ****************************************************************************
3195 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
3196 lookup_ctrl_t
*lcp
= (lookup_ctrl_t
*)p2
;
3204 u
= lcp
->data
[2].ui
;
3205 refp
= get_ref_p(obj
, t
);
3213 * ****************************************************************************
3216 * callback function which clears the reference bit according to
3217 * the type of object.
3221 * return - 1: the object is no longer ref'ed, 0: otherwise.
3223 * ****************************************************************************
3231 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
3232 lookup_ctrl_t
*lcp
= (lookup_ctrl_t
*)p2
;
3240 t
= lcp
->data
[2].ui
;
3241 refp
= get_ref_p(obj
, t
);
3244 while (i
< NUM_OF_REF
[obj
->type
]) {
3245 ref
= get_ref_n(obj
, i
);
3261 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
3262 lookup_ctrl_t
*lcp
= (lookup_ctrl_t
*)p2
;
3264 const void ***child
;
3269 uint32_t **upp
, *up
;
3276 child
= (const void ***)lcp
->data
[1].ptr
;
3277 child_flag
= lcp
->data
[2].ui
;
3279 while (i
< NUM_OF_CHILD
[obj
->type
]) {
3282 (vnum
= (uint32_t)*vpp
) > 0 &&
3283 *(vpp
+ 1) != NULL
) {
3284 upp
= get_child_np(obj
, i
);
3286 if (child_flag
== 0 &&
3287 sizeof (typeof (**upp
)) ==
3288 sizeof (typeof (**child
))) {
3289 *upp
= (uint32_t *)vpp
;
3299 up
= reallocarray(*upp
, num
+ 1,
3302 return (ISNS_RSP_INTERNAL_ERROR
);
3311 } else if (child_flag
== 0) {
3312 *up
= (uint32_t)*vpp
;
3315 o
= (isns_obj_t
*)*vpp
;
3316 *up
= get_obj_uid(o
);
3317 if (is_obj_online(o
) == 0) {
3335 * ****************************************************************************
3338 * callback function which removes a child object UID from the
3339 * children objet UID array of the parent object.
3343 * return - 1: no more such type of child object, 0: otherwise.
3345 * ****************************************************************************
3353 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
3354 lookup_ctrl_t
*lcp
= (lookup_ctrl_t
*)p2
;
3355 uint32_t child_type
= lcp
->data
[1].ui
;
3356 uint32_t child_uid
= lcp
->data
[2].ui
;
3357 uint32_t *cuidp
, cuid
, num_of_child
= 0;
3360 /* get the children object UID array */
3361 cuidp
= get_child_t(obj
, child_type
);
3362 if (cuidp
!= NULL
) {
3363 num_of_child
= *cuidp
;
3367 while (num_of_child
> 0) {
3369 if (cuid
== child_uid
) {
3376 /* check if all of child object UIDs are removed */
3378 while (i
< NUM_OF_CHILD
[obj
->type
]) {
3379 cuidp
= get_child_n(obj
, i
);
3380 if (cuidp
!= NULL
) {
3381 num_of_child
= *cuidp
;
3382 while (num_of_child
> 0) {
3404 isns_obj_t
*parent
= (isns_obj_t
*)p1
;
3405 lookup_ctrl_t
*lcp
= (lookup_ctrl_t
*)p2
;
3407 const void ***child
;
3417 isns_type_t pt
; /* parent object type */
3418 isns_type_t ct
; /* child object type */
3419 isns_type_t rt
; /* ref object type */
3420 isns_type_t et
; /* peer object type */
3427 uint8_t flag
[MAX_OBJ_TYPE
+ 1] = { 0 };
3433 child
= (const void ***)lcp
->data
[1].ptr
;
3435 for (i
= 0; i
< NUM_OF_CHILD
[pt
]; i
++) {
3436 ct
= TYPE_OF_CHILD
[pt
][i
];
3437 rt
= TYPE_OF_REF
[ct
][0];
3442 et
= TYPE_OF_REF
[ct
][1];
3445 vnum
= (uint32_t)*vpp
;
3446 up
= get_child_t(parent
, et
);
3460 (void) setup_ref_lcp(&lc
, vp
, NULL
);
3472 } /* End of while each unum */
3475 } /* End of while each vnum */
3477 if (flag
[ct
] != 0) {
3483 while (j
< NUM_OF_CHILD
[pt
]) {
3484 if (TYPE_OF_CHILD
[pt
][j
] == et
) {
3487 evnum
= (uint32_t)*evpp
;
3500 if (vp
!= NULL
&& evp
!= NULL
) {
3501 (void) setup_ref_lcp(&lc
, vp
, evp
);
3502 ec
= ref_new2new(&lc
, vp
, evp
);
3510 } /* End of while each vnum */
3513 } /* End of for each type of child */
3524 isns_obj_t
*obj
= (isns_obj_t
*)p1
;
3525 lookup_ctrl_t
*lcp
= (lookup_ctrl_t
*)p2
;
3535 uu
= lcp
->data
[2].ui
;
3537 ref
= get_ref_t(obj
, et
);
3556 lookup_ctrl_t
*lcp
= (lookup_ctrl_t
*)p2
;
3557 isns_obj_t
*a
= (isns_obj_t
*)p1
;
3558 isns_obj_t
*b
= (isns_obj_t
*)lcp
->data
[2].ptr
;
3570 const isns_obj_t
*vp
3581 lcp
->data
[2].ui
= uu
;
3585 lcp
->curr_uid
= uid
;
3586 match
= cache_lookup(lcp
, &uid
, cb_ref_new2old
);
3587 } while (match
== 0 && uid
!= 0);
3590 /* no such ref, create a default one */
3591 SET_UID_LCP(&lc
, et
, uu
);
3593 lc
.data
[2].ptr
= (uchar_t
*)vp
;
3595 ec
= cache_lookup(&lc
, NULL
, cb_new_ref
);
3604 const isns_obj_t
*p1
,
3605 const isns_obj_t
*p2
3610 if (is_obj_there(lcp
) != 0) {
3614 ec
= new_ref(p1
, p2
);
3621 const isns_obj_t
*p1
,
3622 const isns_obj_t
*p2
3629 obj
= make_ref
[p1
->type
](p1
, p2
);
3631 ec
= register_object(obj
, NULL
, NULL
);
3633 ec
= ISNS_RSP_INTERNAL_ERROR
;
3640 * ****************************************************************************
3643 * Physically remove an object along with the children objects,
3644 * the reference object and the parent object recursively.
3645 * Apporiate SCN is triggered.
3647 * lcp - the lookup control for the object being removed.
3648 * parent_flag - 1: the object being removed is the parent object;
3650 * child_flag - 1: the object being removed is a child object;
3652 * pending - 1: do not remove the ESI entry immediately;
3653 * 0: remove the ESI entry without any delay.
3654 * return - error code.
3656 * ****************************************************************************
3669 uint32_t *cuidp
, num
;
3674 /* remove the object from object container */
3675 obj
= cache_remove(lcp
, 0);
3682 if (scn_q
!= NULL
) {
3683 (void) make_scn(ISNS_OBJECT_REMOVED
, obj
);
3686 /* dereg children */
3688 while (ec
== 0 && !parent_flag
&&
3689 i
< NUM_OF_CHILD
[obj
->type
]) {
3690 type
= TYPE_OF_CHILD
[obj
->type
][i
];
3691 cuidp
= get_child_n(obj
, i
);
3692 if (cuidp
!= NULL
) {
3697 while (ec
== 0 && num
> 0) {
3700 SET_UID_LCP(lcp
, type
, uid
);
3711 /* clear the ref bit on the ref'd object */
3712 if (ec
== 0 && TYPE_OF_REF
[obj
->type
][0] > 0) {
3715 (void) setup_ref_lcp(lcp
, obj
, NULL
);
3716 lcp
->curr_uid
= uid
;
3717 lcp
->data
[2].ui
= obj
->type
;
3718 if (cache_lookup(lcp
, &uid
, cb_clear_ref
) != 0) {
3719 UPDATE_LCP_UID(lcp
, uid
);
3728 /* remove it from the parent */
3729 if (ec
== 0 && !child_flag
&&
3730 TYPE_OF_PARENT
[obj
->type
] > 0 &&
3731 (uid
= setup_parent_lcp(lcp
, obj
)) != 0) {
3732 if (cache_lookup(lcp
, NULL
, cb_remove_child
) != 0) {
3733 UPDATE_LCP_UID(lcp
, uid
);
3741 if (ec
== 0 && !child_flag
) {
3742 /* remove it from persistent data store */
3744 ec
= write_data(DATA_DELETE
, obj
);
3746 /* remove esi event entry */
3748 (void) esi_remove_obj(obj
, pending
);
3751 /* save the parent uid for caller */
3752 if (TYPE_OF_PARENT
[obj
->type
] != 0) {
3753 lcp
->curr_uid
= get_parent_uid(obj
);
3755 /* it's the parent itself */
3756 lcp
->curr_uid
= get_obj_uid(obj
);
3760 /* remove this portal from scn registry */
3762 obj
->type
== OBJ_PORTAL
) {
3763 (void) remove_scn_portal(get_obj_uid(obj
));
3766 /* free the object */
3767 (void) free_object(obj
);
3773 * ****************************************************************************
3776 * Remove one association object from object container.
3778 * lcp - the lookup control for the object being removed.
3779 * return - error code.
3781 * ****************************************************************************
3790 obj
= cache_remove(lcp
, 1);
3792 /* free the object */
3801 * ****************************************************************************
3804 * Remove one object from object container.
3806 * lcp - the lookup control for the object being removed.
3807 * return - error code.
3809 * ****************************************************************************
3817 return (do_dereg(lcp
, 0, 0, pending
));
3821 * ****************************************************************************
3824 * Synchronize the cache with persistent data store.
3825 * Flush the cache data to data store if the input ec is zero,
3826 * retreat the changes in cache and ignore data store update
3827 * if there is an error.
3830 * return - error code.
3832 * ****************************************************************************
3839 /* cache is updated successfully, commit the data to data store */
3840 if (IS_CACHE_UPDATED()) {
3842 ec
= write_data(DATA_COMMIT
, NULL
);
3845 /* successful, trigger the SCN */
3846 (void) queue_msg_set(scn_q
, SCN_TRIGGER
, NULL
);
3851 /* ignore all SCNs which have been generated */
3852 (void) queue_msg_set(scn_q
, SCN_IGNORE
, NULL
);
3854 (void) write_data(DATA_RETREAT
, NULL
);
3860 static pthread_mutex_t name_mtx
[3] = {
3861 PTHREAD_MUTEX_INITIALIZER
,
3862 PTHREAD_MUTEX_INITIALIZER
,
3863 PTHREAD_MUTEX_INITIALIZER
3865 static const char *name_pattern
[3] = {
3870 static uint32_t name_count
[3] = {
3877 * ****************************************************************************
3880 * make a default unique name for a newly registered network entity,
3881 * discovery domain or discovery domain set object.
3883 * len - pointer of the length of the new name for returning.
3884 * tag - which attribute of the new name is for.
3885 * return - the name being made.
3887 * ****************************************************************************
3897 char name
[32] = { 0 };
3906 case ISNS_EID_ATTR_ID
:
3908 lc
.type
= OBJ_ENTITY
;
3909 lc
.id
[0] = ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID
);
3911 case ISNS_DD_NAME_ATTR_ID
:
3914 lc
.id
[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID
);
3916 case ISNS_DD_SET_NAME_ATTR_ID
:
3919 lc
.id
[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID
);
3926 lc
.op
[0] = OP_STRING
;
3929 (void) pthread_mutex_lock(&name_mtx
[i
]);
3930 count
= ++ name_count
[i
];
3931 (void) pthread_mutex_unlock(&name_mtx
[i
]);
3932 /* no more space, failure */
3936 (void) sprintf(name
, name_pattern
[i
], count
);
3937 lc
.data
[0].ptr
= (uchar_t
*)name
;
3938 } while (is_obj_there(&lc
) != 0);
3940 /* 4-bytes aligned length */
3941 *len
= strlen(name
);
3942 *len
= *len
+ (4 - *len
% 4);
3943 p
= (char *)malloc(*len
);
3945 (void) strcpy(p
, name
);
3956 print_object(NULL
, (isns_obj_t
*)p
);