dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / isns / isnsd / obj.c
blob254a64a7e60b8ca3079c076acc7ce15adadc155f
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <pthread.h>
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"
40 #include "isns_pdu.h"
41 #include "isns_obj.h"
42 #include "isns_dd.h"
43 #include "isns_func.h"
44 #include "isns_dseng.h"
45 #include "isns_log.h"
46 #include "isns_scn.h"
47 #include "isns_utils.h"
48 #include "isns_esi.h"
51 * external variables
53 #ifdef DEBUG
54 extern int verbose_mc;
55 extern void print_object(char *, isns_obj_t *);
56 #endif
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;
66 * global data
70 * local variables
72 /* type of parent object */
73 const int TYPE_OF_PARENT[MAX_OBJ_TYPE_FOR_SIZE] = {
76 ISCSI_PARENT_TYPE,
77 PORTAL_PARENT_TYPE,
78 PG_PARENT_TYPE,
79 0, /* OBJ_DD */
80 0, /* OBJ_DDS */
81 0, /* MAX_OBJ_TYPE */
82 0, /* OBJ_DUMMY1 */
83 0, /* OBJ_DUMMY2 */
84 0, /* OBJ_DUMMY3 */
85 0, /* OBJ_DUMMY4 */
86 ASSOC_ISCSI_PARENT_TYPE,
87 ASSOC_DD_PARENT_TYPE
90 /* number of children object type */
91 const int NUM_OF_CHILD[MAX_OBJ_TYPE] = {
93 MAX_ENTITY_CHILD,
94 MAX_ISCSI_CHILD,
95 MAX_PORTAL_CHILD,
96 MAX_PG_CHILD,
101 /* type of a child object */
102 const int TYPE_OF_CHILD[MAX_OBJ_TYPE][MAX_CHILD_TYPE] = {
103 { 0, 0 },
104 { OBJ_ISCSI, OBJ_PORTAL },
105 { 0, 0 },
106 { 0, 0 },
107 { 0, 0 },
108 { 0, 0 },
109 { 0, 0 }
112 /* number of attributes of certain type of object */
113 const int NUM_OF_ATTRS[MAX_OBJ_TYPE_FOR_SIZE] = {
115 NUM_OF_ENTITY_ATTRS,
116 NUM_OF_ISCSI_ATTRS,
117 NUM_OF_PORTAL_ATTRS,
118 NUM_OF_PG_ATTRS,
119 NUM_OF_DD_ATTRS,
120 NUM_OF_DDS_ATTRS,
121 0, /* MAX_OBJ_TYPE */
122 0, /* OBJ_DUMMY1 */
123 0, /* OBJ_DUMMY2 */
124 0, /* OBJ_DUMMY3 */
125 0, /* OBJ_DUMMY4 */
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,
137 ISNS_DD_ID_ATTR_ID,
138 ISNS_DD_SET_ID_ATTR_ID,
139 0, /* MAX_OBJ_TYPE */
140 0, /* OBJ_DUMMY1 */
141 0, /* OBJ_DUMMY2 */
142 0, /* OBJ_DUMMY3 */
143 0, /* OBJ_DUMMY4 */
144 ISNS_DD_ISCSI_INDEX_ATTR_ID,
145 ISNS_DD_ID_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 */
158 0, /* OBJ_DUMMY1 */
159 0, /* OBJ_DUMMY2 */
160 0, /* OBJ_DUMMY3 */
161 0, /* OBJ_DUMMY4 */
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] = {
168 { 0 },
169 { ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID), 0 },
170 { ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID),
171 0 },
172 { ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID),
173 ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID),
174 0 },
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] = {
184 { 0 },
185 { OP_STRING, 0 },
186 { OP_STRING, 0 },
187 { OP_MEMORY_IP6, OP_INTEGER, 0 },
188 { OP_STRING, OP_MEMORY_IP6, OP_INTEGER },
189 { OP_STRING, 0 },
190 { OP_STRING, 0 }
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),
199 sizeof (isns_pg_t),
200 sizeof (isns_dd_t),
201 sizeof (isns_dds_t),
207 sizeof (isns_assoc_iscsi_t),
208 sizeof (isns_assoc_dd_t)
211 #ifdef DEBUG
212 const int NUM_OF_REF[MAX_OBJ_TYPE_FOR_SIZE] = {
213 #else
214 static const int NUM_OF_REF[MAX_OBJ_TYPE_FOR_SIZE] = {
215 #endif
220 PG_REF_COUNT,
232 /* the type of the reference object */
233 static const int TYPE_OF_REF[MAX_OBJ_TYPE][MAX_REF_COUNT + 1] = {
234 { 0 },
235 { 0 },
236 { OBJ_PG, OBJ_PORTAL, 0 },
237 { OBJ_PG, OBJ_ISCSI, 0 },
238 { 0, OBJ_ISCSI, OBJ_PORTAL },
239 { 0 },
240 { 0 }
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] = {
246 { 0, 0 },
247 { 0, 0 },
248 { OP_STRING, 0 },
249 { OP_MEMORY_IP6, OP_INTEGER },
250 { 0, 0 },
251 { 0, 0 },
252 { 0, 0 }
255 /* the index of the attribute of being matched object */
256 static const int REF_MATCH_ID1[MAX_OBJ_TYPE][MAX_REF_MATCH] = {
257 { 0, 0 },
258 { 0, 0 },
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) },
262 { 0, 0 },
263 { 0, 0 },
264 { 0, 0 }
267 /* the index of the attribute of matching object */
268 static const int REF_MATCH_ID2[MAX_OBJ_TYPE][MAX_REF_MATCH] = {
269 { 0, 0 },
270 { 0, 0 },
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) },
274 { 0, 0 },
275 { 0, 0 },
276 { 0, 0 }
280 * local functions.
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 *) = {
310 NULL,
311 NULL,
312 &make_default_pg,
313 &make_default_pg,
314 NULL,
315 NULL,
316 NULL
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 *) = {
327 NULL,
328 &entity_hval,
329 &iscsi_hval,
330 &portal_hval,
331 &pg_hval,
332 &dd_hval,
333 &dds_hval
337 * ****************************************************************************
339 * entity_hval:
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 * ****************************************************************************
351 static uint32_t
352 entity_hval(
353 void *p,
354 /* LINTED E_FUNC_ARG_UNUSED */
355 uint16_t chunk,
356 uint32_t *flags
359 uchar_t *key;
360 isns_obj_t *obj;
361 lookup_ctrl_t *lcp;
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)].
367 value.ptr;
368 } else {
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 * ****************************************************************************
380 * iscsi_hval:
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 * ****************************************************************************
392 static uint32_t
393 iscsi_hval(
394 void *p,
395 /* LINTED E_FUNC_ARG_UNUSED */
396 uint16_t chunk,
397 uint32_t *flags
400 uchar_t *key;
401 isns_obj_t *obj;
402 lookup_ctrl_t *lcp;
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)].
408 value.ptr;
409 } else {
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 * ****************************************************************************
421 * portal_hval:
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 * ****************************************************************************
432 static uint32_t
433 portal_hval(
434 void *p,
435 /* LINTED E_FUNC_ARG_UNUSED */
436 uint16_t chunk,
437 uint32_t *flags
440 char buff[INET6_ADDRSTRLEN + 8] = { 0 };
441 char buff2[8] = { 0 };
442 uchar_t *key;
443 isns_obj_t *obj;
444 lookup_ctrl_t *lcp;
446 in6_addr_t *ip;
447 uint32_t port;
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;
456 } else {
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 * ****************************************************************************
474 * pg_hval:
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 * ****************************************************************************
485 static uint32_t
486 pg_hval(
487 void *p,
488 uint16_t chunk,
489 uint32_t *flags
492 char buff[INET6_ADDRSTRLEN + 8] = { 0 };
493 char buff2[8] = { 0 };
494 uchar_t *key = NULL;
495 isns_obj_t *obj;
496 lookup_ctrl_t *lcp;
498 in6_addr_t *ip = NULL;
499 uint32_t port;
501 if ((*flags & FLAGS_CTRL_MASK) == 0) {
502 /* p is a portal group object */
503 obj = (isns_obj_t *)p;
504 if (chunk == 0) {
505 /* the first chunk */
506 key = obj->attrs[ATTR_INDEX_PG
507 (ISNS_PG_ISCSI_NAME_ATTR_ID)].value.ptr;
508 } else {
509 /* another chunk */
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;
515 } else {
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;
523 } else {
524 /* another chunk */
525 ip = lcp->data[0].ip;
526 port = lcp->data[1].ui;
527 *flags |= 1;
531 if (key == NULL) {
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 * ****************************************************************************
544 * dd_hval:
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 * ****************************************************************************
555 static uint32_t
556 dd_hval(
557 void *p,
558 /* LINTED E_FUNC_ARG_UNUSED */
559 uint16_t chunk,
560 uint32_t *flags
563 uchar_t *key;
564 isns_obj_t *obj;
565 lookup_ctrl_t *lcp;
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)].
571 value.ptr;
572 } else {
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 * ****************************************************************************
584 * dds_hval:
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 * ****************************************************************************
595 static uint32_t
596 dds_hval(
597 void *p,
598 /* LINTED E_FUNC_ARG_UNUSED */
599 uint16_t chunk,
600 uint32_t *flags
603 uchar_t *key;
604 isns_obj_t *obj;
605 lookup_ctrl_t *lcp;
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)].
611 value.ptr;
612 } else {
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 * ****************************************************************************
624 * obj_hval:
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 * ****************************************************************************
635 uint32_t
636 obj_hval(
637 void *p,
638 uint16_t chunk,
639 uint32_t *flags
642 isns_type_t type = ((isns_obj_t *)p)->type;
644 return (hval_func[type](p, chunk, flags));
648 * ****************************************************************************
650 * get_obj_uid:
651 * get the UID of an object.
653 * p - the pointer pointers to an object.
654 * return - the UID.
656 * ****************************************************************************
658 uint32_t
659 get_obj_uid(
660 const void *p
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;
666 return (uid);
670 * ****************************************************************************
672 * set_obj_uid:
673 * set the UID of an object.
675 * p - the pointer pointers to an object.
676 * uid - the UID.
677 * return - the UID.
679 * ****************************************************************************
681 uint32_t
682 set_obj_uid(
683 void *p,
684 uint32_t uid
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];
692 attr->len = 4;
693 attr->value.ui = uid;
695 return (uid);
699 * ****************************************************************************
701 * obj_cmp:
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 * ****************************************************************************
712 obj_cmp(
713 void *p1,
714 void *p2,
715 int flags
718 isns_obj_t *obj = (isns_obj_t *)p1;
719 lookup_ctrl_t buff = { 0 };
720 lookup_ctrl_t *lcp;
721 uint32_t uid;
723 if (flags == 0) {
724 lcp = set_lookup_ctrl(&buff, (isns_obj_t *)p2);
725 } else {
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) {
733 return (-1);
737 return (key_cmp(lcp, obj));
741 * ****************************************************************************
743 * replace_object:
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 * ****************************************************************************
755 replace_object(
756 void *p1,
757 void *p2,
758 uint32_t *uid_p,
759 int flag
762 int ec = 0;
764 #ifndef SKIP_SRC_AUTH
765 uint32_t *pp_dst, *pp_src, swap;
766 #endif
767 int online;
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 */
780 SET_CACHE_UPDATED();
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);
787 swap = *pp_dst;
788 *pp_dst = *pp_src;
789 if (swap != 0) {
790 *pp_src = swap;
793 #endif
795 /* update all of attributes */
796 if (copy_attrs(dst, src) != 0) {
797 return (ISNS_RSP_INTERNAL_ERROR);
800 /* free up the src object */
801 if (flag != 0) {
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 */
809 if (sys_q != NULL) {
810 ec = write_data(DATA_UPDATE, dst);
811 } else {
812 /* we should never have duplicated entry in data store */
813 ec = ISNS_RSP_INTERNAL_ERROR;
816 /* trigger a scn */
817 if (ec == 0) {
818 if (scn_q != NULL) {
819 (void) make_scn((online == 0) ?
820 ISNS_OBJECT_ADDED :
821 ISNS_OBJECT_UPDATED,
822 dst);
824 if (uid_p != NULL) {
825 *uid_p = get_obj_uid(dst);
829 return (ec);
833 * ****************************************************************************
835 * add_object:
836 * post function after adding a new object.
838 * p - object which has been added.
839 * return - error code.
841 * ****************************************************************************
844 add_object(
845 void *p
848 int ec = 0;
850 isns_obj_t *obj = (isns_obj_t *)p;
852 /* add the new object to data store */
853 if (sys_q != NULL) {
854 ec = write_data(DATA_ADD, obj);
857 /* trigger a scn */
858 if (ec == 0 && scn_q != NULL) {
859 (void) make_scn(ISNS_OBJECT_ADDED, obj);
862 return (ec);
866 * ****************************************************************************
868 * obj_tab_init:
869 * initialize the object hash tables.
871 * c - points to the cache.
872 * return - error code.
874 * ****************************************************************************
877 obj_tab_init(
878 struct cache *c
881 htab_t *t;
883 htab_init();
886 * allocate an array of pointer for the object hash tables.
888 c->t = (struct htab **)calloc(sizeof (struct htab *), MAX_OBJ_TYPE);
889 if (c->t == NULL) {
890 return (1);
894 * hash table for network entity objects.
896 t = htab_create(UID_FLAGS_SEQ, 8, 1);
897 if (t != NULL) {
898 t->c = c;
899 c->t[OBJ_ENTITY] = t;
900 } else {
901 return (1);
905 * hash table for iscsi storage node objects.
907 t = htab_create(UID_FLAGS_SEQ, 8, 1);
908 if (t != NULL) {
909 t->c = c;
910 c->t[OBJ_ISCSI] = t;
911 } else {
912 return (1);
916 * hash table for portal objects.
918 t = htab_create(UID_FLAGS_SEQ, 8, 1);
919 if (t != NULL) {
920 t->c = c;
921 c->t[OBJ_PORTAL] = t;
922 } else {
923 return (1);
927 * hash table for portal group objects.
929 t = htab_create(UID_FLAGS_SEQ, 8, 2);
930 if (t != NULL) {
931 t->c = c;
932 c->t[OBJ_PG] = t;
933 } else {
934 return (1);
938 * hash table for discovery domain objects.
940 t = htab_create(0, 6, 1);
941 if (t != NULL) {
942 t->c = c;
943 c->t[OBJ_DD] = t;
944 } else {
945 return (1);
949 * hash table for discovery domain set objects.
951 t = htab_create(0, 4, 1);
952 if (t != NULL) {
953 t->c = c;
954 c->t[OBJ_DDS] = t;
955 } else {
956 return (1);
959 return (0);
963 * ****************************************************************************
965 * get_ref_np:
966 * get the ref pointer of the portal group object.
968 * obj - portal group object.
969 * return - ref pointer.
971 * ****************************************************************************
973 static uint32_t *
974 get_ref_np(
975 isns_obj_t *obj,
976 int n
979 uint32_t *refp =
980 obj->type == OBJ_PG ? &((isns_pg_t *)obj)->ref[n] : NULL;
982 return (refp);
985 #ifdef DEBUG
986 uint32_t
987 #else
988 static uint32_t
989 #endif
990 get_ref_n(
991 isns_obj_t *obj,
992 int n
995 return (*get_ref_np(obj, n));
998 static uint32_t *
999 get_ref_p(
1000 isns_obj_t *obj,
1001 isns_type_t rt
1004 isns_type_t t = obj->type;
1006 int i = 0;
1007 while (i < NUM_OF_REF[t]) {
1008 if (rt == TYPE_OF_REF[t][i + 1]) {
1009 return (get_ref_np(obj, i));
1011 i ++;
1014 return (NULL);
1017 uint32_t
1018 get_ref_t(
1019 isns_obj_t *obj,
1020 isns_type_t type
1023 uint32_t *refp = get_ref_p(obj, type);
1025 if (refp != NULL) {
1026 return (*refp);
1027 /* LINTED E_NOP_ELSE_STMT */
1028 } else {
1029 ASSERT(0);
1032 return (0);
1036 * ****************************************************************************
1038 * get_parent_p:
1039 * get the pointer of the parent object.
1041 * obj - an object.
1042 * return - parent object pointer.
1044 * ****************************************************************************
1046 uint32_t *
1047 get_parent_p(
1048 const isns_obj_t *obj
1051 uint32_t *pp;
1052 switch (obj->type) {
1053 case OBJ_ISCSI:
1054 pp = &((isns_iscsi_t *)obj)->puid;
1055 break;
1056 case OBJ_PORTAL:
1057 pp = &((isns_portal_t *)obj)->puid;
1058 break;
1059 case OBJ_PG:
1060 pp = &((isns_pg_t *)obj)->puid;
1061 break;
1062 case OBJ_ASSOC_ISCSI:
1063 pp = &((isns_assoc_iscsi_t *)obj)->puid;
1064 break;
1065 case OBJ_ASSOC_DD:
1066 pp = &((isns_assoc_dd_t *)obj)->puid;
1067 break;
1068 default:
1069 pp = NULL;
1070 break;
1073 return (pp);
1076 uint32_t
1077 get_parent_uid(
1078 const isns_obj_t *obj
1081 uint32_t *pp = get_parent_p(obj);
1082 if (pp != NULL) {
1083 return (*pp);
1086 return (0);
1090 * ****************************************************************************
1092 * get_child_np:
1093 * get the pointer of the UID array of the n'th child of an object.
1095 * obj - an object.
1096 * n - the child index.
1097 * return - the pointer of the UID array.
1099 * ****************************************************************************
1101 static uint32_t **
1102 get_child_np(
1103 isns_obj_t *obj,
1104 int n
1107 uint32_t **pp =
1108 obj->type == OBJ_ENTITY ? &((isns_entity_t *)obj)->cuid[n] : NULL;
1110 return (pp);
1114 * ****************************************************************************
1116 * get_child_n:
1117 * get the UID array of the n'th child of an object.
1119 * obj - an object.
1120 * n - the child index.
1121 * return - the UID array.
1123 * ****************************************************************************
1125 #ifdef DEBUG
1126 uint32_t *
1127 #else
1128 static uint32_t *
1129 #endif
1130 get_child_n(
1131 isns_obj_t *obj,
1132 int n
1135 uint32_t **pp = get_child_np(obj, n);
1137 if (pp != NULL) {
1138 return (*pp);
1141 ASSERT(0);
1142 return (NULL);
1146 * ****************************************************************************
1148 * get_child_p:
1149 * get the pointer of the UID array of the child matching the type.
1151 * base - an object.
1152 * child_type - the child object type.
1153 * return - the pointer of the UID array.
1155 * ****************************************************************************
1157 static uint32_t **
1158 get_child_p(
1159 isns_obj_t *base,
1160 int child_type
1163 uint32_t **pp = NULL;
1164 int i = 0;
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);
1168 break;
1170 i ++;
1173 return (pp);
1177 * ****************************************************************************
1179 * get_child_t:
1180 * get the UID array of the child object matching the type.
1182 * base - an object.
1183 * child_type - the child object type.
1184 * return - the UID array.
1186 * ****************************************************************************
1188 uint32_t *
1189 get_child_t(
1190 isns_obj_t *base,
1191 int child_type
1194 uint32_t **pp = get_child_p(base, child_type);
1196 if (pp != NULL) {
1197 return (*pp);
1198 } else {
1199 return (NULL);
1204 * ****************************************************************************
1206 * key_cmp:
1207 * compare the object against the lookup control data.
1209 * lcp - the lookup control data.
1210 * obj - an object.
1211 * return - comparison result.
1213 * ****************************************************************************
1216 key_cmp(
1217 lookup_ctrl_t *lcp,
1218 isns_obj_t *obj
1221 int i = 0;
1222 int match = 1;
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]) {
1226 case OP_STRING:
1227 match = (strcmp((const char *)lcp->data[i].ptr,
1228 (const char *)attr->value.ptr) == 0);
1229 break;
1230 case OP_INTEGER:
1231 match = (lcp->data[i].ui == attr->value.ui);
1232 break;
1233 case OP_MEMORY_IP6:
1234 match = !memcmp((void *)lcp->data[i].ip,
1235 (void *)attr->value.ip,
1236 sizeof (in6_addr_t));
1237 break;
1238 default:
1239 ASSERT(0);
1240 match = 0;
1241 break;
1243 i ++;
1246 if (i && match) {
1247 return (0);
1248 } else {
1249 return (1);
1254 * ****************************************************************************
1256 * set_lookup_ctrl:
1257 * fill in the lookup control data for an object.
1259 * lcp - the lookup control data.
1260 * obj - an object.
1261 * return - the lookup control data.
1263 * ****************************************************************************
1265 static lookup_ctrl_t *
1266 set_lookup_ctrl(
1267 lookup_ctrl_t *lcp,
1268 isns_obj_t *obj
1271 isns_type_t type = obj->type;
1272 uint32_t id, op;
1273 int i = 0;
1275 lcp->type = type;
1276 while (i < MAX_KEY_ATTRS) {
1277 op = KEY_ATTR_OP[type][i];
1278 if (op != 0) {
1279 id = KEY_ATTR_INDEX[type][i];
1280 lcp->id[i] = id;
1281 lcp->op[i] = op;
1282 lcp->data[i].ui = obj->attrs[id].value.ui;
1283 } else {
1284 break;
1286 i ++;
1289 return (lcp);
1293 * ****************************************************************************
1295 * assign_attr:
1296 * assign an attribute.
1298 * attr - the attribute being assigned.
1299 * tmp - the attribute.
1300 * return - error code.
1302 * ****************************************************************************
1305 assign_attr(
1306 isns_attr_t *attr,
1307 const isns_attr_t *tmp
1310 uint32_t t;
1312 switch (tmp->tag) {
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) {
1317 int len;
1318 char *name = make_unique_name(&len, tmp->tag);
1319 if (name != NULL) {
1320 attr->value.ptr = (uchar_t *)name;
1321 attr->tag = tmp->tag;
1322 attr->len = len;
1323 } else {
1324 /* memory exhausted */
1325 return (1);
1328 case ISNS_PORTAL_NAME_ATTR_ID:
1329 case ISNS_ISCSI_NAME_ATTR_ID:
1330 case ISNS_ISCSI_ALIAS_ATTR_ID:
1331 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
1332 case ISNS_PG_ISCSI_NAME_ATTR_ID:
1333 case ISNS_DD_ISCSI_NAME_ATTR_ID:
1334 if (tmp->len == 0) {
1335 return (0);
1336 } else if (tmp->len >= attr->len) {
1337 attr->value.ptr = realloc(
1338 attr->value.ptr, tmp->len + 1);
1340 if (attr->value.ptr != NULL) {
1341 (void) strncpy((char *)attr->value.ptr,
1342 (char *)tmp->value.ptr, tmp->len);
1343 attr->value.ptr[tmp->len] = 0;
1344 attr->tag = tmp->tag;
1345 attr->len = tmp->len;
1346 } else {
1347 /* memory exhausted */
1348 return (1);
1350 break;
1351 case ISNS_MGMT_IP_ADDR_ATTR_ID:
1352 case ISNS_PORTAL_IP_ADDR_ATTR_ID:
1353 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
1354 if (attr->value.ip == NULL) {
1355 attr->value.ip = (in6_addr_t *)calloc(1, tmp->len);
1357 if (attr->value.ip != NULL) {
1358 (void) memcpy((void *)attr->value.ip,
1359 (void *)tmp->value.ip, tmp->len);
1360 attr->tag = tmp->tag;
1361 attr->len = tmp->len;
1362 } else {
1363 /* memory exhausted */
1364 return (1);
1366 break;
1367 case ISNS_ENTITY_INDEX_ATTR_ID:
1368 case ISNS_PORTAL_INDEX_ATTR_ID:
1369 case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
1370 case ISNS_PG_INDEX_ATTR_ID:
1371 case ISNS_DD_SET_ID_ATTR_ID:
1372 case ISNS_DD_ID_ATTR_ID:
1373 if (attr->value.ui != 0) {
1374 break;
1376 case ISNS_ENTITY_PROTOCOL_ATTR_ID:
1377 case ISNS_VERSION_RANGE_ATTR_ID:
1379 case ISNS_PORTAL_PORT_ATTR_ID:
1380 case ISNS_ESI_PORT_ATTR_ID:
1381 case ISNS_SCN_PORT_ATTR_ID:
1383 case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
1384 case ISNS_ISCSI_SCN_BITMAP_ATTR_ID:
1386 case ISNS_PG_PORTAL_PORT_ATTR_ID:
1387 case ISNS_PG_TAG_ATTR_ID:
1389 case ISNS_DD_SET_STATUS_ATTR_ID:
1390 case ISNS_DD_ISCSI_INDEX_ATTR_ID:
1391 attr->tag = tmp->tag;
1392 attr->len = tmp->len;
1393 attr->value.ui = tmp->value.ui;
1394 break;
1395 case ISNS_ENTITY_REG_PERIOD_ATTR_ID:
1396 attr->tag = tmp->tag;
1397 attr->len = tmp->len;
1398 attr->value.ui = tmp->value.ui;
1399 t = get_reg_period();
1400 if (attr->value.ui > t) {
1401 attr->value.ui = t;
1402 } else if (attr->value.ui < ONE_DAY) {
1403 attr->value.ui = ONE_DAY;
1405 break;
1406 case ISNS_ESI_INTERVAL_ATTR_ID:
1407 attr->tag = tmp->tag;
1408 attr->len = tmp->len;
1409 attr->value.ui = tmp->value.ui;
1410 if (attr->value.ui > ONE_DAY) {
1411 attr->value.ui = ONE_DAY;
1412 } else if (attr->value.ui < MIN_ESI_INTVAL) {
1413 attr->value.ui = MIN_ESI_INTVAL; /* 20 seconds */
1415 break;
1416 default:
1417 ASSERT(0);
1418 /* don't assign the attribute */
1419 break;
1421 return (0);
1425 * ****************************************************************************
1427 * copy_attrs:
1428 * copy all of attributes from one object to another.
1430 * dst - the destination object.
1431 * tmp - the source object.
1432 * return - error code.
1434 * ****************************************************************************
1436 static int
1437 copy_attrs(
1438 isns_obj_t *dst,
1439 const isns_obj_t *src
1442 int i = 0;
1443 int n = NUM_OF_ATTRS[dst->type];
1445 isns_attr_t *dst_attr;
1446 const isns_attr_t *src_attr;
1448 while (i < n) {
1449 src_attr = &(src->attrs[i]);
1450 if (src_attr->tag != 0) {
1451 dst_attr = &(dst->attrs[i]);
1452 if (assign_attr(dst_attr, src_attr) != 0) {
1453 return (1);
1456 i ++;
1459 return (0);
1463 * ****************************************************************************
1465 * extract_attr:
1466 * extract an attribute from a TLV format data.
1468 * attr - the attribute.
1469 * tlv - the TLV format data.
1470 * return - error code.
1472 * ****************************************************************************
1475 extract_attr(
1476 isns_attr_t *attr,
1477 const isns_tlv_t *tlv,
1478 int flag
1481 int ec = 0;
1483 uint32_t min_len = 4, max_len = 224;
1485 switch (tlv->attr_id) {
1486 case ISNS_EID_ATTR_ID:
1487 min_len = 0;
1488 case ISNS_PORTAL_NAME_ATTR_ID:
1489 case ISNS_ISCSI_ALIAS_ATTR_ID:
1490 case ISNS_DD_SET_NAME_ATTR_ID:
1491 case ISNS_DD_NAME_ATTR_ID:
1492 max_len = 256;
1493 case ISNS_ISCSI_NAME_ATTR_ID:
1494 case ISNS_PG_ISCSI_NAME_ATTR_ID:
1495 if (tlv->attr_len < min_len || tlv->attr_len > max_len) {
1496 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1497 } else {
1498 attr->tag = tlv->attr_id;
1499 attr->len = tlv->attr_len;
1500 attr->value.ptr = (uchar_t *)&(tlv->attr_value[0]);
1502 break;
1503 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
1504 attr->tag = tlv->attr_id;
1505 attr->len = tlv->attr_len;
1506 attr->value.ptr = (uchar_t *)&(tlv->attr_value[0]);
1507 break;
1508 case ISNS_MGMT_IP_ADDR_ATTR_ID:
1509 case ISNS_PORTAL_IP_ADDR_ATTR_ID:
1510 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
1511 if (tlv->attr_len != 16) {
1512 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1513 } else {
1514 attr->tag = tlv->attr_id;
1515 attr->len = tlv->attr_len;
1516 attr->value.ip = (void *)&(tlv->attr_value[0]);
1518 break;
1519 case ISNS_ENTITY_PROTOCOL_ATTR_ID:
1520 case ISNS_VERSION_RANGE_ATTR_ID:
1521 case ISNS_ENTITY_REG_PERIOD_ATTR_ID:
1522 /* fall throught */
1523 case ISNS_PORTAL_PORT_ATTR_ID:
1524 case ISNS_ESI_INTERVAL_ATTR_ID:
1525 case ISNS_ESI_PORT_ATTR_ID:
1526 case ISNS_SCN_PORT_ATTR_ID:
1527 /* fall throught */
1528 case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
1529 /* fall throught */
1530 case ISNS_PG_PORTAL_PORT_ATTR_ID:
1531 /* fall throught */
1532 case ISNS_DD_SET_ID_ATTR_ID:
1533 case ISNS_DD_SET_STATUS_ATTR_ID:
1534 /* fall throught */
1535 case ISNS_DD_ID_ATTR_ID:
1536 if (tlv->attr_len != 4) {
1537 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1538 break;
1540 case ISNS_PG_TAG_ATTR_ID:
1541 attr->tag = tlv->attr_id;
1542 attr->len = tlv->attr_len;
1543 if (tlv->attr_len == 4) {
1544 attr->value.ui = ntohl(*(uint32_t *)
1545 &(tlv->attr_value[0]));
1546 } else {
1547 attr->value.ui = 0;
1549 break;
1550 case ISNS_ISCSI_SCN_BITMAP_ATTR_ID:
1551 /* ignore scn bitmap attribute during object registration, */
1552 /* it is registered by scn_reg message. */
1553 case ISNS_ENTITY_ISAKMP_P1_ATTR_ID:
1554 case ISNS_ENTITY_CERT_ATTR_ID:
1555 case ISNS_PORTAL_SEC_BMP_ATTR_ID:
1556 case ISNS_PORTAL_ISAKMP_P1_ATTR_ID:
1557 case ISNS_PORTAL_ISAKMP_P2_ATTR_ID:
1558 case ISNS_PORTAL_CERT_ATTR_ID:
1559 break;
1560 case ISNS_PORTAL_INDEX_ATTR_ID:
1561 case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
1562 case ISNS_PG_INDEX_ATTR_ID:
1563 if (flag == 0) {
1564 if (tlv->attr_len != 4) {
1565 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1566 } else {
1567 attr->tag = tlv->attr_id;
1568 attr->len = tlv->attr_len;
1569 attr->value.ui = ntohl(*(uint32_t *)
1570 &(tlv->attr_value[0]));
1572 break;
1574 case ISNS_ENTITY_INDEX_ATTR_ID:
1575 case ISNS_TIMESTAMP_ATTR_ID:
1576 default:
1577 if (flag == 0) {
1578 ec = ISNS_RSP_INVALID_QRY;
1579 } else {
1580 ec = ISNS_RSP_INVALID_REGIS;
1582 break;
1585 return (ec);
1589 * ****************************************************************************
1591 * copy_attr:
1592 * copy an attribute from a TLV format data.
1594 * attr - the attribute.
1595 * tlv - the TLV format data.
1596 * return - error code.
1598 * ****************************************************************************
1600 static int
1601 copy_attr(
1602 isns_attr_t *attr,
1603 const isns_tlv_t *tlv
1606 int ec = 0;
1608 isns_attr_t tmp = { 0 };
1610 /* extract the attribute first */
1611 ec = extract_attr(&tmp, tlv, 1);
1613 /* assign the attribute */
1614 if (ec == 0 && tmp.tag != 0) {
1615 if (assign_attr(attr, &tmp) != 0) {
1616 ec = ISNS_RSP_INTERNAL_ERROR;
1620 return (ec);
1624 * ****************************************************************************
1626 * get_timestamp:
1627 * get current timestamp.
1629 * return - current timestamp.
1631 * ****************************************************************************
1633 uint32_t
1634 get_timestamp(
1637 uint32_t t;
1638 int flag;
1640 /* block the scheduler */
1641 (void) pthread_mutex_lock(&el_mtx);
1643 /* get most current time */
1644 if (sys_q != NULL) {
1645 /* need to wakeup idle */
1646 flag = 1;
1647 } else {
1648 flag = 0;
1650 t = get_stopwatch(flag);
1652 /* unblock it */
1653 (void) pthread_mutex_unlock(&el_mtx);
1655 return (t);
1659 * ****************************************************************************
1661 * get_reg_period:
1662 * get the longest registration period.
1664 * return - the longest registration period.
1666 * ****************************************************************************
1668 static uint32_t
1669 get_reg_period(
1672 uint32_t t;
1673 uint32_t period;
1675 /* get most current time */
1676 t = get_timestamp();
1678 /* just one second before the end of the world */
1679 period = INFINITY - t - 1;
1681 return (period);
1685 * ****************************************************************************
1687 * obj_calloc:
1688 * allocate memory space for an object.
1690 * type - the object type.
1691 * return - pointer of the object being allocated.
1693 * ****************************************************************************
1695 isns_obj_t *
1696 obj_calloc(
1697 int type
1700 isns_obj_t *obj = NULL;
1702 obj = (isns_obj_t *)calloc(1, SIZEOF_OBJ[type]);
1703 if (obj != NULL) {
1704 obj->type = type;
1705 #ifdef DEBUG
1706 if (verbose_mc) {
1707 printf("object(%d) allocated\n", type);
1709 #endif
1712 return (obj);
1716 * ****************************************************************************
1718 * make_default_entity:
1719 * generate a default network entity object.
1721 * return - pointer of the default network entity object.
1723 * ****************************************************************************
1725 isns_obj_t *
1726 make_default_entity(
1729 uint32_t t;
1731 isns_obj_t *obj = obj_calloc(OBJ_ENTITY);
1732 isns_attr_t *attr;
1733 if (obj != NULL) {
1734 int len;
1735 char *eid = make_unique_name(&len, ISNS_EID_ATTR_ID);
1736 if (!eid) {
1737 free(obj);
1738 return (NULL);
1740 attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)];
1742 /* set default entity name */
1743 attr->tag = ISNS_EID_ATTR_ID;
1744 attr->len = len;
1745 attr->value.ptr = (uchar_t *)eid;
1747 /* set default registration period */
1748 attr = &obj->attrs[
1749 ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID)];
1750 if (attr->tag == 0) {
1751 attr->tag = ISNS_ENTITY_REG_PERIOD_ATTR_ID;
1752 attr->len = 4;
1753 t = get_reg_period();
1754 attr->value.ui = t;
1758 return (obj);
1762 * ****************************************************************************
1764 * make_default_pg:
1765 * generate a default portal group object.
1767 * iscsi - the iscsi storage node object.
1768 * portal - the portal object.
1769 * return - pointer of the default portal group object.
1771 * ****************************************************************************
1773 static isns_obj_t *
1774 make_default_pg(
1775 const isns_obj_t *p1,
1776 const isns_obj_t *p2
1779 const isns_obj_t *iscsi, *portal;
1780 const isns_attr_t *name, *addr, *port;
1781 isns_obj_t *pg;
1783 uchar_t *pg_name;
1784 in6_addr_t *pg_addr;
1786 isns_attr_t *attr;
1788 uint32_t *refp;
1790 if (p1->type == OBJ_ISCSI) {
1791 iscsi = p1;
1792 portal = p2;
1793 } else {
1794 iscsi = p2;
1795 portal = p1;
1797 name = &iscsi->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
1798 addr = &portal->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID)];
1799 port = &portal->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID)];
1801 pg = obj_calloc(OBJ_PG);
1802 pg_name = (uchar_t *)malloc(name->len);
1803 pg_addr = (in6_addr_t *)malloc(addr->len);
1804 if (pg != NULL && pg_name != NULL && pg_addr != NULL) {
1805 (void) strcpy((char *)pg_name, (char *)name->value.ptr);
1806 attr = &pg->attrs[ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID)];
1807 attr->tag = ISNS_PG_ISCSI_NAME_ATTR_ID;
1808 attr->len = name->len;
1809 attr->value.ptr = pg_name;
1811 (void) memcpy((void *)pg_addr,
1812 (void *)addr->value.ip, addr->len);
1813 attr = &pg->attrs[ATTR_INDEX_PG(
1814 ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)];
1815 attr->tag = ISNS_PG_PORTAL_IP_ADDR_ATTR_ID;
1816 attr->len = addr->len;
1817 attr->value.ip = pg_addr;
1819 attr = &pg->attrs[ATTR_INDEX_PG(
1820 ISNS_PG_PORTAL_PORT_ATTR_ID)];
1821 attr->tag = ISNS_PG_PORTAL_PORT_ATTR_ID;
1822 attr->len = port->len;
1823 attr->value.ui = port->value.ui;
1825 attr = &pg->attrs[ATTR_INDEX_PG(
1826 ISNS_PG_TAG_ATTR_ID)];
1827 attr->tag = ISNS_PG_TAG_ATTR_ID;
1828 attr->len = 4;
1829 attr->value.ui = ISNS_DEFAULT_PGT;
1831 refp = get_ref_p(pg, OBJ_ISCSI);
1832 *refp = get_obj_uid(iscsi);
1834 refp = get_ref_p(pg, OBJ_PORTAL);
1835 *refp = get_obj_uid(portal);
1837 (void) set_parent_obj(pg, get_parent_uid(iscsi));
1838 } else {
1839 free(pg);
1840 free(pg_name);
1841 free(pg_addr);
1842 pg = NULL;
1845 return (pg);
1849 * ****************************************************************************
1851 * reg_get_entity:
1852 * parse the Operating Attributes of the DevAttrReg message and
1853 * create the Network Entity object if it has one.
1855 * p - the pointer of the object for returning.
1856 * op - the operating attributes.
1857 * op_len - the length of the operating attributes.
1858 * return - error code.
1860 * ****************************************************************************
1863 reg_get_entity(
1864 isns_obj_t **p,
1865 isns_tlv_t **op,
1866 uint16_t *op_len
1869 int ec = 0;
1871 isns_tlv_t *tmp;
1872 uint16_t tmp_len;
1873 isns_attr_t *attr;
1875 isns_obj_t *entity = NULL;
1877 tmp = *op;
1878 tmp_len = *op_len;
1880 /* parse the entity object */
1881 if (tmp_len >= 8 && IS_ENTITY_KEY(tmp->attr_id)) {
1882 entity = obj_calloc(OBJ_ENTITY);
1883 if (entity != NULL) {
1884 do {
1885 attr = &entity->attrs[
1886 ATTR_INDEX_ENTITY(tmp->attr_id)];
1887 ec = copy_attr(attr, tmp);
1888 NEXT_TLV(tmp, tmp_len);
1889 } while (ec == 0 &&
1890 tmp_len >= 8 &&
1891 IS_ENTITY_ATTR(tmp->attr_id));
1892 } else {
1893 ec = ISNS_RSP_INTERNAL_ERROR;
1896 if (ec == 0) {
1897 /* set default registration period */
1898 attr = &entity->attrs[
1899 ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID)];
1900 if (attr->tag == 0) {
1901 attr->tag = ISNS_ENTITY_REG_PERIOD_ATTR_ID;
1902 attr->len = 4;
1903 attr->value.ui = get_reg_period();
1905 } else if (entity != NULL) {
1906 free(entity);
1907 entity = NULL;
1911 *p = entity;
1912 *op = tmp;
1913 *op_len = tmp_len;
1915 return (ec);
1919 * ****************************************************************************
1921 * reg_get_iscsi:
1922 * parse the Operating Attributes of the DevAttrReg message and
1923 * create an iSCSI Storage Node object.
1925 * p - the pointer of the object for returning.
1926 * pg_key1 - the pointer of iscsi storage node name for returning.
1927 * op - the operating attributes.
1928 * op_len - the length of the operating attributes.
1929 * return - error code.
1931 * ****************************************************************************
1933 static int
1934 reg_get_iscsi(
1935 isns_obj_t **p,
1936 isns_attr_t *pg_key1,
1937 isns_tlv_t **op,
1938 uint16_t *op_len
1941 int ec = 0;
1943 isns_tlv_t *tmp;
1944 uint16_t tmp_len;
1945 isns_attr_t *attr;
1947 isns_obj_t *obj = NULL;
1949 tmp = *op;
1950 tmp_len = *op_len;
1952 /* keep the iscsi storage node name for */
1953 /* parsing a pg object which is immediately */
1954 /* followed with a PGT by the iscsi storage node */
1955 pg_key1->tag = PG_KEY1;
1956 pg_key1->len = tmp->attr_len;
1957 pg_key1->value.ptr = (uchar_t *)&tmp->attr_value[0];
1959 /* parse one iscsi storage node object */
1960 obj = obj_calloc(OBJ_ISCSI);
1961 if (obj != NULL) {
1962 /* parse key & non-key attributes */
1963 do {
1964 attr = &obj->attrs[
1965 ATTR_INDEX_ISCSI(tmp->attr_id)];
1966 ec = copy_attr(attr, tmp);
1967 NEXT_TLV(tmp, tmp_len);
1968 } while (ec == 0 &&
1969 tmp_len >= 8 &&
1970 IS_ISCSI_ATTR(tmp->attr_id));
1971 } else {
1972 /* no memory */
1973 ec = ISNS_RSP_INTERNAL_ERROR;
1976 *p = obj;
1977 *op = tmp;
1978 *op_len = tmp_len;
1980 return (ec);
1984 * ****************************************************************************
1986 * reg_get_portal:
1987 * parse the Operating Attributes of the DevAttrReg message and
1988 * create a Portal object.
1990 * p - the pointer of the object for returning.
1991 * pg_key1 - the pointer of portal ip addr for returning.
1992 * pg_key2 - the pointer of portal port for returning.
1993 * op - the operating attributes.
1994 * op_len - the length of the operating attributes.
1995 * return - error code.
1997 * ****************************************************************************
1999 static int
2000 reg_get_portal(
2001 isns_obj_t **p,
2002 isns_attr_t *pg_key1,
2003 isns_attr_t *pg_key2,
2004 isns_tlv_t **op,
2005 uint16_t *op_len
2008 int ec = 0;
2010 isns_tlv_t *tmp;
2011 uint16_t tmp_len;
2012 isns_attr_t *attr;
2014 isns_obj_t *obj = NULL;
2016 isns_tlv_t *ip;
2018 tmp = *op;
2019 tmp_len = *op_len;
2021 /* keep the portal ip addr */
2022 pg_key1->tag = PG_KEY2;
2023 pg_key1->len = tmp->attr_len;
2024 pg_key1->value.ip = (void *)&tmp->attr_value[0];
2025 ip = tmp;
2027 NEXT_TLV(tmp, tmp_len);
2028 if (tmp_len > 8 &&
2029 tmp->attr_id == PORTAL_KEY2 &&
2030 tmp->attr_len == 4) {
2031 /* keep the portal port */
2032 pg_key2->tag = PG_KEY3;
2033 pg_key2->len = tmp->attr_len;
2034 pg_key2->value.ui = ntohl(*(uint32_t *)&tmp->attr_value[0]);
2036 /* parse one portal object */
2037 obj = obj_calloc(OBJ_PORTAL);
2038 if (obj != NULL) {
2039 /* copy ip addr attribute */
2040 attr = &obj->attrs[
2041 ATTR_INDEX_PORTAL(ip->attr_id)];
2042 ec = copy_attr(attr, ip);
2043 /* copy port attribute */
2044 if (ec == 0) {
2045 attr = &obj->attrs[
2046 ATTR_INDEX_PORTAL(tmp->attr_id)];
2047 ec = copy_attr(attr, tmp);
2049 /* parse non-key attributes */
2050 NEXT_TLV(tmp, tmp_len);
2051 while (ec == 0 &&
2052 tmp_len >= 8 &&
2053 IS_PORTAL_ATTR(tmp->attr_id)) {
2054 attr = &obj->attrs[
2055 ATTR_INDEX_PORTAL(
2056 tmp->attr_id)];
2057 ec = copy_attr(attr, tmp);
2058 NEXT_TLV(tmp, tmp_len);
2060 } else {
2061 /* no memory */
2062 ec = ISNS_RSP_INTERNAL_ERROR;
2064 } else {
2065 /* ip address is not followed by port */
2066 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2069 *p = obj;
2070 *op = tmp;
2071 *op_len = tmp_len;
2073 return (ec);
2077 * ****************************************************************************
2079 * reg_get_pg:
2080 * parse the Operating Attributes of the DevAttrReg message and
2081 * create a Portal Group object.
2083 * p - the pointer of the object for returning.
2084 * op - the operating attributes.
2085 * op_len - the length of the operating attributes.
2086 * return - error code.
2088 * ****************************************************************************
2090 static int
2091 reg_get_pg(
2092 isns_obj_t **p,
2093 isns_tlv_t **op,
2094 uint16_t *op_len
2097 int ec = 0;
2099 isns_tlv_t *tmp;
2100 uint16_t tmp_len;
2101 isns_attr_t *attr;
2103 isns_obj_t *obj = NULL;
2105 tmp = *op;
2106 tmp_len = *op_len;
2108 /* parse a complete pg object */
2109 obj = obj_calloc(OBJ_PG);
2110 if (obj != NULL) {
2111 /* parse attributes */
2112 do {
2113 attr = &obj->attrs[
2114 ATTR_INDEX_PG(tmp->attr_id)];
2115 ec = copy_attr(attr, tmp);
2116 NEXT_TLV(tmp, tmp_len);
2117 } while (ec == 0 &&
2118 tmp_len >= 8 &&
2119 IS_PG_ATTR(tmp->attr_id));
2120 } else {
2121 ec = ISNS_RSP_INTERNAL_ERROR;
2124 *p = obj;
2125 *op = tmp;
2126 *op_len = tmp_len;
2128 return (ec);
2132 * ****************************************************************************
2134 * reg_get_pg1:
2135 * parse the Operating Attributes of the DevAttrReg message and
2136 * create a Portal Group object which is followed to a Portal object.
2138 * p - the pointer of the object for returning.
2139 * pgt - the size-3 array of pointers which have the pg portal ip addr, port
2140 * and the pg tag attributes.
2141 * op - the operating attributes.
2142 * op_len - the length of the operating attributes.
2143 * return - error code.
2145 * ****************************************************************************
2147 static int
2148 reg_get_pg1(
2149 isns_obj_t **p,
2150 isns_attr_t const *pgt,
2151 isns_tlv_t **op,
2152 uint16_t *op_len
2155 int ec = 0;
2157 isns_tlv_t *tmp;
2158 uint16_t tmp_len;
2159 isns_attr_t *attr;
2161 isns_obj_t *obj = NULL;
2162 int i = 0;
2164 tmp = *op;
2165 tmp_len = *op_len;
2167 if (pgt[0].tag == PG_KEY2 &&
2168 pgt[1].tag == PG_KEY3) {
2169 /* the pg iscsi storage node name is */
2170 /* followed to a portal group tag */
2171 obj = obj_calloc(OBJ_PG);
2172 if (obj != NULL) {
2173 /* copy pg iscsi storage node name */
2174 attr = &obj->attrs[
2175 ATTR_INDEX_PG(tmp->attr_id)];
2176 ec = copy_attr(attr, tmp);
2177 /* copy pg ip addr, pg port & pgt */
2178 while (ec == 0 && i < 3) {
2179 attr = &obj->attrs[
2180 ATTR_INDEX_PG(pgt[i].tag)];
2181 ec = assign_attr(attr, &pgt[i]);
2182 i ++;
2184 NEXT_TLV(tmp, tmp_len);
2185 } else {
2186 /* no memory */
2187 ec = ISNS_RSP_INTERNAL_ERROR;
2189 } else {
2190 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2193 *p = obj;
2194 *op = tmp;
2195 *op_len = tmp_len;
2197 return (ec);
2201 * ****************************************************************************
2203 * reg_get_pg2:
2204 * parse the Operating Attributes of the DevAttrReg message and
2205 * create a Portal Group object which is followed to a iSCSI
2206 * Storage Node object.
2208 * p - the pointer of the object for returning.
2209 * pgt - the size-3 array of pointers which have the pg iscsi storage
2210 * node name and the pg tag attributes.
2211 * op - the operating attributes.
2212 * op_len - the length of the operating attributes.
2213 * return - error code.
2215 * ****************************************************************************
2217 static int
2218 reg_get_pg2(
2219 isns_obj_t **p,
2220 isns_attr_t const *pgt,
2221 isns_tlv_t **op,
2222 uint16_t *op_len
2225 int ec = 0;
2227 isns_tlv_t *tmp;
2228 uint16_t tmp_len;
2229 isns_attr_t *attr;
2231 isns_obj_t *obj = NULL;
2232 int i = 0;
2234 isns_tlv_t *ip;
2236 tmp = *op;
2237 tmp_len = *op_len;
2239 /* keep ip address */
2240 ip = tmp;
2241 NEXT_TLV(tmp, tmp_len);
2243 if (tmp_len > 8 &&
2244 /* expect pg portal port */
2245 tmp->attr_id == PG_KEY3 &&
2246 tmp->attr_len == 4 &&
2247 /* expect pg tag */
2248 pgt[2].tag == PG_PGT &&
2249 /* expect pg iscsi storage node name only */
2250 pgt[1].tag == 0 &&
2251 pgt[0].tag == PG_KEY1) {
2252 /* the pg portal ip addr & port is followed */
2253 /* to a pg tag and we have the iscsi storage */
2254 /* node parsed previously */
2255 obj = obj_calloc(OBJ_PG);
2256 if (obj != NULL) {
2257 /* copy the pg ip addr */
2258 attr = &obj->attrs[
2259 ATTR_INDEX_PG(ip->attr_id)];
2260 ec = copy_attr(attr, ip);
2261 /* copy the pg port */
2262 if (ec == 0) {
2263 attr = &obj->attrs[
2264 ATTR_INDEX_PG(tmp->attr_id)];
2265 ec = copy_attr(attr, tmp);
2267 /* copy pg iscsi storage node name & pgt */
2268 while (ec == 0 && i < 3) {
2269 attr = &obj->attrs[
2270 ATTR_INDEX_PG(pgt[i].tag)];
2271 ec = assign_attr(attr, &pgt[i]);
2272 i += 2;
2274 NEXT_TLV(tmp, tmp_len);
2275 } else {
2276 ec = ISNS_RSP_INTERNAL_ERROR;
2278 } else {
2279 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2282 *p = obj;
2283 *op = tmp;
2284 *op_len = tmp_len;
2286 return (ec);
2290 * ****************************************************************************
2292 * reg_get_obj:
2293 * parse and create one object from the rest of Operating Attributes
2294 * of the DevAttrReg message, the object can be iSCSI Storage Node,
2295 * Portal or Portal Group.
2297 * p - the pointer of the object for returning.
2298 * pgt - an attribute array with size 3, the elements are:
2299 * 0: the first pg key attribute, it is either the name of an
2300 * iscsi storage node object or the ip addr of a portal object.
2301 * 1: the second pg key attribute, i.e. the portal port.
2302 * 2: the portal group tag attribute.
2303 * op - the operating attributes.
2304 * op_len - the length of the operating attributes.
2305 * return - error code.
2307 * ****************************************************************************
2310 reg_get_obj(
2311 isns_obj_t **p,
2312 isns_attr_t *pgt,
2313 isns_tlv_t **op,
2314 uint16_t *op_len
2317 int ec = 0;
2319 int derefd = 0;
2321 uint32_t pg_tag;
2323 if (*op_len == 0) {
2324 *p = NULL;
2325 return (0);
2328 switch ((*op)->attr_id) {
2329 case ISCSI_KEY:
2330 ec = reg_get_iscsi(p, &pgt[0], op, op_len);
2331 pgt[1].tag = 0;
2332 pgt[2].tag = 0;
2333 break;
2334 case PORTAL_KEY1:
2335 ec = reg_get_portal(p, &pgt[0], &pgt[1], op, op_len);
2336 pgt[2].tag = 0;
2337 break;
2338 case PG_KEY1:
2339 if (pgt[2].tag == PG_PGT) {
2340 /* pg iscsi storage node name is */
2341 /* followed to a pgt */
2342 ec = reg_get_pg1(p, pgt, op, op_len);
2343 } else {
2344 /* a complete pg object */
2345 ec = reg_get_pg(p, op, op_len);
2346 pgt[0].tag = 0;
2347 pgt[1].tag = 0;
2348 pgt[2].tag = 0;
2350 break;
2351 case PG_KEY2:
2352 /* pg portal ip addr is followed to a pgt */
2353 ec = reg_get_pg2(p, pgt, op, op_len);
2354 break;
2355 case PG_PGT:
2356 switch (pgt[0].tag) {
2357 case 0:
2358 /* portal group tag does not follow */
2359 /* iscsi storage node or portal object */
2360 *p = NULL;
2361 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2362 break;
2363 case PG_KEY1:
2364 case PG_KEY2:
2365 pgt[2].tag = PG_PGT;
2366 pgt[2].len = (*op)->attr_len;
2367 pg_tag = 0;
2368 switch ((*op)->attr_len) {
2369 case 4:
2370 pg_tag = ntohl(*(uint32_t *)
2371 &(*op)->attr_value[0]);
2372 case 0:
2373 pgt[2].value.ui = pg_tag;
2374 break;
2375 default:
2376 *p = NULL;
2377 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2378 break;
2380 if (ec == 0) {
2381 derefd = 1;
2382 NEXT_TLV(*op, *op_len);
2383 ec = reg_get_obj(p, pgt, op, op_len);
2385 break;
2386 default:
2387 /* should never happen */
2388 ASSERT(0);
2389 *p = NULL;
2390 ec = ISNS_RSP_INTERNAL_ERROR;
2391 break;
2393 break;
2394 default:
2395 *p = NULL;
2396 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2397 break;
2400 if (ec == 0 && derefd == 0) {
2401 ec = update_deref_obj(*p);
2404 if (ec != 0 && *p != NULL) {
2405 free_one_object(*p);
2406 *p = NULL;
2409 return (ec);
2413 * ****************************************************************************
2415 * reg_auth_src:
2416 * Authorize the source attribute the DevAttrReg message.
2417 * The update can only performed by the node who has the owenership.
2419 * p - the pointer of the object for returning.
2420 * pgt - an attribute array with size 3, the elements are:
2421 * 0: the first pg key attribute, it is either the name of an
2422 * iscsi storage node object or the ip addr of a portal object.
2423 * 1: the second pg key attribute, i.e. the portal port.
2424 * 2: the portal group tag attribute.
2425 * op - the operating attributes.
2426 * op_len - the length of the operating attributes.
2427 * return - error code.
2429 * ****************************************************************************
2432 reg_auth_src(
2433 isns_type_t type,
2434 uint32_t uid,
2435 uchar_t *src
2438 lookup_ctrl_t lc;
2439 uint32_t puid;
2441 puid = is_parent_there(src);
2443 if (TYPE_OF_PARENT[type] != 0) {
2444 SET_UID_LCP(&lc, type, uid);
2445 uid = cache_lookup(&lc, NULL, cb_get_parent);
2446 type = TYPE_OF_PARENT[type];
2449 if (uid != 0 && puid == 0) {
2450 SET_UID_LCP(&lc, type, uid);
2451 uid = cache_lookup(&lc, NULL, cb_node_child);
2454 if (puid != uid) {
2455 return (0);
2458 return (1);
2462 * ****************************************************************************
2464 * is_obj_online:
2465 * determine if the object is currently registered with the server.
2467 * obj - the object being checked.
2468 * return - 0: not registered, otherwise registered.
2470 * ****************************************************************************
2473 is_obj_online(
2474 const isns_obj_t *obj
2477 int online = 1;
2479 switch (obj->type) {
2480 case OBJ_ISCSI:
2481 online = obj->attrs[ATTR_INDEX_ISCSI(
2482 ISNS_ISCSI_NODE_TYPE_ATTR_ID)].value.ui == 0 ? 0 : 1;
2483 break;
2484 default:
2485 break;
2488 return (online);
2491 static int
2492 set_obj_offline(
2493 isns_obj_t *obj
2496 switch (obj->type) {
2497 case OBJ_ISCSI:
2498 obj->attrs[ATTR_INDEX_ISCSI(
2499 ISNS_ISCSI_NODE_TYPE_ATTR_ID)].value.ui = 0;
2500 break;
2501 default:
2502 break;
2505 return (0);
2509 * ****************************************************************************
2511 * assoc_clone:
2512 * clone the association object.
2514 * p - the object being cloned.
2515 * clone_flag - 0: the object is being removed;
2516 * 1: only the association is being removed.
2517 * return - the clone object.
2519 * ****************************************************************************
2521 void *
2522 assoc_clone(
2523 void *p,
2524 int clone_flag
2527 isns_type_t type;
2528 isns_obj_t *clone;
2529 const isns_attr_t *src_attr;
2530 isns_attr_t *dst_attr;
2531 uint32_t id, op;
2532 int i = 0;
2534 const isns_obj_t *obj;
2535 uint32_t dd_flag;
2536 int online;
2538 int state;
2540 obj = (isns_obj_t *)p;
2542 if (obj->type != OBJ_ISCSI) {
2543 return (NULL);
2546 dd_flag = (get_dd_id(get_obj_uid(obj), ISNS_DEFAULT_DD_ID) == 0) ?
2547 0 : 1;
2548 online = is_obj_online(obj);
2550 state = (clone_flag << 2) | (dd_flag << 1) | online;
2552 /* clone_flag dd_flag online action */
2553 /* 0 0 0 ASSERT(0) */
2554 /* 0 0 1 NULL */
2555 /* 0 1 0 itself */
2556 /* 0 1 1 clone it */
2557 /* 1 0 0 NULL */
2558 /* 1 0 1 itself */
2559 /* 1 1 0 itself */
2560 /* 1 1 1 itself */
2562 switch (state) {
2563 case 0:
2564 ASSERT(0);
2565 case 1:
2566 case 4:
2567 return (NULL);
2568 case 2:
2569 case 5:
2570 case 6:
2571 case 7:
2572 return (p);
2573 case 3:
2574 default:
2575 break;
2578 type = obj->type;
2579 clone = obj_calloc(type);
2581 if (clone != NULL) {
2582 id = UID_ATTR_INDEX[type];
2583 src_attr = &(obj->attrs[id]);
2584 dst_attr = &(clone->attrs[id]);
2585 if (assign_attr(dst_attr, src_attr) != 0) {
2586 free_one_object(clone);
2587 return (NULL);
2590 while (i < MAX_KEY_ATTRS) {
2591 op = KEY_ATTR_OP[type][i];
2592 if (op != 0) {
2593 id = KEY_ATTR_INDEX[type][i];
2594 src_attr = &(obj->attrs[id]);
2595 dst_attr = &(clone->attrs[id]);
2596 if (assign_attr(dst_attr, src_attr) != 0) {
2597 free_one_object(clone);
2598 return (NULL);
2600 } else {
2601 break;
2603 i ++;
2607 return ((void *)clone);
2611 * ****************************************************************************
2613 * free_one_object:
2614 * free up one object.
2616 * obj - the object being freed.
2618 * ****************************************************************************
2620 void
2621 free_one_object(
2622 isns_obj_t *obj
2625 int i;
2626 uint32_t *cuid;
2627 if (obj == NULL) {
2628 return;
2630 for (i = 0; i < NUM_OF_ATTRS[obj->type]; i++) {
2631 isns_attr_t *attr = &obj->attrs[i];
2632 switch (attr->tag) {
2633 case ISNS_EID_ATTR_ID:
2634 case ISNS_ISCSI_NAME_ATTR_ID:
2635 case ISNS_ISCSI_ALIAS_ATTR_ID:
2636 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
2637 case ISNS_PG_ISCSI_NAME_ATTR_ID:
2638 case ISNS_PORTAL_IP_ADDR_ATTR_ID:
2639 case ISNS_PORTAL_NAME_ATTR_ID:
2640 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
2641 case ISNS_DD_SET_NAME_ATTR_ID:
2642 case ISNS_DD_NAME_ATTR_ID:
2643 case ISNS_DD_ISCSI_NAME_ATTR_ID:
2644 case ISNS_DD_FC_PORT_NAME_ATTR_ID:
2645 case ISNS_DD_PORTAL_IP_ADDR_ATTR_ID:
2646 #ifdef DEBUG
2647 if (verbose_mc) {
2648 printf("memory(%d) deallocated\n",
2649 attr->len);
2651 #endif
2652 free(attr->value.ptr);
2653 attr->value.ptr = NULL;
2654 break;
2655 default:
2656 break;
2660 /* free child uids */
2661 i = 0;
2662 while (i < NUM_OF_CHILD[obj->type]) {
2663 cuid = get_child_n(obj, i);
2664 free(cuid);
2665 i ++;
2668 /* at last, free the object itself */
2669 #ifdef DEBUG
2670 if (verbose_mc) {
2671 printf("object(%d) deallocated\n", obj->type);
2673 #endif
2674 free(obj);
2678 * ****************************************************************************
2680 * free_object:
2681 * free up one object.
2683 * obj - the object being freed.
2685 * ****************************************************************************
2687 void
2688 free_object(
2689 isns_obj_t *obj
2692 free_one_object(obj);
2696 * ****************************************************************************
2698 * set_parent_obj:
2699 * set the parent object UID.
2701 * obj - the child object.
2702 * puid- the parent object UID.
2703 * return - error code.
2705 * ****************************************************************************
2708 set_parent_obj(
2709 isns_obj_t *obj,
2710 uint32_t puid
2713 uint32_t *const p = get_parent_p(obj);
2714 if (p != NULL) {
2715 *p = puid;
2718 return (0);
2722 * ****************************************************************************
2724 * buff_child_obj:
2725 * add a child object UID to the child object array.
2727 * obj - the parent object.
2728 * child_type - the type of the child object.
2729 * number - the number of the child object.
2730 * return - the length of the child object UID array.
2732 * ****************************************************************************
2735 buff_child_obj(
2736 const isns_type_t ptype,
2737 const isns_type_t ctype,
2738 const void *c,
2739 void const ***child
2742 int ec = 0;
2744 int i = 0;
2745 void const ***pp, **p;
2746 uint32_t num, new_num;
2748 pp = NULL;
2749 /* get the pointer of the array which the child belongs to */
2750 while (i < NUM_OF_CHILD[ptype]) {
2751 if (TYPE_OF_CHILD[ptype][i] == ctype) {
2752 pp = &child[i];
2753 break;
2755 i ++;
2758 /* the child type is not applicable */
2759 if (pp == NULL) {
2760 return (ec);
2763 p = *pp;
2764 /* get an empty slot from the uid array for this child */
2765 if (p != NULL) {
2766 num = (uint32_t)*p;
2767 i = 0;
2768 while (i < num) {
2769 if (p[++i] == NULL) {
2770 /* found it */
2771 p[i] = c;
2772 return (ec);
2775 p = *pp;
2776 new_num = num + 1;
2777 } else {
2778 num = 0;
2779 new_num = 1;
2782 /* the array is full, enlarge the child uid array */
2783 p = reallocarray(p, new_num + 1, sizeof (void *));
2784 if (p != NULL) {
2785 *pp = p;
2786 *p = (void *)new_num;
2787 p[new_num] = c;
2788 } else {
2789 ec = ISNS_RSP_INTERNAL_ERROR;
2792 return (ec);
2796 * ****************************************************************************
2798 * update_child_object:
2799 * update the child object of a network entity object.
2801 * puid - the UID of the parent object, i.e. the network entity object.
2802 * child_type - the type of the child object.
2803 * child_uid - the uid of the child object.
2804 * return - error code.
2806 * ****************************************************************************
2809 update_child_obj(
2810 const isns_type_t ptype,
2811 const uint32_t puid,
2812 void const ***child,
2813 int child_flag
2816 int ec = 0;
2818 lookup_ctrl_t lc;
2820 SET_UID_LCP(&lc, ptype, puid);
2822 lc.data[1].ptr = (uchar_t *)child;
2823 lc.data[2].ui = child_flag;
2825 ec = cache_lookup(&lc, NULL, cb_add_child);
2827 return (ec);
2831 update_ref_obj(
2832 const isns_obj_t *obj
2835 uint32_t uid;
2836 lookup_ctrl_t lc;
2837 isns_type_t t;
2839 t = obj->type;
2841 if (TYPE_OF_REF[t][0] != 0) {
2842 (void) setup_ref_lcp(&lc, obj, NULL);
2844 lc.id[2] = t;
2845 lc.data[2].ui = get_obj_uid(obj);
2847 uid = 0;
2848 do {
2849 lc.curr_uid = uid;
2850 (void) cache_lookup(&lc, &uid, cb_set_ref);
2851 } while (uid != 0);
2854 return (0);
2858 * ****************************************************************************
2860 * verify_ref_obj:
2861 * update the reference bit of a portal group object.
2863 * obj - the object being ref'ed.
2864 * return - error code.
2866 * ****************************************************************************
2869 verify_ref_obj(
2870 const isns_type_t ptype,
2871 const uint32_t puid,
2872 void const ***child
2875 int ec = 0;
2877 lookup_ctrl_t lc;
2879 SET_UID_LCP(&lc, ptype, puid);
2881 lc.data[1].ptr = (uchar_t *)child;
2883 ec = cache_lookup(&lc, NULL, cb_verify_ref);
2885 return (ec);
2889 update_deref_obj(
2890 isns_obj_t *obj
2893 int ec = 0;
2895 isns_type_t t, rt;
2896 lookup_ctrl_t lc;
2897 int i, ref_count;
2899 uint32_t uid, *refp;
2901 t = obj->type;
2902 i = ref_count = 0;
2903 while (i < NUM_OF_REF[t]) {
2904 rt = TYPE_OF_REF[t][i + 1];
2905 (void) setup_deref_lcp(&lc, obj, rt);
2906 uid = is_obj_there(&lc);
2907 if (uid != 0) {
2908 refp = get_ref_p(obj, lc.type);
2909 *refp = uid;
2910 ref_count ++;
2912 i ++;
2915 if (i > 0 && ref_count == 0) {
2916 ec = ISNS_RSP_INVALID_REGIS;
2919 return (ec);
2923 * ****************************************************************************
2925 * register_object:
2926 * add one object to the object container.
2928 * obj - the object being added.
2929 * uid_p- the pointer for returning object UID.
2930 * update_p- the pointer for returning flag which indicates if the object
2931 * is newly registered or updated with an existing one.
2932 * return - error code.
2934 * ****************************************************************************
2937 register_object(
2938 isns_obj_t *obj,
2939 uint32_t *uid_p,
2940 int *update_p
2943 return (cache_add(obj, 0, uid_p, update_p));
2947 * ****************************************************************************
2949 * register_assoc:
2950 * add one association object to the object container, the association
2951 * object has only the information for discovery domain membership, i.e.
2952 * a name and UID only.
2954 * obj - the association object being added.
2955 * uid_p- the pointer for returning object UID.
2956 * return - error code.
2958 * ****************************************************************************
2961 register_assoc(
2962 isns_obj_t *obj,
2963 uint32_t *uid_p
2966 return (cache_add(obj, 1, uid_p, NULL));
2970 * ****************************************************************************
2972 * is_obj_there:
2973 * check if the object is registered or not.
2975 * lcp - the lookup control data.
2976 * return - the object UID.
2978 * ****************************************************************************
2980 uint32_t
2981 is_obj_there(
2982 lookup_ctrl_t *lcp
2985 uint32_t uid;
2987 (void) cache_lookup(lcp, &uid, NULL);
2989 return (uid);
2992 uint32_t
2993 is_parent_there(
2994 uchar_t *src
2997 lookup_ctrl_t lc;
2999 lc.curr_uid = 0;
3000 lc.type = OBJ_ISCSI;
3001 lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
3002 lc.op[0] = OP_STRING;
3003 lc.data[0].ptr = src;
3004 lc.op[1] = 0;
3006 return (cache_lookup(&lc, NULL, cb_get_parent));
3010 * ****************************************************************************
3012 * setup_ref_lcp:
3013 * prepare the lookup control data for looking up a portal group
3014 * object which references to a iscsi stroage node and/or a portal
3015 * object.
3017 * lcp - the lookup control data.
3018 * iscsi- the ref'ed iscsi storage node object.
3019 * portal- the ref'ed portal object.
3020 * return - error code.
3022 * ****************************************************************************
3024 static int
3025 setup_ref_lcp(
3026 lookup_ctrl_t *lcp,
3027 const isns_obj_t *iscsi,
3028 const isns_obj_t *portal
3031 int i = 0, j = 0;
3033 lcp->curr_uid = 0;
3034 lcp->type = TYPE_OF_REF[iscsi->type][0];
3036 /* extrace the matching attributes from iscsi storage node object */
3037 while (iscsi != NULL &&
3038 i < MAX_REF_MATCH &&
3039 REF_MATCH_OPS[iscsi->type][i] > 0) {
3040 lcp->id[i] = REF_MATCH_ID2[iscsi->type][i];
3041 lcp->op[i] = REF_MATCH_OPS[iscsi->type][i];
3042 lcp->data[i].ptr = iscsi->attrs[
3043 REF_MATCH_ID1[iscsi->type][i]].value.ptr;
3044 i ++;
3047 /* extrace the matching attributes from portal object */
3048 while (portal != NULL &&
3049 i < MAX_LOOKUP_CTRL &&
3050 j < MAX_REF_MATCH &&
3051 REF_MATCH_OPS[portal->type][j] > 0) {
3052 lcp->id[i] = REF_MATCH_ID2[portal->type][j];
3053 lcp->op[i] = REF_MATCH_OPS[portal->type][j];
3054 lcp->data[i].ptr = portal->attrs[
3055 REF_MATCH_ID1[portal->type][j]].value.ptr;
3056 j ++;
3057 i ++;
3060 if (i < MAX_LOOKUP_CTRL) {
3061 lcp->op[i] = 0;
3064 return (0);
3067 static int
3068 setup_deref_lcp(
3069 lookup_ctrl_t *lcp,
3070 const isns_obj_t *pg,
3071 isns_type_t t
3074 int i = 0;
3076 lcp->curr_uid = 0;
3077 lcp->type = t;
3079 /* extrace the matching attributes from iscsi storage node object */
3080 while (i < MAX_REF_MATCH &&
3081 REF_MATCH_OPS[t][i] > 0) {
3082 lcp->id[i] = REF_MATCH_ID1[t][i];
3083 lcp->op[i] = REF_MATCH_OPS[t][i];
3084 lcp->data[i].ptr = pg->attrs[
3085 REF_MATCH_ID2[t][i]].value.ptr;
3086 i ++;
3089 if (i < MAX_LOOKUP_CTRL) {
3090 lcp->op[i] = 0;
3093 return (0);
3097 * ****************************************************************************
3099 * setup_parent_lcp:
3100 * prepare the lookup control data for looking up parent object
3101 * with a child object.
3103 * lcp - the lookup control data.
3104 * obj - the child object.
3105 * return - parent object UID.
3107 * ****************************************************************************
3109 static uint32_t
3110 setup_parent_lcp(
3111 lookup_ctrl_t *lcp,
3112 isns_obj_t *obj
3115 isns_type_t ptype;
3116 uint32_t puid;
3118 puid = get_parent_uid(obj);
3119 if (puid != 0) {
3120 ptype = TYPE_OF_PARENT[obj->type];
3121 SET_UID_LCP(lcp, ptype, puid);
3122 lcp->data[1].ui = obj->type;
3123 lcp->data[2].ui = get_obj_uid(obj);
3126 return (puid);
3129 static int
3130 cb_get_parent(
3131 void *p1,
3132 /* LINTED E_FUNC_ARG_UNUSED */
3133 void *p2
3136 return (get_parent_uid(p1));
3139 static int
3140 cb_node_child(
3141 void *p1,
3142 /* LINTED E_FUNC_ARG_UNUSED */
3143 void *p2
3146 isns_obj_t *obj = (isns_obj_t *)p1;
3148 uint32_t num, uid;
3150 uint32_t *cuid = get_child_t(obj, OBJ_ISCSI);
3152 if (cuid != NULL) {
3153 num = *cuid;
3154 } else {
3155 num = 0;
3158 while (num > 0) {
3159 uid = *++cuid;
3160 if (uid != 0) {
3161 return (uid);
3163 num --;
3166 return (0);
3170 * ****************************************************************************
3172 * cb_set_ref:
3173 * callback function which sets the reference bit to 1 according to
3174 * the type of object.
3176 * p1 - the object.
3177 * p2 - the lcp.
3178 * return - error code.
3180 * ****************************************************************************
3182 static int
3183 cb_set_ref(
3184 void *p1,
3185 void *p2
3188 isns_obj_t *obj = (isns_obj_t *)p1;
3189 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3191 isns_type_t t;
3192 uint32_t u;
3194 uint32_t *refp;
3196 t = lcp->id[2];
3197 u = lcp->data[2].ui;
3198 refp = get_ref_p(obj, t);
3199 *refp = u;
3201 /* successful */
3202 return (0);
3206 * ****************************************************************************
3208 * cb_clear_ref:
3209 * callback function which clears the reference bit according to
3210 * the type of object.
3212 * p1 - the object.
3213 * p2 - the lcp.
3214 * return - 1: the object is no longer ref'ed, 0: otherwise.
3216 * ****************************************************************************
3218 static int
3219 cb_clear_ref(
3220 void *p1,
3221 void *p2
3224 isns_obj_t *obj = (isns_obj_t *)p1;
3225 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3227 isns_type_t t;
3228 uint32_t *refp;
3230 int i = 0;
3231 uint32_t ref;
3233 t = lcp->data[2].ui;
3234 refp = get_ref_p(obj, t);
3235 *refp = 0;
3237 while (i < NUM_OF_REF[obj->type]) {
3238 ref = get_ref_n(obj, i);
3239 if (ref != 0) {
3240 return (0);
3242 i ++;
3245 return (1);
3248 static int
3249 cb_add_child(
3250 void *p1,
3251 void *p2
3254 isns_obj_t *obj = (isns_obj_t *)p1;
3255 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3257 const void ***child;
3258 const void **vpp;
3259 uint32_t vnum;
3260 int child_flag;
3262 uint32_t **upp, *up;
3263 uint32_t num;
3265 isns_obj_t *o;
3267 int i = 0;
3269 child = (const void ***)lcp->data[1].ptr;
3270 child_flag = lcp->data[2].ui;
3272 while (i < NUM_OF_CHILD[obj->type]) {
3273 vpp = child[i];
3274 if (vpp != NULL &&
3275 (vnum = (uint32_t)*vpp) > 0 &&
3276 *(vpp + 1) != NULL) {
3277 upp = get_child_np(obj, i);
3278 if (*upp == NULL) {
3279 if (child_flag == 0 &&
3280 sizeof (typeof (**upp)) ==
3281 sizeof (typeof (**child))) {
3282 *upp = (uint32_t *)vpp;
3283 vpp = NULL;
3284 child[i] = NULL;
3286 num = vnum;
3287 } else {
3288 num = **upp + vnum;
3290 if (vpp != NULL) {
3291 /* copy required */
3292 up = reallocarray(*upp, num + 1,
3293 sizeof (uint32_t));
3294 if (up == NULL) {
3295 return (ISNS_RSP_INTERNAL_ERROR);
3297 *upp = up;
3298 *up = num;
3299 up += num;
3300 vpp += vnum;
3301 while (vnum > 0) {
3302 if (*vpp == NULL) {
3303 *up = 0;
3304 } else if (child_flag == 0) {
3305 *up = (uint32_t)*vpp;
3306 *vpp = NULL;
3307 } else {
3308 o = (isns_obj_t *)*vpp;
3309 *up = get_obj_uid(o);
3310 if (is_obj_online(o) == 0) {
3311 free_object(o);
3313 *vpp = NULL;
3315 up --;
3316 vpp --;
3317 vnum --;
3321 i ++;
3324 return (0);
3328 * ****************************************************************************
3330 * cb_remove_child:
3331 * callback function which removes a child object UID from the
3332 * children objet UID array of the parent object.
3334 * p1 - the object.
3335 * p2 - the lcp.
3336 * return - 1: no more such type of child object, 0: otherwise.
3338 * ****************************************************************************
3340 static int
3341 cb_remove_child(
3342 void *p1,
3343 void *p2
3346 isns_obj_t *obj = (isns_obj_t *)p1;
3347 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3348 uint32_t child_type = lcp->data[1].ui;
3349 uint32_t child_uid = lcp->data[2].ui;
3350 uint32_t *cuidp, cuid, num_of_child = 0;
3351 int i;
3353 /* get the children object UID array */
3354 cuidp = get_child_t(obj, child_type);
3355 if (cuidp != NULL) {
3356 num_of_child = *cuidp;
3359 /* remove it */
3360 while (num_of_child > 0) {
3361 cuid = *++cuidp;
3362 if (cuid == child_uid) {
3363 *cuidp = 0;
3364 break;
3366 num_of_child --;
3369 /* check if all of child object UIDs are removed */
3370 i = 0;
3371 while (i < NUM_OF_CHILD[obj->type]) {
3372 cuidp = get_child_n(obj, i);
3373 if (cuidp != NULL) {
3374 num_of_child = *cuidp;
3375 while (num_of_child > 0) {
3376 cuid = *++cuidp;
3377 if (cuid != 0) {
3378 return (0);
3380 num_of_child --;
3383 i ++;
3386 return (1);
3389 static int
3390 cb_verify_ref(
3391 void *p1,
3392 void *p2
3395 int ec = 0;
3397 isns_obj_t *parent = (isns_obj_t *)p1;
3398 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3400 const void ***child;
3402 const void **vpp;
3403 const void *vp;
3404 uint32_t vnum;
3406 const void **evpp;
3407 const void *evp;
3408 uint32_t evnum;
3410 isns_type_t pt; /* parent object type */
3411 isns_type_t ct; /* child object type */
3412 isns_type_t rt; /* ref object type */
3413 isns_type_t et; /* peer object type */
3415 uint32_t *up;
3416 uint32_t u;
3417 uint32_t unum;
3419 lookup_ctrl_t lc;
3420 uint8_t flag[MAX_OBJ_TYPE + 1] = { 0 };
3422 int i, j, k;
3424 pt = parent->type;
3426 child = (const void ***)lcp->data[1].ptr;
3428 for (i = 0; i < NUM_OF_CHILD[pt]; i++) {
3429 ct = TYPE_OF_CHILD[pt][i];
3430 rt = TYPE_OF_REF[ct][0];
3431 if (rt == 0) {
3432 continue;
3435 et = TYPE_OF_REF[ct][1];
3436 vpp = child[i];
3437 if (vpp != NULL) {
3438 vnum = (uint32_t)*vpp;
3439 up = get_child_t(parent, et);
3440 if (up != NULL) {
3441 unum = *up;
3442 } else {
3443 unum = 0;
3445 } else {
3446 vnum = 0;
3449 j = vnum;
3450 while (j > 0) {
3451 vp = vpp[j];
3452 if (vp != NULL) {
3453 (void) setup_ref_lcp(&lc, vp, NULL);
3454 k = unum;
3455 while (k > 0) {
3456 u = up[k];
3457 if (u != 0) {
3458 ec = ref_new2old(
3459 &lc, et, u, vp);
3460 if (ec != 0) {
3461 return (ec);
3464 k --;
3465 } /* End of while each unum */
3467 j --;
3468 } /* End of while each vnum */
3470 if (flag[ct] != 0) {
3471 continue;
3474 evnum = 0;
3475 j = 0;
3476 while (j < NUM_OF_CHILD[pt]) {
3477 if (TYPE_OF_CHILD[pt][j] == et) {
3478 evpp = child[j];
3479 if (evpp != NULL) {
3480 evnum = (uint32_t)*evpp;
3482 break;
3484 j ++;
3487 j = vnum;
3488 while (j > 0) {
3489 vp = vpp[j];
3490 k = evnum;
3491 while (k > 0) {
3492 evp = evpp[k];
3493 if (vp != NULL && evp != NULL) {
3494 (void) setup_ref_lcp(&lc, vp, evp);
3495 ec = ref_new2new(&lc, vp, evp);
3496 if (ec != 0) {
3497 return (ec);
3500 k --;
3502 j --;
3503 } /* End of while each vnum */
3505 flag[et] = 1;
3506 } /* End of for each type of child */
3508 return (ec);
3511 static int
3512 cb_ref_new2old(
3513 void *p1,
3514 void *p2
3517 isns_obj_t *obj = (isns_obj_t *)p1;
3518 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3520 isns_type_t et;
3521 uint32_t uu;
3523 uint32_t ref;
3525 int match;
3527 et = lcp->id[2];
3528 uu = lcp->data[2].ui;
3530 ref = get_ref_t(obj, et);
3532 if (ref == uu) {
3533 match = 1;
3534 } else {
3535 match = 0;
3538 return (match);
3541 static int
3542 cb_new_ref(
3543 void *p1,
3544 void *p2
3547 int ec = 0;
3549 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3550 isns_obj_t *a = (isns_obj_t *)p1;
3551 isns_obj_t *b = (isns_obj_t *)lcp->data[2].ptr;
3553 ec = new_ref(a, b);
3555 return (ec);
3558 static int
3559 ref_new2old(
3560 lookup_ctrl_t *lcp,
3561 isns_type_t et,
3562 uint32_t uu,
3563 const isns_obj_t *vp
3566 int ec = 0;
3568 int match;
3569 uint32_t uid;
3571 lookup_ctrl_t lc;
3573 lcp->id[2] = et;
3574 lcp->data[2].ui = uu;
3576 uid = 0;
3577 do {
3578 lcp->curr_uid = uid;
3579 match = cache_lookup(lcp, &uid, cb_ref_new2old);
3580 } while (match == 0 && uid != 0);
3582 if (match == 0) {
3583 /* no such ref, create a default one */
3584 SET_UID_LCP(&lc, et, uu);
3586 lc.data[2].ptr = (uchar_t *)vp;
3588 ec = cache_lookup(&lc, NULL, cb_new_ref);
3591 return (ec);
3594 static int
3595 ref_new2new(
3596 lookup_ctrl_t *lcp,
3597 const isns_obj_t *p1,
3598 const isns_obj_t *p2
3601 int ec = 0;
3603 if (is_obj_there(lcp) != 0) {
3604 return (0);
3607 ec = new_ref(p1, p2);
3609 return (ec);
3612 static int
3613 new_ref(
3614 const isns_obj_t *p1,
3615 const isns_obj_t *p2
3618 int ec = 0;
3620 isns_obj_t *obj;
3622 obj = make_ref[p1->type](p1, p2);
3623 if (obj != NULL) {
3624 ec = register_object(obj, NULL, NULL);
3625 } else {
3626 ec = ISNS_RSP_INTERNAL_ERROR;
3629 return (ec);
3633 * ****************************************************************************
3635 * do_dereg:
3636 * Physically remove an object along with the children objects,
3637 * the reference object and the parent object recursively.
3638 * Apporiate SCN is triggered.
3640 * lcp - the lookup control for the object being removed.
3641 * parent_flag - 1: the object being removed is the parent object;
3642 * 0: otherwise.
3643 * child_flag - 1: the object being removed is a child object;
3644 * 0: otherwise.
3645 * pending - 1: do not remove the ESI entry immediately;
3646 * 0: remove the ESI entry without any delay.
3647 * return - error code.
3649 * ****************************************************************************
3651 static int
3652 do_dereg(
3653 lookup_ctrl_t *lcp,
3654 int parent_flag,
3655 int child_flag,
3656 int pending
3659 int ec = 0;
3661 isns_obj_t *obj;
3662 uint32_t *cuidp, num;
3663 isns_type_t type;
3664 uint32_t uid;
3665 int i;
3667 /* remove the object from object container */
3668 obj = cache_remove(lcp, 0);
3670 if (obj == NULL) {
3671 return (0);
3674 /* trigger a scn */
3675 if (scn_q != NULL) {
3676 (void) make_scn(ISNS_OBJECT_REMOVED, obj);
3679 /* dereg children */
3680 i = 0;
3681 while (ec == 0 && !parent_flag &&
3682 i < NUM_OF_CHILD[obj->type]) {
3683 type = TYPE_OF_CHILD[obj->type][i];
3684 cuidp = get_child_n(obj, i);
3685 if (cuidp != NULL) {
3686 num = *cuidp;
3687 } else {
3688 num = 0;
3690 while (ec == 0 && num > 0) {
3691 uid = cuidp[num];
3692 if (uid != 0) {
3693 SET_UID_LCP(lcp, type, uid);
3694 ec = do_dereg(lcp,
3695 parent_flag,
3697 pending);
3699 num --;
3701 i ++;
3704 /* clear the ref bit on the ref'd object */
3705 if (ec == 0 && TYPE_OF_REF[obj->type][0] > 0) {
3706 uid = 0;
3707 do {
3708 (void) setup_ref_lcp(lcp, obj, NULL);
3709 lcp->curr_uid = uid;
3710 lcp->data[2].ui = obj->type;
3711 if (cache_lookup(lcp, &uid, cb_clear_ref) != 0) {
3712 UPDATE_LCP_UID(lcp, uid);
3713 ec = do_dereg(lcp,
3714 parent_flag,
3715 child_flag,
3716 pending);
3718 } while (uid != 0);
3721 /* remove it from the parent */
3722 if (ec == 0 && !child_flag &&
3723 TYPE_OF_PARENT[obj->type] > 0 &&
3724 (uid = setup_parent_lcp(lcp, obj)) != 0) {
3725 if (cache_lookup(lcp, NULL, cb_remove_child) != 0) {
3726 UPDATE_LCP_UID(lcp, uid);
3727 ec = do_dereg(lcp,
3729 child_flag,
3734 if (ec == 0 && !child_flag) {
3735 /* remove it from persistent data store */
3736 if (sys_q) {
3737 ec = write_data(DATA_DELETE, obj);
3739 /* remove esi event entry */
3740 if (ec == 0) {
3741 (void) esi_remove_obj(obj, pending);
3744 /* save the parent uid for caller */
3745 if (TYPE_OF_PARENT[obj->type] != 0) {
3746 lcp->curr_uid = get_parent_uid(obj);
3747 } else {
3748 /* it's the parent itself */
3749 lcp->curr_uid = get_obj_uid(obj);
3753 /* remove this portal from scn registry */
3754 if (ec == 0 &&
3755 obj->type == OBJ_PORTAL) {
3756 (void) remove_scn_portal(get_obj_uid(obj));
3759 /* free the object */
3760 (void) free_object(obj);
3762 return (ec);
3766 * ****************************************************************************
3768 * dereg_assoc:
3769 * Remove one association object from object container.
3771 * lcp - the lookup control for the object being removed.
3772 * return - error code.
3774 * ****************************************************************************
3777 dereg_assoc(
3778 lookup_ctrl_t *lcp
3781 isns_obj_t *obj;
3783 obj = cache_remove(lcp, 1);
3785 /* free the object */
3786 if (obj != NULL) {
3787 free_object(obj);
3790 return (0);
3794 * ****************************************************************************
3796 * dereg_object:
3797 * Remove one object from object container.
3799 * lcp - the lookup control for the object being removed.
3800 * return - error code.
3802 * ****************************************************************************
3805 dereg_object(
3806 lookup_ctrl_t *lcp,
3807 int pending
3810 return (do_dereg(lcp, 0, 0, pending));
3814 * ****************************************************************************
3816 * data_sync:
3817 * Synchronize the cache with persistent data store.
3818 * Flush the cache data to data store if the input ec is zero,
3819 * retreat the changes in cache and ignore data store update
3820 * if there is an error.
3822 * ec - error code.
3823 * return - error code.
3825 * ****************************************************************************
3828 data_sync(
3829 int ec
3832 /* cache is updated successfully, commit the data to data store */
3833 if (IS_CACHE_UPDATED()) {
3834 if (ec == 0) {
3835 ec = write_data(DATA_COMMIT, NULL);
3837 if (ec == 0) {
3838 /* successful, trigger the SCN */
3839 (void) queue_msg_set(scn_q, SCN_TRIGGER, NULL);
3840 } else {
3841 shutdown_server();
3843 } else {
3844 /* ignore all SCNs which have been generated */
3845 (void) queue_msg_set(scn_q, SCN_IGNORE, NULL);
3847 (void) write_data(DATA_RETREAT, NULL);
3850 return (ec);
3853 static pthread_mutex_t name_mtx[3] = {
3854 PTHREAD_MUTEX_INITIALIZER,
3855 PTHREAD_MUTEX_INITIALIZER,
3856 PTHREAD_MUTEX_INITIALIZER
3858 static const char *name_pattern[3] = {
3859 "ENTITY_ID_%d",
3860 "DD_%d",
3861 "DD-Set_%d"
3863 static uint32_t name_count[3] = {
3870 * ****************************************************************************
3872 * make_unique_name:
3873 * make a default unique name for a newly registered network entity,
3874 * discovery domain or discovery domain set object.
3876 * len - pointer of the length of the new name for returning.
3877 * tag - which attribute of the new name is for.
3878 * return - the name being made.
3880 * ****************************************************************************
3882 static char *
3883 make_unique_name(
3884 int *len,
3885 uint32_t tag
3888 int i;
3889 int count;
3890 char name[32] = { 0 };
3892 char *p;
3894 lookup_ctrl_t lc;
3896 lc.curr_uid = 0;
3898 switch (tag) {
3899 case ISNS_EID_ATTR_ID:
3900 i = 0;
3901 lc.type = OBJ_ENTITY;
3902 lc.id[0] = ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID);
3903 break;
3904 case ISNS_DD_NAME_ATTR_ID:
3905 i = 1;
3906 lc.type = OBJ_DD;
3907 lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
3908 break;
3909 case ISNS_DD_SET_NAME_ATTR_ID:
3910 i = 2;
3911 lc.type = OBJ_DDS;
3912 lc.id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
3913 break;
3914 default:
3915 ASSERT(0);
3916 break;
3919 lc.op[0] = OP_STRING;
3920 lc.op[1] = 0;
3921 do {
3922 (void) pthread_mutex_lock(&name_mtx[i]);
3923 count = ++ name_count[i];
3924 (void) pthread_mutex_unlock(&name_mtx[i]);
3925 /* no more space, failure */
3926 if (count == 0) {
3927 return (NULL);
3929 (void) sprintf(name, name_pattern[i], count);
3930 lc.data[0].ptr = (uchar_t *)name;
3931 } while (is_obj_there(&lc) != 0);
3933 /* 4-bytes aligned length */
3934 *len = strlen(name);
3935 *len = *len + (4 - *len % 4);
3936 p = (char *)malloc(*len);
3937 if (p != NULL) {
3938 (void) strcpy(p, name);
3940 return (p);
3943 #ifdef DEBUG
3944 void
3945 obj_dump(
3946 void *p
3949 print_object(NULL, (isns_obj_t *)p);
3951 #endif