dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / isns / isnsd / dd.c
blob039ca4b77ad3af99d124307d2df7fcb74884bcc9
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
31 #include "isns_server.h"
32 #include "isns_msgq.h"
33 #include "isns_htab.h"
34 #include "isns_dd.h"
35 #include "isns_cache.h"
36 #include "isns_obj.h"
37 #include "isns_pdu.h"
38 #include "isns_dseng.h"
39 #include "isns_scn.h"
40 #include "isns_utils.h"
43 * extern global variables
45 extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
47 extern msg_queue_t *sys_q;
48 extern msg_queue_t *scn_q;
50 extern int cache_flag;
53 * extern functions.
57 * global variables
61 * local variables
65 * local functions.
67 static matrix_t *new_matrix(uint32_t, uint32_t);
69 static int
70 cb_update_ds_attr(
71 void *p1,
72 void *p2
75 int ec = 0;
77 isns_obj_t *obj = (isns_obj_t *)p1;
78 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
79 uint32_t tag = lcp->id[1];
80 uint32_t which;
81 isns_attr_t *attr;
83 uint32_t len;
84 uchar_t *name;
85 lookup_ctrl_t lc;
86 uint32_t uid;
88 switch (tag) {
89 case ISNS_DD_NAME_ATTR_ID:
90 which = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
91 break;
92 case ISNS_DD_FEATURES_ATTR_ID:
93 which = ATTR_INDEX_DD(ISNS_DD_FEATURES_ATTR_ID);
94 break;
95 case ISNS_DD_SET_NAME_ATTR_ID:
96 which = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
97 break;
98 case ISNS_DD_SET_STATUS_ATTR_ID:
99 which = ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID);
100 break;
101 default:
102 ASSERT(0);
103 break;
106 attr = &obj->attrs[which];
108 switch (tag) {
109 case ISNS_DD_NAME_ATTR_ID:
110 case ISNS_DD_SET_NAME_ATTR_ID:
111 len = lcp->data[1].ui;
112 name = lcp->data[2].ptr;
113 lc.type = lcp->type;
114 lc.curr_uid = 0;
115 lc.id[0] = which;
116 lc.op[0] = OP_STRING;
117 lc.data[0].ptr = name;
118 lc.op[1] = 0;
119 /* check if the name is in use */
120 uid = is_obj_there(&lc);
121 if (uid != 0) {
122 if (uid != get_obj_uid(obj)) {
123 ec = ERR_NAME_IN_USE;
125 return (ec);
127 if (len > attr->len) {
128 uchar_t *tmp = (uchar_t *)malloc(len);
129 if (tmp != NULL) {
130 free(attr->value.ptr);
131 attr->value.ptr = tmp;
132 } else {
133 /* memory exhausted */
134 return (ISNS_RSP_INTERNAL_ERROR);
137 (void) strcpy((char *)attr->value.ptr, (char *)name);
138 attr->len = len;
139 break;
140 case ISNS_DD_FEATURES_ATTR_ID:
141 case ISNS_DD_SET_STATUS_ATTR_ID:
142 if (attr->tag != tag ||
143 attr->value.ui != lcp->data[1].ui) {
144 attr->tag = tag;
145 attr->len = 4;
146 attr->value.ui = lcp->data[1].ui;
147 } else {
148 return (ec);
150 break;
153 /* cache has been updated, set the flag */
154 SET_CACHE_UPDATED();
156 /* update data store */
157 if (sys_q != NULL) {
158 ec = write_data(DATA_UPDATE, obj);
161 return (ec);
164 static isns_obj_t *
165 make_member_node(
166 const uint32_t uid,
167 isns_attr_t *attr1
170 isns_obj_t *obj = NULL;
171 isns_attr_t *attr;
172 isns_attr_t tmp;
174 switch (attr1->tag) {
175 case ISNS_DD_ISCSI_NAME_ATTR_ID:
176 obj = obj_calloc(OBJ_ISCSI);
177 attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
178 tmp.tag = ISNS_ISCSI_NAME_ATTR_ID;
179 tmp.len = attr1->len;
180 tmp.value.ptr = attr1->value.ptr;
181 if (assign_attr(attr, &tmp) != 0) {
182 free_object(obj);
183 obj = NULL;
184 } else if (uid != 0) {
185 (void) set_obj_uid(obj, uid);
187 break;
188 default:
189 ASSERT(0);
190 break;
193 return (obj);
196 static isns_obj_t *
197 make_member_dd(
198 const uint32_t uid
201 isns_obj_t *obj = NULL;
202 isns_attr_t name = { 0 };
204 obj = obj_calloc(OBJ_DD);
205 if (obj != NULL) {
206 (void) set_obj_uid(obj, uid);
207 name.tag = ISNS_DD_NAME_ATTR_ID;
208 if (assign_attr(
209 &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)],
210 &name) != 0) {
211 free_object(obj);
212 obj = NULL;
216 return (obj);
219 static int
220 get_member_info(
221 isns_obj_t *assoc,
222 uint32_t *m_type,
223 uint32_t *m_id,
224 int flag
227 int ec = 0;
228 lookup_ctrl_t lc = { 0 };
230 isns_obj_t *obj;
231 isns_attr_t *attr1, *attr2;
232 uint32_t tmp_id = 0;
233 int i = 0;
235 *m_type = 0;
236 *m_id = 0;
238 attr1 = &assoc->attrs[ATTR_INDEX_ASSOC_ISCSI(
239 ISNS_DD_ISCSI_INDEX_ATTR_ID)];
240 attr2 = &assoc->attrs[ATTR_INDEX_ASSOC_ISCSI(
241 ISNS_DD_ISCSI_NAME_ATTR_ID)];
243 lc.type = OBJ_ISCSI;
244 if (attr1->tag != 0 && attr1->value.ui != 0) {
245 *m_id = attr1->value.ui;
246 lc.id[i] = UID_ATTR_INDEX[OBJ_ISCSI];
247 lc.op[i] = OP_INTEGER;
248 lc.data[i].ui = *m_id;
249 i ++;
251 if (attr2->tag != 0) {
252 lc.id[i] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
253 lc.op[i] = OP_STRING;
254 lc.data[i].ptr = attr2->value.ptr;
255 i ++;
256 } else if (scn_q != NULL || sys_q != NULL) {
257 lc.id[i] = ISNS_ISCSI_NAME_ATTR_ID;
260 /* a member id or member name is required */
261 if (i == 0) {
262 if (flag != 0) {
263 /* add member */
264 return (ISNS_RSP_INVALID_REGIS);
265 } else {
266 /* remove member (isnsp msg request only) */
267 return (0);
271 ec = cache_lookup(&lc, &tmp_id, cb_clone_attrs);
273 if (ec == 0 && tmp_id == 0) {
274 if (flag != 0) {
275 /* add member */
276 if (attr1->tag == 0 || sys_q == NULL) {
277 /* object does not exist, create one */
278 obj = make_member_node(*m_id, attr2);
279 if (obj == NULL) {
280 ec = ISNS_RSP_INTERNAL_ERROR;
281 } else {
282 ec = register_assoc(obj, &tmp_id);
283 if (ec != 0) {
284 free_object(obj);
287 } else {
288 /* don't create it if uid is specified */
289 ec = ISNS_RSP_NO_SUCH_ENTRY;
291 } else {
292 /* remove member */
293 ec = ERR_NO_SUCH_ASSOCIATION;
297 if (attr1->tag == 0) {
298 attr1->tag = ISNS_DD_ISCSI_INDEX_ATTR_ID;
299 attr1->len = 4;
300 attr1->value.ui = tmp_id;
301 } else if (attr2->tag == 0) {
302 attr2->tag = ISNS_DD_ISCSI_NAME_ATTR_ID;
303 attr2->len = strlen((char *)lc.data[1].ptr);
304 attr2->len += 4 - (attr2->len % 4);
305 attr2->value.ptr = lc.data[1].ptr;
308 *m_type = OBJ_ISCSI;
309 *m_id = tmp_id;
311 return (ec);
314 static int
315 get_dds_member_info(
316 uint32_t m_id
319 int ec = 0;
320 lookup_ctrl_t lc;
322 isns_obj_t *obj;
323 uint32_t tmp_id;
325 if (m_id != 0) {
326 SET_UID_LCP(&lc, OBJ_DD, m_id);
327 } else {
328 return (ISNS_RSP_INVALID_REGIS);
331 tmp_id = is_obj_there(&lc);
333 if (tmp_id == 0) {
334 /* object does not exist, create one */
335 obj = make_member_dd(m_id);
336 if (obj != NULL) {
337 ec = register_object(obj, NULL, NULL);
338 } else {
339 /* no memory */
340 ec = ISNS_RSP_INTERNAL_ERROR;
344 return (ec);
347 static int
348 update_matrix(
349 matrix_t *matrix,
350 const uchar_t op,
351 const uint32_t puid,
352 const uint32_t m_id,
353 int ddd_flag
356 int ec = 0;
358 uint32_t new_x = 0, new_y = 0;
359 matrix_t *tmp_matrix;
361 uint32_t i, j, k = 0;
362 uint32_t x_info;
363 bmp_t *bmp, *tmp_bmp;
365 uint32_t primary = GET_PRIMARY(m_id);
366 uint32_t second = GET_SECOND(m_id);
368 if (primary >= matrix->x) {
369 if (op == '-') {
370 ec = ERR_NO_SUCH_ASSOCIATION;
371 goto update_matrix_done;
373 /* enlarge the matrix on x axis */
374 if (primary >= matrix->x * 2) {
375 new_x = primary + 1;
376 } else {
377 new_x = matrix->x * 2;
381 i = 0;
382 while (i < matrix->y) {
383 bmp = MATRIX_X_UNIT(matrix, i);
384 x_info = MATRIX_X_INFO(bmp);
385 if (x_info == puid) {
386 break;
387 } else if (x_info == 0 && k == 0) {
388 /* the first available slot */
389 k = i;
391 i ++;
393 if (i == matrix->y) {
394 if (op == '-') {
395 ec = ERR_NO_SUCH_ASSOCIATION;
396 goto update_matrix_done;
397 } else if (k == 0) {
398 new_y = matrix->y * 2;
399 } else {
400 i = k;
405 * enlarge the matrix.
407 if (new_x != 0 || new_y != 0) {
408 if (new_x == 0) {
409 new_x = matrix->x;
411 if (new_y == 0) {
412 new_y = matrix->y;
414 tmp_matrix = new_matrix(new_x, new_y);
415 if (tmp_matrix != NULL) {
416 j = 0;
417 while (j < matrix->y) {
418 bmp = MATRIX_X_UNIT(matrix, j);
419 x_info = MATRIX_X_INFO(bmp);
420 if (x_info != 0) {
421 tmp_bmp = MATRIX_X_UNIT(tmp_matrix, j);
422 (void) memcpy((void *)tmp_bmp,
423 (void *)bmp, SIZEOF_X_UNIT(matrix));
425 j ++;
427 free(matrix->m);
428 matrix->x = tmp_matrix->x;
429 matrix->y = tmp_matrix->y;
430 matrix->m = tmp_matrix->m;
431 free(tmp_matrix);
432 } else {
433 ec = ISNS_RSP_INTERNAL_ERROR;
434 goto update_matrix_done;
438 bmp = MATRIX_X_UNIT(matrix, i);
440 MATRIX_X_INFO(bmp) = puid;
441 if (op == '+') {
442 if (TEST_MEMBERSHIP(bmp, primary, second) == 0) {
443 SET_MEMBERSHIP(bmp, primary, second);
444 SET_CACHE_UPDATED();
445 if (ddd_flag != 0) {
446 bmp = MATRIX_X_UNIT(matrix, 0);
447 ASSERT(MATRIX_X_INFO(bmp) ==
448 ISNS_DEFAULT_DD_ID);
449 CLEAR_MEMBERSHIP(bmp, primary, second);
451 } else {
452 ec = ERR_ALREADY_ASSOCIATED;
454 } else if (op == '-') {
455 if (TEST_MEMBERSHIP(bmp, primary, second) != 0) {
456 CLEAR_MEMBERSHIP(bmp, primary, second);
457 SET_CACHE_UPDATED();
458 if (ddd_flag != 0) {
459 i = 1;
460 while (i < matrix->y) {
461 bmp = MATRIX_X_UNIT(matrix, i);
462 x_info = MATRIX_X_INFO(bmp);
463 if (x_info != 0 &&
464 TEST_MEMBERSHIP(bmp,
465 primary, second) != 0) {
466 break;
468 i ++;
470 if (i == matrix->y) {
471 bmp = MATRIX_X_UNIT(matrix, 0);
472 ASSERT(MATRIX_X_INFO(bmp) ==
473 ISNS_DEFAULT_DD_ID);
474 SET_MEMBERSHIP(bmp, primary, second);
477 } else {
478 ec = ERR_NO_SUCH_ASSOCIATION;
482 update_matrix_done:
483 return (ec);
486 /*ARGSUSED*/
487 static int
488 update_dd_matrix(
489 const uchar_t op,
490 const uint32_t dd_id,
491 const uint32_t m_type,
492 const uint32_t m_id
495 matrix_t *matrix;
497 ASSERT(m_type == OBJ_ISCSI);
499 matrix = cache_get_matrix(OBJ_DD);
501 return (update_matrix(matrix, op, dd_id, m_id, 1));
504 static int
505 update_dds_matrix(
506 const uchar_t op,
507 const uint32_t dds_id,
508 const uint32_t m_id
511 matrix_t *dds_matrix = cache_get_matrix(OBJ_DDS);
513 return (update_matrix(dds_matrix, op, dds_id, m_id, 0));
516 static int
517 clear_matrix(
518 matrix_t *matrix,
519 const uint32_t uid,
520 bmp_t **p,
521 uint32_t *n,
522 int ddd_flag
525 int ec = 0;
526 bmp_t *bmp;
527 uint32_t x_info;
528 int i, j;
530 uint32_t primary;
531 uint32_t second;
533 if (p != NULL) {
534 *p = NULL;
535 *n = 0;
538 i = 0;
539 while (i < matrix->y) {
540 bmp = MATRIX_X_UNIT(matrix, i);
541 x_info = MATRIX_X_INFO(bmp);
542 if (x_info == uid) {
543 if (p != NULL) {
544 /* dup it for caller */
545 *n = matrix->x;
546 *p = (bmp_t *)malloc(*n * sizeof (bmp_t));
547 if (*p != NULL) {
548 (void) memcpy(*p, &bmp[MATRIX_X_HEADER],
549 *n * sizeof (bmp_t));
550 } else {
551 ec = ISNS_RSP_INTERNAL_ERROR;
554 /* clean it */
555 (void) memset(bmp, 0, SIZEOF_X_UNIT(matrix));
556 break;
558 i ++;
561 if (ddd_flag != 0 && p != NULL) {
562 bmp = MATRIX_X_UNIT(matrix, 0);
563 ASSERT(MATRIX_X_INFO(bmp) == ISNS_DEFAULT_DD_ID);
564 /* Test the membership for each node which is a */
565 /* member in the dd that is being deleted. */
566 FOR_EACH_MEMBER(*p, *n, i, {
567 j = get_dd_id(i, 0);
568 if (j == 0) {
569 /* put it to the default dd */
570 primary = GET_PRIMARY(i);
571 second = GET_SECOND(i);
572 SET_MEMBERSHIP(bmp, primary, second);
577 return (ec);
580 static int
581 get_matrix(
582 matrix_t *matrix,
583 const uint32_t uid,
584 bmp_t **p,
585 uint32_t *n
588 int ec = 0;
589 bmp_t *bmp;
590 uint32_t x_info;
591 int i;
593 *n = 0;
594 *p = NULL;
596 i = 0;
597 while (i < matrix->y) {
598 bmp = MATRIX_X_UNIT(matrix, i);
599 x_info = MATRIX_X_INFO(bmp);
600 if (x_info == uid) {
601 /* dup it for caller */
602 *n = matrix->x;
603 *p = (bmp_t *)malloc(*n * sizeof (bmp_t));
604 if (*p != NULL) {
605 (void) memcpy(*p, &bmp[MATRIX_X_HEADER],
606 *n * sizeof (bmp_t));
607 } else {
608 *n = 0;
609 ec = ISNS_RSP_INTERNAL_ERROR;
611 break;
613 i ++;
616 return (ec);
619 static int
620 clear_dd_matrix(
621 const uint32_t dd_id,
622 bmp_t **p,
623 uint32_t *n
626 matrix_t *matrix = cache_get_matrix(OBJ_DD);
628 return (clear_matrix(matrix, dd_id, p, n, 1));
631 static int
632 clear_dds_matrix(
633 const uint32_t dds_id
636 matrix_t *matrix = cache_get_matrix(OBJ_DDS);
638 return (clear_matrix(matrix, dds_id, NULL, NULL, 0));
642 get_dd_matrix(
643 const uint32_t dd_id,
644 bmp_t **p,
645 uint32_t *n
648 matrix_t *matrix = cache_get_matrix(OBJ_DD);
650 return (get_matrix(matrix, dd_id, p, n));
654 get_dds_matrix(
655 const uint32_t dds_id,
656 bmp_t **p,
657 uint32_t *n
660 matrix_t *matrix = cache_get_matrix(OBJ_DDS);
662 return (get_matrix(matrix, dds_id, p, n));
665 /*ARGSUSED*/
666 static int
667 cb_get_dds_status(
668 void *p1,
669 void *p2
672 isns_obj_t *obj = (isns_obj_t *)p1;
674 isns_attr_t *attr = &obj->attrs[
675 ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID)];
677 return (DDS_ENABLED(attr->value.ui) ? 1 : 0);
680 static int
681 get_dds_status(
682 uint32_t dds_id
685 lookup_ctrl_t lc;
687 if (dds_id == 0) {
688 return (0);
691 SET_UID_LCP(&lc, OBJ_DDS, dds_id);
693 return (cache_lookup(&lc, NULL, cb_get_dds_status));
697 is_dd_active(
698 uint32_t dd_id
701 int active = 0;
703 matrix_t *dds_matrix;
704 uint32_t primary;
705 uint32_t second;
706 uint32_t x_info;
707 bmp_t *bmp;
708 int i;
710 if (dd_id == 0) {
711 return (active);
714 dds_matrix = cache_get_matrix(OBJ_DDS);
715 primary = GET_PRIMARY(dd_id);
716 second = GET_SECOND(dd_id);
718 if (primary < dds_matrix->x) {
719 i = 0;
720 while (i < dds_matrix->y) {
721 bmp = MATRIX_X_UNIT(dds_matrix, i);
722 x_info = MATRIX_X_INFO(bmp);
723 if (x_info != 0 &&
724 TEST_MEMBERSHIP(bmp, primary, second) != 0) {
725 if (get_dds_status(x_info) != 0) {
726 active = 1;
727 break;
730 i ++;
734 return (active);
738 get_scope(
739 uchar_t *node_name,
740 bmp_t **p,
741 uint32_t *n
744 int ec = 0;
746 lookup_ctrl_t lc;
747 uint32_t uid;
749 matrix_t *dd_matrix;
750 uint32_t primary;
751 uint32_t second;
752 uint32_t x_info;
753 bmp_t *bmp;
754 int i, j;
756 bmp_t *tmp_p;
757 uint32_t tmp_n;
759 bmp_t *short_p;
760 uint32_t short_n;
762 /* clear it */
763 *p = NULL;
764 *n = 0;
766 /* get the source object uid */
767 lc.curr_uid = 0;
768 lc.type = OBJ_ISCSI;
769 lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
770 lc.op[0] = OP_STRING;
771 lc.data[0].ptr = node_name;
772 lc.op[1] = 0;
774 uid = is_obj_there(&lc);
776 /* no such object */
777 if (uid == 0) {
778 return (ec);
781 dd_matrix = cache_get_matrix(OBJ_DD);
782 primary = GET_PRIMARY(uid);
783 second = GET_SECOND(uid);
785 if (primary < dd_matrix->x) {
786 i = 0;
787 while (i < dd_matrix->y) {
788 bmp = MATRIX_X_UNIT(dd_matrix, i);
789 x_info = MATRIX_X_INFO(bmp);
790 if (ec == 0 && x_info != 0 &&
791 TEST_MEMBERSHIP(bmp, primary, second) != 0) {
792 if (is_dd_active(x_info) != 0 &&
793 (ec = get_dd_matrix(x_info,
794 &tmp_p, &tmp_n)) == 0) {
795 if (*p == NULL) {
796 *p = tmp_p;
797 *n = tmp_n;
798 } else {
799 if (*n >= tmp_n) {
800 short_p = tmp_p;
801 short_n = tmp_n;
802 } else {
803 short_p = *p;
804 short_n = *n;
805 *p = tmp_p;
806 *n = tmp_n;
808 j = 0;
809 while (j < short_n) {
810 (*p)[j] |= short_p[j];
811 j ++;
813 free(short_p);
817 i ++;
821 primary ++;
822 if (ec == 0 && *p == NULL) {
823 *p = (bmp_t *)calloc(primary, sizeof (bmp_t));
824 if (*p != NULL) {
825 *n = primary;
826 } else {
827 *n = 0;
828 ec = ISNS_RSP_INTERNAL_ERROR;
832 if (*p != NULL) {
833 (*p)[primary - 1] |= (1 << second);
836 return (ec);
840 cb_clone_attrs(
841 void *p1,
842 void *p2
845 int ec = 0;
847 isns_obj_t *obj = (isns_obj_t *)p1;
848 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
850 isns_attr_t *attr;
852 int i = 1;
854 while (i < MAX_LOOKUP_CTRL &&
855 lcp->op[i] != 0) {
856 i ++;
859 while (ec == 0 &&
860 i < MAX_LOOKUP_CTRL &&
861 lcp->id[i] != 0) {
862 switch (lcp->id[i]) {
863 case ISNS_ISCSI_NAME_ATTR_ID:
864 attr = &obj->attrs[ATTR_INDEX_ISCSI(
865 ISNS_ISCSI_NAME_ATTR_ID)];
866 lcp->data[i].ptr = (uchar_t *)malloc(attr->len);
867 if (lcp->data[i].ptr != NULL) {
868 (void) strcpy((char *)lcp->data[i].ptr,
869 (char *)attr->value.ptr);
870 } else {
871 /* memory exhausted */
872 ec = ISNS_RSP_INTERNAL_ERROR;
874 break;
875 case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
876 attr = &obj->attrs[ATTR_INDEX_ISCSI(
877 ISNS_ISCSI_NODE_TYPE_ATTR_ID)];
878 lcp->data[i].ui = attr->value.ui;
879 break;
880 case ISNS_PG_ISCSI_NAME_ATTR_ID:
881 attr = &obj->attrs[ATTR_INDEX_PG(
882 ISNS_PG_ISCSI_NAME_ATTR_ID)];
883 lcp->data[i].ptr = (uchar_t *)malloc(attr->len);
884 if (lcp->data[i].ptr != NULL) {
885 (void) strcpy((char *)lcp->data[i].ptr,
886 (char *)attr->value.ptr);
887 } else {
888 /* memory exhausted */
889 ec = ISNS_RSP_INTERNAL_ERROR;
891 break;
892 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
893 attr = &obj->attrs[ATTR_INDEX_PG(
894 ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)];
895 lcp->data[i].ip = (in6_addr_t *)malloc(attr->len);
896 if (lcp->data[i].ip != NULL) {
897 (void) memcpy(lcp->data[i].ip,
898 attr->value.ip, attr->len);
899 } else {
900 /* memory exhausted */
901 ec = ISNS_RSP_INTERNAL_ERROR;
903 break;
904 case ISNS_PG_PORTAL_PORT_ATTR_ID:
905 attr = &obj->attrs[ATTR_INDEX_PG(
906 ISNS_PG_PORTAL_PORT_ATTR_ID)];
907 lcp->data[i].ui = attr->value.ui;
908 break;
909 case ISNS_PORTAL_IP_ADDR_ATTR_ID:
910 attr = &obj->attrs[ATTR_INDEX_PORTAL(
911 ISNS_PORTAL_IP_ADDR_ATTR_ID)];
912 lcp->data[i].ip = (in6_addr_t *)malloc(attr->len);
913 if (lcp->data[i].ip != NULL) {
914 (void) memcpy(lcp->data[i].ip,
915 attr->value.ip, attr->len);
916 } else {
917 /* memory exhausted */
918 ec = ISNS_RSP_INTERNAL_ERROR;
920 break;
921 case ISNS_PORTAL_PORT_ATTR_ID:
922 case ISNS_ESI_PORT_ATTR_ID:
923 attr = &obj->attrs[ATTR_INDEX_PORTAL(lcp->id[i])];
924 if (attr->tag != 0 && attr->value.ui != 0) {
925 lcp->data[i].ui = attr->value.ui;
926 } else {
927 lcp->data[i].ui = 0;
929 break;
930 default:
931 ASSERT(0);
932 lcp->data[i].ui = 0;
933 break;
935 i ++;
938 return (ec);
941 static matrix_t *
942 new_matrix(
943 uint32_t x,
944 uint32_t y
947 matrix_t *matrix;
949 matrix = (matrix_t *)malloc(sizeof (matrix_t));
950 if (matrix != NULL) {
951 matrix->x = x;
952 matrix->y = y;
953 matrix->m = (bmp_t *)calloc(y, SIZEOF_X_UNIT(matrix));
954 if (matrix->m == NULL) {
955 free(matrix);
956 matrix = NULL;
960 return (matrix);
964 dd_matrix_init(
965 struct cache *c
968 matrix_t *x;
969 bmp_t *bmp;
970 uint32_t primary;
971 uint32_t second;
974 * allocate an array of pointer for dd and dd-set matrix.
976 c->x = (matrix_t **)calloc(2, sizeof (matrix_t *));
977 if (c->x == NULL) {
978 return (1);
982 * create dd matrix.
984 x = new_matrix(8, 64);
985 if (x != NULL) {
986 x->c = c;
987 c->x[0] = x;
988 } else {
989 return (1);
993 * Mark the first array on the y axis for Default DD.
995 bmp = MATRIX_X_UNIT(x, 0);
996 MATRIX_X_INFO(bmp) = ISNS_DEFAULT_DD_ID;
999 * create dd set matrix.
1001 x = new_matrix(2, 16);
1002 if (x != NULL) {
1003 x->c = c;
1004 c->x[1] = x;
1005 } else {
1006 return (1);
1010 * Mark the first array on the y axis for Default DD-set.
1012 bmp = MATRIX_X_UNIT(x, 0);
1013 MATRIX_X_INFO(bmp) = ISNS_DEFAULT_DD_SET_ID;
1016 * Add Default DD as a member of Default DD-set.
1018 primary = GET_PRIMARY(ISNS_DEFAULT_DD_ID);
1019 second = GET_SECOND(ISNS_DEFAULT_DD_ID);
1020 SET_MEMBERSHIP(bmp, primary, second);
1022 return (0);
1025 static uint32_t
1026 get_ds_id(
1027 matrix_t *matrix,
1028 uint32_t m_id,
1029 uint32_t curr_id
1032 bmp_t *bmp;
1033 uint32_t primary = GET_PRIMARY(m_id);
1034 uint32_t second = GET_SECOND(m_id);
1035 uint32_t dd_id = 0;
1036 uint32_t uid;
1037 int i = 0;
1039 if (matrix->x > primary) {
1040 while (i < matrix->y) {
1041 bmp = MATRIX_X_UNIT(matrix, i);
1042 uid = MATRIX_X_INFO(bmp);
1043 if (uid > curr_id &&
1044 TEST_MEMBERSHIP(bmp, primary, second) != 0) {
1045 if (dd_id == 0 || uid < dd_id) {
1046 dd_id = uid;
1049 i ++;
1053 return (dd_id);
1056 uint32_t
1057 get_common_dd(
1058 uint32_t m_id1,
1059 uint32_t m_id2,
1060 uint32_t curr_id
1063 matrix_t *matrix;
1065 bmp_t *bmp;
1066 uint32_t primary1 = GET_PRIMARY(m_id1);
1067 uint32_t second1 = GET_SECOND(m_id1);
1068 uint32_t primary2 = GET_PRIMARY(m_id2);
1069 uint32_t second2 = GET_SECOND(m_id2);
1070 uint32_t dd_id = 0;
1071 int i = 0;
1073 matrix = cache_get_matrix(OBJ_DD);
1075 if (matrix->x > primary1 && matrix->x > primary2) {
1076 while (i < matrix->y) {
1077 bmp = MATRIX_X_UNIT(matrix, i);
1078 if (MATRIX_X_INFO(bmp) > curr_id &&
1079 TEST_MEMBERSHIP(bmp, primary1, second1) != 0 &&
1080 TEST_MEMBERSHIP(bmp, primary2, second2) != 0) {
1081 dd_id = MATRIX_X_INFO(bmp);
1082 break;
1084 i ++;
1088 return (dd_id);
1091 uint32_t
1092 get_dd_id(
1093 uint32_t m_id,
1094 uint32_t curr_id
1097 matrix_t *matrix = cache_get_matrix(OBJ_DD);
1099 return (get_ds_id(matrix, m_id, curr_id));
1102 uint32_t
1103 get_dds_id(
1104 uint32_t m_id,
1105 uint32_t curr_id
1108 matrix_t *matrix = cache_get_matrix(OBJ_DDS);
1110 return (get_ds_id(matrix, m_id, curr_id));
1113 static int
1114 create_ds_object(
1115 isns_type_t type,
1116 isns_obj_t **ds_p,
1117 isns_attr_t *name_attr,
1118 isns_attr_t *uid_attr,
1119 isns_attr_t *status_attr
1122 int ec = 0;
1124 isns_obj_t *obj;
1125 int id1, id2, id3;
1127 if (type == OBJ_DD) {
1128 id1 = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
1129 id2 = ATTR_INDEX_DD(ISNS_DD_ID_ATTR_ID);
1130 id3 = ATTR_INDEX_DD(ISNS_DD_FEATURES_ATTR_ID);
1131 } else {
1132 ASSERT(type == OBJ_DDS);
1133 id1 = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
1134 id2 = ATTR_INDEX_DDS(ISNS_DD_SET_ID_ATTR_ID);
1135 id3 = ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID);
1138 obj = obj_calloc(type);
1139 if (obj != NULL &&
1140 (name_attr != NULL && name_attr->tag != 0 &&
1141 assign_attr(&obj->attrs[id1], name_attr) == 0) &&
1142 (uid_attr == NULL || uid_attr->value.ui == 0 ||
1143 assign_attr(&obj->attrs[id2], uid_attr) == 0) &&
1144 (status_attr == NULL || status_attr->value.ui == 0 ||
1145 assign_attr(&obj->attrs[id3], status_attr) == 0)) {
1146 *ds_p = obj;
1147 } else {
1148 /* no memory */
1149 free_object(obj);
1150 ec = ISNS_RSP_INTERNAL_ERROR;
1153 return (ec);
1157 create_dd_object(
1158 isns_tlv_t *op,
1159 uint16_t op_len,
1160 isns_obj_t **dd_p
1163 int ec = 0;
1164 uint8_t *value;
1165 isns_attr_t name = { 0 };
1166 isns_attr_t dd_id = { 0 }, features = { 0 };
1168 name.tag = ISNS_DD_NAME_ATTR_ID;
1170 while (op_len > 8 && ec == 0) {
1171 value = &op->attr_value[0];
1172 switch (op->attr_id) {
1173 case ISNS_DD_ID_ATTR_ID:
1174 if (op->attr_len == 4) {
1175 dd_id.tag = ISNS_DD_ID_ATTR_ID;
1176 dd_id.len = 4;
1177 dd_id.value.ui = ntohl(*(uint32_t *)value);
1178 } else if (op->attr_len != 0) {
1179 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1181 break;
1182 case ISNS_DD_NAME_ATTR_ID:
1183 if (op->attr_len > 0 &&
1184 op->attr_len <= 256) {
1185 name.len = op->attr_len;
1186 name.value.ptr = (uchar_t *)value;
1187 } else if (op->attr_len != 0) {
1188 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1190 break;
1191 case ISNS_DD_ISCSI_INDEX_ATTR_ID:
1192 case ISNS_DD_ISCSI_NAME_ATTR_ID:
1193 break;
1194 case ISNS_DD_FC_PORT_NAME_ATTR_ID:
1195 case ISNS_DD_PORTAL_INDEX_ATTR_ID:
1196 case ISNS_DD_PORTAL_IP_ADDR_ATTR_ID:
1197 case ISNS_DD_PORTAL_PORT_ATTR_ID:
1198 ec = ISNS_RSP_REGIS_NOT_SUPPORTED;
1199 break;
1200 case ISNS_DD_FEATURES_ATTR_ID:
1201 if (op->attr_len == 4) {
1202 features.tag = ISNS_DD_FEATURES_ATTR_ID;
1203 features.len = op->attr_len;
1204 features.value.ui = ntohl(*(uint32_t *)value);
1205 } else if (op->attr_len != 0) {
1206 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1208 break;
1209 default:
1210 ec = ISNS_RSP_INVALID_REGIS;
1211 break;
1213 NEXT_TLV(op, op_len);
1216 if (ec == 0) {
1217 ec = create_ds_object(OBJ_DD, dd_p,
1218 &name, &dd_id, &features);
1221 return (ec);
1225 create_dds_object(
1226 isns_tlv_t *op,
1227 uint16_t op_len,
1228 isns_obj_t **dds_p
1231 int ec = 0;
1232 uint8_t *value;
1233 isns_attr_t name = { 0 };
1234 isns_attr_t dds_id = { 0 }, code = { 0 };
1236 name.tag = ISNS_DD_SET_NAME_ATTR_ID;
1238 while (op_len > 8 && ec == 0) {
1239 value = &op->attr_value[0];
1240 switch (op->attr_id) {
1241 case ISNS_DD_SET_ID_ATTR_ID:
1242 if (op->attr_len == 4) {
1243 dds_id.tag = ISNS_DD_ID_ATTR_ID;
1244 dds_id.len = 4;
1245 dds_id.value.ui = ntohl(*(uint32_t *)value);
1246 } else if (op->attr_len != 0) {
1247 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1249 break;
1250 case ISNS_DD_SET_NAME_ATTR_ID:
1251 if (op->attr_len > 0 &&
1252 op->attr_len <= 256) {
1253 name.len = op->attr_len;
1254 name.value.ptr = (uchar_t *)value;
1255 } else if (op->attr_len != 0) {
1256 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1258 break;
1259 case ISNS_DD_SET_STATUS_ATTR_ID:
1260 if (op->attr_len == 4) {
1261 code.tag = ISNS_DD_SET_STATUS_ATTR_ID;
1262 code.len = op->attr_len;
1263 code.value.ui = ntohl(*(uint32_t *)value);
1264 } else if (op->attr_len != 0) {
1265 ec = ISNS_RSP_MSG_FORMAT_ERROR;
1267 break;
1268 case ISNS_DD_ID_ATTR_ID:
1269 break;
1270 default:
1271 ec = ISNS_RSP_INVALID_REGIS;
1272 break;
1274 NEXT_TLV(op, op_len);
1277 if (ec == 0) {
1278 ec = create_ds_object(OBJ_DDS, dds_p,
1279 &name, &dds_id, &code);
1282 return (ec);
1286 adm_create_dd(
1287 isns_obj_t **dd_p,
1288 uchar_t *name,
1289 uint32_t uid,
1290 uint32_t features
1293 uint32_t len;
1294 isns_attr_t name_attr = { 0 };
1295 isns_attr_t uid_attr = { 0 };
1296 isns_attr_t features_attr = { 0 };
1298 name_attr.tag = ISNS_DD_NAME_ATTR_ID;
1299 if (name != NULL) {
1300 /* need to include the null terminator */
1301 /* and be on 4 bytes aligned */
1302 len = strlen((char *)name) + 1;
1303 len += 4 - (len % 4);
1304 name_attr.len = len;
1305 name_attr.value.ptr = name;
1308 uid_attr.tag = ISNS_DD_ID_ATTR_ID;
1309 uid_attr.len = 4;
1310 uid_attr.value.ui = uid;
1312 features_attr.tag = ISNS_DD_FEATURES_ATTR_ID;
1313 features_attr.len = 4;
1314 features_attr.value.ui = features;
1316 return (create_ds_object(OBJ_DD, dd_p,
1317 &name_attr, &uid_attr, &features_attr));
1321 adm_create_dds(
1322 isns_obj_t **dds_p,
1323 uchar_t *name,
1324 uint32_t uid,
1325 uint32_t code
1328 uint32_t len;
1329 isns_attr_t name_attr = { 0 };
1330 isns_attr_t uid_attr = { 0 };
1331 isns_attr_t code_attr = { 0 };
1333 name_attr.tag = ISNS_DD_SET_NAME_ATTR_ID;
1334 if (name != NULL) {
1335 /* need to include the null terminator */
1336 /* and be on 4 bytes aligned */
1337 len = strlen((char *)name) + 1;
1338 len += 4 - (len % 4);
1339 name_attr.len = len;
1340 name_attr.value.ptr = name;
1343 uid_attr.tag = ISNS_DD_SET_ID_ATTR_ID;
1344 uid_attr.len = 4;
1345 uid_attr.value.ui = uid;
1347 code_attr.tag = ISNS_DD_SET_STATUS_ATTR_ID;
1348 code_attr.len = 4;
1349 code_attr.value.ui = code;
1351 return (create_ds_object(OBJ_DDS, dds_p,
1352 &name_attr, &uid_attr, &code_attr));
1355 static int
1356 update_ds_name(
1357 isns_type_t type,
1358 uint32_t uid,
1359 uint32_t tag,
1360 uint32_t len,
1361 uchar_t *name
1364 int ec = 0;
1366 lookup_ctrl_t lc;
1368 SET_UID_LCP(&lc, type, uid);
1370 lc.id[1] = tag;
1371 lc.data[1].ui = len;
1372 lc.data[2].ptr = name;
1374 ec = cache_rekey(&lc, &uid, cb_update_ds_attr);
1375 if (uid == 0) {
1376 ec = ISNS_RSP_INVALID_REGIS;
1379 return (ec);
1383 update_dd_name(
1384 uint32_t uid,
1385 uint32_t len,
1386 uchar_t *name
1390 * We do now allow changing the default DD and DD-set name.
1392 if (uid == ISNS_DEFAULT_DD_ID) {
1393 return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1396 return (update_ds_name(OBJ_DD, uid, ISNS_DD_NAME_ATTR_ID, len, name));
1400 update_dds_name(
1401 uint32_t uid,
1402 uint32_t len,
1403 uchar_t *name
1407 * We do now allow changing the default DD and DD-set name.
1409 if (uid == ISNS_DEFAULT_DD_ID) {
1410 return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1413 return (update_ds_name(OBJ_DDS, uid,
1414 ISNS_DD_SET_NAME_ATTR_ID, len, name));
1417 static int
1418 update_ds_uint32(
1419 isns_type_t type,
1420 uint32_t uid,
1421 uint32_t tag,
1422 uint32_t value
1425 int ec = 0;
1427 lookup_ctrl_t lc;
1429 SET_UID_LCP(&lc, type, uid);
1431 lc.id[1] = tag;
1432 lc.data[1].ui = value;
1434 ec = cache_lookup(&lc, &uid, cb_update_ds_attr);
1435 if (uid == 0) {
1436 ec = ISNS_RSP_INVALID_REGIS;
1439 return (ec);
1443 update_dd_features(
1444 uint32_t uid,
1445 uint32_t features
1448 return (update_ds_uint32(OBJ_DD, uid,
1449 ISNS_DD_FEATURES_ATTR_ID, features));
1453 update_dds_status(
1454 uint32_t uid,
1455 uint32_t enabled
1458 return (update_ds_uint32(OBJ_DDS, uid,
1459 ISNS_DD_SET_STATUS_ATTR_ID, enabled));
1463 add_dd_member(
1464 isns_obj_t *assoc
1467 int ec = 0;
1469 uint32_t dd_id;
1470 uint32_t m_id, m_type;
1472 dd_id = get_parent_uid(assoc);
1474 * We do now allow placing any node to the default DD explicitly.
1476 if (dd_id == ISNS_DEFAULT_DD_ID) {
1477 return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1480 ec = get_member_info(assoc, &m_type, &m_id, 1);
1481 if (ec == 0) {
1482 ec = update_dd_matrix(
1483 '+', /* add member */
1484 dd_id,
1485 m_type,
1486 m_id);
1489 if (ec == 0) {
1490 if (sys_q != NULL) {
1491 /* add the membership to data store */
1492 ec = write_data(DATA_ADD, assoc);
1495 /* trigger a management scn */
1496 if (ec == 0 && scn_q != NULL) {
1497 (void) make_scn(ISNS_MEMBER_ADDED, assoc);
1501 return (ec);
1505 add_dds_member(
1506 isns_obj_t *assoc
1509 int ec = 0;
1511 uint32_t m_id = assoc->attrs[ATTR_INDEX_ASSOC_DD(
1512 ISNS_DD_ID_ATTR_ID)].value.ui;
1513 uint32_t dds_id;
1515 dds_id = get_parent_uid(assoc);
1517 * We do now allow changing the membership of the default DD
1518 * and DD-set.
1520 if (dds_id == ISNS_DEFAULT_DD_SET_ID ||
1521 m_id == ISNS_DEFAULT_DD_ID) {
1522 return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1525 ec = get_dds_member_info(m_id);
1526 if (ec == 0) {
1527 ec = update_dds_matrix(
1528 '+', /* add member */
1529 dds_id,
1530 m_id);
1533 if (ec == 0) {
1534 if (sys_q != NULL) {
1535 /* add the membership to data store */
1536 ec = write_data(DATA_ADD, assoc);
1539 /* trigger a management scn */
1540 if (ec == 0 && scn_q != NULL) {
1541 (void) make_scn(ISNS_MEMBER_ADDED, assoc);
1545 return (ec);
1549 remove_dd_member(
1550 isns_obj_t *assoc
1553 int ec = 0;
1555 uint32_t dd_id;
1556 uint32_t m_type;
1557 uint32_t m_id;
1559 lookup_ctrl_t lc;
1561 dd_id = get_parent_uid(assoc);
1563 * We do now allow removing the member from default DD explicitly.
1565 if (dd_id == ISNS_DEFAULT_DD_ID) {
1566 return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1569 ec = get_member_info(assoc, &m_type, &m_id, 0);
1570 if (ec == 0) {
1571 ec = update_dd_matrix(
1572 '-', /* remove member */
1573 dd_id,
1574 m_type,
1575 m_id);
1576 if (ec == 0) {
1577 /* update data store */
1578 if (sys_q != NULL) {
1579 /* remove it from data store */
1580 ec = write_data(
1581 DATA_DELETE_ASSOC, assoc);
1584 /* trigger a management scn */
1585 if (ec == 0 && scn_q != NULL) {
1586 (void) make_scn(ISNS_MEMBER_REMOVED, assoc);
1589 /* remove it from object container if */
1590 /* it is not a registered object */
1591 if (ec == 0) {
1592 SET_UID_LCP(&lc, m_type, m_id);
1593 ec = dereg_assoc(&lc);
1598 return (ec);
1602 remove_dds_member(
1603 uint32_t dds_id,
1604 uint32_t m_id
1607 int ec = 0;
1609 isns_obj_t *clone;
1612 * We do now allow removing the member from default DD-set.
1614 if (dds_id == ISNS_DEFAULT_DD_SET_ID) {
1615 return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1618 if (m_id != 0) {
1619 ec = update_dds_matrix(
1620 '-', /* remove member */
1621 dds_id,
1622 m_id);
1623 if (ec == 0) {
1624 clone = obj_calloc(OBJ_ASSOC_DD);
1625 if (clone != NULL) {
1626 (void) set_obj_uid((void *)clone, m_id);
1627 (void) set_parent_obj(clone, dds_id);
1629 /* update data store */
1630 if (sys_q != NULL) {
1631 if (clone != NULL) {
1632 /* remove it from data store */
1633 ec = write_data(
1634 DATA_DELETE_ASSOC, clone);
1635 } else {
1636 ec = ISNS_RSP_INTERNAL_ERROR;
1640 /* trigger a management scn */
1641 if (ec == 0 &&
1642 scn_q != NULL &&
1643 clone != NULL) {
1644 (void) make_scn(ISNS_MEMBER_REMOVED, clone);
1646 free_object(clone);
1650 return (ec);
1653 static int
1654 remove_member_wildchar(
1655 matrix_t *matrix,
1656 uint32_t m_id
1659 int ec = 0;
1661 bmp_t *bmp;
1662 uint32_t x_info;
1663 int i;
1665 uint32_t primary = GET_PRIMARY(m_id);
1666 uint32_t second = GET_SECOND(m_id);
1668 isns_obj_t *clone;
1670 if (primary >= matrix->x) {
1671 return (ec);
1674 i = 0;
1675 while (ec == 0 && i < matrix->y) {
1676 bmp = MATRIX_X_UNIT(matrix, i);
1677 x_info = MATRIX_X_INFO(bmp);
1678 if (x_info != 0 &&
1679 TEST_MEMBERSHIP(bmp, primary, second) != 0) {
1680 /* clean the membership */
1681 CLEAR_MEMBERSHIP(bmp, primary, second);
1682 /* update data store */
1683 if (sys_q != NULL) {
1684 clone = obj_calloc(OBJ_ASSOC_DD);
1685 if (clone != NULL) {
1686 (void) set_obj_uid((void *)clone, m_id);
1687 (void) set_parent_obj(clone, x_info);
1688 /* remove it from data store */
1689 ec = write_data(
1690 DATA_DELETE_ASSOC, clone);
1691 free_object(clone);
1692 } else {
1693 ec = ISNS_RSP_INTERNAL_ERROR;
1697 i ++;
1700 return (ec);
1704 remove_dd_object(
1705 uint32_t dd_id
1708 matrix_t *dds_matrix;
1710 bmp_t *p;
1711 uint32_t n;
1712 int ec;
1714 lookup_ctrl_t lc;
1715 uint32_t uid;
1718 * We do now allow removing the default DD.
1720 if (dd_id == ISNS_DEFAULT_DD_ID) {
1721 return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1724 SET_UID_LCP(&lc, OBJ_DD, dd_id);
1726 /* de-register the object at first */
1727 ec = dereg_object(&lc, 0);
1729 /* clear it from all of dd-set */
1730 dds_matrix = cache_get_matrix(OBJ_DDS);
1731 (void) remove_member_wildchar(dds_matrix, dd_id);
1733 /* clear its member bitmap */
1734 (void) clear_dd_matrix(dd_id, &p, &n);
1736 /* deregister the member nodes which are not-registered node */
1737 /* and have no longer membership in other DD(s). */
1738 if (p != NULL) {
1739 SET_UID_LCP(&lc, OBJ_ISCSI, 0);
1740 FOR_EACH_MEMBER(p, n, uid, {
1741 lc.data[0].ui = uid;
1742 (void) dereg_assoc(&lc);
1744 free(p);
1747 return (ec);
1751 remove_dds_object(
1752 uint32_t dds_id
1755 int ec;
1757 lookup_ctrl_t lc;
1760 * We do now allow removing the default DD-set.
1762 if (dds_id == ISNS_DEFAULT_DD_SET_ID) {
1763 return (ISNS_RSP_OPTION_NOT_UNDERSTOOD);
1766 (void) clear_dds_matrix(dds_id);
1768 SET_UID_LCP(&lc, OBJ_DDS, dds_id);
1770 ec = dereg_object(&lc, 0);
1772 return (ec);
1776 update_ddd(
1777 void *p,
1778 const uchar_t op
1781 isns_obj_t *obj;
1782 uint32_t uid;
1784 matrix_t *matrix;
1786 obj = (isns_obj_t *)p;
1787 if (obj->type != OBJ_ISCSI) {
1788 return (0);
1791 matrix = cache_get_matrix(OBJ_DD);
1792 uid = get_obj_uid(obj);
1794 return (update_matrix(matrix, op, ISNS_DEFAULT_DD_ID, uid, 0));
1798 verify_ddd(
1801 int ec = 0;
1803 lookup_ctrl_t lc;
1804 isns_obj_t *obj;
1806 uchar_t *name;
1807 uint32_t uid;
1808 uint32_t features;
1809 uint32_t code;
1811 /* Ensure the Default DD is registered. */
1812 uid = ISNS_DEFAULT_DD_ID;
1814 SET_UID_LCP(&lc, OBJ_DD, uid);
1816 (void) cache_lock_write();
1818 if (is_obj_there(&lc) == 0) {
1819 name = (uchar_t *)DEFAULT_DD_NAME;
1820 features = DEFAULT_DD_FEATURES;
1821 ec = adm_create_dd(&obj, name, uid, features);
1822 if (ec == 0) {
1823 ec = register_object(obj, NULL, NULL);
1824 if (ec != 0) {
1825 free_object(obj);
1826 goto verify_done;
1828 } else {
1829 goto verify_done;
1833 /* Ensure the Default DD-set is registered. */
1834 uid = ISNS_DEFAULT_DD_SET_ID;
1836 SET_UID_LCP(&lc, OBJ_DDS, uid);
1838 if (is_obj_there(&lc) == 0) {
1839 name = (uchar_t *)DEFAULT_DD_SET_NAME;
1840 code = DEFAULT_DD_SET_STATUS;
1841 ec = adm_create_dds(&obj, name, uid, code);
1842 if (ec == 0) {
1843 ec = register_object(obj, NULL, NULL);
1844 if (ec != 0) {
1845 free_object(obj);
1850 verify_done:
1852 ec = cache_unlock_sync(ec);
1854 return (ec);