1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
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>
35
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"
49
50 /*
51 * external variables
52 */
53 #ifdef DEBUG
54 extern int verbose_mc;
55 extern void print_object(char *, isns_obj_t *);
56 #endif
57
58 extern msg_queue_t *sys_q;
59 extern msg_queue_t *scn_q;
60
61 extern pthread_mutex_t el_mtx;
62
63 extern int cache_flag;
64
65 /*
66 * global data
67 */
68
69 /*
70 * local variables
71 */
72 /* type of parent object */
73 const int TYPE_OF_PARENT[MAX_OBJ_TYPE_FOR_SIZE] = {
74 0,
75 0,
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
88 };
89
90 /* number of children object type */
91 const int NUM_OF_CHILD[MAX_OBJ_TYPE] = {
92 0,
93 MAX_ENTITY_CHILD,
94 MAX_ISCSI_CHILD,
95 MAX_PORTAL_CHILD,
96 MAX_PG_CHILD,
97 0,
98 0
99 };
100
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 }
110 };
111
112 /* number of attributes of certain type of object */
113 const int NUM_OF_ATTRS[MAX_OBJ_TYPE_FOR_SIZE] = {
114 0,
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
128 };
129
130 /* the tag of UID of each type of object */
131 static const int UID_TAG[MAX_OBJ_TYPE_FOR_SIZE] = {
132 0,
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
146 };
147
148 /* the index of UID of each type of object */
149 const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE] = {
150 0,
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)
164 };
165
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 }
180 };
181
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 }
191 };
192
193 /* the size of each type of object */
194 static const int SIZEOF_OBJ[MAX_OBJ_TYPE_FOR_SIZE] = {
195 0,
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),
202 0,
203 0,
204 0,
205 0,
206 0,
207 sizeof (isns_assoc_iscsi_t),
208 sizeof (isns_assoc_dd_t)
209 };
210
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
216 0,
217 0,
218 0,
219 0,
220 PG_REF_COUNT,
221 0,
222 0,
223 0,
224 0,
225 0,
226 0,
227 0,
228 0,
229 0
230 };
231
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 }
241 };
242
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 }
253 };
254
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 }
265 };
266
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 }
277 };
278
279 /*
280 * local functions.
281 */
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 *);
306
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
317 };
318
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
334 };
335
336 /*
337 * ****************************************************************************
338 *
339 * entity_hval:
340 * caculate the hash value of a network entity object.
341 *
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.
348 *
349 * ****************************************************************************
350 */
351 static uint32_t
entity_hval(void * p,uint16_t chunk,uint32_t * flags)352 entity_hval(
353 void *p,
354 /* LINTED E_FUNC_ARG_UNUSED */
355 uint16_t chunk,
356 uint32_t *flags
357 )
358 {
359 uchar_t *key;
360 isns_obj_t *obj;
361 lookup_ctrl_t *lcp;
362
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;
372 }
373
374 return (htab_compute_hval(key));
375 }
376
377 /*
378 * ****************************************************************************
379 *
380 * iscsi_hval:
381 * caculate the hash value of an iscsi storage node object.
382 *
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.
389 *
390 * ****************************************************************************
391 */
392 static uint32_t
iscsi_hval(void * p,uint16_t chunk,uint32_t * flags)393 iscsi_hval(
394 void *p,
395 /* LINTED E_FUNC_ARG_UNUSED */
396 uint16_t chunk,
397 uint32_t *flags
398 )
399 {
400 uchar_t *key;
401 isns_obj_t *obj;
402 lookup_ctrl_t *lcp;
403
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;
413 }
414
415 return (htab_compute_hval(key));
416 }
417
418 /*
419 * ****************************************************************************
420 *
421 * portal_hval:
422 * caculate the hash value of a portal object.
423 *
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.
429 *
430 * ****************************************************************************
431 */
432 static uint32_t
portal_hval(void * p,uint16_t chunk,uint32_t * flags)433 portal_hval(
434 void *p,
435 /* LINTED E_FUNC_ARG_UNUSED */
436 uint16_t chunk,
437 uint32_t *flags
438 )
439 {
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;
445
446 in6_addr_t *ip;
447 uint32_t port;
448
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;
461 }
462
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);
467
468 return (htab_compute_hval(key));
469 }
470
471 /*
472 * ****************************************************************************
473 *
474 * pg_hval:
475 * caculate the hash value of a portal group object.
476 *
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.
482 *
483 * ****************************************************************************
484 */
485 static uint32_t
pg_hval(void * p,uint16_t chunk,uint32_t * flags)486 pg_hval(
487 void *p,
488 uint16_t chunk,
489 uint32_t *flags
490 )
491 {
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;
497
498 in6_addr_t *ip = NULL;
499 uint32_t port;
500
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;
514 }
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;
528 }
529 }
530
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);
536 }
537
538 return (htab_compute_hval(key));
539 }
540
541 /*
542 * ****************************************************************************
543 *
544 * dd_hval:
545 * caculate the hash value of a DD object.
546 *
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.
552 *
553 * ****************************************************************************
554 */
555 static uint32_t
dd_hval(void * p,uint16_t chunk,uint32_t * flags)556 dd_hval(
557 void *p,
558 /* LINTED E_FUNC_ARG_UNUSED */
559 uint16_t chunk,
560 uint32_t *flags
561 )
562 {
563 uchar_t *key;
564 isns_obj_t *obj;
565 lookup_ctrl_t *lcp;
566
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;
576 }
577
578 return (htab_compute_hval(key));
579 }
580
581 /*
582 * ****************************************************************************
583 *
584 * dds_hval:
585 * caculate the hash value of a DD-set object.
586 *
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.
592 *
593 * ****************************************************************************
594 */
595 static uint32_t
dds_hval(void * p,uint16_t chunk,uint32_t * flags)596 dds_hval(
597 void *p,
598 /* LINTED E_FUNC_ARG_UNUSED */
599 uint16_t chunk,
600 uint32_t *flags
601 )
602 {
603 uchar_t *key;
604 isns_obj_t *obj;
605 lookup_ctrl_t *lcp;
606
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;
616 }
617
618 return (htab_compute_hval(key));
619 }
620
621 /*
622 * ****************************************************************************
623 *
624 * obj_hval:
625 * caculate the hash value of an object.
626 *
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.
632 *
633 * ****************************************************************************
634 */
635 uint32_t
obj_hval(void * p,uint16_t chunk,uint32_t * flags)636 obj_hval(
637 void *p,
638 uint16_t chunk,
639 uint32_t *flags
640 )
641 {
642 isns_type_t type = ((isns_obj_t *)p)->type;
643
644 return (hval_func[type](p, chunk, flags));
645 }
646
647 /*
648 * ****************************************************************************
649 *
650 * get_obj_uid:
651 * get the UID of an object.
652 *
653 * p - the pointer pointers to an object.
654 * return - the UID.
655 *
656 * ****************************************************************************
657 */
658 uint32_t
get_obj_uid(const void * p)659 get_obj_uid(
660 const void *p
661 )
662 {
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);
667 }
668
669 /*
670 * ****************************************************************************
671 *
672 * set_obj_uid:
673 * set the UID of an object.
674 *
675 * p - the pointer pointers to an object.
676 * uid - the UID.
677 * return - the UID.
678 *
679 * ****************************************************************************
680 */
681 uint32_t
set_obj_uid(void * p,uint32_t uid)682 set_obj_uid(
683 void *p,
684 uint32_t uid
685 )
686 {
687 isns_obj_t *obj = (isns_obj_t *)p;
688 isns_attr_t *attr = &obj->attrs[UID_ATTR_INDEX[obj->type]];
689
690 /* set the tag, len and value */
691 attr->tag = UID_TAG[obj->type];
692 attr->len = 4;
693 attr->value.ui = uid;
694
695 return (uid);
696 }
697
698 /*
699 * ****************************************************************************
700 *
701 * obj_cmp:
702 * compare between two objects or an object with a lookup control data.
703 *
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.
708 *
709 * ****************************************************************************
710 */
711 int
obj_cmp(void * p1,void * p2,int flags)712 obj_cmp(
713 void *p1,
714 void *p2,
715 int flags
716 )
717 {
718 isns_obj_t *obj = (isns_obj_t *)p1;
719 lookup_ctrl_t buff = { 0 };
720 lookup_ctrl_t *lcp;
721 uint32_t uid;
722
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);
734 }
735 }
736
737 return (key_cmp(lcp, obj));
738 }
739
740 /*
741 * ****************************************************************************
742 *
743 * replace_object:
744 * replace an existing object with the new one.
745 *
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.
751 *
752 * ****************************************************************************
753 */
754 int
replace_object(void * p1,void * p2,uint32_t * uid_p,int flag)755 replace_object(
756 void *p1,
757 void *p2,
758 uint32_t *uid_p,
759 int flag
760 )
761 {
762 int ec = 0;
763
764 #ifndef SKIP_SRC_AUTH
765 uint32_t *pp_dst, *pp_src, swap;
766 #endif
767 int online;
768
769 isns_obj_t *dst = (isns_obj_t *)p1;
770 isns_obj_t *src = (isns_obj_t *)p2;
771
772 if (src->type == OBJ_DD || src->type == OBJ_DDS) {
773 /* replace not allowed */
774 return (ERR_NAME_IN_USE);
775 }
776
777 online = is_obj_online(dst);
778
779 /* set cache update flag */
780 SET_CACHE_UPDATED();
781
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;
791 }
792 }
793 #endif
794
795 /* update all of attributes */
796 if (copy_attrs(dst, src) != 0) {
797 return (ISNS_RSP_INTERNAL_ERROR);
798 }
799
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);
806 }
807
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;
814 }
815
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);
823 }
824 if (uid_p != NULL) {
825 *uid_p = get_obj_uid(dst);
826 }
827 }
828
829 return (ec);
830 }
831
832 /*
833 * ****************************************************************************
834 *
835 * add_object:
836 * post function after adding a new object.
837 *
838 * p - object which has been added.
839 * return - error code.
840 *
841 * ****************************************************************************
842 */
843 int
add_object(void * p)844 add_object(
845 void *p
846 )
847 {
848 int ec = 0;
849
850 isns_obj_t *obj = (isns_obj_t *)p;
851
852 /* add the new object to data store */
853 if (sys_q != NULL) {
854 ec = write_data(DATA_ADD, obj);
855 }
856
857 /* trigger a scn */
858 if (ec == 0 && scn_q != NULL) {
859 (void) make_scn(ISNS_OBJECT_ADDED, obj);
860 }
861
862 return (ec);
863 }
864
865 /*
866 * ****************************************************************************
867 *
868 * obj_tab_init:
869 * initialize the object hash tables.
870 *
871 * c - points to the cache.
872 * return - error code.
873 *
874 * ****************************************************************************
875 */
876 int
obj_tab_init(struct cache * c)877 obj_tab_init(
878 struct cache *c
879 )
880 {
881 htab_t *t;
882
883 htab_init();
884
885 /*
886 * allocate an array of pointer for the object hash tables.
887 */
888 c->t = (struct htab **)calloc(sizeof (struct htab *), MAX_OBJ_TYPE);
889 if (c->t == NULL) {
890 return (1);
891 }
892
893 /*
894 * hash table for network entity objects.
895 */
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);
902 }
903
904 /*
905 * hash table for iscsi storage node objects.
906 */
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);
913 }
914
915 /*
916 * hash table for portal objects.
917 */
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);
924 }
925
926 /*
927 * hash table for portal group objects.
928 */
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);
935 }
936
937 /*
938 * hash table for discovery domain objects.
939 */
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);
946 }
947
948 /*
949 * hash table for discovery domain set objects.
950 */
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);
957 }
958
959 return (0);
960 }
961
962 /*
963 * ****************************************************************************
964 *
965 * get_ref_np:
966 * get the ref pointer of the portal group object.
967 *
968 * obj - portal group object.
969 * return - ref pointer.
970 *
971 * ****************************************************************************
972 */
973 static uint32_t *
get_ref_np(isns_obj_t * obj,int n)974 get_ref_np(
975 isns_obj_t *obj,
976 int n
977 )
978 {
979 uint32_t *refp =
980 obj->type == OBJ_PG ? &((isns_pg_t *)obj)->ref[n] : NULL;
981
982 return (refp);
983 }
984
985 #ifdef DEBUG
986 uint32_t
987 #else
988 static uint32_t
989 #endif
get_ref_n(isns_obj_t * obj,int n)990 get_ref_n(
991 isns_obj_t *obj,
992 int n
993 )
994 {
995 return (*get_ref_np(obj, n));
996 }
997
998 static uint32_t *
get_ref_p(isns_obj_t * obj,isns_type_t rt)999 get_ref_p(
1000 isns_obj_t *obj,
1001 isns_type_t rt
1002 )
1003 {
1004 isns_type_t t = obj->type;
1005
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));
1010 }
1011 i ++;
1012 }
1013
1014 return (NULL);
1015 }
1016
1017 uint32_t
get_ref_t(isns_obj_t * obj,isns_type_t type)1018 get_ref_t(
1019 isns_obj_t *obj,
1020 isns_type_t type
1021 )
1022 {
1023 uint32_t *refp = get_ref_p(obj, type);
1024
1025 if (refp != NULL) {
1026 return (*refp);
1027 /* LINTED E_NOP_ELSE_STMT */
1028 } else {
1029 ASSERT(0);
1030 }
1031
1032 return (0);
1033 }
1034
1035 /*
1036 * ****************************************************************************
1037 *
1038 * get_parent_p:
1039 * get the pointer of the parent object.
1040 *
1041 * obj - an object.
1042 * return - parent object pointer.
1043 *
1044 * ****************************************************************************
1045 */
1046 uint32_t *const
get_parent_p(const isns_obj_t * obj)1047 get_parent_p(
1048 const isns_obj_t *obj
1049 )
1050 {
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;
1071 }
1072
1073 return (pp);
1074 }
1075
1076 uint32_t
get_parent_uid(const isns_obj_t * obj)1077 get_parent_uid(
1078 const isns_obj_t *obj
1079 )
1080 {
1081 uint32_t *pp = get_parent_p(obj);
1082 if (pp != NULL) {
1083 return (*pp);
1084 }
1085
1086 return (0);
1087 }
1088
1089 /*
1090 * ****************************************************************************
1091 *
1092 * get_child_np:
1093 * get the pointer of the UID array of the n'th child of an object.
1094 *
1095 * obj - an object.
1096 * n - the child index.
1097 * return - the pointer of the UID array.
1098 *
1099 * ****************************************************************************
1100 */
1101 static uint32_t **
get_child_np(isns_obj_t * obj,int n)1102 get_child_np(
1103 isns_obj_t *obj,
1104 int n
1105 )
1106 {
1107 uint32_t **pp =
1108 obj->type == OBJ_ENTITY ? &((isns_entity_t *)obj)->cuid[n] : NULL;
1109
1110 return (pp);
1111 }
1112
1113 /*
1114 * ****************************************************************************
1115 *
1116 * get_child_n:
1117 * get the UID array of the n'th child of an object.
1118 *
1119 * obj - an object.
1120 * n - the child index.
1121 * return - the UID array.
1122 *
1123 * ****************************************************************************
1124 */
1125 #ifdef DEBUG
1126 uint32_t *
1127 #else
1128 static uint32_t *
1129 #endif
get_child_n(isns_obj_t * obj,int n)1130 get_child_n(
1131 isns_obj_t *obj,
1132 int n
1133 )
1134 {
1135 uint32_t **pp = get_child_np(obj, n);
1136
1137 if (pp != NULL) {
1138 return (*pp);
1139 }
1140
1141 ASSERT(0);
1142 return (NULL);
1143 }
1144
1145 /*
1146 * ****************************************************************************
1147 *
1148 * get_child_p:
1149 * get the pointer of the UID array of the child matching the type.
1150 *
1151 * base - an object.
1152 * child_type - the child object type.
1153 * return - the pointer of the UID array.
1154 *
1155 * ****************************************************************************
1156 */
1157 static uint32_t **
get_child_p(isns_obj_t * base,int child_type)1158 get_child_p(
1159 isns_obj_t *base,
1160 int child_type
1161 )
1162 {
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;
1169 }
1170 i ++;
1171 }
1172
1173 return (pp);
1174 }
1175
1176 /*
1177 * ****************************************************************************
1178 *
1179 * get_child_t:
1180 * get the UID array of the child object matching the type.
1181 *
1182 * base - an object.
1183 * child_type - the child object type.
1184 * return - the UID array.
1185 *
1186 * ****************************************************************************
1187 */
1188 uint32_t *
get_child_t(isns_obj_t * base,int child_type)1189 get_child_t(
1190 isns_obj_t *base,
1191 int child_type
1192 )
1193 {
1194 uint32_t **pp = get_child_p(base, child_type);
1195
1196 if (pp != NULL) {
1197 return (*pp);
1198 } else {
1199 return (NULL);
1200 }
1201 }
1202
1203 /*
1204 * ****************************************************************************
1205 *
1206 * key_cmp:
1207 * compare the object against the lookup control data.
1208 *
1209 * lcp - the lookup control data.
1210 * obj - an object.
1211 * return - comparison result.
1212 *
1213 * ****************************************************************************
1214 */
1215 int
key_cmp(lookup_ctrl_t * lcp,isns_obj_t * obj)1216 key_cmp(
1217 lookup_ctrl_t *lcp,
1218 isns_obj_t *obj
1219 )
1220 {
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;
1242 }
1243 i ++;
1244 }
1245
1246 if (i && match) {
1247 return (0);
1248 } else {
1249 return (1);
1250 }
1251 }
1252
1253 /*
1254 * ****************************************************************************
1255 *
1256 * set_lookup_ctrl:
1257 * fill in the lookup control data for an object.
1258 *
1259 * lcp - the lookup control data.
1260 * obj - an object.
1261 * return - the lookup control data.
1262 *
1263 * ****************************************************************************
1264 */
1265 static lookup_ctrl_t *
set_lookup_ctrl(lookup_ctrl_t * lcp,isns_obj_t * obj)1266 set_lookup_ctrl(
1267 lookup_ctrl_t *lcp,
1268 isns_obj_t *obj
1269 )
1270 {
1271 isns_type_t type = obj->type;
1272 uint32_t id, op;
1273 int i = 0;
1274
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;
1285 }
1286 i ++;
1287 }
1288
1289 return (lcp);
1290 }
1291
1292 /*
1293 * ****************************************************************************
1294 *
1295 * assign_attr:
1296 * assign an attribute.
1297 *
1298 * attr - the attribute being assigned.
1299 * tmp - the attribute.
1300 * return - error code.
1301 *
1302 * ****************************************************************************
1303 */
1304 int
assign_attr(isns_attr_t * attr,const isns_attr_t * tmp)1305 assign_attr(
1306 isns_attr_t *attr,
1307 const isns_attr_t *tmp
1308 )
1309 {
1310 uint32_t t;
1311
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);
1326 }
1327 }
1328 /* FALLTHROUGH */
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) {
1336 return (0);
1337 } else if (tmp->len >= attr->len) {
1338 attr->value.ptr = realloc(
1339 attr->value.ptr, tmp->len + 1);
1340 }
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;
1347 } else {
1348 /* memory exhausted */
1349 return (1);
1350 }
1351 break;
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);
1357 }
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;
1363 } else {
1364 /* memory exhausted */
1365 return (1);
1366 }
1367 break;
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) {
1375 break;
1376 }
1377 /* FALLTHROUGH */
1378 case ISNS_ENTITY_PROTOCOL_ATTR_ID:
1379 case ISNS_VERSION_RANGE_ATTR_ID:
1380
1381 case ISNS_PORTAL_PORT_ATTR_ID:
1382 case ISNS_ESI_PORT_ATTR_ID:
1383 case ISNS_SCN_PORT_ATTR_ID:
1384
1385 case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
1386 case ISNS_ISCSI_SCN_BITMAP_ATTR_ID:
1387
1388 case ISNS_PG_PORTAL_PORT_ATTR_ID:
1389 case ISNS_PG_TAG_ATTR_ID:
1390
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;
1396 break;
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) {
1403 attr->value.ui = t;
1404 } else if (attr->value.ui < ONE_DAY) {
1405 attr->value.ui = ONE_DAY;
1406 }
1407 break;
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 */
1416 }
1417 break;
1418 default:
1419 ASSERT(0);
1420 /* don't assign the attribute */
1421 break;
1422 }
1423 return (0);
1424 }
1425
1426 /*
1427 * ****************************************************************************
1428 *
1429 * copy_attrs:
1430 * copy all of attributes from one object to another.
1431 *
1432 * dst - the destination object.
1433 * tmp - the source object.
1434 * return - error code.
1435 *
1436 * ****************************************************************************
1437 */
1438 static int
copy_attrs(isns_obj_t * dst,const isns_obj_t * src)1439 copy_attrs(
1440 isns_obj_t *dst,
1441 const isns_obj_t *src
1442 )
1443 {
1444 int i = 0;
1445 int n = NUM_OF_ATTRS[dst->type];
1446
1447 isns_attr_t *dst_attr;
1448 const isns_attr_t *src_attr;
1449
1450 while (i < n) {
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) {
1455 return (1);
1456 }
1457 }
1458 i ++;
1459 }
1460
1461 return (0);
1462 }
1463
1464 /*
1465 * ****************************************************************************
1466 *
1467 * extract_attr:
1468 * extract an attribute from a TLV format data.
1469 *
1470 * attr - the attribute.
1471 * tlv - the TLV format data.
1472 * return - error code.
1473 *
1474 * ****************************************************************************
1475 */
1476 int
extract_attr(isns_attr_t * attr,const isns_tlv_t * tlv,int flag)1477 extract_attr(
1478 isns_attr_t *attr,
1479 const isns_tlv_t *tlv,
1480 int flag
1481 )
1482 {
1483 int ec = 0;
1484
1485 uint32_t min_len = 4, max_len = 224;
1486
1487 switch (tlv->attr_id) {
1488 case ISNS_EID_ATTR_ID:
1489 min_len = 0;
1490 /* FALLTHROUGH */
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:
1495 max_len = 256;
1496 /* FALLTHROUGH */
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;
1501 } else {
1502 attr->tag = tlv->attr_id;
1503 attr->len = tlv->attr_len;
1504 attr->value.ptr = (uchar_t *)&(tlv->attr_value[0]);
1505 }
1506 break;
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]);
1511 break;
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;
1517 } else {
1518 attr->tag = tlv->attr_id;
1519 attr->len = tlv->attr_len;
1520 attr->value.ip = (void *)&(tlv->attr_value[0]);
1521 }
1522 break;
1523 case ISNS_ENTITY_PROTOCOL_ATTR_ID:
1524 case ISNS_VERSION_RANGE_ATTR_ID:
1525 case ISNS_ENTITY_REG_PERIOD_ATTR_ID:
1526 /* fall throught */
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:
1531 /* fall throught */
1532 case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
1533 /* fall throught */
1534 case ISNS_PG_PORTAL_PORT_ATTR_ID:
1535 /* fall throught */
1536 case ISNS_DD_SET_ID_ATTR_ID:
1537 case ISNS_DD_SET_STATUS_ATTR_ID:
1538 /* fall throught */
1539 case ISNS_DD_ID_ATTR_ID:
1540 if (tlv->attr_len != 4) {
1541 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1542 break;
1543 }
1544 /* FALLTHROUGH */
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]));
1551 } else {
1552 attr->value.ui = 0;
1553 }
1554 break;
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:
1564 break;
1565 case ISNS_PORTAL_INDEX_ATTR_ID:
1566 case ISNS_ISCSI_NODE_INDEX_ATTR_ID:
1567 case ISNS_PG_INDEX_ATTR_ID:
1568 if (flag == 0) {
1569 if (tlv->attr_len != 4) {
1570 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1571 } else {
1572 attr->tag = tlv->attr_id;
1573 attr->len = tlv->attr_len;
1574 attr->value.ui = ntohl(*(uint32_t *)
1575 &(tlv->attr_value[0]));
1576 }
1577 break;
1578 }
1579 /* FALLTHROUGH */
1580 case ISNS_ENTITY_INDEX_ATTR_ID:
1581 case ISNS_TIMESTAMP_ATTR_ID:
1582 default:
1583 if (flag == 0) {
1584 ec = ISNS_RSP_INVALID_QRY;
1585 } else {
1586 ec = ISNS_RSP_INVALID_REGIS;
1587 }
1588 break;
1589 }
1590
1591 return (ec);
1592 }
1593
1594 /*
1595 * ****************************************************************************
1596 *
1597 * copy_attr:
1598 * copy an attribute from a TLV format data.
1599 *
1600 * attr - the attribute.
1601 * tlv - the TLV format data.
1602 * return - error code.
1603 *
1604 * ****************************************************************************
1605 */
1606 static int
copy_attr(isns_attr_t * attr,const isns_tlv_t * tlv)1607 copy_attr(
1608 isns_attr_t *attr,
1609 const isns_tlv_t *tlv
1610 )
1611 {
1612 int ec = 0;
1613
1614 isns_attr_t tmp = { 0 };
1615
1616 /* extract the attribute first */
1617 ec = extract_attr(&tmp, tlv, 1);
1618
1619 /* assign the attribute */
1620 if (ec == 0 && tmp.tag != 0) {
1621 if (assign_attr(attr, &tmp) != 0) {
1622 ec = ISNS_RSP_INTERNAL_ERROR;
1623 }
1624 }
1625
1626 return (ec);
1627 }
1628
1629 /*
1630 * ****************************************************************************
1631 *
1632 * get_timestamp:
1633 * get current timestamp.
1634 *
1635 * return - current timestamp.
1636 *
1637 * ****************************************************************************
1638 */
1639 uint32_t
get_timestamp()1640 get_timestamp(
1641 )
1642 {
1643 uint32_t t;
1644 int flag;
1645
1646 /* block the scheduler */
1647 (void) pthread_mutex_lock(&el_mtx);
1648
1649 /* get most current time */
1650 if (sys_q != NULL) {
1651 /* need to wakeup idle */
1652 flag = 1;
1653 } else {
1654 flag = 0;
1655 }
1656 t = get_stopwatch(flag);
1657
1658 /* unblock it */
1659 (void) pthread_mutex_unlock(&el_mtx);
1660
1661 return (t);
1662 }
1663
1664 /*
1665 * ****************************************************************************
1666 *
1667 * get_reg_period:
1668 * get the longest registration period.
1669 *
1670 * return - the longest registration period.
1671 *
1672 * ****************************************************************************
1673 */
1674 static uint32_t
get_reg_period()1675 get_reg_period(
1676 )
1677 {
1678 uint32_t t;
1679 uint32_t period;
1680
1681 /* get most current time */
1682 t = get_timestamp();
1683
1684 /* just one second before the end of the world */
1685 period = INFINITY - t - 1;
1686
1687 return (period);
1688 }
1689
1690 /*
1691 * ****************************************************************************
1692 *
1693 * obj_calloc:
1694 * allocate memory space for an object.
1695 *
1696 * type - the object type.
1697 * return - pointer of the object being allocated.
1698 *
1699 * ****************************************************************************
1700 */
1701 isns_obj_t *
obj_calloc(int type)1702 obj_calloc(
1703 int type
1704 )
1705 {
1706 isns_obj_t *obj = NULL;
1707
1708 obj = (isns_obj_t *)calloc(1, SIZEOF_OBJ[type]);
1709 if (obj != NULL) {
1710 obj->type = type;
1711 #ifdef DEBUG
1712 if (verbose_mc) {
1713 printf("object(%d) allocated\n", type);
1714 }
1715 #endif
1716 }
1717
1718 return (obj);
1719 }
1720
1721 /*
1722 * ****************************************************************************
1723 *
1724 * make_default_entity:
1725 * generate a default network entity object.
1726 *
1727 * return - pointer of the default network entity object.
1728 *
1729 * ****************************************************************************
1730 */
1731 isns_obj_t *
make_default_entity()1732 make_default_entity(
1733 )
1734 {
1735 uint32_t t;
1736
1737 isns_obj_t *obj = obj_calloc(OBJ_ENTITY);
1738 isns_attr_t *attr;
1739 if (obj != NULL) {
1740 int len;
1741 char *eid = make_unique_name(&len, ISNS_EID_ATTR_ID);
1742 if (!eid) {
1743 free(obj);
1744 return (NULL);
1745 }
1746 attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)];
1747
1748 /* set default entity name */
1749 attr->tag = ISNS_EID_ATTR_ID;
1750 attr->len = len;
1751 attr->value.ptr = (uchar_t *)eid;
1752
1753 /* set default registration period */
1754 attr = &obj->attrs[
1755 ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID)];
1756 if (attr->tag == 0) {
1757 attr->tag = ISNS_ENTITY_REG_PERIOD_ATTR_ID;
1758 attr->len = 4;
1759 t = get_reg_period();
1760 attr->value.ui = t;
1761 }
1762 }
1763
1764 return (obj);
1765 }
1766
1767 /*
1768 * ****************************************************************************
1769 *
1770 * make_default_pg:
1771 * generate a default portal group object.
1772 *
1773 * iscsi - the iscsi storage node object.
1774 * portal - the portal object.
1775 * return - pointer of the default portal group object.
1776 *
1777 * ****************************************************************************
1778 */
1779 static isns_obj_t *
make_default_pg(const isns_obj_t * p1,const isns_obj_t * p2)1780 make_default_pg(
1781 const isns_obj_t *p1,
1782 const isns_obj_t *p2
1783 )
1784 {
1785 const isns_obj_t *iscsi, *portal;
1786 const isns_attr_t *name, *addr, *port;
1787 isns_obj_t *pg;
1788
1789 uchar_t *pg_name;
1790 in6_addr_t *pg_addr;
1791
1792 isns_attr_t *attr;
1793
1794 uint32_t *refp;
1795
1796 if (p1->type == OBJ_ISCSI) {
1797 iscsi = p1;
1798 portal = p2;
1799 } else {
1800 iscsi = p2;
1801 portal = p1;
1802 }
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)];
1806
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;
1816
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;
1824
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;
1830
1831 attr = &pg->attrs[ATTR_INDEX_PG(
1832 ISNS_PG_TAG_ATTR_ID)];
1833 attr->tag = ISNS_PG_TAG_ATTR_ID;
1834 attr->len = 4;
1835 attr->value.ui = ISNS_DEFAULT_PGT;
1836
1837 refp = get_ref_p(pg, OBJ_ISCSI);
1838 *refp = get_obj_uid(iscsi);
1839
1840 refp = get_ref_p(pg, OBJ_PORTAL);
1841 *refp = get_obj_uid(portal);
1842
1843 (void) set_parent_obj(pg, get_parent_uid(iscsi));
1844 } else {
1845 free(pg);
1846 free(pg_name);
1847 free(pg_addr);
1848 pg = NULL;
1849 }
1850
1851 return (pg);
1852 }
1853
1854 /*
1855 * ****************************************************************************
1856 *
1857 * reg_get_entity:
1858 * parse the Operating Attributes of the DevAttrReg message and
1859 * create the Network Entity object if it has one.
1860 *
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.
1865 *
1866 * ****************************************************************************
1867 */
1868 int
reg_get_entity(isns_obj_t ** p,isns_tlv_t ** op,uint16_t * op_len)1869 reg_get_entity(
1870 isns_obj_t **p,
1871 isns_tlv_t **op,
1872 uint16_t *op_len
1873 )
1874 {
1875 int ec = 0;
1876
1877 isns_tlv_t *tmp;
1878 uint16_t tmp_len;
1879 isns_attr_t *attr;
1880
1881 isns_obj_t *entity = NULL;
1882
1883 tmp = *op;
1884 tmp_len = *op_len;
1885
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) {
1890 do {
1891 attr = &entity->attrs[
1892 ATTR_INDEX_ENTITY(tmp->attr_id)];
1893 ec = copy_attr(attr, tmp);
1894 NEXT_TLV(tmp, tmp_len);
1895 } while (ec == 0 &&
1896 tmp_len >= 8 &&
1897 IS_ENTITY_ATTR(tmp->attr_id));
1898 } else {
1899 ec = ISNS_RSP_INTERNAL_ERROR;
1900 }
1901
1902 if (ec == 0) {
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;
1908 attr->len = 4;
1909 attr->value.ui = get_reg_period();
1910 }
1911 } else if (entity != NULL) {
1912 free(entity);
1913 entity = NULL;
1914 }
1915 }
1916
1917 *p = entity;
1918 *op = tmp;
1919 *op_len = tmp_len;
1920
1921 return (ec);
1922 }
1923
1924 /*
1925 * ****************************************************************************
1926 *
1927 * reg_get_iscsi:
1928 * parse the Operating Attributes of the DevAttrReg message and
1929 * create an iSCSI Storage Node object.
1930 *
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.
1936 *
1937 * ****************************************************************************
1938 */
1939 static int
reg_get_iscsi(isns_obj_t ** p,isns_attr_t * pg_key1,isns_tlv_t ** op,uint16_t * op_len)1940 reg_get_iscsi(
1941 isns_obj_t **p,
1942 isns_attr_t *pg_key1,
1943 isns_tlv_t **op,
1944 uint16_t *op_len
1945 )
1946 {
1947 int ec = 0;
1948
1949 isns_tlv_t *tmp;
1950 uint16_t tmp_len;
1951 isns_attr_t *attr;
1952
1953 isns_obj_t *obj = NULL;
1954
1955 tmp = *op;
1956 tmp_len = *op_len;
1957
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];
1964
1965 /* parse one iscsi storage node object */
1966 obj = obj_calloc(OBJ_ISCSI);
1967 if (obj != NULL) {
1968 /* parse key & non-key attributes */
1969 do {
1970 attr = &obj->attrs[
1971 ATTR_INDEX_ISCSI(tmp->attr_id)];
1972 ec = copy_attr(attr, tmp);
1973 NEXT_TLV(tmp, tmp_len);
1974 } while (ec == 0 &&
1975 tmp_len >= 8 &&
1976 IS_ISCSI_ATTR(tmp->attr_id));
1977 } else {
1978 /* no memory */
1979 ec = ISNS_RSP_INTERNAL_ERROR;
1980 }
1981
1982 *p = obj;
1983 *op = tmp;
1984 *op_len = tmp_len;
1985
1986 return (ec);
1987 }
1988
1989 /*
1990 * ****************************************************************************
1991 *
1992 * reg_get_portal:
1993 * parse the Operating Attributes of the DevAttrReg message and
1994 * create a Portal object.
1995 *
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.
2002 *
2003 * ****************************************************************************
2004 */
2005 static int
reg_get_portal(isns_obj_t ** p,isns_attr_t * pg_key1,isns_attr_t * pg_key2,isns_tlv_t ** op,uint16_t * op_len)2006 reg_get_portal(
2007 isns_obj_t **p,
2008 isns_attr_t *pg_key1,
2009 isns_attr_t *pg_key2,
2010 isns_tlv_t **op,
2011 uint16_t *op_len
2012 )
2013 {
2014 int ec = 0;
2015
2016 isns_tlv_t *tmp;
2017 uint16_t tmp_len;
2018 isns_attr_t *attr;
2019
2020 isns_obj_t *obj = NULL;
2021
2022 isns_tlv_t *ip;
2023
2024 tmp = *op;
2025 tmp_len = *op_len;
2026
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];
2031 ip = tmp;
2032
2033 NEXT_TLV(tmp, tmp_len);
2034 if (tmp_len > 8 &&
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]);
2041
2042 /* parse one portal object */
2043 obj = obj_calloc(OBJ_PORTAL);
2044 if (obj != NULL) {
2045 /* copy ip addr attribute */
2046 attr = &obj->attrs[
2047 ATTR_INDEX_PORTAL(ip->attr_id)];
2048 ec = copy_attr(attr, ip);
2049 /* copy port attribute */
2050 if (ec == 0) {
2051 attr = &obj->attrs[
2052 ATTR_INDEX_PORTAL(tmp->attr_id)];
2053 ec = copy_attr(attr, tmp);
2054 }
2055 /* parse non-key attributes */
2056 NEXT_TLV(tmp, tmp_len);
2057 while (ec == 0 &&
2058 tmp_len >= 8 &&
2059 IS_PORTAL_ATTR(tmp->attr_id)) {
2060 attr = &obj->attrs[
2061 ATTR_INDEX_PORTAL(
2062 tmp->attr_id)];
2063 ec = copy_attr(attr, tmp);
2064 NEXT_TLV(tmp, tmp_len);
2065 }
2066 } else {
2067 /* no memory */
2068 ec = ISNS_RSP_INTERNAL_ERROR;
2069 }
2070 } else {
2071 /* ip address is not followed by port */
2072 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2073 }
2074
2075 *p = obj;
2076 *op = tmp;
2077 *op_len = tmp_len;
2078
2079 return (ec);
2080 }
2081
2082 /*
2083 * ****************************************************************************
2084 *
2085 * reg_get_pg:
2086 * parse the Operating Attributes of the DevAttrReg message and
2087 * create a Portal Group object.
2088 *
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.
2093 *
2094 * ****************************************************************************
2095 */
2096 static int
reg_get_pg(isns_obj_t ** p,isns_tlv_t ** op,uint16_t * op_len)2097 reg_get_pg(
2098 isns_obj_t **p,
2099 isns_tlv_t **op,
2100 uint16_t *op_len
2101 )
2102 {
2103 int ec = 0;
2104
2105 isns_tlv_t *tmp;
2106 uint16_t tmp_len;
2107 isns_attr_t *attr;
2108
2109 isns_obj_t *obj = NULL;
2110
2111 tmp = *op;
2112 tmp_len = *op_len;
2113
2114 /* parse a complete pg object */
2115 obj = obj_calloc(OBJ_PG);
2116 if (obj != NULL) {
2117 /* parse attributes */
2118 do {
2119 attr = &obj->attrs[
2120 ATTR_INDEX_PG(tmp->attr_id)];
2121 ec = copy_attr(attr, tmp);
2122 NEXT_TLV(tmp, tmp_len);
2123 } while (ec == 0 &&
2124 tmp_len >= 8 &&
2125 IS_PG_ATTR(tmp->attr_id));
2126 } else {
2127 ec = ISNS_RSP_INTERNAL_ERROR;
2128 }
2129
2130 *p = obj;
2131 *op = tmp;
2132 *op_len = tmp_len;
2133
2134 return (ec);
2135 }
2136
2137 /*
2138 * ****************************************************************************
2139 *
2140 * reg_get_pg1:
2141 * parse the Operating Attributes of the DevAttrReg message and
2142 * create a Portal Group object which is followed to a Portal object.
2143 *
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.
2150 *
2151 * ****************************************************************************
2152 */
2153 static int
reg_get_pg1(isns_obj_t ** p,isns_attr_t const * pgt,isns_tlv_t ** op,uint16_t * op_len)2154 reg_get_pg1(
2155 isns_obj_t **p,
2156 isns_attr_t const *pgt,
2157 isns_tlv_t **op,
2158 uint16_t *op_len
2159 )
2160 {
2161 int ec = 0;
2162
2163 isns_tlv_t *tmp;
2164 uint16_t tmp_len;
2165 isns_attr_t *attr;
2166
2167 isns_obj_t *obj = NULL;
2168 int i = 0;
2169
2170 tmp = *op;
2171 tmp_len = *op_len;
2172
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);
2178 if (obj != NULL) {
2179 /* copy pg iscsi storage node name */
2180 attr = &obj->attrs[
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) {
2185 attr = &obj->attrs[
2186 ATTR_INDEX_PG(pgt[i].tag)];
2187 ec = assign_attr(attr, &pgt[i]);
2188 i ++;
2189 }
2190 NEXT_TLV(tmp, tmp_len);
2191 } else {
2192 /* no memory */
2193 ec = ISNS_RSP_INTERNAL_ERROR;
2194 }
2195 } else {
2196 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2197 }
2198
2199 *p = obj;
2200 *op = tmp;
2201 *op_len = tmp_len;
2202
2203 return (ec);
2204 }
2205
2206 /*
2207 * ****************************************************************************
2208 *
2209 * reg_get_pg2:
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.
2213 *
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.
2220 *
2221 * ****************************************************************************
2222 */
2223 static int
reg_get_pg2(isns_obj_t ** p,isns_attr_t const * pgt,isns_tlv_t ** op,uint16_t * op_len)2224 reg_get_pg2(
2225 isns_obj_t **p,
2226 isns_attr_t const *pgt,
2227 isns_tlv_t **op,
2228 uint16_t *op_len
2229 )
2230 {
2231 int ec = 0;
2232
2233 isns_tlv_t *tmp;
2234 uint16_t tmp_len;
2235 isns_attr_t *attr;
2236
2237 isns_obj_t *obj = NULL;
2238 int i = 0;
2239
2240 isns_tlv_t *ip;
2241
2242 tmp = *op;
2243 tmp_len = *op_len;
2244
2245 /* keep ip address */
2246 ip = tmp;
2247 NEXT_TLV(tmp, tmp_len);
2248
2249 if (tmp_len > 8 &&
2250 /* expect pg portal port */
2251 tmp->attr_id == PG_KEY3 &&
2252 tmp->attr_len == 4 &&
2253 /* expect pg tag */
2254 pgt[2].tag == PG_PGT &&
2255 /* expect pg iscsi storage node name only */
2256 pgt[1].tag == 0 &&
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);
2262 if (obj != NULL) {
2263 /* copy the pg ip addr */
2264 attr = &obj->attrs[
2265 ATTR_INDEX_PG(ip->attr_id)];
2266 ec = copy_attr(attr, ip);
2267 /* copy the pg port */
2268 if (ec == 0) {
2269 attr = &obj->attrs[
2270 ATTR_INDEX_PG(tmp->attr_id)];
2271 ec = copy_attr(attr, tmp);
2272 }
2273 /* copy pg iscsi storage node name & pgt */
2274 while (ec == 0 && i < 3) {
2275 attr = &obj->attrs[
2276 ATTR_INDEX_PG(pgt[i].tag)];
2277 ec = assign_attr(attr, &pgt[i]);
2278 i += 2;
2279 }
2280 NEXT_TLV(tmp, tmp_len);
2281 } else {
2282 ec = ISNS_RSP_INTERNAL_ERROR;
2283 }
2284 } else {
2285 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2286 }
2287
2288 *p = obj;
2289 *op = tmp;
2290 *op_len = tmp_len;
2291
2292 return (ec);
2293 }
2294
2295 /*
2296 * ****************************************************************************
2297 *
2298 * reg_get_obj:
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.
2302 *
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.
2312 *
2313 * ****************************************************************************
2314 */
2315 int
reg_get_obj(isns_obj_t ** p,isns_attr_t * pgt,isns_tlv_t ** op,uint16_t * op_len)2316 reg_get_obj(
2317 isns_obj_t **p,
2318 isns_attr_t *pgt,
2319 isns_tlv_t **op,
2320 uint16_t *op_len
2321 )
2322 {
2323 int ec = 0;
2324
2325 int derefd = 0;
2326
2327 uint32_t pg_tag;
2328
2329 if (*op_len == 0) {
2330 *p = NULL;
2331 return (0);
2332 }
2333
2334 switch ((*op)->attr_id) {
2335 case ISCSI_KEY:
2336 ec = reg_get_iscsi(p, &pgt[0], op, op_len);
2337 pgt[1].tag = 0;
2338 pgt[2].tag = 0;
2339 break;
2340 case PORTAL_KEY1:
2341 ec = reg_get_portal(p, &pgt[0], &pgt[1], op, op_len);
2342 pgt[2].tag = 0;
2343 break;
2344 case PG_KEY1:
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);
2349 } else {
2350 /* a complete pg object */
2351 ec = reg_get_pg(p, op, op_len);
2352 pgt[0].tag = 0;
2353 pgt[1].tag = 0;
2354 pgt[2].tag = 0;
2355 }
2356 break;
2357 case PG_KEY2:
2358 /* pg portal ip addr is followed to a pgt */
2359 ec = reg_get_pg2(p, pgt, op, op_len);
2360 break;
2361 case PG_PGT:
2362 switch (pgt[0].tag) {
2363 case 0:
2364 /* portal group tag does not follow */
2365 /* iscsi storage node or portal object */
2366 *p = NULL;
2367 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2368 break;
2369 case PG_KEY1:
2370 case PG_KEY2:
2371 pgt[2].tag = PG_PGT;
2372 pgt[2].len = (*op)->attr_len;
2373 pg_tag = 0;
2374 switch ((*op)->attr_len) {
2375 case 4:
2376 pg_tag = ntohl(*(uint32_t *)
2377 &(*op)->attr_value[0]);
2378 /* FALLTHROUGH */
2379 case 0:
2380 pgt[2].value.ui = pg_tag;
2381 break;
2382 default:
2383 *p = NULL;
2384 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2385 break;
2386 }
2387 if (ec == 0) {
2388 derefd = 1;
2389 NEXT_TLV(*op, *op_len);
2390 ec = reg_get_obj(p, pgt, op, op_len);
2391 }
2392 break;
2393 default:
2394 /* should never happen */
2395 ASSERT(0);
2396 *p = NULL;
2397 ec = ISNS_RSP_INTERNAL_ERROR;
2398 break;
2399 }
2400 break;
2401 default:
2402 *p = NULL;
2403 ec = ISNS_RSP_MSG_FORMAT_ERROR;
2404 break;
2405 }
2406
2407 if (ec == 0 && derefd == 0) {
2408 ec = update_deref_obj(*p);
2409 }
2410
2411 if (ec != 0 && *p != NULL) {
2412 free_one_object(*p);
2413 *p = NULL;
2414 }
2415
2416 return (ec);
2417 }
2418
2419 /*
2420 * ****************************************************************************
2421 *
2422 * reg_auth_src:
2423 * Authorize the source attribute the DevAttrReg message.
2424 * The update can only performed by the node who has the owenership.
2425 *
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.
2435 *
2436 * ****************************************************************************
2437 */
2438 int
reg_auth_src(isns_type_t type,uint32_t uid,uchar_t * src)2439 reg_auth_src(
2440 isns_type_t type,
2441 uint32_t uid,
2442 uchar_t *src
2443 )
2444 {
2445 lookup_ctrl_t lc;
2446 uint32_t puid;
2447
2448 puid = is_parent_there(src);
2449
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];
2454 }
2455
2456 if (uid != 0 && puid == 0) {
2457 SET_UID_LCP(&lc, type, uid);
2458 uid = cache_lookup(&lc, NULL, cb_node_child);
2459 }
2460
2461 if (puid != uid) {
2462 return (0);
2463 }
2464
2465 return (1);
2466 }
2467
2468 /*
2469 * ****************************************************************************
2470 *
2471 * is_obj_online:
2472 * determine if the object is currently registered with the server.
2473 *
2474 * obj - the object being checked.
2475 * return - 0: not registered, otherwise registered.
2476 *
2477 * ****************************************************************************
2478 */
2479 int
is_obj_online(const isns_obj_t * obj)2480 is_obj_online(
2481 const isns_obj_t *obj
2482 )
2483 {
2484 int online = 1;
2485
2486 switch (obj->type) {
2487 case OBJ_ISCSI:
2488 online = obj->attrs[ATTR_INDEX_ISCSI(
2489 ISNS_ISCSI_NODE_TYPE_ATTR_ID)].value.ui == 0 ? 0 : 1;
2490 break;
2491 default:
2492 break;
2493 }
2494
2495 return (online);
2496 }
2497
2498 static int
set_obj_offline(isns_obj_t * obj)2499 set_obj_offline(
2500 isns_obj_t *obj
2501 )
2502 {
2503 switch (obj->type) {
2504 case OBJ_ISCSI:
2505 obj->attrs[ATTR_INDEX_ISCSI(
2506 ISNS_ISCSI_NODE_TYPE_ATTR_ID)].value.ui = 0;
2507 break;
2508 default:
2509 break;
2510 }
2511
2512 return (0);
2513 }
2514
2515 /*
2516 * ****************************************************************************
2517 *
2518 * assoc_clone:
2519 * clone the association object.
2520 *
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.
2525 *
2526 * ****************************************************************************
2527 */
2528 void *
assoc_clone(void * p,int clone_flag)2529 assoc_clone(
2530 void *p,
2531 int clone_flag
2532 )
2533 {
2534 isns_type_t type;
2535 isns_obj_t *clone;
2536 const isns_attr_t *src_attr;
2537 isns_attr_t *dst_attr;
2538 uint32_t id, op;
2539 int i = 0;
2540
2541 const isns_obj_t *obj;
2542 uint32_t dd_flag;
2543 int online;
2544
2545 int state;
2546
2547 obj = (isns_obj_t *)p;
2548
2549 if (obj->type != OBJ_ISCSI) {
2550 return (NULL);
2551 }
2552
2553 dd_flag = (get_dd_id(get_obj_uid(obj), ISNS_DEFAULT_DD_ID) == 0) ?
2554 0 : 1;
2555 online = is_obj_online(obj);
2556
2557 state = (clone_flag << 2) | (dd_flag << 1) | online;
2558
2559 /* clone_flag dd_flag online action */
2560 /* 0 0 0 ASSERT(0) */
2561 /* 0 0 1 NULL */
2562 /* 0 1 0 itself */
2563 /* 0 1 1 clone it */
2564 /* 1 0 0 NULL */
2565 /* 1 0 1 itself */
2566 /* 1 1 0 itself */
2567 /* 1 1 1 itself */
2568
2569 switch (state) {
2570 case 0:
2571 ASSERT(0);
2572 case 1:
2573 case 4:
2574 return (NULL);
2575 case 2:
2576 case 5:
2577 case 6:
2578 case 7:
2579 return (p);
2580 case 3:
2581 default:
2582 break;
2583 }
2584
2585 type = obj->type;
2586 clone = obj_calloc(type);
2587
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);
2594 return (NULL);
2595 }
2596
2597 while (i < MAX_KEY_ATTRS) {
2598 op = KEY_ATTR_OP[type][i];
2599 if (op != 0) {
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);
2605 return (NULL);
2606 }
2607 } else {
2608 break;
2609 }
2610 i ++;
2611 }
2612 }
2613
2614 return ((void *)clone);
2615 }
2616
2617 /*
2618 * ****************************************************************************
2619 *
2620 * free_one_object:
2621 * free up one object.
2622 *
2623 * obj - the object being freed.
2624 *
2625 * ****************************************************************************
2626 */
2627 void
free_one_object(isns_obj_t * obj)2628 free_one_object(
2629 isns_obj_t *obj
2630 )
2631 {
2632 int i;
2633 uint32_t *cuid;
2634 if (obj == NULL) {
2635 return;
2636 }
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:
2653 #ifdef DEBUG
2654 if (verbose_mc) {
2655 printf("memory(%d) deallocated\n",
2656 attr->len);
2657 }
2658 #endif
2659 free(attr->value.ptr);
2660 attr->value.ptr = NULL;
2661 break;
2662 default:
2663 break;
2664 }
2665 }
2666
2667 /* free child uids */
2668 i = 0;
2669 while (i < NUM_OF_CHILD[obj->type]) {
2670 cuid = get_child_n(obj, i);
2671 free(cuid);
2672 i ++;
2673 }
2674
2675 /* at last, free the object itself */
2676 #ifdef DEBUG
2677 if (verbose_mc) {
2678 printf("object(%d) deallocated\n", obj->type);
2679 }
2680 #endif
2681 free(obj);
2682 }
2683
2684 /*
2685 * ****************************************************************************
2686 *
2687 * free_object:
2688 * free up one object.
2689 *
2690 * obj - the object being freed.
2691 *
2692 * ****************************************************************************
2693 */
2694 void
free_object(isns_obj_t * obj)2695 free_object(
2696 isns_obj_t *obj
2697 )
2698 {
2699 free_one_object(obj);
2700 }
2701
2702 /*
2703 * ****************************************************************************
2704 *
2705 * set_parent_obj:
2706 * set the parent object UID.
2707 *
2708 * obj - the child object.
2709 * puid- the parent object UID.
2710 * return - error code.
2711 *
2712 * ****************************************************************************
2713 */
2714 int
set_parent_obj(isns_obj_t * obj,uint32_t puid)2715 set_parent_obj(
2716 isns_obj_t *obj,
2717 uint32_t puid
2718 )
2719 {
2720 uint32_t *const p = get_parent_p(obj);
2721 if (p != NULL) {
2722 *p = puid;
2723 }
2724
2725 return (0);
2726 }
2727
2728 /*
2729 * ****************************************************************************
2730 *
2731 * buff_child_obj:
2732 * add a child object UID to the child object array.
2733 *
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.
2738 *
2739 * ****************************************************************************
2740 */
2741 int
buff_child_obj(const isns_type_t ptype,const isns_type_t ctype,const void * c,void const *** child)2742 buff_child_obj(
2743 const isns_type_t ptype,
2744 const isns_type_t ctype,
2745 const void *c,
2746 void const ***child
2747 )
2748 {
2749 int ec = 0;
2750
2751 int i = 0;
2752 void const ***pp, **p;
2753 uint32_t num, new_num;
2754
2755 pp = NULL;
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) {
2759 pp = &child[i];
2760 break;
2761 }
2762 i ++;
2763 }
2764
2765 /* the child type is not applicable */
2766 if (pp == NULL) {
2767 return (ec);
2768 }
2769
2770 p = *pp;
2771 /* get an empty slot from the uid array for this child */
2772 if (p != NULL) {
2773 num = (uint32_t)*p;
2774 i = 0;
2775 while (i < num) {
2776 if (p[++i] == NULL) {
2777 /* found it */
2778 p[i] = c;
2779 return (ec);
2780 }
2781 }
2782 p = *pp;
2783 new_num = num + 1;
2784 } else {
2785 num = 0;
2786 new_num = 1;
2787 }
2788
2789 /* the array is full, enlarge the child uid array */
2790 p = (void const **)realloc(p, (new_num + 1) * sizeof (void *));
2791 if (p != NULL) {
2792 *pp = p;
2793 *p = (void *)new_num;
2794 p[new_num] = c;
2795 } else {
2796 ec = ISNS_RSP_INTERNAL_ERROR;
2797 }
2798
2799 return (ec);
2800 }
2801
2802 /*
2803 * ****************************************************************************
2804 *
2805 * update_child_object:
2806 * update the child object of a network entity object.
2807 *
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.
2812 *
2813 * ****************************************************************************
2814 */
2815 int
update_child_obj(const isns_type_t ptype,const uint32_t puid,void const *** child,int child_flag)2816 update_child_obj(
2817 const isns_type_t ptype,
2818 const uint32_t puid,
2819 void const ***child,
2820 int child_flag
2821 )
2822 {
2823 int ec = 0;
2824
2825 lookup_ctrl_t lc;
2826
2827 SET_UID_LCP(&lc, ptype, puid);
2828
2829 lc.data[1].ptr = (uchar_t *)child;
2830 lc.data[2].ui = child_flag;
2831
2832 ec = cache_lookup(&lc, NULL, cb_add_child);
2833
2834 return (ec);
2835 }
2836
2837 int
update_ref_obj(const isns_obj_t * obj)2838 update_ref_obj(
2839 const isns_obj_t *obj
2840 )
2841 {
2842 uint32_t uid;
2843 lookup_ctrl_t lc;
2844 isns_type_t t;
2845
2846 t = obj->type;
2847
2848 if (TYPE_OF_REF[t][0] != 0) {
2849 (void) setup_ref_lcp(&lc, obj, NULL);
2850
2851 lc.id[2] = t;
2852 lc.data[2].ui = get_obj_uid(obj);
2853
2854 uid = 0;
2855 do {
2856 lc.curr_uid = uid;
2857 (void) cache_lookup(&lc, &uid, cb_set_ref);
2858 } while (uid != 0);
2859 }
2860
2861 return (0);
2862 }
2863
2864 /*
2865 * ****************************************************************************
2866 *
2867 * verify_ref_obj:
2868 * update the reference bit of a portal group object.
2869 *
2870 * obj - the object being ref'ed.
2871 * return - error code.
2872 *
2873 * ****************************************************************************
2874 */
2875 int
verify_ref_obj(const isns_type_t ptype,const uint32_t puid,void const *** child)2876 verify_ref_obj(
2877 const isns_type_t ptype,
2878 const uint32_t puid,
2879 void const ***child
2880 )
2881 {
2882 int ec = 0;
2883
2884 lookup_ctrl_t lc;
2885
2886 SET_UID_LCP(&lc, ptype, puid);
2887
2888 lc.data[1].ptr = (uchar_t *)child;
2889
2890 ec = cache_lookup(&lc, NULL, cb_verify_ref);
2891
2892 return (ec);
2893 }
2894
2895 int
update_deref_obj(isns_obj_t * obj)2896 update_deref_obj(
2897 isns_obj_t *obj
2898 )
2899 {
2900 int ec = 0;
2901
2902 isns_type_t t, rt;
2903 lookup_ctrl_t lc;
2904 int i, ref_count;
2905
2906 uint32_t uid, *refp;
2907
2908 t = obj->type;
2909 i = ref_count = 0;
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);
2914 if (uid != 0) {
2915 refp = get_ref_p(obj, lc.type);
2916 *refp = uid;
2917 ref_count ++;
2918 }
2919 i ++;
2920 }
2921
2922 if (i > 0 && ref_count == 0) {
2923 ec = ISNS_RSP_INVALID_REGIS;
2924 }
2925
2926 return (ec);
2927 }
2928
2929 /*
2930 * ****************************************************************************
2931 *
2932 * register_object:
2933 * add one object to the object container.
2934 *
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.
2940 *
2941 * ****************************************************************************
2942 */
2943 int
register_object(isns_obj_t * obj,uint32_t * uid_p,int * update_p)2944 register_object(
2945 isns_obj_t *obj,
2946 uint32_t *uid_p,
2947 int *update_p
2948 )
2949 {
2950 return (cache_add(obj, 0, uid_p, update_p));
2951 }
2952
2953 /*
2954 * ****************************************************************************
2955 *
2956 * register_assoc:
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.
2960 *
2961 * obj - the association object being added.
2962 * uid_p- the pointer for returning object UID.
2963 * return - error code.
2964 *
2965 * ****************************************************************************
2966 */
2967 int
register_assoc(isns_obj_t * obj,uint32_t * uid_p)2968 register_assoc(
2969 isns_obj_t *obj,
2970 uint32_t *uid_p
2971 )
2972 {
2973 return (cache_add(obj, 1, uid_p, NULL));
2974 }
2975
2976 /*
2977 * ****************************************************************************
2978 *
2979 * is_obj_there:
2980 * check if the object is registered or not.
2981 *
2982 * lcp - the lookup control data.
2983 * return - the object UID.
2984 *
2985 * ****************************************************************************
2986 */
2987 uint32_t
is_obj_there(lookup_ctrl_t * lcp)2988 is_obj_there(
2989 lookup_ctrl_t *lcp
2990 )
2991 {
2992 uint32_t uid;
2993
2994 (void) cache_lookup(lcp, &uid, NULL);
2995
2996 return (uid);
2997 }
2998
2999 uint32_t
is_parent_there(uchar_t * src)3000 is_parent_there(
3001 uchar_t *src
3002 )
3003 {
3004 lookup_ctrl_t lc;
3005
3006 lc.curr_uid = 0;
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;
3011 lc.op[1] = 0;
3012
3013 return (cache_lookup(&lc, NULL, cb_get_parent));
3014 }
3015
3016 /*
3017 * ****************************************************************************
3018 *
3019 * setup_ref_lcp:
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
3022 * object.
3023 *
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.
3028 *
3029 * ****************************************************************************
3030 */
3031 static int
setup_ref_lcp(lookup_ctrl_t * lcp,const isns_obj_t * iscsi,const isns_obj_t * portal)3032 setup_ref_lcp(
3033 lookup_ctrl_t *lcp,
3034 const isns_obj_t *iscsi,
3035 const isns_obj_t *portal
3036 )
3037 {
3038 int i = 0, j = 0;
3039
3040 lcp->curr_uid = 0;
3041 lcp->type = TYPE_OF_REF[iscsi->type][0];
3042
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;
3051 i ++;
3052 }
3053
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;
3063 j ++;
3064 i ++;
3065 }
3066
3067 if (i < MAX_LOOKUP_CTRL) {
3068 lcp->op[i] = 0;
3069 }
3070
3071 return (0);
3072 }
3073
3074 static int
setup_deref_lcp(lookup_ctrl_t * lcp,const isns_obj_t * pg,isns_type_t t)3075 setup_deref_lcp(
3076 lookup_ctrl_t *lcp,
3077 const isns_obj_t *pg,
3078 isns_type_t t
3079 )
3080 {
3081 int i = 0;
3082
3083 lcp->curr_uid = 0;
3084 lcp->type = t;
3085
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;
3093 i ++;
3094 }
3095
3096 if (i < MAX_LOOKUP_CTRL) {
3097 lcp->op[i] = 0;
3098 }
3099
3100 return (0);
3101 }
3102
3103 /*
3104 * ****************************************************************************
3105 *
3106 * setup_parent_lcp:
3107 * prepare the lookup control data for looking up parent object
3108 * with a child object.
3109 *
3110 * lcp - the lookup control data.
3111 * obj - the child object.
3112 * return - parent object UID.
3113 *
3114 * ****************************************************************************
3115 */
3116 static uint32_t
setup_parent_lcp(lookup_ctrl_t * lcp,isns_obj_t * obj)3117 setup_parent_lcp(
3118 lookup_ctrl_t *lcp,
3119 isns_obj_t *obj
3120 )
3121 {
3122 isns_type_t ptype;
3123 uint32_t puid;
3124
3125 puid = get_parent_uid(obj);
3126 if (puid != 0) {
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);
3131 }
3132
3133 return (puid);
3134 }
3135
3136 static int
cb_get_parent(void * p1,void * p2)3137 cb_get_parent(
3138 void *p1,
3139 /* LINTED E_FUNC_ARG_UNUSED */
3140 void *p2
3141 )
3142 {
3143 return (get_parent_uid(p1));
3144 }
3145
3146 static int
cb_node_child(void * p1,void * p2)3147 cb_node_child(
3148 void *p1,
3149 /* LINTED E_FUNC_ARG_UNUSED */
3150 void *p2
3151 )
3152 {
3153 isns_obj_t *obj = (isns_obj_t *)p1;
3154
3155 uint32_t num, uid;
3156
3157 uint32_t *cuid = get_child_t(obj, OBJ_ISCSI);
3158
3159 if (cuid != NULL) {
3160 num = *cuid;
3161 } else {
3162 num = 0;
3163 }
3164
3165 while (num > 0) {
3166 uid = *++cuid;
3167 if (uid != 0) {
3168 return (uid);
3169 }
3170 num --;
3171 }
3172
3173 return (0);
3174 }
3175
3176 /*
3177 * ****************************************************************************
3178 *
3179 * cb_set_ref:
3180 * callback function which sets the reference bit to 1 according to
3181 * the type of object.
3182 *
3183 * p1 - the object.
3184 * p2 - the lcp.
3185 * return - error code.
3186 *
3187 * ****************************************************************************
3188 */
3189 static int
cb_set_ref(void * p1,void * p2)3190 cb_set_ref(
3191 void *p1,
3192 void *p2
3193 )
3194 {
3195 isns_obj_t *obj = (isns_obj_t *)p1;
3196 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3197
3198 isns_type_t t;
3199 uint32_t u;
3200
3201 uint32_t *refp;
3202
3203 t = lcp->id[2];
3204 u = lcp->data[2].ui;
3205 refp = get_ref_p(obj, t);
3206 *refp = u;
3207
3208 /* successful */
3209 return (0);
3210 }
3211
3212 /*
3213 * ****************************************************************************
3214 *
3215 * cb_clear_ref:
3216 * callback function which clears the reference bit according to
3217 * the type of object.
3218 *
3219 * p1 - the object.
3220 * p2 - the lcp.
3221 * return - 1: the object is no longer ref'ed, 0: otherwise.
3222 *
3223 * ****************************************************************************
3224 */
3225 static int
cb_clear_ref(void * p1,void * p2)3226 cb_clear_ref(
3227 void *p1,
3228 void *p2
3229 )
3230 {
3231 isns_obj_t *obj = (isns_obj_t *)p1;
3232 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3233
3234 isns_type_t t;
3235 uint32_t *refp;
3236
3237 int i = 0;
3238 uint32_t ref;
3239
3240 t = lcp->data[2].ui;
3241 refp = get_ref_p(obj, t);
3242 *refp = 0;
3243
3244 while (i < NUM_OF_REF[obj->type]) {
3245 ref = get_ref_n(obj, i);
3246 if (ref != 0) {
3247 return (0);
3248 }
3249 i ++;
3250 }
3251
3252 return (1);
3253 }
3254
3255 static int
cb_add_child(void * p1,void * p2)3256 cb_add_child(
3257 void *p1,
3258 void *p2
3259 )
3260 {
3261 isns_obj_t *obj = (isns_obj_t *)p1;
3262 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3263
3264 const void ***child;
3265 const void **vpp;
3266 uint32_t vnum;
3267 int child_flag;
3268
3269 uint32_t **upp, *up;
3270 uint32_t num;
3271
3272 isns_obj_t *o;
3273
3274 int i = 0;
3275
3276 child = (const void ***)lcp->data[1].ptr;
3277 child_flag = lcp->data[2].ui;
3278
3279 while (i < NUM_OF_CHILD[obj->type]) {
3280 vpp = child[i];
3281 if (vpp != NULL &&
3282 (vnum = (uint32_t)*vpp) > 0 &&
3283 *(vpp + 1) != NULL) {
3284 upp = get_child_np(obj, i);
3285 if (*upp == NULL) {
3286 if (child_flag == 0 &&
3287 sizeof (typeof (**upp)) ==
3288 sizeof (typeof (**child))) {
3289 *upp = (uint32_t *)vpp;
3290 vpp = NULL;
3291 child[i] = NULL;
3292 }
3293 num = vnum;
3294 } else {
3295 num = **upp + vnum;
3296 }
3297 if (vpp != NULL) {
3298 /* copy required */
3299 up = (uint32_t *)realloc(*upp,
3300 (num + 1) * sizeof (uint32_t));
3301 if (up == NULL) {
3302 return (ISNS_RSP_INTERNAL_ERROR);
3303 }
3304 *upp = up;
3305 *up = num;
3306 up += num;
3307 vpp += vnum;
3308 while (vnum > 0) {
3309 if (*vpp == NULL) {
3310 *up = 0;
3311 } else if (child_flag == 0) {
3312 *up = (uint32_t)*vpp;
3313 *vpp = NULL;
3314 } else {
3315 o = (isns_obj_t *)*vpp;
3316 *up = get_obj_uid(o);
3317 if (is_obj_online(o) == 0) {
3318 free_object(o);
3319 }
3320 *vpp = NULL;
3321 }
3322 up --;
3323 vpp --;
3324 vnum --;
3325 }
3326 }
3327 }
3328 i ++;
3329 }
3330
3331 return (0);
3332 }
3333
3334 /*
3335 * ****************************************************************************
3336 *
3337 * cb_remove_child:
3338 * callback function which removes a child object UID from the
3339 * children objet UID array of the parent object.
3340 *
3341 * p1 - the object.
3342 * p2 - the lcp.
3343 * return - 1: no more such type of child object, 0: otherwise.
3344 *
3345 * ****************************************************************************
3346 */
3347 static int
cb_remove_child(void * p1,void * p2)3348 cb_remove_child(
3349 void *p1,
3350 void *p2
3351 )
3352 {
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;
3358 int i;
3359
3360 /* get the children object UID array */
3361 cuidp = get_child_t(obj, child_type);
3362 if (cuidp != NULL) {
3363 num_of_child = *cuidp;
3364 }
3365
3366 /* remove it */
3367 while (num_of_child > 0) {
3368 cuid = *++cuidp;
3369 if (cuid == child_uid) {
3370 *cuidp = 0;
3371 break;
3372 }
3373 num_of_child --;
3374 }
3375
3376 /* check if all of child object UIDs are removed */
3377 i = 0;
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) {
3383 cuid = *++cuidp;
3384 if (cuid != 0) {
3385 return (0);
3386 }
3387 num_of_child --;
3388 }
3389 }
3390 i ++;
3391 }
3392
3393 return (1);
3394 }
3395
3396 static int
cb_verify_ref(void * p1,void * p2)3397 cb_verify_ref(
3398 void *p1,
3399 void *p2
3400 )
3401 {
3402 int ec = 0;
3403
3404 isns_obj_t *parent = (isns_obj_t *)p1;
3405 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3406
3407 const void ***child;
3408
3409 const void **vpp;
3410 const void *vp;
3411 uint32_t vnum;
3412
3413 const void **evpp;
3414 const void *evp;
3415 uint32_t evnum;
3416
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 */
3421
3422 uint32_t *up;
3423 uint32_t u;
3424 uint32_t unum;
3425
3426 lookup_ctrl_t lc;
3427 uint8_t flag[MAX_OBJ_TYPE + 1] = { 0 };
3428
3429 int i, j, k;
3430
3431 pt = parent->type;
3432
3433 child = (const void ***)lcp->data[1].ptr;
3434
3435 for (i = 0; i < NUM_OF_CHILD[pt]; i++) {
3436 ct = TYPE_OF_CHILD[pt][i];
3437 rt = TYPE_OF_REF[ct][0];
3438 if (rt == 0) {
3439 continue;
3440 }
3441
3442 et = TYPE_OF_REF[ct][1];
3443 vpp = child[i];
3444 if (vpp != NULL) {
3445 vnum = (uint32_t)*vpp;
3446 up = get_child_t(parent, et);
3447 if (up != NULL) {
3448 unum = *up;
3449 } else {
3450 unum = 0;
3451 }
3452 } else {
3453 vnum = 0;
3454 }
3455
3456 j = vnum;
3457 while (j > 0) {
3458 vp = vpp[j];
3459 if (vp != NULL) {
3460 (void) setup_ref_lcp(&lc, vp, NULL);
3461 k = unum;
3462 while (k > 0) {
3463 u = up[k];
3464 if (u != 0) {
3465 ec = ref_new2old(
3466 &lc, et, u, vp);
3467 if (ec != 0) {
3468 return (ec);
3469 }
3470 }
3471 k --;
3472 } /* End of while each unum */
3473 }
3474 j --;
3475 } /* End of while each vnum */
3476
3477 if (flag[ct] != 0) {
3478 continue;
3479 }
3480
3481 evnum = 0;
3482 j = 0;
3483 while (j < NUM_OF_CHILD[pt]) {
3484 if (TYPE_OF_CHILD[pt][j] == et) {
3485 evpp = child[j];
3486 if (evpp != NULL) {
3487 evnum = (uint32_t)*evpp;
3488 }
3489 break;
3490 }
3491 j ++;
3492 }
3493
3494 j = vnum;
3495 while (j > 0) {
3496 vp = vpp[j];
3497 k = evnum;
3498 while (k > 0) {
3499 evp = evpp[k];
3500 if (vp != NULL && evp != NULL) {
3501 (void) setup_ref_lcp(&lc, vp, evp);
3502 ec = ref_new2new(&lc, vp, evp);
3503 if (ec != 0) {
3504 return (ec);
3505 }
3506 }
3507 k --;
3508 }
3509 j --;
3510 } /* End of while each vnum */
3511
3512 flag[et] = 1;
3513 } /* End of for each type of child */
3514
3515 return (ec);
3516 }
3517
3518 static int
cb_ref_new2old(void * p1,void * p2)3519 cb_ref_new2old(
3520 void *p1,
3521 void *p2
3522 )
3523 {
3524 isns_obj_t *obj = (isns_obj_t *)p1;
3525 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
3526
3527 isns_type_t et;
3528 uint32_t uu;
3529
3530 uint32_t ref;
3531
3532 int match;
3533
3534 et = lcp->id[2];
3535 uu = lcp->data[2].ui;
3536
3537 ref = get_ref_t(obj, et);
3538
3539 if (ref == uu) {
3540 match = 1;
3541 } else {
3542 match = 0;
3543 }
3544
3545 return (match);
3546 }
3547
3548 static int
cb_new_ref(void * p1,void * p2)3549 cb_new_ref(
3550 void *p1,
3551 void *p2
3552 )
3553 {
3554 int ec = 0;
3555
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;
3559
3560 ec = new_ref(a, b);
3561
3562 return (ec);
3563 }
3564
3565 static int
ref_new2old(lookup_ctrl_t * lcp,isns_type_t et,uint32_t uu,const isns_obj_t * vp)3566 ref_new2old(
3567 lookup_ctrl_t *lcp,
3568 isns_type_t et,
3569 uint32_t uu,
3570 const isns_obj_t *vp
3571 )
3572 {
3573 int ec = 0;
3574
3575 int match;
3576 uint32_t uid;
3577
3578 lookup_ctrl_t lc;
3579
3580 lcp->id[2] = et;
3581 lcp->data[2].ui = uu;
3582
3583 uid = 0;
3584 do {
3585 lcp->curr_uid = uid;
3586 match = cache_lookup(lcp, &uid, cb_ref_new2old);
3587 } while (match == 0 && uid != 0);
3588
3589 if (match == 0) {
3590 /* no such ref, create a default one */
3591 SET_UID_LCP(&lc, et, uu);
3592
3593 lc.data[2].ptr = (uchar_t *)vp;
3594
3595 ec = cache_lookup(&lc, NULL, cb_new_ref);
3596 }
3597
3598 return (ec);
3599 }
3600
3601 static int
ref_new2new(lookup_ctrl_t * lcp,const isns_obj_t * p1,const isns_obj_t * p2)3602 ref_new2new(
3603 lookup_ctrl_t *lcp,
3604 const isns_obj_t *p1,
3605 const isns_obj_t *p2
3606 )
3607 {
3608 int ec = 0;
3609
3610 if (is_obj_there(lcp) != 0) {
3611 return (0);
3612 }
3613
3614 ec = new_ref(p1, p2);
3615
3616 return (ec);
3617 }
3618
3619 static int
new_ref(const isns_obj_t * p1,const isns_obj_t * p2)3620 new_ref(
3621 const isns_obj_t *p1,
3622 const isns_obj_t *p2
3623 )
3624 {
3625 int ec = 0;
3626
3627 isns_obj_t *obj;
3628
3629 obj = make_ref[p1->type](p1, p2);
3630 if (obj != NULL) {
3631 ec = register_object(obj, NULL, NULL);
3632 } else {
3633 ec = ISNS_RSP_INTERNAL_ERROR;
3634 }
3635
3636 return (ec);
3637 }
3638
3639 /*
3640 * ****************************************************************************
3641 *
3642 * do_dereg:
3643 * Physically remove an object along with the children objects,
3644 * the reference object and the parent object recursively.
3645 * Apporiate SCN is triggered.
3646 *
3647 * lcp - the lookup control for the object being removed.
3648 * parent_flag - 1: the object being removed is the parent object;
3649 * 0: otherwise.
3650 * child_flag - 1: the object being removed is a child object;
3651 * 0: otherwise.
3652 * pending - 1: do not remove the ESI entry immediately;
3653 * 0: remove the ESI entry without any delay.
3654 * return - error code.
3655 *
3656 * ****************************************************************************
3657 */
3658 static int
do_dereg(lookup_ctrl_t * lcp,int parent_flag,int child_flag,int pending)3659 do_dereg(
3660 lookup_ctrl_t *lcp,
3661 int parent_flag,
3662 int child_flag,
3663 int pending
3664 )
3665 {
3666 int ec = 0;
3667
3668 isns_obj_t *obj;
3669 uint32_t *cuidp, num;
3670 isns_type_t type;
3671 uint32_t uid;
3672 int i;
3673
3674 /* remove the object from object container */
3675 obj = cache_remove(lcp, 0);
3676
3677 if (obj == NULL) {
3678 return (0);
3679 }
3680
3681 /* trigger a scn */
3682 if (scn_q != NULL) {
3683 (void) make_scn(ISNS_OBJECT_REMOVED, obj);
3684 }
3685
3686 /* dereg children */
3687 i = 0;
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) {
3693 num = *cuidp;
3694 } else {
3695 num = 0;
3696 }
3697 while (ec == 0 && num > 0) {
3698 uid = cuidp[num];
3699 if (uid != 0) {
3700 SET_UID_LCP(lcp, type, uid);
3701 ec = do_dereg(lcp,
3702 parent_flag,
3703 1,
3704 pending);
3705 }
3706 num --;
3707 }
3708 i ++;
3709 }
3710
3711 /* clear the ref bit on the ref'd object */
3712 if (ec == 0 && TYPE_OF_REF[obj->type][0] > 0) {
3713 uid = 0;
3714 do {
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);
3720 ec = do_dereg(lcp,
3721 parent_flag,
3722 child_flag,
3723 pending);
3724 }
3725 } while (uid != 0);
3726 }
3727
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);
3734 ec = do_dereg(lcp,
3735 1,
3736 child_flag,
3737 0);
3738 }
3739 }
3740
3741 if (ec == 0 && !child_flag) {
3742 /* remove it from persistent data store */
3743 if (sys_q) {
3744 ec = write_data(DATA_DELETE, obj);
3745 }
3746 /* remove esi event entry */
3747 if (ec == 0) {
3748 (void) esi_remove_obj(obj, pending);
3749 }
3750
3751 /* save the parent uid for caller */
3752 if (TYPE_OF_PARENT[obj->type] != 0) {
3753 lcp->curr_uid = get_parent_uid(obj);
3754 } else {
3755 /* it's the parent itself */
3756 lcp->curr_uid = get_obj_uid(obj);
3757 }
3758 }
3759
3760 /* remove this portal from scn registry */
3761 if (ec == 0 &&
3762 obj->type == OBJ_PORTAL) {
3763 (void) remove_scn_portal(get_obj_uid(obj));
3764 }
3765
3766 /* free the object */
3767 (void) free_object(obj);
3768
3769 return (ec);
3770 }
3771
3772 /*
3773 * ****************************************************************************
3774 *
3775 * dereg_assoc:
3776 * Remove one association object from object container.
3777 *
3778 * lcp - the lookup control for the object being removed.
3779 * return - error code.
3780 *
3781 * ****************************************************************************
3782 */
3783 int
dereg_assoc(lookup_ctrl_t * lcp)3784 dereg_assoc(
3785 lookup_ctrl_t *lcp
3786 )
3787 {
3788 isns_obj_t *obj;
3789
3790 obj = cache_remove(lcp, 1);
3791
3792 /* free the object */
3793 if (obj != NULL) {
3794 free_object(obj);
3795 }
3796
3797 return (0);
3798 }
3799
3800 /*
3801 * ****************************************************************************
3802 *
3803 * dereg_object:
3804 * Remove one object from object container.
3805 *
3806 * lcp - the lookup control for the object being removed.
3807 * return - error code.
3808 *
3809 * ****************************************************************************
3810 */
3811 int
dereg_object(lookup_ctrl_t * lcp,int pending)3812 dereg_object(
3813 lookup_ctrl_t *lcp,
3814 int pending
3815 )
3816 {
3817 return (do_dereg(lcp, 0, 0, pending));
3818 }
3819
3820 /*
3821 * ****************************************************************************
3822 *
3823 * data_sync:
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.
3828 *
3829 * ec - error code.
3830 * return - error code.
3831 *
3832 * ****************************************************************************
3833 */
3834 int
data_sync(int ec)3835 data_sync(
3836 int ec
3837 )
3838 {
3839 /* cache is updated successfully, commit the data to data store */
3840 if (IS_CACHE_UPDATED()) {
3841 if (ec == 0) {
3842 ec = write_data(DATA_COMMIT, NULL);
3843 }
3844 if (ec == 0) {
3845 /* successful, trigger the SCN */
3846 (void) queue_msg_set(scn_q, SCN_TRIGGER, (void *)NULL);
3847 } else {
3848 shutdown_server();
3849 }
3850 } else {
3851 /* ignore all SCNs which have been generated */
3852 (void) queue_msg_set(scn_q, SCN_IGNORE, (void *)NULL);
3853
3854 (void) write_data(DATA_RETREAT, NULL);
3855 }
3856
3857 return (ec);
3858 }
3859
3860 static pthread_mutex_t name_mtx[3] = {
3861 PTHREAD_MUTEX_INITIALIZER,
3862 PTHREAD_MUTEX_INITIALIZER,
3863 PTHREAD_MUTEX_INITIALIZER
3864 };
3865 static const char *name_pattern[3] = {
3866 "ENTITY_ID_%d",
3867 "DD_%d",
3868 "DD-Set_%d"
3869 };
3870 static uint32_t name_count[3] = {
3871 0,
3872 0,
3873 0
3874 };
3875
3876 /*
3877 * ****************************************************************************
3878 *
3879 * make_unique_name:
3880 * make a default unique name for a newly registered network entity,
3881 * discovery domain or discovery domain set object.
3882 *
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.
3886 *
3887 * ****************************************************************************
3888 */
3889 static char *
make_unique_name(int * len,uint32_t tag)3890 make_unique_name(
3891 int *len,
3892 uint32_t tag
3893 )
3894 {
3895 int i;
3896 int count;
3897 char name[32] = { 0 };
3898
3899 char *p;
3900
3901 lookup_ctrl_t lc;
3902
3903 lc.curr_uid = 0;
3904
3905 switch (tag) {
3906 case ISNS_EID_ATTR_ID:
3907 i = 0;
3908 lc.type = OBJ_ENTITY;
3909 lc.id[0] = ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID);
3910 break;
3911 case ISNS_DD_NAME_ATTR_ID:
3912 i = 1;
3913 lc.type = OBJ_DD;
3914 lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
3915 break;
3916 case ISNS_DD_SET_NAME_ATTR_ID:
3917 i = 2;
3918 lc.type = OBJ_DDS;
3919 lc.id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
3920 break;
3921 default:
3922 ASSERT(0);
3923 break;
3924 }
3925
3926 lc.op[0] = OP_STRING;
3927 lc.op[1] = 0;
3928 do {
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 */
3933 if (count == 0) {
3934 return (NULL);
3935 }
3936 (void) sprintf(name, name_pattern[i], count);
3937 lc.data[0].ptr = (uchar_t *)name;
3938 } while (is_obj_there(&lc) != 0);
3939
3940 /* 4-bytes aligned length */
3941 *len = strlen(name);
3942 *len = *len + (4 - *len % 4);
3943 p = (char *)malloc(*len);
3944 if (p != NULL) {
3945 (void) strcpy(p, name);
3946 }
3947 return (p);
3948 }
3949
3950 #ifdef DEBUG
3951 void
obj_dump(void * p)3952 obj_dump(
3953 void *p
3954 )
3955 {
3956 print_object(NULL, (isns_obj_t *)p);
3957 }
3958 #endif
3959