dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / isns / isnsd / admintf.c
blob9587420e87bc6446540ed81794a74b4622a45d65
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <libxml/xmlreader.h>
31 #include <libxml/xmlwriter.h>
32 #include <libxml/tree.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #include <pthread.h>
39 #include "isns_server.h"
40 #include "isns_cfg.h"
41 #include "isns_htab.h"
42 #include "isns_cache.h"
43 #include "isns_obj.h"
44 #include "isns_dd.h"
45 #include "isns_utils.h"
46 #include "isns_mgmt.h"
47 #include "isns_protocol.h"
48 #include "admintf.h"
50 extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
52 static isns_type_t
53 get_lc_type(
54 object_type obj
57 isns_type_t type;
59 switch (obj) {
60 case Node:
61 type = OBJ_ISCSI;
62 break;
63 case DiscoveryDomain:
64 case DiscoveryDomainMember:
65 type = OBJ_DD;
66 break;
67 case DiscoveryDomainSet:
68 case DiscoveryDomainSetMember:
69 type = OBJ_DDS;
70 break;
71 default:
72 ASSERT(0);
73 break;
76 return (type);
79 static uint32_t
80 get_lc_id(
81 object_type obj
84 uint32_t id;
86 switch (obj) {
87 case Node:
88 id = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
89 break;
90 case DiscoveryDomain:
91 case DiscoveryDomainMember:
92 id = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
93 break;
94 case DiscoveryDomainSet:
95 case DiscoveryDomainSetMember:
96 id = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
97 break;
98 default:
99 ASSERT(0);
100 break;
103 return (id);
107 * ****************************************************************************
109 * cb_get_node_info: callback for get_node_op
110 * The routine process matching node and add a Node object elements
111 * to the response doc.
113 * p1 - matching node object
114 * p2 - lookup control data that was used for node look up
115 * returns parent index(newtork entity) in look up control.
116 * return - error code
118 * ****************************************************************************
120 static int
121 cb_get_node_info(
122 void *p1,
123 void *p2
126 xmlNodePtr n_obj, n_node, sub_node, root;
127 xmlAttrPtr n_attr;
128 isns_attr_t *attr;
130 isns_obj_t *obj = (isns_obj_t *)p1;
131 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
132 xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
134 root = xmlDocGetRootElement(doc);
135 if (root == NULL) {
136 return (ERR_XML_ADDCHILD_FAILED);
139 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
140 if (n_obj) {
141 n_obj = xmlAddChild(root, n_obj);
142 if (n_obj == NULL) {
143 return (ERR_XML_ADDCHILD_FAILED);
145 } else {
146 return (ERR_XML_ADDCHILD_FAILED);
149 n_node = xmlNewNode(NULL, (xmlChar *)NODEOBJECT);
150 if (n_node) {
151 n_node = xmlAddChild(n_obj, n_node);
152 if (n_node == NULL) {
153 return (ERR_XML_ADDCHILD_FAILED);
155 } else {
156 return (ERR_XML_ADDCHILD_FAILED);
159 /* get node name, alias, type and generate xml info */
160 attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
161 n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
162 (xmlChar *)attr->value.ptr);
163 if (n_attr == NULL) {
164 return (ERR_XML_SETPROP_FAILED);
167 attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_TYPE_ATTR_ID)];
168 switch (attr->value.ui) {
169 case ISNS_CONTROL_NODE_TYPE | ISNS_INITIATOR_NODE_TYPE:
170 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
171 (xmlChar *)CONTROLNODEINITIATORTYPE);
172 break;
173 case ISNS_CONTROL_NODE_TYPE | ISNS_TARGET_NODE_TYPE:
174 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
175 (xmlChar *)CONTROLNODETARGETTYPE);
176 break;
177 case ISNS_TARGET_NODE_TYPE:
178 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
179 (xmlChar *)TARGETTYPE);
180 break;
181 case ISNS_INITIATOR_NODE_TYPE:
182 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
183 (xmlChar *)INITIATORTYPE);
184 break;
185 case ISNS_CONTROL_NODE_TYPE:
186 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
187 (xmlChar *)CONTROLNODETYPE);
188 break;
189 default:
190 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
191 (xmlChar *)UNKNOWNTYPE);
193 if (n_attr == NULL) {
194 return (ERR_XML_SETPROP_FAILED);
197 attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_ALIAS_ATTR_ID)];
198 n_attr = xmlSetProp(n_node, (xmlChar *)ALIASATTR,
199 (xmlChar *)attr->value.ptr);
200 if (n_attr == NULL) {
201 return (ERR_XML_SETPROP_FAILED);
205 * A node can have all or no SCN subsribtion.
206 * May avoid redundant code with scsusrciption table.
208 attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_SCN_BITMAP_ATTR_ID)];
209 if (IS_SCN_INIT_SELF_INFO_ONLY(attr->value.ui)) {
210 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
211 (xmlChar *)SCNINITSELFONLY);
212 if (sub_node == NULL) {
213 return (ERR_XML_NEWCHILD_FAILED);
216 if (IS_SCN_TARGET_SELF_INFO_ONLY(attr->value.ui)) {
217 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
218 (xmlChar *)SCNTARGETSELFONLY);
219 if (sub_node == NULL) {
220 return (ERR_XML_NEWCHILD_FAILED);
223 if (IS_SCN_MGMT_REG(attr->value.ui)) {
224 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
225 (xmlChar *)SCNTARGETSELFONLY);
226 if (sub_node == NULL) {
227 return (ERR_XML_NEWCHILD_FAILED);
230 if (IS_SCN_OBJ_REMOVED(attr->value.ui)) {
231 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
232 (xmlChar *)SCNOBJECTREMOVED);
233 if (sub_node == NULL) {
234 return (ERR_XML_NEWCHILD_FAILED);
237 if (IS_SCN_OBJ_ADDED(attr->value.ui)) {
238 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
239 (xmlChar *)SCNOBJECTADDED);
240 if (sub_node == NULL) {
241 return (ERR_XML_NEWCHILD_FAILED);
244 if (IS_SCN_OBJ_UPDATED(attr->value.ui)) {
245 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
246 (xmlChar *)SCNOBJECTUPDATED);
247 if (sub_node == NULL) {
248 return (ERR_XML_NEWCHILD_FAILED);
251 if (IS_SCN_MEMBER_REMOVED(attr->value.ui)) {
252 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
253 (xmlChar *)SCNMEMBERREMOVED);
254 if (sub_node == NULL) {
255 return (ERR_XML_NEWCHILD_FAILED);
258 if (IS_SCN_MEMBER_ADDED(attr->value.ui)) {
259 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
260 (xmlChar *)SCNMEMBERADDED);
261 if (sub_node == NULL) {
262 return (ERR_XML_NEWCHILD_FAILED);
266 /* set the parent object id, i.e. the network entity object id */
267 lcp->id[2] = get_parent_uid(obj);
268 /* pass back the node object element to add entity, portal info to it */
269 lcp->data[2].ptr = (uchar_t *)n_node;
271 /* successful */
272 return (0);
276 * ****************************************************************************
278 * cb_get_entity_info: callback for get_node_op
279 * The routine process matching network entity and add children elements
280 * to a Node object for given entity.
282 * p1 - matching entity object
283 * p2 - lookup control data that was used for node look up
284 * returns parent index(newtork entity) in look up control.
285 * return - error code
287 * ****************************************************************************
289 static int
290 cb_get_entity_info(
291 void *p1,
292 void *p2
295 isns_obj_t *obj = (isns_obj_t *)p1;
296 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
297 xmlNodePtr n_node = (xmlNodePtr)lcp->data[2].ptr;
298 xmlNodePtr sub_node, subchild_node, subgrandchild_node;
299 char numbuf[32];
300 char buff[INET6_ADDRSTRLEN + 1] = { 0 };
301 isns_attr_t *attr;
303 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)NETWORKENTITY, NULL);
305 if (sub_node) {
306 attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)];
307 subchild_node = xmlNewChild(sub_node, NULL,
308 (xmlChar *)ENTITYID, (xmlChar *)attr->value.ptr);
309 if (subchild_node == NULL) {
310 return (ERR_XML_NEWCHILD_FAILED);
312 attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_ENTITY_PROTOCOL_ATTR_ID)];
313 (void) sprintf(numbuf, "%u", attr->value.ui);
314 subchild_node = xmlNewChild(sub_node, NULL,
315 (xmlChar *)ENTITYPROTOCOL, (xmlChar *)numbuf);
316 if (subchild_node == NULL) {
317 return (ERR_XML_NEWCHILD_FAILED);
319 attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_MGMT_IP_ADDR_ATTR_ID)];
320 if (attr->value.ip) {
321 /* convert the ipv6 to ipv4 */
322 if (((int *)attr->value.ip)[0] == 0x00 &&
323 ((int *)attr->value.ip)[1] == 0x00 &&
324 ((uchar_t *)attr->value.ip)[8] == 0x00 &&
325 ((uchar_t *)attr->value.ip)[9] == 0x00 &&
326 ((uchar_t *)attr->value.ip)[10] == 0xFF &&
327 ((uchar_t *)attr->value.ip)[11] == 0xFF) {
328 subchild_node = xmlNewChild(sub_node, NULL,
329 (xmlChar *)MANAGEMENTIPADDR,
330 (xmlChar *)inet_ntop(AF_INET,
331 (void *)&(((uint32_t *)attr->value.ip)[3]),
332 buff, sizeof (buff)));
333 } else {
334 subchild_node = xmlNewChild(sub_node, NULL,
335 (xmlChar *)MANAGEMENTIPADDR,
336 (xmlChar *)inet_ntop(AF_INET6,
337 (void *)attr->value.ip, buff, sizeof (buff)));
339 if (subchild_node == NULL) {
340 return (ERR_XML_NEWCHILD_FAILED);
343 attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_TIMESTAMP_ATTR_ID)];
344 if (attr->value.ui) {
345 (void) sprintf(numbuf, "%u", attr->value.ui);
346 subchild_node = xmlNewChild(sub_node, NULL,
347 (xmlChar *)ENTITYREGTIMESTAMP, (xmlChar *)numbuf);
348 if (subchild_node == NULL) {
349 return (ERR_XML_NEWCHILD_FAILED);
352 attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_VERSION_RANGE_ATTR_ID)];
353 if (attr->value.ui) {
354 subchild_node = xmlNewNode(NULL,
355 (xmlChar *)PROTOCOLVERSIONRANGE);
356 subchild_node = xmlAddChild(sub_node, subchild_node);
357 if (subchild_node == NULL) {
358 return (ERR_XML_NEWCHILD_FAILED);
361 (void) sprintf(numbuf, "%u",
362 (attr->value.ui >> ISNS_VER_SHIFT) & ISNS_VERSION);
363 subgrandchild_node = xmlNewChild(subchild_node, NULL,
364 (xmlChar *)PROTOCOLMAXVERSION, (xmlChar *)numbuf);
365 if (subgrandchild_node == NULL) {
366 return (ERR_XML_NEWCHILD_FAILED);
368 (void) sprintf(numbuf, "%u", attr->value.ui & ISNS_VERSION);
369 subgrandchild_node = xmlNewChild(subchild_node, NULL,
370 (xmlChar *)PROTOCOLMINVERSION, (xmlChar *)numbuf);
371 if (subgrandchild_node == NULL) {
372 return (ERR_XML_NEWCHILD_FAILED);
375 attr =
376 &obj->attrs[ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID)];
377 if (attr->value.ui) {
378 (void) sprintf(numbuf, "%u", attr->value.ui);
379 subchild_node = xmlNewChild(sub_node, NULL,
380 (xmlChar *)REGISTRATIONPERIOD, (xmlChar *)numbuf);
381 if (subchild_node == NULL) {
382 return (ERR_XML_NEWCHILD_FAILED);
385 } else {
386 return (ERR_XML_NEWCHILD_FAILED);
389 /* successful */
390 return (0);
394 * ****************************************************************************
396 * cb_get_pg_info: callback for get_node_op
397 * The routine process matching portal group and returns ip address
398 * and port number for further portal processing.
400 * p1 - matching portal group object
401 * p2 - lookup control data that was used for portal group look up
402 * returns portal ip address, port and group tag in look up control.
403 * return - error code
405 * ****************************************************************************
407 static int
408 cb_get_pg_info(
409 void *p1,
410 void *p2
413 isns_obj_t *obj = (isns_obj_t *)p1;
414 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
416 isns_attr_t *attr;
418 /* get pg portal ip address and port attributes */
419 attr = &obj->attrs[ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)];
420 (void) memcpy(lcp->data[1].ip, attr->value.ip, sizeof (in6_addr_t));
421 attr = &obj->attrs[ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID)];
422 lcp->data[2].ui = attr->value.ui;
423 attr = &obj->attrs[ATTR_INDEX_PG(ISNS_PG_TAG_ATTR_ID)];
424 lcp->id[2] = attr->value.ui;
426 /* successful */
427 return (0);
431 * ****************************************************************************
433 * cb_get_portal_info: callback for get_node_op
434 * The routine process matching portal and add portal object info to
435 * the node object.
437 * p1 - matching portal object
438 * p2 - lookup control data that was used for portal look up
439 * return - error code
441 * ****************************************************************************
443 static int
444 cb_get_portal_info(
445 void *p1,
446 void *p2
449 isns_obj_t *obj = (isns_obj_t *)p1;
450 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
451 xmlNodePtr n_node = (xmlNodePtr)lcp->data[2].ptr;
452 uint32_t tag = lcp->id[2];
453 xmlNodePtr sub_node, subchild_node, subgrandchild_node;
454 char numbuf[32];
455 char buff[INET6_ADDRSTRLEN + 1] = { 0 };
456 isns_attr_t *attr;
458 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)PORTAL, NULL);
460 /* get portal object attributes. */
461 if (sub_node) {
462 attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID)];
463 if (attr->value.ip) {
464 /* convert the ipv6 to ipv4 */
465 if (((int *)attr->value.ip)[0] == 0x00 &&
466 ((int *)attr->value.ip)[1] == 0x00 &&
467 ((uchar_t *)attr->value.ip)[8] == 0x00 &&
468 ((uchar_t *)attr->value.ip)[9] == 0x00 &&
469 ((uchar_t *)attr->value.ip)[10] == 0xFF &&
470 ((uchar_t *)attr->value.ip)[11] == 0xFF) {
471 subchild_node = xmlNewChild(sub_node, NULL,
472 (xmlChar *)IPADDR,
473 (xmlChar *)inet_ntop(AF_INET,
474 (void *)&(((uint32_t *)attr->value.ip)[3]),
475 buff, sizeof (buff)));
476 } else {
477 subchild_node = xmlNewChild(sub_node, NULL,
478 (xmlChar *)IPADDR,
479 (xmlChar *)inet_ntop(AF_INET6,
480 (void *)attr->value.ip, buff, sizeof (buff)));
482 if (subchild_node == NULL) {
483 return (ERR_XML_NEWCHILD_FAILED);
486 subchild_node = xmlNewChild(sub_node, NULL, (xmlChar *)UDPTCPPORT,
487 NULL);
488 if (subchild_node) {
489 attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID)];
490 subgrandchild_node = xmlNewChild(subchild_node, NULL,
491 (xmlChar *)PORTTYPE, IS_PORT_UDP(attr->value.ui) ?
492 (xmlChar *)UDPPORT : (xmlChar *)TCPPORT);
493 if (subgrandchild_node == NULL) {
494 return (ERR_XML_NEWCHILD_FAILED);
496 (void) sprintf(numbuf, "%u", PORT_NUMBER(attr->value.ui));
497 subgrandchild_node = xmlNewChild(subchild_node, NULL,
498 (xmlChar *)PORTNUMBER, (xmlChar *)numbuf);
499 if (subgrandchild_node == NULL) {
500 return (ERR_XML_NEWCHILD_FAILED);
502 } else {
503 return (ERR_XML_NEWCHILD_FAILED);
505 (void) sprintf(numbuf, "%u", tag);
506 subchild_node = xmlNewChild(sub_node, NULL, (xmlChar *)GROUPTAG,
507 (xmlChar *)numbuf);
508 if (subchild_node == NULL) {
509 return (ERR_XML_NEWCHILD_FAILED);
511 attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_NAME_ATTR_ID)];
512 if (attr->value.ptr) {
513 subchild_node = xmlNewChild(sub_node, NULL,
514 (xmlChar *)SYMBOLICNAME, (xmlChar *)attr->value.ptr);
515 if (subchild_node == NULL) {
516 return (ERR_XML_NEWCHILD_FAILED);
519 attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_ESI_INTERVAL_ATTR_ID)];
520 if (attr->value.ui) {
521 (void) sprintf(numbuf, "%u", attr->value.ui);
522 subchild_node = xmlNewChild(sub_node, NULL,
523 (xmlChar *)ESIINTERVAL, (xmlChar *)numbuf);
524 if (subchild_node == NULL) {
525 return (ERR_XML_NEWCHILD_FAILED);
528 attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_ESI_PORT_ATTR_ID)];
529 if (attr->value.ui) {
530 subchild_node = xmlNewChild(sub_node, NULL,
531 (xmlChar *)ESIPORT, NULL);
532 if (subchild_node) {
533 subgrandchild_node = xmlNewChild(subchild_node, NULL,
534 (xmlChar *)PORTTYPE, IS_PORT_UDP(attr->value.ui) ?
535 (xmlChar *)UDPPORT : (xmlChar *)TCPPORT);
536 if (subgrandchild_node == NULL) {
537 return (ERR_XML_NEWCHILD_FAILED);
539 (void) sprintf(numbuf, "%u", PORT_NUMBER(attr->value.ui));
540 subgrandchild_node = xmlNewChild(subchild_node, NULL,
541 (xmlChar *)PORTNUMBER, (xmlChar *)numbuf);
542 if (subgrandchild_node == NULL) {
543 return (ERR_XML_NEWCHILD_FAILED);
545 } else {
546 return (ERR_XML_NEWCHILD_FAILED);
549 attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_SCN_PORT_ATTR_ID)];
550 if (attr->value.ui) {
551 subchild_node = xmlNewChild(sub_node, NULL,
552 (xmlChar *)SCNPORT, NULL);
553 if (subchild_node) {
554 subgrandchild_node = xmlNewChild(subchild_node, NULL,
555 (xmlChar *)PORTTYPE, IS_PORT_UDP(attr->value.ui) ?
556 (xmlChar *)UDPPORT : (xmlChar *)TCPPORT);
557 (void) sprintf(numbuf, "%u", PORT_NUMBER(attr->value.ui));
558 if (subgrandchild_node == NULL) {
559 return (ERR_XML_NEWCHILD_FAILED);
561 subgrandchild_node = xmlNewChild(subchild_node, NULL,
562 (xmlChar *)PORTNUMBER, (xmlChar *)numbuf);
563 if (subgrandchild_node == NULL) {
564 return (ERR_XML_NEWCHILD_FAILED);
566 } else {
567 return (ERR_XML_NEWCHILD_FAILED);
570 } else if (sub_node == NULL) {
571 return (ERR_XML_NEWCHILD_FAILED);
574 /* successful */
575 return (0);
579 * ****************************************************************************
581 * cb_get_dd_info: callback for get_dd_op
582 * The routine process matching dd object
584 * p1 - matching dd object
585 * p2 - lookup control data that was used for dd look up
586 * return - error code
588 * ****************************************************************************
590 static int
591 cb_get_dd_info(
592 void *p1,
593 void *p2
596 xmlNodePtr n_obj, n_node, sub_node, root;
597 xmlAttrPtr n_attr;
598 isns_attr_t *attr;
599 char numbuf[32];
601 isns_obj_t *obj = (isns_obj_t *)p1;
602 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
603 xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
605 root = xmlDocGetRootElement(doc);
606 if (root == NULL) {
607 return (ERR_SYNTAX_MISSING_ROOT);
609 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
610 if (n_obj) {
611 n_obj = xmlAddChild(root, n_obj);
612 if (n_obj == NULL) {
613 return (ERR_XML_ADDCHILD_FAILED);
615 } else {
616 return (ERR_XML_ADDCHILD_FAILED);
619 n_node = xmlNewNode(NULL, (xmlChar *)DDOBJECT);
620 if (n_node) {
621 n_node = xmlAddChild(n_obj, n_node);
622 if (n_node == NULL) {
623 return (ERR_XML_ADDCHILD_FAILED);
625 } else {
626 return (ERR_XML_ADDCHILD_FAILED);
629 attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)];
630 n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
631 (xmlChar *)attr->value.ptr);
632 if (n_attr == NULL) {
633 return (ERR_XML_SETPROP_FAILED);
635 attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_ID_ATTR_ID)];
636 (void) sprintf(numbuf, "%u", attr->value.ui);
637 n_attr = xmlSetProp(n_node, (xmlChar *)IDATTR,
638 (xmlChar *)numbuf);
639 if (n_attr == NULL) {
640 return (ERR_XML_SETPROP_FAILED);
642 attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_FEATURES_ATTR_ID)];
643 if (DD_BOOTLIST_ENABLED(attr->value.ui)) {
644 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)BOOTLISTENABLEDELEM,
645 (xmlChar *)XMLTRUE);
646 if (sub_node == NULL) {
647 return (ERR_XML_NEWCHILD_FAILED);
649 } else {
650 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)BOOTLISTENABLEDELEM,
651 (xmlChar *)XMLFALSE);
652 if (sub_node == NULL) {
653 return (ERR_XML_NEWCHILD_FAILED);
657 /* successful */
658 return (0);
662 * ****************************************************************************
664 * cb_get_ddset_info: callback for get_ddset_op
665 * The routine process matching dd object
667 * p1 - matching dds object
668 * p2 - lookup control data that was used for dd set look up
669 * return - error code
671 * ****************************************************************************
673 static int
674 cb_get_ddset_info(
675 void *p1,
676 void *p2
679 xmlNodePtr n_obj, n_node, sub_node, root;
680 xmlAttrPtr n_attr;
681 isns_attr_t *attr;
682 char numbuf[32];
684 isns_obj_t *obj = (isns_obj_t *)p1;
685 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
686 xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
688 root = xmlDocGetRootElement(doc);
689 if (root == NULL) {
690 return (ERR_SYNTAX_MISSING_ROOT);
693 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
694 if (n_obj) {
695 n_obj = xmlAddChild(root, n_obj);
696 if (n_obj == NULL) {
697 return (ERR_XML_NEWCHILD_FAILED);
699 } else {
700 return (ERR_XML_NEWNODE_FAILED);
703 n_node = xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
704 if (n_node) {
705 n_node = xmlAddChild(n_obj, n_node);
706 if (n_node == NULL) {
707 return (ERR_XML_ADDCHILD_FAILED);
709 } else {
710 return (ERR_XML_NEWNODE_FAILED);
713 /* get node name, alias, type and generate xml info */
714 attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID)];
715 n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
716 (xmlChar *)attr->value.ptr);
717 if (n_attr == NULL) {
718 return (ERR_XML_SETPROP_FAILED);
720 attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_ID_ATTR_ID)];
721 (void) sprintf(numbuf, "%u", attr->value.ui);
722 n_attr = xmlSetProp(n_node, (xmlChar *)IDATTR,
723 (xmlChar *)numbuf);
724 if (n_attr == NULL) {
725 return (ERR_XML_SETPROP_FAILED);
727 attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID)];
728 if (DDS_ENABLED(attr->value.ui)) {
729 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)ENABLEDELEM,
730 (xmlChar *)XMLTRUE);
731 if (sub_node == NULL) {
732 return (ERR_XML_NEWCHILD_FAILED);
734 } else {
735 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)ENABLEDELEM,
736 (xmlChar *)XMLFALSE);
737 if (sub_node == NULL) {
738 return (ERR_XML_NEWCHILD_FAILED);
742 /* successful */
743 return (0);
747 * ****************************************************************************
749 * cb_enumerate_node_info: callback for enumerate_node_op
750 * The routine is invoked for each node object.
752 * p1 - node object
753 * p2 - lookup control data that was used for node look up
754 * return - error code
756 * ****************************************************************************
758 static int
759 cb_enumerate_node_info(
760 void *p1,
761 void *p2
764 xmlNodePtr n_obj, n_node, root;
765 xmlAttrPtr n_attr;
766 isns_attr_t *attr;
768 isns_obj_t *obj = (isns_obj_t *)p1;
769 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
770 xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
772 root = xmlDocGetRootElement(doc);
773 if (root == NULL) {
774 return (ERR_SYNTAX_MISSING_ROOT);
777 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
778 if (n_obj) {
779 n_obj = xmlAddChild(root, n_obj);
780 if (n_obj == NULL) {
781 return (ERR_XML_ADDCHILD_FAILED);
783 } else {
784 return (ERR_XML_NEWNODE_FAILED);
787 n_node = xmlNewNode(NULL, (xmlChar *)NODEOBJECT);
788 if (n_node) {
789 n_node = xmlAddChild(n_obj, n_node);
790 if (n_node == NULL) {
791 return (ERR_XML_ADDCHILD_FAILED);
793 } else {
794 return (ERR_XML_NEWNODE_FAILED);
797 /* get node name, alias, type and generate xml info */
798 attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
799 n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
800 (xmlChar *)attr->value.ptr);
801 if (n_attr == NULL) {
802 return (ERR_XML_SETPROP_FAILED);
804 attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_TYPE_ATTR_ID)];
805 switch (attr->value.ui) {
806 case ISNS_CONTROL_NODE_TYPE | ISNS_INITIATOR_NODE_TYPE:
807 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
808 (xmlChar *)CONTROLNODEINITIATORTYPE);
809 break;
810 case ISNS_CONTROL_NODE_TYPE | ISNS_TARGET_NODE_TYPE:
811 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
812 (xmlChar *)CONTROLNODETARGETTYPE);
813 break;
814 case ISNS_TARGET_NODE_TYPE:
815 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
816 (xmlChar *)TARGETTYPE);
817 break;
818 case ISNS_INITIATOR_NODE_TYPE:
819 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
820 (xmlChar *)INITIATORTYPE);
821 break;
822 case ISNS_CONTROL_NODE_TYPE:
823 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
824 (xmlChar *)CONTROLNODETYPE);
825 break;
826 default:
827 n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
828 (xmlChar *)UNKNOWNTYPE);
830 if (n_attr == NULL) {
831 return (ERR_XML_SETPROP_FAILED);
833 attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_ALIAS_ATTR_ID)];
834 n_attr = xmlSetProp(n_node, (xmlChar *)ALIASATTR,
835 (xmlChar *)attr->value.ptr);
836 if (n_attr == NULL) {
837 return (ERR_XML_SETPROP_FAILED);
840 /* successful */
841 return (0);
845 * ****************************************************************************
847 * i_enumerate_dd_dds_info:
848 * The routine is implemnetation for enumerate dd and enumerate dds.
850 * p1 - dd or dd set object
851 * p2 - lookup control data that was used for dd and dd set look up
852 * return - error code
854 * ****************************************************************************
856 static int
857 i_enumerate_dd_dds_info(
858 void *p1,
859 void *p2,
860 isns_type_t obj_type
863 xmlNodePtr n_obj, n_node, sub_node, root;
864 xmlAttrPtr n_attr;
865 isns_attr_t *attr;
866 char numbuf[32];
868 isns_obj_t *obj = (isns_obj_t *)p1;
869 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
870 xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
872 root = xmlDocGetRootElement(doc);
873 if (root == NULL) {
874 return (ERR_SYNTAX_MISSING_ROOT);
877 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
878 if (n_obj) {
879 n_obj = xmlAddChild(root, n_obj);
880 if (n_obj == NULL) {
881 return (ERR_XML_ADDCHILD_FAILED);
883 } else {
884 return (ERR_XML_NEWNODE_FAILED);
887 if (obj_type == OBJ_DD) {
888 n_node = xmlNewNode(NULL, (xmlChar *)DDOBJECT);
889 } else {
890 n_node = xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
893 if (n_node) {
894 n_node = xmlAddChild(n_obj, n_node);
895 if (n_node == NULL) {
896 return (ERR_XML_ADDCHILD_FAILED);
898 } else {
899 return (ERR_XML_NEWNODE_FAILED);
902 if (obj_type == OBJ_DD) {
903 /* get name, id, feaure and generate xml info */
904 attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)];
905 n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
906 (xmlChar *)attr->value.ptr);
907 if (n_attr == NULL) {
908 return (ERR_XML_SETPROP_FAILED);
910 attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_ID_ATTR_ID)];
911 (void) sprintf(numbuf, "%u", attr->value.ui);
912 n_attr = xmlSetProp(n_node, (xmlChar *)IDATTR,
913 (xmlChar *)numbuf);
914 if (n_attr == NULL) {
915 return (ERR_XML_SETPROP_FAILED);
917 attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_FEATURES_ATTR_ID)];
918 if (DD_BOOTLIST_ENABLED(attr->value.ui)) {
919 sub_node = xmlNewChild(n_node, NULL,
920 (xmlChar *)BOOTLISTENABLEDELEM, (xmlChar *)XMLTRUE);
921 if (sub_node == NULL) {
922 return (ERR_XML_NEWCHILD_FAILED);
924 } else {
925 sub_node = xmlNewChild(n_node, NULL,
926 (xmlChar *)BOOTLISTENABLEDELEM, (xmlChar *)XMLFALSE);
927 if (sub_node == NULL) {
928 return (ERR_XML_NEWCHILD_FAILED);
931 } else {
932 /* get name, id, status and generate xml info */
933 attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID)];
934 n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
935 (xmlChar *)attr->value.ptr);
936 if (n_attr == NULL) {
937 return (ERR_XML_SETPROP_FAILED);
939 attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_ID_ATTR_ID)];
940 (void) sprintf(numbuf, "%u", attr->value.ui);
941 n_attr = xmlSetProp(n_node, (xmlChar *)IDATTR,
942 (xmlChar *)numbuf);
943 if (n_attr == NULL) {
944 return (ERR_XML_SETPROP_FAILED);
946 attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID)];
947 if (DDS_ENABLED(attr->value.ui)) {
948 sub_node = xmlNewChild(n_node, NULL,
949 (xmlChar *)ENABLEDELEM, (xmlChar *)XMLTRUE);
950 if (sub_node == NULL) {
951 return (ERR_XML_NEWCHILD_FAILED);
953 } else {
954 sub_node = xmlNewChild(n_node, NULL,
955 (xmlChar *)ENABLEDELEM, (xmlChar *)XMLFALSE);
956 if (sub_node == NULL) {
957 return (ERR_XML_NEWCHILD_FAILED);
962 /* successful */
963 return (0);
967 * ****************************************************************************
969 * cb_enumerate_dd_info: callback for enumerate_dd_op
970 * The routine is invoked for each dd object.
972 * p1 - dd object
973 * p2 - lookup control data that was used for dd look up
974 * return - error code
976 * ****************************************************************************
978 static int
979 cb_enumerate_dd_info(
980 void *p1,
981 void *p2
984 return (i_enumerate_dd_dds_info(p1, p2, OBJ_DD));
988 * ****************************************************************************
990 * cb_enumerate_ddset_info: callback for enumerate_dd_op
991 * The routine is invoked for each dd object.
993 * p1 - dd object
994 * p2 - lookup control data that was used for dd set look up
995 * return - error code
997 * ****************************************************************************
999 static int
1000 cb_enumerate_ddset_info(
1001 void *p1,
1002 void *p2
1005 return (i_enumerate_dd_dds_info(p1, p2, OBJ_DDS));
1009 * ****************************************************************************
1011 * cb_getAssociated_node_info:
1012 * The routine is implemnetation for enumerate dd and enumerate dds.
1014 * p1 - dd or dd set object
1015 * p2 - lookup control data that was used for dd and dd set look up
1016 * return - error code
1018 * ****************************************************************************
1020 static int
1021 cb_getAssociated_node_info(
1022 void *p1,
1023 void *p2
1026 xmlNodePtr n_obj, n_node, root;
1027 xmlAttrPtr n_attr;
1028 isns_attr_t *attr;
1030 isns_obj_t *obj = (isns_obj_t *)p1;
1031 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
1032 xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
1033 uchar_t *ddname = lcp->data[2].ptr;
1035 root = xmlDocGetRootElement(doc);
1036 if (root == NULL) {
1037 return (ERR_SYNTAX_MISSING_ROOT);
1039 n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
1040 if (n_obj) {
1041 n_obj = xmlAddChild(root, n_obj);
1042 if (n_obj == NULL) {
1043 return (ERR_XML_ADDCHILD_FAILED);
1045 } else {
1046 return (ERR_XML_NEWNODE_FAILED);
1049 n_node = xmlNewNode(NULL, (xmlChar *)DDOBJECTMEMBER);
1050 if (n_node) {
1051 n_node = xmlAddChild(n_obj, n_node);
1052 if (n_node == NULL) {
1053 return (ERR_XML_ADDCHILD_FAILED);
1055 } else {
1056 return (ERR_XML_NEWNODE_FAILED);
1059 /* get node name, alias, type and generate xml info */
1060 attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
1061 n_attr = xmlSetProp(n_node, (xmlChar *)NODENAMEATTR,
1062 (xmlChar *)attr->value.ptr);
1063 if (n_attr == NULL) {
1064 return (ERR_XML_SETPROP_FAILED);
1066 n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
1067 (xmlChar *)ddname);
1068 if (n_attr == NULL) {
1069 return (ERR_XML_SETPROP_FAILED);
1072 /* successful */
1073 return (0);
1077 * ****************************************************************************
1079 * cb_getAssociated_node_to_dd_info:
1080 * The routine is implemnetation for enumerate dd and enumerate dds.
1082 * p1 - dd or dd set object
1083 * p2 - lookup control data that was used for dd and dd set look up
1084 * return - error code
1086 * ****************************************************************************
1088 static int
1089 cb_getAssociated_node_to_dd_info(
1090 void *p1,
1091 void *p2
1094 xmlNodePtr n_obj, n_node, root;
1095 xmlAttrPtr n_attr;
1096 isns_attr_t *attr;
1098 isns_obj_t *obj = (isns_obj_t *)p1;
1099 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
1100 xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
1101 uchar_t *nodename = lcp->data[2].ptr;
1103 root = xmlDocGetRootElement(doc);
1104 if (root == NULL) {
1105 return (ERR_SYNTAX_MISSING_ROOT);
1107 n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
1108 if (n_obj) {
1109 n_obj = xmlAddChild(root, n_obj);
1110 if (n_obj == NULL) {
1111 return (ERR_XML_ADDCHILD_FAILED);
1113 } else {
1114 return (ERR_XML_NEWNODE_FAILED);
1117 n_node = xmlNewNode(NULL, (xmlChar *)DDOBJECTMEMBER);
1118 if (n_node) {
1119 n_node = xmlAddChild(n_obj, n_node);
1120 if (n_node == NULL) {
1121 return (ERR_XML_ADDCHILD_FAILED);
1123 } else {
1124 return (ERR_XML_NEWNODE_FAILED);
1127 /* get node name, alias, type and generate xml info */
1128 n_attr = xmlSetProp(n_node, (xmlChar *)NODENAMEATTR,
1129 (xmlChar *)nodename);
1130 if (n_attr == NULL) {
1131 return (ERR_XML_SETPROP_FAILED);
1133 attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)];
1134 n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
1135 (xmlChar *)attr->value.ptr);
1136 if (n_attr == NULL) {
1137 return (ERR_XML_SETPROP_FAILED);
1140 /* successful */
1141 return (0);
1145 * ****************************************************************************
1147 * cb_getAssociated_dd_info:
1148 * The routine is implemnetation for getting dds membership.
1150 * p1 - dd or dd set object
1151 * p2 - lookup control data that was used for dd and dd set look up
1152 * return - error code
1154 * ****************************************************************************
1156 static int
1157 cb_getAssociated_dd_info(
1158 void *p1,
1159 void *p2
1162 xmlNodePtr n_obj, n_node, root;
1163 xmlAttrPtr n_attr;
1164 isns_attr_t *attr;
1166 isns_obj_t *obj = (isns_obj_t *)p1;
1167 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
1168 xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
1169 uchar_t *ddsetname = lcp->data[2].ptr;
1171 root = xmlDocGetRootElement(doc);
1172 if (root == NULL) {
1173 return (ERR_SYNTAX_MISSING_ROOT);
1175 n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
1176 if (n_obj) {
1177 n_obj = xmlAddChild(root, n_obj);
1178 if (n_obj == NULL) {
1179 return (ERR_XML_ADDCHILD_FAILED);
1181 } else {
1182 return (ERR_XML_NEWNODE_FAILED);
1185 n_node = xmlNewNode(NULL, (xmlChar *)DDSETOBJECTMEMBER);
1186 if (n_node) {
1187 n_node = xmlAddChild(n_obj, n_node);
1188 if (n_node == NULL) {
1189 return (ERR_XML_ADDCHILD_FAILED);
1191 } else {
1192 return (ERR_XML_NEWNODE_FAILED);
1195 /* get node name, alias, type and generate xml info */
1196 attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)];
1197 n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
1198 (xmlChar *)attr->value.ptr);
1199 if (n_attr == NULL) {
1200 return (ERR_XML_SETPROP_FAILED);
1202 n_attr = xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR,
1203 (xmlChar *)ddsetname);
1204 if (n_attr == NULL) {
1205 return (ERR_XML_SETPROP_FAILED);
1208 /* successful */
1209 return (0);
1213 * ****************************************************************************
1215 * cb_getAssociated_dd_to_ddset_info:
1216 * The routine is implemnetation for enumerate dd and enumerate dds.
1218 * p1 - dd or dd set object
1219 * p2 - lookup control data that was used for dd and dd set look up
1220 * return - error code
1222 * ****************************************************************************
1224 static int
1225 cb_getAssociated_dd_to_ddset_info(
1226 void *p1,
1227 void *p2
1230 xmlNodePtr n_obj, n_node, root;
1231 xmlAttrPtr n_attr;
1232 isns_attr_t *attr;
1234 isns_obj_t *obj = (isns_obj_t *)p1;
1235 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
1236 xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
1237 uchar_t *ddname = lcp->data[2].ptr;
1239 root = xmlDocGetRootElement(doc);
1240 if (root == NULL) {
1241 return (ERR_SYNTAX_MISSING_ROOT);
1243 n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
1244 if (n_obj) {
1245 n_obj = xmlAddChild(root, n_obj);
1246 if (n_obj == NULL) {
1247 return (ERR_XML_ADDCHILD_FAILED);
1249 } else {
1250 return (ERR_XML_NEWNODE_FAILED);
1253 n_node = xmlNewNode(NULL, (xmlChar *)DDSETOBJECTMEMBER);
1254 if (n_node) {
1255 n_node = xmlAddChild(n_obj, n_node);
1256 if (n_node == NULL) {
1257 return (ERR_XML_ADDCHILD_FAILED);
1259 } else {
1260 return (ERR_XML_NEWNODE_FAILED);
1263 /* get node name, alias, type and generate xml info */
1264 n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
1265 (xmlChar *)ddname);
1266 if (n_attr == NULL) {
1267 return (ERR_XML_SETPROP_FAILED);
1269 attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID)];
1270 n_attr = xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR,
1271 (xmlChar *)attr->value.ptr);
1272 if (n_attr == NULL) {
1273 return (ERR_XML_SETPROP_FAILED);
1276 /* successful */
1277 return (0);
1281 * ****************************************************************************
1283 * handle_partial_success:
1285 * doc - response doc to fill up
1286 * ret - return code from the caller.
1288 * ****************************************************************************
1290 static int
1291 handle_partial_success(
1292 xmlDocPtr doc,
1293 int ret
1296 xmlNodePtr n_obj, n_node, root;
1297 char numbuf[32];
1299 root = xmlDocGetRootElement(doc);
1300 if (root == NULL) {
1301 return (ERR_SYNTAX_MISSING_ROOT);
1303 n_obj = xmlNewNode(NULL, (xmlChar *)RESULTELEMENT);
1304 if (n_obj) {
1305 if (root->children) {
1306 n_obj = xmlAddPrevSibling(root->children, n_obj);
1307 (void) sprintf(numbuf, "%d", (ret != 0) ? PARTIAL_SUCCESS : 0);
1308 n_node = xmlNewChild(n_obj, NULL, (xmlChar *)STATUSELEMENT,
1309 (xmlChar *)numbuf);
1310 if (n_node == NULL) {
1311 return (ERR_XML_NEWCHILD_FAILED);
1313 n_node = xmlNewChild(n_obj, NULL, (xmlChar *)MESSAGEELEMENT,
1314 (xmlChar *)result_code_to_str((ret != 0) ?
1315 PARTIAL_SUCCESS : 0));
1316 if (n_node == NULL) {
1317 return (ERR_XML_NEWCHILD_FAILED);
1319 } else {
1320 n_obj = xmlAddChild(root, n_obj);
1321 if (n_obj == NULL) {
1322 return (ERR_XML_ADDCHILD_FAILED);
1324 (void) sprintf(numbuf, "%d", ret);
1325 n_node = xmlNewChild(n_obj, NULL, (xmlChar *)STATUSELEMENT,
1326 (xmlChar *)numbuf);
1327 if (n_node == NULL) {
1328 return (ERR_XML_NEWCHILD_FAILED);
1330 n_node = xmlNewChild(n_obj, NULL, (xmlChar *)MESSAGEELEMENT,
1331 (xmlChar *)result_code_to_str(ret));
1332 if (n_node == NULL) {
1333 return (ERR_XML_NEWCHILD_FAILED);
1336 } else {
1337 return (ERR_XML_NEWNODE_FAILED);
1340 return (0);
1344 * ****************************************************************************
1346 * handle_partial_failure:
1348 * doc - response doc to fill up
1349 * ret - return code from the caller.
1351 * ****************************************************************************
1353 static int
1354 handle_partial_failure(
1355 xmlDocPtr doc,
1356 int ret,
1357 boolean_t all_failed
1360 xmlNodePtr n_obj, n_node, root;
1361 char numbuf[32];
1363 root = xmlDocGetRootElement(doc);
1364 if (root == NULL) {
1365 return (ERR_SYNTAX_MISSING_ROOT);
1367 n_obj = xmlNewNode(NULL, (xmlChar *)RESULTELEMENT);
1368 if (n_obj) {
1369 if (root->children) {
1370 /* some or all associations failed to create */
1371 n_obj = xmlAddPrevSibling(root->children, n_obj);
1372 /* capture last error. should come up with all failed?? */
1373 (void) sprintf(numbuf, "%d",
1374 all_failed ? ret : PARTIAL_FAILURE);
1375 n_node = xmlNewChild(n_obj, NULL, (xmlChar *)STATUSELEMENT,
1376 (xmlChar *)numbuf);
1377 if (n_node == NULL) {
1378 return (ERR_XML_NEWCHILD_FAILED);
1380 n_node = xmlNewChild(n_obj, NULL, (xmlChar *)MESSAGEELEMENT,
1381 (xmlChar *)result_code_to_str(all_failed ? ret :
1382 PARTIAL_FAILURE));
1383 if (n_node == NULL) {
1384 return (ERR_XML_NEWCHILD_FAILED);
1386 } else {
1387 n_obj = xmlAddChild(root, n_obj);
1388 if (n_obj == NULL) {
1389 return (ERR_XML_ADDCHILD_FAILED);
1391 (void) sprintf(numbuf, "%d", (ret != 0) ? ret : 0);
1392 n_node = xmlNewChild(n_obj, NULL, (xmlChar *)STATUSELEMENT,
1393 (xmlChar *)numbuf);
1394 if (n_node == NULL) {
1395 return (ERR_XML_NEWCHILD_FAILED);
1397 n_node = xmlNewChild(n_obj, NULL, (xmlChar *)MESSAGEELEMENT,
1398 (xmlChar *)result_code_to_str((ret != 0) ? ret : 0));
1399 if (n_node == NULL) {
1400 return (ERR_XML_NEWCHILD_FAILED);
1403 } else {
1404 return (ERR_XML_NEWNODE_FAILED);
1407 return (0);
1411 * ****************************************************************************
1413 * get_serverconfig_op:
1414 * The routine process server administrative setting.
1416 * doc - response doc to fill up.
1418 * ****************************************************************************
1421 get_serverconfig_op(
1422 xmlDocPtr doc
1425 extern uint64_t esi_threshold;
1426 extern uint8_t mgmt_scn;
1427 extern ctrl_node_t *control_nodes;
1428 extern pthread_mutex_t ctrl_node_mtx;
1429 extern char data_store[MAXPATHLEN];
1431 xmlNodePtr n_obj, root;
1432 char numbuf[32];
1433 ctrl_node_t *ctrl_node_p;
1434 int ret = 0;
1436 root = xmlDocGetRootElement(doc);
1437 if (root == NULL) {
1438 return (ERR_SYNTAX_MISSING_ROOT);
1440 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSSERVER);
1441 if (n_obj) {
1442 n_obj = xmlAddChild(root, n_obj);
1443 if (n_obj == NULL) {
1444 return (ERR_XML_ADDCHILD_FAILED);
1446 } else {
1447 return (ERR_XML_ADDCHILD_FAILED);
1450 if (xmlNewChild(n_obj, NULL, (xmlChar *)DATASTORELOCATION,
1451 (xmlChar *)data_store) == NULL) {
1452 return (ERR_XML_NEWCHILD_FAILED);
1455 (void) sprintf(numbuf, "%llu", esi_threshold);
1456 if (xmlNewChild(n_obj, NULL, (xmlChar *)ESIRETRYTHRESHOLD,
1457 (xmlChar *)numbuf) == NULL) {
1458 return (ERR_XML_NEWCHILD_FAILED);
1460 if (xmlNewChild(n_obj, NULL, (xmlChar *)MANAGEMENTSCNENABLED,
1461 (mgmt_scn) ? (uchar_t *)XMLTRUE : (uchar_t *)XMLFALSE) == NULL) {
1462 return (ERR_XML_NEWCHILD_FAILED);
1465 (void) pthread_mutex_lock(&ctrl_node_mtx);
1466 if (control_nodes == NULL) {
1467 if (xmlNewChild(n_obj, NULL, (xmlChar *)CONTROLNODENAME,
1468 (xmlChar *)NULL) == NULL) {
1469 (void) pthread_mutex_unlock(&ctrl_node_mtx);
1470 return (ERR_XML_NEWCHILD_FAILED);
1472 } else {
1473 ctrl_node_p = control_nodes;
1474 while (ctrl_node_p != NULL) {
1475 if (xmlNewChild(n_obj, NULL, (xmlChar *)CONTROLNODENAME,
1476 (xmlChar *)ctrl_node_p->name) == NULL) {
1477 (void) pthread_mutex_unlock(&ctrl_node_mtx);
1478 return (ERR_XML_NEWCHILD_FAILED);
1480 ctrl_node_p = ctrl_node_p->next;
1483 (void) pthread_mutex_unlock(&ctrl_node_mtx);
1485 return (handle_partial_success(doc, ret));
1489 * ****************************************************************************
1491 * get_node_op:
1492 * service get operation on a given node.
1494 * req - contains all info for a request.
1495 * doc - response doc to fill up
1497 * ****************************************************************************
1500 get_node_op(
1501 request_t *req,
1502 xmlDocPtr doc
1503 /* any additional arguments go here */
1506 int ret = 0, ret_save = 0;
1507 int i = 0;
1508 lookup_ctrl_t lc, lc2, lc3;
1509 uint32_t uid;
1510 char buff2[INET6_ADDRSTRLEN];
1512 /* prepare lookup ctrl data for looking for the node object */
1513 lc.curr_uid = 0;
1514 lc.type = get_lc_type(req->op_info.obj);
1515 lc.id[0] = get_lc_id(req->op_info.obj);
1516 lc.op[0] = OP_STRING;
1517 lc.op[1] = 0;
1518 lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */
1519 while (i < req->count) {
1520 lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
1521 ret = cache_lookup(&lc, &uid, cb_get_node_info);
1522 if (uid == 0) {
1523 ret = ERR_MATCHING_ISCSI_NODE_NOT_FOUND;
1526 /* generate network entity object information */
1527 if (ret == 0 && lc.id[2] != 0) {
1529 * !!! there might be no entity and portal info for
1530 * !!! the node if it is not a registered node
1532 /* prepare lookup ctrl data for looking for entity */
1533 SET_UID_LCP(&lc2, OBJ_ENTITY, lc.id[2]);
1535 lc2.data[1].ptr = (uchar_t *)doc;
1536 /* cb_get_node_info callback returned Node object. */
1537 lc2.data[2].ptr = lc.data[2].ptr;
1538 ret = cache_lookup(&lc2, &uid, cb_get_entity_info);
1539 if (uid == 0) {
1540 ret = ERR_MATCHING_NETWORK_ENTITY_NOT_FOUND;
1544 /* generate portal information */
1545 if (ret == 0 && lc.id[2] != 0) {
1546 /* prepare lookup ctrl data for looking for pg */
1547 lc2.curr_uid = 0;
1548 lc2.type = OBJ_PG;
1549 lc2.id[0] = ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID);
1550 lc2.op[0] = OP_STRING;
1551 /* lc.data[0].ptr contains node name */
1552 lc2.data[0].ptr = lc.data[0].ptr;
1553 lc2.op[1] = 0;
1554 lc2.data[1].ip = (in6_addr_t *)buff2;
1556 /* prepare lookup ctrl data for looking for portal */
1557 lc3.curr_uid = 0;
1558 lc3.type = OBJ_PORTAL;
1559 lc3.id[0] = ATTR_INDEX_PORTAL(
1560 ISNS_PORTAL_IP_ADDR_ATTR_ID);
1561 lc3.op[0] = OP_MEMORY_IP6;
1562 lc3.id[1] = ATTR_INDEX_PORTAL(
1563 ISNS_PORTAL_PORT_ATTR_ID);
1564 lc3.op[1] = OP_INTEGER;
1565 lc3.op[2] = 0;
1566 /* cb_get_node_info callback returned Node object. */
1567 lc3.data[2].ptr = lc.data[2].ptr;
1568 for (;;) {
1569 ret = cache_lookup(&lc2, &uid, cb_get_pg_info);
1570 if (uid != 0) {
1571 /* we found a portal group */
1572 lc2.curr_uid = uid;
1573 /* it is a null pg if pgt is zero. */
1574 if (lc2.id[2] != 0) {
1575 /* pass ip addr */
1576 lc3.data[0].ip = lc2.data[1].ip;
1577 /* pass port num */
1578 lc3.data[1].ui = lc2.data[2].ui;
1579 /* pass pgt */
1580 lc3.id[2] = lc2.id[2];
1581 ret = cache_lookup(&lc3, &uid,
1582 cb_get_portal_info);
1584 } else {
1586 * no more portal group which is
1587 * tied to this stroage node object.
1589 break;
1593 /* save error for this iteration */
1594 if (ret != 0) {
1595 ret_save = ret;
1597 ret = 0;
1598 i++;
1601 return (handle_partial_success(doc, ret_save));
1605 * ****************************************************************************
1607 * i_get_dd_dds_op:
1608 * serves get operatrion on dd or dds.
1610 * req - contains all info for a request.
1611 * doc - response doc to fill up
1612 * obj_type - object type(either dd or dd set)
1614 * ****************************************************************************
1616 static int
1617 i_get_dd_dds_op(
1618 request_t *req,
1619 xmlDocPtr doc,
1620 isns_type_t obj_type
1621 /* any additional arguments go here */
1624 result_code_t ret = 0, ret_save = 0;
1625 int i = 0;
1626 lookup_ctrl_t lc;
1627 uint32_t uid;
1629 if ((obj_type != OBJ_DD) && (obj_type != OBJ_DDS)) {
1630 return (ERR_INVALID_MGMT_REQUEST);
1633 /* prepare lookup ctrl data for looking for the node object */
1634 lc.curr_uid = 0;
1635 lc.type = obj_type;
1636 lc.id[0] = get_lc_id(req->op_info.obj);
1637 lc.op[0] = OP_STRING;
1638 lc.op[1] = 0;
1639 lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */
1640 while (i < req->count) {
1641 if (obj_type == OBJ_DD) {
1642 lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
1643 ret = cache_lookup(&lc, &uid, cb_get_dd_info);
1644 if (uid == 0) {
1645 /* set an error and continue. */
1646 ret = ERR_MATCHING_DD_NOT_FOUND;
1648 } else {
1649 lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
1650 ret = cache_lookup(&lc, &uid, cb_get_ddset_info);
1651 if (uid == 0) {
1652 /* set an error and continue. */
1653 ret = ERR_MATCHING_DDSET_NOT_FOUND;
1656 /* save error for this iteration */
1657 if (ret != 0) {
1658 ret_save = ret;
1660 ret = 0;
1661 i++;
1664 return (handle_partial_success(doc, ret_save));
1668 * ****************************************************************************
1670 * i_delete_ddmember_op:
1671 * serves delete member operatrion on dd.
1673 * container - dd name
1674 * member - node name
1676 * ****************************************************************************
1678 static int
1679 i_delete_ddmember_op(
1680 uchar_t *container,
1681 uchar_t *member
1684 int ret = 0;
1686 isns_assoc_iscsi_t aiscsi;
1687 isns_obj_t *assoc;
1688 isns_attr_t *attr;
1689 int len;
1691 lookup_ctrl_t lc;
1692 uint32_t dd_id;
1694 /* prepare lookup ctrl data for looking for the dd object */
1695 lc.curr_uid = 0;
1696 lc.type = OBJ_DD;
1697 lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
1698 lc.op[0] = OP_STRING;
1699 lc.data[0].ptr = container;
1700 lc.op[1] = 0;
1702 if ((dd_id = is_obj_there(&lc)) != 0) {
1703 aiscsi.type = OBJ_ASSOC_ISCSI;
1704 aiscsi.puid = dd_id;
1706 len = strlen((char *)member) + 1;
1707 len += 4 - (len % 4);
1709 attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
1710 ISNS_DD_ISCSI_NAME_ATTR_ID)];
1711 attr->tag = ISNS_DD_ISCSI_NAME_ATTR_ID;
1712 attr->len = len;
1713 attr->value.ptr = (uchar_t *)member;
1714 attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
1715 ISNS_DD_ISCSI_INDEX_ATTR_ID)];
1716 attr->tag = 0; /* clear it */
1717 assoc = (isns_obj_t *)&aiscsi;
1718 ret = remove_dd_member(assoc);
1719 } else {
1720 ret = ERR_MATCHING_DD_NOT_FOUND;
1723 return (ret);
1727 * ****************************************************************************
1729 * i_delete_ddsetmember_op:
1730 * serves delete member operatrion on dd set.
1732 * container - dd set name
1733 * member - dd name
1735 * ****************************************************************************
1737 static int
1738 i_delete_ddsetmember_op(
1739 uchar_t *container,
1740 uchar_t *member
1743 int ret = 0;
1745 lookup_ctrl_t lc, lc2;
1746 uint32_t container_id, member_id;
1748 /* prepare lookup ctrl data for looking for the dd-set object */
1749 lc.curr_uid = 0;
1750 lc.type = OBJ_DDS;
1751 lc.id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
1752 lc.op[0] = OP_STRING;
1753 lc.data[0].ptr = container;
1754 lc.op[1] = 0;
1756 /* prepare lookup ctrl data for looking for the dd object */
1757 lc2.curr_uid = 0;
1758 lc2.type = OBJ_DD;
1759 lc2.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
1760 lc2.op[0] = OP_STRING;
1761 lc2.data[0].ptr = member;
1762 lc2.op[1] = 0;
1764 if ((container_id = is_obj_there(&lc)) != 0) {
1765 if ((member_id = is_obj_there(&lc2)) != 0) {
1766 ret = remove_dds_member(container_id, member_id);
1767 } else {
1768 ret = ERR_MATCHING_DD_NOT_FOUND;
1770 } else {
1771 ret = ERR_MATCHING_DDSET_NOT_FOUND;
1774 return (ret);
1778 * ****************************************************************************
1780 * get_dd_op:
1781 * service get operation on given dd(s).
1783 * req - contains all info for a request.
1784 * doc - response doc to fill up
1786 * ****************************************************************************
1789 get_dd_op(
1790 request_t *req,
1791 xmlDocPtr doc
1792 /* any additional arguments go here */
1795 return (i_get_dd_dds_op(req, doc, OBJ_DD));
1799 * ****************************************************************************
1801 * get_ddset_op:
1802 * service get operation on given dd set(s).
1804 * req - contains all info for a request.
1805 * doc - response doc to fill up
1807 * ****************************************************************************
1810 get_ddset_op(
1811 request_t *req,
1812 xmlDocPtr doc
1813 /* any additional arguments go here */
1816 return (i_get_dd_dds_op(req, doc, OBJ_DDS));
1820 * ****************************************************************************
1822 * enumerate_node_op:
1823 * services enumerate node op.
1825 * req - contains enumerate request info.
1826 * doc - response doc to fill up
1828 * ****************************************************************************
1831 enumerate_node_op(
1832 xmlDocPtr doc
1833 /* any additional arguments go here */
1836 htab_t *htab = cache_get_htab(OBJ_ISCSI);
1837 uint32_t uid = 0;
1838 lookup_ctrl_t lc;
1839 int ret = 0, ret_save = 0;
1841 SET_UID_LCP(&lc, OBJ_ISCSI, 0);
1843 lc.data[1].ptr = (uchar_t *)doc;
1844 lc.data[2].ui = 0;
1846 FOR_EACH_ITEM(htab, uid, {
1847 lc.data[0].ui = uid;
1848 ret = cache_lookup(&lc, NULL, cb_enumerate_node_info);
1849 if (ret != 0) {
1850 ret_save = ret;
1854 return (handle_partial_success(doc, ret_save));
1858 * ****************************************************************************
1860 * enumerate_dd_op:
1861 * services enumerate discovery domain op.
1863 * req - contains enumerate request info.
1864 * doc - response doc to fill up
1866 * ****************************************************************************
1869 enumerate_dd_op(
1870 xmlDocPtr doc
1871 /* any additional arguments go here */
1875 htab_t *htab = cache_get_htab(OBJ_DD);
1876 uint32_t uid = 0;
1877 lookup_ctrl_t lc;
1878 int ret = 0, ret_save = 0;
1880 SET_UID_LCP(&lc, OBJ_DD, 0);
1882 lc.data[1].ptr = (uchar_t *)doc;
1883 lc.data[2].ui = 0;
1885 FOR_EACH_ITEM(htab, uid, {
1886 lc.data[0].ui = uid;
1887 ret = cache_lookup(&lc, NULL, cb_enumerate_dd_info);
1888 if (ret != 0) {
1889 ret_save = ret;
1893 return (handle_partial_success(doc, ret_save));
1897 * ****************************************************************************
1899 * enumerate_ddset_op:
1900 * services enumerate discovery domain set op.
1902 * req - contains enumerate request info.
1903 * doc - response doc to fill up
1905 * ****************************************************************************
1908 enumerate_ddset_op(
1909 xmlDocPtr doc
1910 /* any additional arguments go here */
1913 htab_t *htab = cache_get_htab(OBJ_DDS);
1914 uint32_t uid = 0;
1915 lookup_ctrl_t lc;
1916 int ret = 0, ret_save = 0;
1918 SET_UID_LCP(&lc, OBJ_DDS, 0);
1920 lc.data[1].ptr = (uchar_t *)doc;
1921 lc.data[2].ui = 0;
1923 FOR_EACH_ITEM(htab, uid, {
1924 lc.data[0].ui = uid;
1925 ret = cache_lookup(&lc, NULL, cb_enumerate_ddset_info);
1926 if (ret != 0) {
1927 ret_save = ret;
1931 return (handle_partial_success(doc, ret_save));
1935 * ****************************************************************************
1937 * getassociated_dd_to_node_op:
1938 * construct a list of node that is associated with a given Discovery
1939 * Domain.
1941 * req - contains getAssociated request info.
1942 * doc - response doc to fill up
1944 * ****************************************************************************
1947 getAssociated_dd_to_node_op(
1948 request_t *req,
1949 xmlDocPtr doc
1950 /* any additional arguments go here */
1953 uint32_t uid = 0, n;
1954 lookup_ctrl_t lc, lc2;
1955 int i = 0, ret = 0, ret_save = 0;
1956 bmp_t *p;
1958 lc.curr_uid = 0;
1959 lc.type = OBJ_DD;
1960 lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
1961 lc.op[0] = OP_STRING;
1962 lc.op[1] = 0;
1964 SET_UID_LCP(&lc2, OBJ_ISCSI, 0);
1966 lc2.data[1].ptr = (uchar_t *)doc;
1968 while (i < req->count) {
1969 lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
1970 if ((uid = is_obj_there(&lc)) != 0) {
1971 ret = get_dd_matrix(uid, &p, &n);
1972 FOR_EACH_MEMBER(p, n, uid, {
1973 lc2.data[0].ui = uid;
1974 lc2.data[2].ptr = (uchar_t *)req->req_data.data[i];
1975 ret = cache_lookup(&lc2, NULL,
1976 cb_getAssociated_node_info);
1978 free(p);
1979 } else {
1980 ret = ERR_MATCHING_DD_NOT_FOUND;
1982 /* save error for this iteration */
1983 if (ret != 0) {
1984 ret_save = ret;
1986 ret = 0;
1987 i++;
1990 return (handle_partial_success(doc, ret_save));
1994 * ****************************************************************************
1996 * getassociated_node_to_dd_op:
1997 * construct a list of Discovery Doamins that is associated with a given
1998 * node.
2000 * req - contains getAssociated request info.
2001 * doc - response doc to fill up
2003 * ****************************************************************************
2006 getAssociated_node_to_dd_op(
2007 request_t *req,
2008 xmlDocPtr doc
2009 /* any additional arguments go here */
2012 uint32_t uid = 0, dd_id;
2013 lookup_ctrl_t lc, lc2;
2014 int i = 0, ret = 0, ret_save = 0;
2016 lc.curr_uid = 0;
2017 lc.type = OBJ_ISCSI;
2018 lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
2019 lc.op[0] = OP_STRING;
2020 lc.op[1] = 0;
2022 SET_UID_LCP(&lc2, OBJ_DD, 0);
2024 lc2.data[1].ptr = (uchar_t *)doc;
2026 while (i < req->count) {
2027 lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
2028 if ((uid = is_obj_there(&lc)) != 0) {
2029 if ((dd_id = get_dd_id(uid, 0)) == 0) {
2030 ret = ERR_NO_ASSOCIATED_DD_FOUND;
2031 i++;
2032 continue;
2033 } else {
2034 do {
2035 lc2.data[0].ui = dd_id;
2036 lc2.data[2].ptr = (uchar_t *)req->req_data.data[i];
2037 ret = cache_lookup(&lc2, NULL,
2038 cb_getAssociated_node_to_dd_info);
2039 dd_id = get_dd_id(uid, dd_id);
2040 } while (dd_id != 0);
2042 } else {
2043 ret = ERR_MATCHING_NODE_NOT_FOUND;
2045 /* save error for this iteration */
2046 if (ret != 0) {
2047 ret_save = ret;
2049 ret = 0;
2050 i++;
2053 return (handle_partial_success(doc, ret_save));
2057 * ****************************************************************************
2059 * getassociated_ddset_to_dd_op:
2060 * construct a list of Discovery Doamins that is associated with a given
2061 * Discover Domain set.
2063 * req - contains getAssociated request info.
2064 * doc - response doc to fill up
2066 * ****************************************************************************
2069 getAssociated_ddset_to_dd_op(
2070 request_t *req,
2071 xmlDocPtr doc
2072 /* any additional arguments go here */
2075 uint32_t uid = 0, n;
2076 lookup_ctrl_t lc, lc2;
2077 int i = 0, ret = 0, ret_save = 0;
2078 bmp_t *p;
2080 lc.curr_uid = 0;
2081 lc.type = OBJ_DDS;
2082 lc.id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
2083 lc.op[0] = OP_STRING;
2084 lc.op[1] = 0;
2086 SET_UID_LCP(&lc2, OBJ_DD, 0);
2088 lc2.data[1].ptr = (uchar_t *)doc;
2090 while (i < req->count) {
2091 lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
2092 if ((uid = is_obj_there(&lc)) != 0) {
2093 ret = get_dds_matrix(uid, &p, &n);
2094 FOR_EACH_MEMBER(p, n, uid, {
2095 lc2.data[0].ui = uid;
2096 lc2.data[2].ptr = (uchar_t *)req->req_data.data[i];
2097 ret = cache_lookup(&lc2, NULL,
2098 cb_getAssociated_dd_info);
2100 free(p);
2101 } else {
2102 ret = ERR_MATCHING_DDSET_NOT_FOUND;
2104 /* save error for this iteration */
2105 if (ret != 0) {
2106 ret_save = ret;
2108 ret = 0;
2109 i++;
2112 return (handle_partial_success(doc, ret_save));
2116 * ****************************************************************************
2118 * getassociated_dd_to_ddset_op:
2119 * construct a list of Discovery Doamin sets that is associated with a
2120 * given Discovery Domain.
2122 * req - contains getAssociated request info.
2123 * doc - response doc to fill up
2125 * ****************************************************************************
2128 getAssociated_dd_to_ddset_op(
2129 request_t *req,
2130 xmlDocPtr doc
2131 /* any additional arguments go here */
2134 uint32_t uid = 0, ddset_id;
2135 lookup_ctrl_t lc, lc2;
2136 int i = 0, ret = 0, ret_save = 0;
2138 lc.curr_uid = 0;
2139 lc.type = OBJ_DD;
2140 lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
2141 lc.op[0] = OP_STRING;
2142 lc.op[1] = 0;
2144 SET_UID_LCP(&lc2, OBJ_DDS, 0);
2146 lc2.data[1].ptr = (uchar_t *)doc;
2148 while (i < req->count) {
2149 lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
2150 if ((uid = is_obj_there(&lc)) != 0) {
2151 lc2.data[2].ui = 0;
2152 if ((ddset_id = get_dds_id(uid, 0)) == 0) {
2153 ret = ERR_NO_ASSOCIATED_DDSET_FOUND;
2154 i++;
2155 continue;
2156 } else {
2157 do {
2158 lc2.data[0].ui = ddset_id;
2159 lc2.data[2].ptr = (uchar_t *)req->req_data.data[i];
2160 ret = cache_lookup(&lc2, NULL,
2161 cb_getAssociated_dd_to_ddset_info);
2162 ddset_id = get_dds_id(uid, ddset_id);
2163 } while (ddset_id != 0);
2165 } else {
2166 ret = ERR_MATCHING_DD_NOT_FOUND;
2168 if (ret != 0) {
2169 ret_save = ret;
2171 i++;
2174 return (handle_partial_success(doc, ret_save));
2178 * ****************************************************************************
2180 * delete_dd_ddset_op:
2181 * removes a list of dd or dd set.
2183 * req - contains delete request info.
2184 * doc - response doc to fill up
2185 * obj_type - object type(either dd or dd set)
2187 * ****************************************************************************
2190 delete_dd_ddset_op(
2191 request_t *req,
2192 xmlDocPtr doc,
2193 object_type type
2194 /* any additional arguments go here */
2197 result_code_t ret = 0, ret_save = 0;
2198 isns_type_t lc_type;
2199 int i = 0, err_count = 0;
2200 lookup_ctrl_t lc;
2201 uint32_t uid;
2202 xmlNodePtr n_obj, n_node, root;
2203 xmlAttrPtr n_attr;
2204 int different_err = 0;
2206 root = xmlDocGetRootElement(doc);
2207 if (root == NULL) {
2208 return (ERR_SYNTAX_MISSING_ROOT);
2210 lc_type = get_lc_type(type);
2211 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2212 return (ERR_INVALID_MGMT_REQUEST);
2215 /* prepare lookup ctrl data for looking for the node object */
2216 lc.curr_uid = 0;
2217 lc.type = lc_type;
2218 lc.id[0] = get_lc_id(req->op_info.obj);
2219 lc.op[0] = OP_STRING;
2220 lc.op[1] = 0;
2221 lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */
2222 while (i < req->count) {
2223 lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
2225 /* lock the cache for writing */
2226 (void) cache_lock_write();
2228 if ((uid = is_obj_there(&lc)) != 0) {
2229 /* remove the dd/ddset */
2230 ret = (lc_type == OBJ_DD) ?
2231 remove_dd_object(uid) :
2232 remove_dds_object(uid);
2233 /* unlock the cache and sync the data */
2234 ret = cache_unlock_sync(ret);
2235 } else {
2236 /* unlock the cache and no need to sync data */
2237 (void) cache_unlock_nosync();
2238 /* set an error and continue. */
2239 ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND :
2240 ERR_MATCHING_DDSET_NOT_FOUND;
2243 if (ret != 0) {
2244 /* keep track if there are different errors encountered. */
2245 if (ret_save != 0 && ret != ret_save) {
2246 different_err++;
2248 err_count++;
2249 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
2250 if (n_obj) {
2251 if ((n_obj = xmlAddChild(root, n_obj)) == NULL) {
2252 return (ERR_XML_ADDCHILD_FAILED);
2254 } else {
2255 return (ERR_XML_NEWNODE_FAILED);
2258 n_node = (lc_type == OBJ_DD) ?
2259 xmlNewNode(NULL, (xmlChar *)DDOBJECT) :
2260 xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
2261 if (n_node) {
2262 if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) {
2263 return (ERR_XML_ADDCHILD_FAILED);
2265 n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
2266 (xmlChar *)req->req_data.data[i]);
2267 if (n_attr == NULL) {
2268 return (ERR_XML_SETPROP_FAILED);
2270 } else {
2271 return (ERR_XML_NEWNODE_FAILED);
2273 ret_save = ret;
2275 i ++;
2278 return (handle_partial_failure(doc, ret_save,
2279 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2283 * ****************************************************************************
2285 * delete_ddmember_ddsetmember_op:
2286 * removes a list of dd memeber or dd seti member.
2288 * req - contains delete request info.
2289 * doc - response doc to fill up
2290 * type - object type(either dd or dd set)
2292 * ****************************************************************************
2295 delete_ddmember_ddsetmember_op(
2296 request_t *req,
2297 xmlDocPtr doc,
2298 object_type type
2299 /* any additional arguments go here */
2302 result_code_t ret = 0, ret_save = 0;
2303 isns_type_t lc_type;
2304 int i = 0, err_count = 0;
2305 lookup_ctrl_t lc, lc2;
2306 uint32_t container_id, member_id;
2307 xmlNodePtr n_node, n_obj, root;
2308 xmlAttrPtr n_attr;
2309 int different_err = 0;
2310 int is_a_member;
2312 lc_type = get_lc_type(type);
2313 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2314 return (ERR_INVALID_MGMT_REQUEST);
2317 /* prepare lookup ctrl data for looking for the node object */
2318 lc.curr_uid = 0;
2319 lc.type = lc_type;
2320 lc.id[0] = get_lc_id(req->op_info.obj);
2321 lc.op[0] = OP_STRING;
2322 lc.op[1] = 0;
2324 lc2.curr_uid = 0;
2325 if (lc_type == OBJ_DD) {
2326 lc2.type = OBJ_ISCSI;
2327 lc2.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
2328 } else {
2329 lc2.type = OBJ_DD;
2330 lc2.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
2332 lc2.op[0] = OP_STRING;
2333 lc2.op[1] = 0;
2335 root = xmlDocGetRootElement(doc);
2336 if (root == NULL) {
2337 return (ERR_SYNTAX_MISSING_ROOT);
2340 while (i < req->count) {
2341 lc.data[0].ptr = (uchar_t *)req->req_data.pair[i]->container;
2343 /* get the dd_id/dds_id */
2344 (void) cache_lock_write();
2345 container_id = is_obj_there(&lc);
2347 if (container_id != 0) {
2348 lc2.data[0].ptr = (uchar_t *)req->req_data.pair[i]->member;
2350 member_id = is_obj_there(&lc2);
2351 if (member_id != 0) {
2352 is_a_member =
2353 (container_id ==
2354 ((lc_type == OBJ_DD) ?
2355 get_dd_id(member_id, container_id - 1) :
2356 get_dds_id(member_id, container_id - 1)));
2358 if (member_id != 0 && is_a_member != 0) {
2359 /* delete the dd member */
2360 ret = (lc_type == OBJ_DD) ?
2361 i_delete_ddmember_op(
2362 (uchar_t *)req->req_data.pair[i]->container,
2363 (uchar_t *)req->req_data.pair[i]->member) :
2364 i_delete_ddsetmember_op(
2365 (uchar_t *)req->req_data.pair[i]->container,
2366 (uchar_t *)req->req_data.pair[i]->member);
2367 /* unlock the cache and sync the data */
2368 ret = cache_unlock_sync(ret);
2369 } else {
2370 /* unlock the cache and no need to sync */
2371 (void) cache_unlock_nosync();
2372 ret = ERR_NO_SUCH_ASSOCIATION;
2374 } else {
2375 /* unlock the cache and no need to sync */
2376 (void) cache_unlock_nosync();
2377 ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND :
2378 ERR_MATCHING_DDSET_NOT_FOUND;
2381 if (ret != 0) {
2382 /* keep track if there are different errors encountered. */
2383 if (ret_save != 0 && ret != ret_save) {
2384 different_err++;
2386 ret_save = ret;
2387 err_count++;
2388 n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
2389 if (n_obj) {
2390 n_obj = xmlAddChild(root, n_obj);
2391 if (n_obj == NULL) {
2392 return (ERR_XML_ADDCHILD_FAILED);
2394 } else {
2395 return (ERR_XML_NEWNODE_FAILED);
2397 if (lc_type == OBJ_DD) {
2398 n_node =
2399 xmlNewNode(NULL, (xmlChar *)DDOBJECTMEMBER);
2400 n_attr = xmlSetProp(n_node, (xmlChar *)NODENAMEATTR,
2401 (xmlChar *)req->req_data.pair[i]->member);
2402 if (n_attr == NULL) {
2403 return (ERR_XML_SETPROP_FAILED);
2405 n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
2406 (xmlChar *)req->req_data.pair[i]->container);
2407 if (n_attr == NULL) {
2408 return (ERR_XML_SETPROP_FAILED);
2410 } else {
2411 n_node =
2412 xmlNewNode(NULL, (xmlChar *)DDSETOBJECTMEMBER);
2413 n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
2414 (xmlChar *)req->req_data.pair[i]->member);
2415 if (n_attr == NULL) {
2416 return (ERR_XML_SETPROP_FAILED);
2418 n_attr = xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR,
2419 (xmlChar *)req->req_data.pair[i]->container);
2420 if (n_attr == NULL) {
2421 return (ERR_XML_SETPROP_FAILED);
2424 if (xmlAddChild(n_obj, n_node) == NULL) {
2425 return (ERR_XML_ADDCHILD_FAILED);
2428 i++;
2431 return (handle_partial_failure(doc, ret_save,
2432 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2436 * ****************************************************************************
2438 * create_ddmember_ddsetmember_op:
2439 * removes a list of dd memeber or dd seti member.
2441 * req - contains delete request info.
2442 * doc - response doc to fill up
2443 * type - object type(either dd or dd set)
2445 * ****************************************************************************
2448 create_ddmember_ddsetmember_op(
2449 request_t *req,
2450 xmlDocPtr doc,
2451 object_type type
2452 /* any additional arguments go here */
2455 result_code_t ret = 0, ret_save = 0;
2456 isns_type_t lc_type;
2457 int i = 0, err_count = 0;
2458 lookup_ctrl_t lc, lc2;
2459 uint32_t container_id, member_id;
2460 xmlNodePtr n_node, n_obj, root;
2461 isns_assoc_iscsi_t aiscsi = { 0 };
2462 isns_assoc_dd_t add = { 0 };
2463 isns_obj_t *assoc;
2464 isns_attr_t *attr;
2465 uint32_t len;
2466 int different_err = 0;
2468 lc_type = get_lc_type(type);
2469 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2470 return (ERR_INVALID_MGMT_REQUEST);
2473 /* prepare lookup ctrl data for looking for the node object */
2474 lc.curr_uid = 0;
2475 lc.type = lc_type;
2476 lc.id[0] = get_lc_id(req->op_info.obj);
2477 lc.op[0] = OP_STRING;
2478 lc.op[1] = 0;
2480 lc2.curr_uid = 0;
2481 if (lc_type == OBJ_DD) {
2482 lc2.type = OBJ_ISCSI;
2483 lc2.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
2484 } else {
2485 lc2.type = OBJ_DD;
2486 lc2.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
2488 lc2.op[0] = OP_STRING;
2489 lc2.op[1] = 0;
2491 root = xmlDocGetRootElement(doc);
2492 if (root == NULL) {
2493 return (ERR_SYNTAX_MISSING_ROOT);
2496 while (i < req->count) {
2497 lc.data[0].ptr = (uchar_t *)req->req_data.pair[i]->container;
2499 /* get the dd_id/dds_id */
2500 (void) cache_lock_write();
2501 container_id = is_obj_there(&lc);
2503 if (container_id != 0) {
2504 (void) memset(&aiscsi, 0, sizeof (aiscsi));
2505 if (lc_type == OBJ_DD) {
2506 aiscsi.puid = container_id;
2507 aiscsi.type = OBJ_ASSOC_ISCSI;
2508 attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
2509 ISNS_DD_ISCSI_NAME_ATTR_ID)];
2510 attr->tag = ISNS_DD_ISCSI_NAME_ATTR_ID;
2511 len = xmlStrlen(
2512 (xmlChar *)req->req_data.pair[i]->member) + 1;
2513 len += 4 - (len % 4); /* on 4 bytes aligned */
2514 attr->len = len;
2515 attr->value.ptr =
2516 (uchar_t *)req->req_data.pair[i]->member;
2517 assoc = (isns_obj_t *)&aiscsi;
2519 /* add the dd member */
2520 ret = add_dd_member(assoc);
2522 /* unlock the cache and sync the data */
2523 ret = cache_unlock_sync(ret);
2524 } else {
2525 lc2.data[0].ptr =
2526 (uchar_t *)req->req_data.pair[i]->member;
2528 if ((member_id = is_obj_there(&lc2)) != 0) {
2529 add.puid = container_id;
2530 add.type = OBJ_ASSOC_DD;
2531 attr = &add.attrs[ATTR_INDEX_ASSOC_DD(
2532 ISNS_DD_ID_ATTR_ID)];
2533 attr->tag = ISNS_DD_ID_ATTR_ID;
2534 attr->len = 4;
2535 attr->value.ui = member_id;
2536 assoc = (isns_obj_t *)&add;
2538 /* add the dd-set member */
2539 ret = add_dds_member(assoc);
2541 /* unlock the cache and sync the data */
2542 ret = cache_unlock_sync(ret);
2543 } else {
2544 /* unlock the cache and no need to sync */
2545 (void) cache_unlock_nosync();
2546 ret = ERR_MATCHING_DD_NOT_FOUND;
2549 } else {
2550 /* unlock the cache and no need to sync */
2551 (void) cache_unlock_nosync();
2552 ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND :
2553 ERR_MATCHING_DDSET_NOT_FOUND;
2555 if (ret != 0) {
2556 /* keep track if there are different errors encountered. */
2557 if (ret_save != 0 && ret != ret_save) {
2558 different_err++;
2560 err_count++;
2561 n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
2562 if (n_obj) {
2563 n_obj = xmlAddChild(root, n_obj);
2564 if (n_obj == NULL) {
2565 return (ERR_XML_ADDCHILD_FAILED);
2567 } else {
2568 return (ERR_XML_NEWNODE_FAILED);
2570 if (lc_type == OBJ_DD) {
2571 n_node =
2572 xmlNewNode(NULL, (xmlChar *)DDOBJECTMEMBER);
2573 if (xmlSetProp(n_node, (xmlChar *)NODENAMEATTR,
2574 (xmlChar *)req->req_data.pair[i]->member) == NULL) {
2575 return (ERR_XML_SETPROP_FAILED);
2577 if (xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
2578 (xmlChar *)req->req_data.pair[i]->container) ==
2579 NULL) {
2580 return (ERR_XML_SETPROP_FAILED);
2582 } else {
2583 n_node =
2584 xmlNewNode(NULL, (xmlChar *)DDSETOBJECTMEMBER);
2585 if (xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
2586 (xmlChar *)req->req_data.pair[i]->member) == NULL) {
2587 return (ERR_XML_SETPROP_FAILED);
2589 if (xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR,
2590 (xmlChar *)req->req_data.pair[i]->container) ==
2591 NULL) {
2592 return (ERR_XML_SETPROP_FAILED);
2595 if (xmlAddChild(n_obj, n_node) == NULL) {
2596 return (ERR_XML_ADDCHILD_FAILED);
2598 ret_save = ret;
2600 i++;
2603 return (handle_partial_failure(doc, ret_save,
2604 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2608 * ****************************************************************************
2610 * rename_dd_ddset_op:
2611 * removes a list of dd memeber or dd seti member.
2613 * req - contains delete request info.
2614 * doc - response doc to fill up
2615 * type - object type(either dd or dd set)
2617 * ****************************************************************************
2619 static int
2620 rename_dd_ddset_op(
2621 request_t *req,
2622 xmlDocPtr doc,
2623 object_type type
2624 /* any additional arguments go here */
2627 result_code_t ret = 0, ret_save = 0;
2628 isns_type_t lc_type;
2629 int i = 0, err_count = 0;
2630 lookup_ctrl_t lc;
2631 uint32_t container_id;
2632 xmlNodePtr n_node, n_obj, root;
2633 uchar_t *name;
2634 uint32_t len;
2635 int different_err = 0;
2637 lc_type = get_lc_type(type);
2638 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2639 return (ERR_INVALID_MGMT_REQUEST);
2642 /* prepare lookup ctrl data for looking for the node object */
2643 SET_UID_LCP(&lc, lc_type, 0);
2645 root = xmlDocGetRootElement(doc);
2646 if (root == NULL) {
2647 return (ERR_SYNTAX_MISSING_ROOT);
2650 while (i < req->count) {
2651 /* id is checked to be not NULL before calling this routine. */
2652 lc.data[0].ui = *(req->req_data.attrlist[i]->id);
2654 /* get the dd_id/dds_id */
2655 (void) cache_lock_write();
2657 if ((container_id = is_obj_there(&lc)) != 0) {
2658 name = (uchar_t *)req->req_data.attrlist[i]->name;
2659 /* the length of the name need to include the */
2660 /* null terminator and be on 4 bytes aligned */
2661 len = xmlStrlen(name) + 1;
2662 len += 4 - (len % 4);
2664 /* rename the dd/dds */
2665 ret = (lc_type == OBJ_DD) ?
2666 update_dd_name(container_id, len, name) :
2667 update_dds_name(container_id, len, name);
2669 /* release the lock and sync the data */
2670 ret = cache_unlock_sync(ret);
2671 } else {
2672 /* release the lock and no need to sync */
2673 (void) cache_unlock_nosync();
2674 ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND :
2675 ERR_MATCHING_DDSET_NOT_FOUND;
2677 if (ret != 0) {
2678 /* keep track if there are different errors encountered. */
2679 if (ret_save != 0 && ret != ret_save) {
2680 different_err++;
2682 ret_save = ret;
2683 err_count++;
2684 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
2685 if (n_obj) {
2686 if ((n_obj = xmlAddChild(root, n_obj)) == NULL) {
2687 return (ERR_XML_ADDCHILD_FAILED);
2689 } else {
2690 return (ERR_XML_NEWNODE_FAILED);
2693 n_node = (lc_type == OBJ_DD) ?
2694 xmlNewNode(NULL, (xmlChar *)DDOBJECT) :
2695 xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
2696 if (n_node) {
2697 if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) {
2698 return (ERR_XML_ADDCHILD_FAILED);
2699 } else {
2700 if (xmlSetProp(n_node, (xmlChar *)NAMEATTR,
2701 (xmlChar *)req->req_data.attrlist[i]->name) ==
2702 NULL) {
2703 return (ERR_XML_SETPROP_FAILED);
2706 } else {
2707 return (ERR_XML_NEWNODE_FAILED);
2711 i++;
2714 return (handle_partial_failure(doc, ret_save,
2715 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2719 * ****************************************************************************
2721 * update_dd_ddset_op:
2722 * removes a list of dd memeber or dd seti member.
2724 * req - contains delete request info.
2725 * doc - response doc to fill up
2726 * type - object type(either dd or dd set)
2728 * ****************************************************************************
2730 static int
2731 update_dd_ddset_op(
2732 request_t *req,
2733 xmlDocPtr doc,
2734 object_type type
2735 /* any additional arguments go here */
2738 result_code_t ret = 0, ret_save = 0;
2739 isns_type_t lc_type;
2740 int i = 0, err_count = 0;
2741 lookup_ctrl_t lc;
2742 uint32_t container_id;
2743 xmlNodePtr n_node, n_obj, root;
2744 int different_err = 0;
2746 lc_type = get_lc_type(type);
2747 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2748 return (ERR_INVALID_MGMT_REQUEST);
2751 /* prepare lookup ctrl data for looking for the node object */
2752 lc.curr_uid = 0;
2753 lc.type = lc_type;
2754 lc.id[0] = get_lc_id(req->op_info.obj);
2755 lc.op[0] = OP_STRING;
2756 lc.op[1] = 0;
2758 root = xmlDocGetRootElement(doc);
2759 if (root == NULL) {
2760 return (ERR_SYNTAX_MISSING_ROOT);
2763 while (i < req->count) {
2764 lc.data[0].ptr = req->req_data.attrlist[i]->name;
2766 /* lock the cache for writing */
2767 (void) cache_lock_write();
2769 if ((container_id = is_obj_there(&lc)) != 0) {
2770 ret = (lc_type == OBJ_DD) ?
2771 /* enabled is checked to be not NULL before calling. */
2772 update_dd_features(container_id,
2773 *(req->req_data.attrlist[i]->enabled) ? 1 : 0):
2774 update_dds_status(container_id,
2775 *(req->req_data.attrlist[i]->enabled) ? 1 : 0);
2776 /* unlock the cache and sync the data */
2777 ret = cache_unlock_sync(ret);
2778 } else {
2779 (void) cache_unlock_nosync();
2780 ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND :
2781 ERR_MATCHING_DDSET_NOT_FOUND;
2783 if (ret != 0) {
2784 /* keep track if there are different errors encountered. */
2785 if (ret_save != 0 && ret != ret_save) {
2786 different_err++;
2788 ret_save = ret;
2789 err_count++;
2790 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
2791 if (n_obj) {
2792 if ((n_obj = xmlAddChild(root, n_obj)) == NULL) {
2793 return (ERR_XML_ADDCHILD_FAILED);
2795 } else {
2796 return (ERR_XML_NEWNODE_FAILED);
2799 n_node = (lc_type == OBJ_DD) ?
2800 xmlNewNode(NULL, (xmlChar *)DDOBJECT) :
2801 xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
2802 if (n_node) {
2803 if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) {
2804 return (ERR_XML_ADDCHILD_FAILED);
2805 } else {
2806 if (xmlSetProp(n_node, (xmlChar *)NAMEATTR,
2807 (xmlChar *)req->req_data.attrlist[i]->name) ==
2808 NULL) {
2809 return (ERR_XML_SETPROP_FAILED);
2812 } else {
2813 return (ERR_XML_NEWNODE_FAILED);
2816 i++;
2819 return (handle_partial_failure(doc, ret_save,
2820 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2824 * ****************************************************************************
2826 * createModify_dd_ddset_op:
2827 * removes a list of dd memeber or dd seti member.
2829 * req - contains delete request info.
2830 * doc - response doc to fill up
2832 * ****************************************************************************
2834 static int
2835 create_dd_ddset_op(
2836 request_t *req,
2837 xmlDocPtr doc,
2838 object_type type
2839 /* any additional arguments go here */
2842 isns_obj_t *obj;
2843 result_code_t ret = 0, ret_save = 0;
2844 isns_type_t lc_type;
2845 lookup_ctrl_t lc;
2846 uint32_t uid;
2847 int i = 0, err_count = 0;
2848 xmlNodePtr n_obj, n_node, root;
2849 int different_err = 0;
2851 lc_type = get_lc_type(type);
2852 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2853 return (ERR_INVALID_MGMT_REQUEST);
2856 root = xmlDocGetRootElement(doc);
2857 if (root == NULL) {
2858 return (ERR_SYNTAX_MISSING_ROOT);
2860 lc_type = get_lc_type(type);
2861 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2862 return (ERR_INVALID_MGMT_REQUEST);
2865 /* prepare lookup ctrl data for looking for the node object */
2866 lc.curr_uid = 0;
2867 lc.type = lc_type;
2868 lc.id[0] = get_lc_id(req->op_info.obj);
2869 lc.op[0] = OP_STRING;
2870 lc.op[1] = 0;
2871 lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */
2872 while (i < req->count) {
2873 lc.data[0].ptr = req->req_data.attrlist[i]->name,
2874 /* grab the write lock */
2875 (void) cache_lock_write();
2877 uid = is_obj_there(&lc);
2878 if (uid == 0) {
2879 ret = (lc_type == OBJ_DD) ?
2880 adm_create_dd(&obj, req->req_data.attrlist[i]->name,
2881 0, 0) :
2882 adm_create_dds(&obj, req->req_data.attrlist[i]->name,
2883 0, 0);
2884 if (ret == 0) {
2885 ret = register_object(obj, NULL, NULL);
2886 if (ret != 0) {
2887 free_object(obj);
2889 /* release the lock and sync the cache and data store */
2890 ret = cache_unlock_sync(ret);
2892 } else {
2893 /* release the lock and no need to sync the data */
2894 (void) cache_unlock_nosync();
2895 ret = ERR_NAME_IN_USE;
2898 if (ret != 0) {
2899 /* keep track if there are different errors encountered. */
2900 if (ret_save != 0 && ret != ret_save) {
2901 different_err++;
2903 ret_save = ret;
2904 err_count++;
2905 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
2906 if (n_obj) {
2907 if ((n_obj = xmlAddChild(root, n_obj)) == NULL) {
2908 return (ERR_XML_ADDCHILD_FAILED);
2910 } else {
2911 return (ERR_XML_ADDCHILD_FAILED);
2914 n_node = (lc_type == OBJ_DD) ?
2915 xmlNewNode(NULL, (xmlChar *)DDOBJECT) :
2916 xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
2917 if (n_node) {
2918 if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) {
2919 return (ERR_XML_ADDCHILD_FAILED);
2920 } else {
2921 if (xmlSetProp(n_node, (xmlChar *)NAMEATTR,
2922 (xmlChar *)req->req_data.attrlist[i]->name) ==
2923 NULL) {
2924 return (ERR_XML_SETPROP_FAILED);
2927 } else {
2928 return (ERR_XML_NEWNODE_FAILED);
2931 i++;
2934 return (handle_partial_failure(doc, ret_save,
2935 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2939 * ****************************************************************************
2941 * createModify_dd_ddset_op:
2942 * removes a list of dd memeber or dd seti member.
2944 * req - contains delete request info.
2945 * doc - response doc to fill up
2947 * ****************************************************************************
2950 createModify_dd_ddset_op(
2951 request_t *req,
2952 xmlDocPtr doc
2953 /* any additional arguments go here */
2956 result_code_t ret = 0;
2958 if (req->req_data.attrlist[0]->id != NULL) {
2959 ret = rename_dd_ddset_op(req, doc, req->op_info.obj);
2960 } else if (req->req_data.attrlist[0]->enabled != NULL) {
2961 ret = update_dd_ddset_op(req, doc, req->op_info.obj);
2962 } else {
2963 ret = create_dd_ddset_op(req, doc, req->op_info.obj);
2966 return (ret);