1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <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>
38
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"
49
50 extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
51
52 static isns_type_t
get_lc_type(object_type obj)53 get_lc_type(
54 object_type obj
55 )
56 {
57 isns_type_t type;
58
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;
74 }
75
76 return (type);
77 }
78
79 static uint32_t
get_lc_id(object_type obj)80 get_lc_id(
81 object_type obj
82 )
83 {
84 uint32_t id;
85
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;
101 }
102
103 return (id);
104 }
105
106 /*
107 * ****************************************************************************
108 *
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.
112 *
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
117 *
118 * ****************************************************************************
119 */
120 static int
cb_get_node_info(void * p1,void * p2)121 cb_get_node_info(
122 void *p1,
123 void *p2
124 )
125 {
126 xmlNodePtr n_obj, n_node, sub_node, root;
127 xmlAttrPtr n_attr;
128 isns_attr_t *attr;
129
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;
133
134 root = xmlDocGetRootElement(doc);
135 if (root == NULL) {
136 return (ERR_XML_ADDCHILD_FAILED);
137 }
138
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);
144 }
145 } else {
146 return (ERR_XML_ADDCHILD_FAILED);
147 }
148
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);
154 }
155 } else {
156 return (ERR_XML_ADDCHILD_FAILED);
157 }
158
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);
165 }
166
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);
192 }
193 if (n_attr == NULL) {
194 return (ERR_XML_SETPROP_FAILED);
195 }
196
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);
202 }
203
204 /*
205 * A node can have all or no SCN subsribtion.
206 * May avoid redundant code with scsusrciption table.
207 */
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);
214 }
215 }
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);
221 }
222 }
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);
228 }
229 }
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);
235 }
236 }
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);
242 }
243 }
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);
249 }
250 }
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);
256 }
257 }
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);
263 }
264 }
265
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;
270
271 /* successful */
272 return (0);
273 }
274
275 /*
276 * ****************************************************************************
277 *
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.
281 *
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
286 *
287 * ****************************************************************************
288 */
289 static int
cb_get_entity_info(void * p1,void * p2)290 cb_get_entity_info(
291 void *p1,
292 void *p2
293 )
294 {
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;
302
303 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)NETWORKENTITY, NULL);
304
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);
311 }
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);
318 }
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)));
338 }
339 if (subchild_node == NULL) {
340 return (ERR_XML_NEWCHILD_FAILED);
341 }
342 }
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);
350 }
351 }
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);
359 }
360
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);
367 }
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);
373 }
374 }
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);
383 }
384 }
385 } else {
386 return (ERR_XML_NEWCHILD_FAILED);
387 }
388
389 /* successful */
390 return (0);
391 }
392
393 /*
394 * ****************************************************************************
395 *
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.
399 *
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
404 *
405 * ****************************************************************************
406 */
407 static int
cb_get_pg_info(void * p1,void * p2)408 cb_get_pg_info(
409 void *p1,
410 void *p2
411 )
412 {
413 isns_obj_t *obj = (isns_obj_t *)p1;
414 lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
415
416 isns_attr_t *attr;
417
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;
425
426 /* successful */
427 return (0);
428 }
429
430 /*
431 * ****************************************************************************
432 *
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.
436 *
437 * p1 - matching portal object
438 * p2 - lookup control data that was used for portal look up
439 * return - error code
440 *
441 * ****************************************************************************
442 */
443 static int
cb_get_portal_info(void * p1,void * p2)444 cb_get_portal_info(
445 void *p1,
446 void *p2
447 )
448 {
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;
457
458 sub_node = xmlNewChild(n_node, NULL, (xmlChar *)PORTAL, NULL);
459
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)));
481 }
482 if (subchild_node == NULL) {
483 return (ERR_XML_NEWCHILD_FAILED);
484 }
485 }
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);
495 }
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);
501 }
502 } else {
503 return (ERR_XML_NEWCHILD_FAILED);
504 }
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);
510 }
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);
517 }
518 }
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);
526 }
527 }
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);
538 }
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);
544 }
545 } else {
546 return (ERR_XML_NEWCHILD_FAILED);
547 }
548 }
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);
560 }
561 subgrandchild_node = xmlNewChild(subchild_node, NULL,
562 (xmlChar *)PORTNUMBER, (xmlChar *)numbuf);
563 if (subgrandchild_node == NULL) {
564 return (ERR_XML_NEWCHILD_FAILED);
565 }
566 } else {
567 return (ERR_XML_NEWCHILD_FAILED);
568 }
569 }
570 } else if (sub_node == NULL) {
571 return (ERR_XML_NEWCHILD_FAILED);
572 }
573
574 /* successful */
575 return (0);
576 }
577
578 /*
579 * ****************************************************************************
580 *
581 * cb_get_dd_info: callback for get_dd_op
582 * The routine process matching dd object
583 *
584 * p1 - matching dd object
585 * p2 - lookup control data that was used for dd look up
586 * return - error code
587 *
588 * ****************************************************************************
589 */
590 static int
cb_get_dd_info(void * p1,void * p2)591 cb_get_dd_info(
592 void *p1,
593 void *p2
594 )
595 {
596 xmlNodePtr n_obj, n_node, sub_node, root;
597 xmlAttrPtr n_attr;
598 isns_attr_t *attr;
599 char numbuf[32];
600
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;
604
605 root = xmlDocGetRootElement(doc);
606 if (root == NULL) {
607 return (ERR_SYNTAX_MISSING_ROOT);
608 }
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);
614 }
615 } else {
616 return (ERR_XML_ADDCHILD_FAILED);
617 }
618
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);
624 }
625 } else {
626 return (ERR_XML_ADDCHILD_FAILED);
627 }
628
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);
634 }
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);
641 }
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);
648 }
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);
654 }
655 }
656
657 /* successful */
658 return (0);
659 }
660
661 /*
662 * ****************************************************************************
663 *
664 * cb_get_ddset_info: callback for get_ddset_op
665 * The routine process matching dd object
666 *
667 * p1 - matching dds object
668 * p2 - lookup control data that was used for dd set look up
669 * return - error code
670 *
671 * ****************************************************************************
672 */
673 static int
cb_get_ddset_info(void * p1,void * p2)674 cb_get_ddset_info(
675 void *p1,
676 void *p2
677 )
678 {
679 xmlNodePtr n_obj, n_node, sub_node, root;
680 xmlAttrPtr n_attr;
681 isns_attr_t *attr;
682 char numbuf[32];
683
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;
687
688 root = xmlDocGetRootElement(doc);
689 if (root == NULL) {
690 return (ERR_SYNTAX_MISSING_ROOT);
691 }
692
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);
698 }
699 } else {
700 return (ERR_XML_NEWNODE_FAILED);
701 }
702
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);
708 }
709 } else {
710 return (ERR_XML_NEWNODE_FAILED);
711 }
712
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);
719 }
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);
726 }
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);
733 }
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);
739 }
740 }
741
742 /* successful */
743 return (0);
744 }
745
746 /*
747 * ****************************************************************************
748 *
749 * cb_enumerate_node_info: callback for enumerate_node_op
750 * The routine is invoked for each node object.
751 *
752 * p1 - node object
753 * p2 - lookup control data that was used for node look up
754 * return - error code
755 *
756 * ****************************************************************************
757 */
758 static int
cb_enumerate_node_info(void * p1,void * p2)759 cb_enumerate_node_info(
760 void *p1,
761 void *p2
762 )
763 {
764 xmlNodePtr n_obj, n_node, root;
765 xmlAttrPtr n_attr;
766 isns_attr_t *attr;
767
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;
771
772 root = xmlDocGetRootElement(doc);
773 if (root == NULL) {
774 return (ERR_SYNTAX_MISSING_ROOT);
775 }
776
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);
782 }
783 } else {
784 return (ERR_XML_NEWNODE_FAILED);
785 }
786
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);
792 }
793 } else {
794 return (ERR_XML_NEWNODE_FAILED);
795 }
796
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);
803 }
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);
829 }
830 if (n_attr == NULL) {
831 return (ERR_XML_SETPROP_FAILED);
832 }
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);
838 }
839
840 /* successful */
841 return (0);
842 }
843
844 /*
845 * ****************************************************************************
846 *
847 * i_enumerate_dd_dds_info:
848 * The routine is implemnetation for enumerate dd and enumerate dds.
849 *
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
853 *
854 * ****************************************************************************
855 */
856 static int
i_enumerate_dd_dds_info(void * p1,void * p2,isns_type_t obj_type)857 i_enumerate_dd_dds_info(
858 void *p1,
859 void *p2,
860 isns_type_t obj_type
861 )
862 {
863 xmlNodePtr n_obj, n_node, sub_node, root;
864 xmlAttrPtr n_attr;
865 isns_attr_t *attr;
866 char numbuf[32];
867
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;
871
872 root = xmlDocGetRootElement(doc);
873 if (root == NULL) {
874 return (ERR_SYNTAX_MISSING_ROOT);
875 }
876
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);
882 }
883 } else {
884 return (ERR_XML_NEWNODE_FAILED);
885 }
886
887 if (obj_type == OBJ_DD) {
888 n_node = xmlNewNode(NULL, (xmlChar *)DDOBJECT);
889 } else {
890 n_node = xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
891 }
892
893 if (n_node) {
894 n_node = xmlAddChild(n_obj, n_node);
895 if (n_node == NULL) {
896 return (ERR_XML_ADDCHILD_FAILED);
897 }
898 } else {
899 return (ERR_XML_NEWNODE_FAILED);
900 }
901
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);
909 }
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);
916 }
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);
923 }
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);
929 }
930 }
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);
938 }
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);
945 }
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);
952 }
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);
958 }
959 }
960 }
961
962 /* successful */
963 return (0);
964 }
965
966 /*
967 * ****************************************************************************
968 *
969 * cb_enumerate_dd_info: callback for enumerate_dd_op
970 * The routine is invoked for each dd object.
971 *
972 * p1 - dd object
973 * p2 - lookup control data that was used for dd look up
974 * return - error code
975 *
976 * ****************************************************************************
977 */
978 static int
cb_enumerate_dd_info(void * p1,void * p2)979 cb_enumerate_dd_info(
980 void *p1,
981 void *p2
982 )
983 {
984 return (i_enumerate_dd_dds_info(p1, p2, OBJ_DD));
985 }
986
987 /*
988 * ****************************************************************************
989 *
990 * cb_enumerate_ddset_info: callback for enumerate_dd_op
991 * The routine is invoked for each dd object.
992 *
993 * p1 - dd object
994 * p2 - lookup control data that was used for dd set look up
995 * return - error code
996 *
997 * ****************************************************************************
998 */
999 static int
cb_enumerate_ddset_info(void * p1,void * p2)1000 cb_enumerate_ddset_info(
1001 void *p1,
1002 void *p2
1003 )
1004 {
1005 return (i_enumerate_dd_dds_info(p1, p2, OBJ_DDS));
1006 }
1007
1008 /*
1009 * ****************************************************************************
1010 *
1011 * cb_getAssociated_node_info:
1012 * The routine is implemnetation for enumerate dd and enumerate dds.
1013 *
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
1017 *
1018 * ****************************************************************************
1019 */
1020 static int
cb_getAssociated_node_info(void * p1,void * p2)1021 cb_getAssociated_node_info(
1022 void *p1,
1023 void *p2
1024 )
1025 {
1026 xmlNodePtr n_obj, n_node, root;
1027 xmlAttrPtr n_attr;
1028 isns_attr_t *attr;
1029
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;
1034
1035 root = xmlDocGetRootElement(doc);
1036 if (root == NULL) {
1037 return (ERR_SYNTAX_MISSING_ROOT);
1038 }
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);
1044 }
1045 } else {
1046 return (ERR_XML_NEWNODE_FAILED);
1047 }
1048
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);
1054 }
1055 } else {
1056 return (ERR_XML_NEWNODE_FAILED);
1057 }
1058
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);
1065 }
1066 n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
1067 (xmlChar *)ddname);
1068 if (n_attr == NULL) {
1069 return (ERR_XML_SETPROP_FAILED);
1070 }
1071
1072 /* successful */
1073 return (0);
1074 }
1075
1076 /*
1077 * ****************************************************************************
1078 *
1079 * cb_getAssociated_node_to_dd_info:
1080 * The routine is implemnetation for enumerate dd and enumerate dds.
1081 *
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
1085 *
1086 * ****************************************************************************
1087 */
1088 static int
cb_getAssociated_node_to_dd_info(void * p1,void * p2)1089 cb_getAssociated_node_to_dd_info(
1090 void *p1,
1091 void *p2
1092 )
1093 {
1094 xmlNodePtr n_obj, n_node, root;
1095 xmlAttrPtr n_attr;
1096 isns_attr_t *attr;
1097
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;
1102
1103 root = xmlDocGetRootElement(doc);
1104 if (root == NULL) {
1105 return (ERR_SYNTAX_MISSING_ROOT);
1106 }
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);
1112 }
1113 } else {
1114 return (ERR_XML_NEWNODE_FAILED);
1115 }
1116
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);
1122 }
1123 } else {
1124 return (ERR_XML_NEWNODE_FAILED);
1125 }
1126
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);
1132 }
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);
1138 }
1139
1140 /* successful */
1141 return (0);
1142 }
1143
1144 /*
1145 * ****************************************************************************
1146 *
1147 * cb_getAssociated_dd_info:
1148 * The routine is implemnetation for getting dds membership.
1149 *
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
1153 *
1154 * ****************************************************************************
1155 */
1156 static int
cb_getAssociated_dd_info(void * p1,void * p2)1157 cb_getAssociated_dd_info(
1158 void *p1,
1159 void *p2
1160 )
1161 {
1162 xmlNodePtr n_obj, n_node, root;
1163 xmlAttrPtr n_attr;
1164 isns_attr_t *attr;
1165
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;
1170
1171 root = xmlDocGetRootElement(doc);
1172 if (root == NULL) {
1173 return (ERR_SYNTAX_MISSING_ROOT);
1174 }
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);
1180 }
1181 } else {
1182 return (ERR_XML_NEWNODE_FAILED);
1183 }
1184
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);
1190 }
1191 } else {
1192 return (ERR_XML_NEWNODE_FAILED);
1193 }
1194
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);
1201 }
1202 n_attr = xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR,
1203 (xmlChar *)ddsetname);
1204 if (n_attr == NULL) {
1205 return (ERR_XML_SETPROP_FAILED);
1206 }
1207
1208 /* successful */
1209 return (0);
1210 }
1211
1212 /*
1213 * ****************************************************************************
1214 *
1215 * cb_getAssociated_dd_to_ddset_info:
1216 * The routine is implemnetation for enumerate dd and enumerate dds.
1217 *
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
1221 *
1222 * ****************************************************************************
1223 */
1224 static int
cb_getAssociated_dd_to_ddset_info(void * p1,void * p2)1225 cb_getAssociated_dd_to_ddset_info(
1226 void *p1,
1227 void *p2
1228 )
1229 {
1230 xmlNodePtr n_obj, n_node, root;
1231 xmlAttrPtr n_attr;
1232 isns_attr_t *attr;
1233
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;
1238
1239 root = xmlDocGetRootElement(doc);
1240 if (root == NULL) {
1241 return (ERR_SYNTAX_MISSING_ROOT);
1242 }
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);
1248 }
1249 } else {
1250 return (ERR_XML_NEWNODE_FAILED);
1251 }
1252
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);
1258 }
1259 } else {
1260 return (ERR_XML_NEWNODE_FAILED);
1261 }
1262
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);
1268 }
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);
1274 }
1275
1276 /* successful */
1277 return (0);
1278 }
1279
1280 /*
1281 * ****************************************************************************
1282 *
1283 * handle_partial_success:
1284 *
1285 * doc - response doc to fill up
1286 * ret - return code from the caller.
1287 *
1288 * ****************************************************************************
1289 */
1290 static int
handle_partial_success(xmlDocPtr doc,int ret)1291 handle_partial_success(
1292 xmlDocPtr doc,
1293 int ret
1294 )
1295 {
1296 xmlNodePtr n_obj, n_node, root;
1297 char numbuf[32];
1298
1299 root = xmlDocGetRootElement(doc);
1300 if (root == NULL) {
1301 return (ERR_SYNTAX_MISSING_ROOT);
1302 }
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);
1312 }
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);
1318 }
1319 } else {
1320 n_obj = xmlAddChild(root, n_obj);
1321 if (n_obj == NULL) {
1322 return (ERR_XML_ADDCHILD_FAILED);
1323 }
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);
1329 }
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);
1334 }
1335 }
1336 } else {
1337 return (ERR_XML_NEWNODE_FAILED);
1338 }
1339
1340 return (0);
1341 }
1342
1343 /*
1344 * ****************************************************************************
1345 *
1346 * handle_partial_failure:
1347 *
1348 * doc - response doc to fill up
1349 * ret - return code from the caller.
1350 *
1351 * ****************************************************************************
1352 */
1353 static int
handle_partial_failure(xmlDocPtr doc,int ret,boolean_t all_failed)1354 handle_partial_failure(
1355 xmlDocPtr doc,
1356 int ret,
1357 boolean_t all_failed
1358 )
1359 {
1360 xmlNodePtr n_obj, n_node, root;
1361 char numbuf[32];
1362
1363 root = xmlDocGetRootElement(doc);
1364 if (root == NULL) {
1365 return (ERR_SYNTAX_MISSING_ROOT);
1366 }
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);
1379 }
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);
1385 }
1386 } else {
1387 n_obj = xmlAddChild(root, n_obj);
1388 if (n_obj == NULL) {
1389 return (ERR_XML_ADDCHILD_FAILED);
1390 }
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);
1396 }
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);
1401 }
1402 }
1403 } else {
1404 return (ERR_XML_NEWNODE_FAILED);
1405 }
1406
1407 return (0);
1408 }
1409
1410 /*
1411 * ****************************************************************************
1412 *
1413 * get_serverconfig_op:
1414 * The routine process server administrative setting.
1415 *
1416 * doc - response doc to fill up.
1417 *
1418 * ****************************************************************************
1419 */
1420 int
get_serverconfig_op(xmlDocPtr doc)1421 get_serverconfig_op(
1422 xmlDocPtr doc
1423 )
1424 {
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];
1430
1431 xmlNodePtr n_obj, root;
1432 char numbuf[32];
1433 ctrl_node_t *ctrl_node_p;
1434 int ret = 0;
1435
1436 root = xmlDocGetRootElement(doc);
1437 if (root == NULL) {
1438 return (ERR_SYNTAX_MISSING_ROOT);
1439 }
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);
1445 }
1446 } else {
1447 return (ERR_XML_ADDCHILD_FAILED);
1448 }
1449
1450 if (xmlNewChild(n_obj, NULL, (xmlChar *)DATASTORELOCATION,
1451 (xmlChar *)data_store) == NULL) {
1452 return (ERR_XML_NEWCHILD_FAILED);
1453 }
1454
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);
1459 }
1460 if (xmlNewChild(n_obj, NULL, (xmlChar *)MANAGEMENTSCNENABLED,
1461 (mgmt_scn) ? (uchar_t *)XMLTRUE : (uchar_t *)XMLFALSE) == NULL) {
1462 return (ERR_XML_NEWCHILD_FAILED);
1463 }
1464
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);
1471 }
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);
1479 }
1480 ctrl_node_p = ctrl_node_p->next;
1481 }
1482 }
1483 (void) pthread_mutex_unlock(&ctrl_node_mtx);
1484
1485 return (handle_partial_success(doc, ret));
1486 }
1487
1488 /*
1489 * ****************************************************************************
1490 *
1491 * get_node_op:
1492 * service get operation on a given node.
1493 *
1494 * req - contains all info for a request.
1495 * doc - response doc to fill up
1496 *
1497 * ****************************************************************************
1498 */
1499 int
get_node_op(request_t * req,xmlDocPtr doc)1500 get_node_op(
1501 request_t *req,
1502 xmlDocPtr doc
1503 /* any additional arguments go here */
1504 )
1505 {
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];
1511
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;
1524 }
1525
1526 /* generate network entity object information */
1527 if (ret == 0 && lc.id[2] != 0) {
1528 /*
1529 * !!! there might be no entity and portal info for
1530 * !!! the node if it is not a registered node
1531 */
1532 /* prepare lookup ctrl data for looking for entity */
1533 SET_UID_LCP(&lc2, OBJ_ENTITY, lc.id[2]);
1534
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;
1541 }
1542 }
1543
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;
1555
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);
1583 }
1584 } else {
1585 /*
1586 * no more portal group which is
1587 * tied to this stroage node object.
1588 */
1589 break;
1590 }
1591 }
1592 }
1593 /* save error for this iteration */
1594 if (ret != 0) {
1595 ret_save = ret;
1596 }
1597 ret = 0;
1598 i++;
1599 }
1600
1601 return (handle_partial_success(doc, ret_save));
1602 }
1603
1604 /*
1605 * ****************************************************************************
1606 *
1607 * i_get_dd_dds_op:
1608 * serves get operatrion on dd or dds.
1609 *
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)
1613 *
1614 * ****************************************************************************
1615 */
1616 static int
i_get_dd_dds_op(request_t * req,xmlDocPtr doc,isns_type_t obj_type)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 */
1622 )
1623 {
1624 result_code_t ret = 0, ret_save = 0;
1625 int i = 0;
1626 lookup_ctrl_t lc;
1627 uint32_t uid;
1628
1629 if ((obj_type != OBJ_DD) && (obj_type != OBJ_DDS)) {
1630 return (ERR_INVALID_MGMT_REQUEST);
1631 }
1632
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;
1647 }
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;
1654 }
1655 }
1656 /* save error for this iteration */
1657 if (ret != 0) {
1658 ret_save = ret;
1659 }
1660 ret = 0;
1661 i++;
1662 }
1663
1664 return (handle_partial_success(doc, ret_save));
1665 }
1666
1667 /*
1668 * ****************************************************************************
1669 *
1670 * i_delete_ddmember_op:
1671 * serves delete member operatrion on dd.
1672 *
1673 * container - dd name
1674 * member - node name
1675 *
1676 * ****************************************************************************
1677 */
1678 static int
i_delete_ddmember_op(uchar_t * container,uchar_t * member)1679 i_delete_ddmember_op(
1680 uchar_t *container,
1681 uchar_t *member
1682 )
1683 {
1684 int ret = 0;
1685
1686 isns_assoc_iscsi_t aiscsi;
1687 isns_obj_t *assoc;
1688 isns_attr_t *attr;
1689 int len;
1690
1691 lookup_ctrl_t lc;
1692 uint32_t dd_id;
1693
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;
1701
1702 if ((dd_id = is_obj_there(&lc)) != 0) {
1703 aiscsi.type = OBJ_ASSOC_ISCSI;
1704 aiscsi.puid = dd_id;
1705
1706 len = strlen((char *)member) + 1;
1707 len += 4 - (len % 4);
1708
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;
1721 }
1722
1723 return (ret);
1724 }
1725
1726 /*
1727 * ****************************************************************************
1728 *
1729 * i_delete_ddsetmember_op:
1730 * serves delete member operatrion on dd set.
1731 *
1732 * container - dd set name
1733 * member - dd name
1734 *
1735 * ****************************************************************************
1736 */
1737 static int
i_delete_ddsetmember_op(uchar_t * container,uchar_t * member)1738 i_delete_ddsetmember_op(
1739 uchar_t *container,
1740 uchar_t *member
1741 )
1742 {
1743 int ret = 0;
1744
1745 lookup_ctrl_t lc, lc2;
1746 uint32_t container_id, member_id;
1747
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;
1755
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;
1763
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;
1769 }
1770 } else {
1771 ret = ERR_MATCHING_DDSET_NOT_FOUND;
1772 }
1773
1774 return (ret);
1775 }
1776
1777 /*
1778 * ****************************************************************************
1779 *
1780 * get_dd_op:
1781 * service get operation on given dd(s).
1782 *
1783 * req - contains all info for a request.
1784 * doc - response doc to fill up
1785 *
1786 * ****************************************************************************
1787 */
1788 int
get_dd_op(request_t * req,xmlDocPtr doc)1789 get_dd_op(
1790 request_t *req,
1791 xmlDocPtr doc
1792 /* any additional arguments go here */
1793 )
1794 {
1795 return (i_get_dd_dds_op(req, doc, OBJ_DD));
1796 }
1797
1798 /*
1799 * ****************************************************************************
1800 *
1801 * get_ddset_op:
1802 * service get operation on given dd set(s).
1803 *
1804 * req - contains all info for a request.
1805 * doc - response doc to fill up
1806 *
1807 * ****************************************************************************
1808 */
1809 int
get_ddset_op(request_t * req,xmlDocPtr doc)1810 get_ddset_op(
1811 request_t *req,
1812 xmlDocPtr doc
1813 /* any additional arguments go here */
1814 )
1815 {
1816 return (i_get_dd_dds_op(req, doc, OBJ_DDS));
1817 }
1818
1819 /*
1820 * ****************************************************************************
1821 *
1822 * enumerate_node_op:
1823 * services enumerate node op.
1824 *
1825 * req - contains enumerate request info.
1826 * doc - response doc to fill up
1827 *
1828 * ****************************************************************************
1829 */
1830 int
enumerate_node_op(xmlDocPtr doc)1831 enumerate_node_op(
1832 xmlDocPtr doc
1833 /* any additional arguments go here */
1834 )
1835 {
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;
1840
1841 SET_UID_LCP(&lc, OBJ_ISCSI, 0);
1842
1843 lc.data[1].ptr = (uchar_t *)doc;
1844 lc.data[2].ui = 0;
1845
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;
1851 }
1852 });
1853
1854 return (handle_partial_success(doc, ret_save));
1855 }
1856
1857 /*
1858 * ****************************************************************************
1859 *
1860 * enumerate_dd_op:
1861 * services enumerate discovery domain op.
1862 *
1863 * req - contains enumerate request info.
1864 * doc - response doc to fill up
1865 *
1866 * ****************************************************************************
1867 */
1868 int
enumerate_dd_op(xmlDocPtr doc)1869 enumerate_dd_op(
1870 xmlDocPtr doc
1871 /* any additional arguments go here */
1872 )
1873 {
1874
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;
1879
1880 SET_UID_LCP(&lc, OBJ_DD, 0);
1881
1882 lc.data[1].ptr = (uchar_t *)doc;
1883 lc.data[2].ui = 0;
1884
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;
1890 }
1891 });
1892
1893 return (handle_partial_success(doc, ret_save));
1894 }
1895
1896 /*
1897 * ****************************************************************************
1898 *
1899 * enumerate_ddset_op:
1900 * services enumerate discovery domain set op.
1901 *
1902 * req - contains enumerate request info.
1903 * doc - response doc to fill up
1904 *
1905 * ****************************************************************************
1906 */
1907 int
enumerate_ddset_op(xmlDocPtr doc)1908 enumerate_ddset_op(
1909 xmlDocPtr doc
1910 /* any additional arguments go here */
1911 )
1912 {
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;
1917
1918 SET_UID_LCP(&lc, OBJ_DDS, 0);
1919
1920 lc.data[1].ptr = (uchar_t *)doc;
1921 lc.data[2].ui = 0;
1922
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;
1928 }
1929 });
1930
1931 return (handle_partial_success(doc, ret_save));
1932 }
1933
1934 /*
1935 * ****************************************************************************
1936 *
1937 * getassociated_dd_to_node_op:
1938 * construct a list of node that is associated with a given Discovery
1939 * Domain.
1940 *
1941 * req - contains getAssociated request info.
1942 * doc - response doc to fill up
1943 *
1944 * ****************************************************************************
1945 */
1946 int
getAssociated_dd_to_node_op(request_t * req,xmlDocPtr doc)1947 getAssociated_dd_to_node_op(
1948 request_t *req,
1949 xmlDocPtr doc
1950 /* any additional arguments go here */
1951 )
1952 {
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;
1957
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;
1963
1964 SET_UID_LCP(&lc2, OBJ_ISCSI, 0);
1965
1966 lc2.data[1].ptr = (uchar_t *)doc;
1967
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);
1977 });
1978 free(p);
1979 } else {
1980 ret = ERR_MATCHING_DD_NOT_FOUND;
1981 }
1982 /* save error for this iteration */
1983 if (ret != 0) {
1984 ret_save = ret;
1985 }
1986 ret = 0;
1987 i++;
1988 }
1989
1990 return (handle_partial_success(doc, ret_save));
1991 }
1992
1993 /*
1994 * ****************************************************************************
1995 *
1996 * getassociated_node_to_dd_op:
1997 * construct a list of Discovery Doamins that is associated with a given
1998 * node.
1999 *
2000 * req - contains getAssociated request info.
2001 * doc - response doc to fill up
2002 *
2003 * ****************************************************************************
2004 */
2005 int
getAssociated_node_to_dd_op(request_t * req,xmlDocPtr doc)2006 getAssociated_node_to_dd_op(
2007 request_t *req,
2008 xmlDocPtr doc
2009 /* any additional arguments go here */
2010 )
2011 {
2012 uint32_t uid = 0, dd_id;
2013 lookup_ctrl_t lc, lc2;
2014 int i = 0, ret = 0, ret_save = 0;
2015
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;
2021
2022 SET_UID_LCP(&lc2, OBJ_DD, 0);
2023
2024 lc2.data[1].ptr = (uchar_t *)doc;
2025
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);
2041 };
2042 } else {
2043 ret = ERR_MATCHING_NODE_NOT_FOUND;
2044 }
2045 /* save error for this iteration */
2046 if (ret != 0) {
2047 ret_save = ret;
2048 }
2049 ret = 0;
2050 i++;
2051 }
2052
2053 return (handle_partial_success(doc, ret_save));
2054 }
2055
2056 /*
2057 * ****************************************************************************
2058 *
2059 * getassociated_ddset_to_dd_op:
2060 * construct a list of Discovery Doamins that is associated with a given
2061 * Discover Domain set.
2062 *
2063 * req - contains getAssociated request info.
2064 * doc - response doc to fill up
2065 *
2066 * ****************************************************************************
2067 */
2068 int
getAssociated_ddset_to_dd_op(request_t * req,xmlDocPtr doc)2069 getAssociated_ddset_to_dd_op(
2070 request_t *req,
2071 xmlDocPtr doc
2072 /* any additional arguments go here */
2073 )
2074 {
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;
2079
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;
2085
2086 SET_UID_LCP(&lc2, OBJ_DD, 0);
2087
2088 lc2.data[1].ptr = (uchar_t *)doc;
2089
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);
2099 });
2100 free(p);
2101 } else {
2102 ret = ERR_MATCHING_DDSET_NOT_FOUND;
2103 }
2104 /* save error for this iteration */
2105 if (ret != 0) {
2106 ret_save = ret;
2107 }
2108 ret = 0;
2109 i++;
2110 }
2111
2112 return (handle_partial_success(doc, ret_save));
2113 }
2114
2115 /*
2116 * ****************************************************************************
2117 *
2118 * getassociated_dd_to_ddset_op:
2119 * construct a list of Discovery Doamin sets that is associated with a
2120 * given Discovery Domain.
2121 *
2122 * req - contains getAssociated request info.
2123 * doc - response doc to fill up
2124 *
2125 * ****************************************************************************
2126 */
2127 int
getAssociated_dd_to_ddset_op(request_t * req,xmlDocPtr doc)2128 getAssociated_dd_to_ddset_op(
2129 request_t *req,
2130 xmlDocPtr doc
2131 /* any additional arguments go here */
2132 )
2133 {
2134 uint32_t uid = 0, ddset_id;
2135 lookup_ctrl_t lc, lc2;
2136 int i = 0, ret = 0, ret_save = 0;
2137
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;
2143
2144 SET_UID_LCP(&lc2, OBJ_DDS, 0);
2145
2146 lc2.data[1].ptr = (uchar_t *)doc;
2147
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);
2164 };
2165 } else {
2166 ret = ERR_MATCHING_DD_NOT_FOUND;
2167 }
2168 if (ret != 0) {
2169 ret_save = ret;
2170 }
2171 i++;
2172 }
2173
2174 return (handle_partial_success(doc, ret_save));
2175 }
2176
2177 /*
2178 * ****************************************************************************
2179 *
2180 * delete_dd_ddset_op:
2181 * removes a list of dd or dd set.
2182 *
2183 * req - contains delete request info.
2184 * doc - response doc to fill up
2185 * obj_type - object type(either dd or dd set)
2186 *
2187 * ****************************************************************************
2188 */
2189 int
delete_dd_ddset_op(request_t * req,xmlDocPtr doc,object_type type)2190 delete_dd_ddset_op(
2191 request_t *req,
2192 xmlDocPtr doc,
2193 object_type type
2194 /* any additional arguments go here */
2195 )
2196 {
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;
2205
2206 root = xmlDocGetRootElement(doc);
2207 if (root == NULL) {
2208 return (ERR_SYNTAX_MISSING_ROOT);
2209 }
2210 lc_type = get_lc_type(type);
2211 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2212 return (ERR_INVALID_MGMT_REQUEST);
2213 }
2214
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];
2224
2225 /* lock the cache for writing */
2226 (void) cache_lock_write();
2227
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;
2241 }
2242
2243 if (ret != 0) {
2244 /* keep track if there are different errors encountered. */
2245 if (ret_save != 0 && ret != ret_save) {
2246 different_err++;
2247 }
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);
2253 }
2254 } else {
2255 return (ERR_XML_NEWNODE_FAILED);
2256 }
2257
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);
2264 }
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);
2269 }
2270 } else {
2271 return (ERR_XML_NEWNODE_FAILED);
2272 }
2273 ret_save = ret;
2274 }
2275 i ++;
2276 }
2277
2278 return (handle_partial_failure(doc, ret_save,
2279 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2280 }
2281
2282 /*
2283 * ****************************************************************************
2284 *
2285 * delete_ddmember_ddsetmember_op:
2286 * removes a list of dd memeber or dd seti member.
2287 *
2288 * req - contains delete request info.
2289 * doc - response doc to fill up
2290 * type - object type(either dd or dd set)
2291 *
2292 * ****************************************************************************
2293 */
2294 int
delete_ddmember_ddsetmember_op(request_t * req,xmlDocPtr doc,object_type type)2295 delete_ddmember_ddsetmember_op(
2296 request_t *req,
2297 xmlDocPtr doc,
2298 object_type type
2299 /* any additional arguments go here */
2300 )
2301 {
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;
2311
2312 lc_type = get_lc_type(type);
2313 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2314 return (ERR_INVALID_MGMT_REQUEST);
2315 }
2316
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;
2323
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);
2331 }
2332 lc2.op[0] = OP_STRING;
2333 lc2.op[1] = 0;
2334
2335 root = xmlDocGetRootElement(doc);
2336 if (root == NULL) {
2337 return (ERR_SYNTAX_MISSING_ROOT);
2338 }
2339
2340 while (i < req->count) {
2341 lc.data[0].ptr = (uchar_t *)req->req_data.pair[i]->container;
2342
2343 /* get the dd_id/dds_id */
2344 (void) cache_lock_write();
2345 container_id = is_obj_there(&lc);
2346
2347 if (container_id != 0) {
2348 lc2.data[0].ptr = (uchar_t *)req->req_data.pair[i]->member;
2349
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)));
2357 }
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;
2373 }
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;
2379 }
2380
2381 if (ret != 0) {
2382 /* keep track if there are different errors encountered. */
2383 if (ret_save != 0 && ret != ret_save) {
2384 different_err++;
2385 }
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);
2393 }
2394 } else {
2395 return (ERR_XML_NEWNODE_FAILED);
2396 }
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);
2404 }
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);
2409 }
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);
2417 }
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);
2422 }
2423 }
2424 if (xmlAddChild(n_obj, n_node) == NULL) {
2425 return (ERR_XML_ADDCHILD_FAILED);
2426 }
2427 }
2428 i++;
2429 }
2430
2431 return (handle_partial_failure(doc, ret_save,
2432 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2433 }
2434
2435 /*
2436 * ****************************************************************************
2437 *
2438 * create_ddmember_ddsetmember_op:
2439 * removes a list of dd memeber or dd seti member.
2440 *
2441 * req - contains delete request info.
2442 * doc - response doc to fill up
2443 * type - object type(either dd or dd set)
2444 *
2445 * ****************************************************************************
2446 */
2447 int
create_ddmember_ddsetmember_op(request_t * req,xmlDocPtr doc,object_type type)2448 create_ddmember_ddsetmember_op(
2449 request_t *req,
2450 xmlDocPtr doc,
2451 object_type type
2452 /* any additional arguments go here */
2453 )
2454 {
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;
2467
2468 lc_type = get_lc_type(type);
2469 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2470 return (ERR_INVALID_MGMT_REQUEST);
2471 }
2472
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;
2479
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);
2487 }
2488 lc2.op[0] = OP_STRING;
2489 lc2.op[1] = 0;
2490
2491 root = xmlDocGetRootElement(doc);
2492 if (root == NULL) {
2493 return (ERR_SYNTAX_MISSING_ROOT);
2494 }
2495
2496 while (i < req->count) {
2497 lc.data[0].ptr = (uchar_t *)req->req_data.pair[i]->container;
2498
2499 /* get the dd_id/dds_id */
2500 (void) cache_lock_write();
2501 container_id = is_obj_there(&lc);
2502
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;
2518
2519 /* add the dd member */
2520 ret = add_dd_member(assoc);
2521
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;
2527
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;
2537
2538 /* add the dd-set member */
2539 ret = add_dds_member(assoc);
2540
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;
2547 }
2548 }
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;
2554 }
2555 if (ret != 0) {
2556 /* keep track if there are different errors encountered. */
2557 if (ret_save != 0 && ret != ret_save) {
2558 different_err++;
2559 }
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);
2566 }
2567 } else {
2568 return (ERR_XML_NEWNODE_FAILED);
2569 }
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);
2576 }
2577 if (xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
2578 (xmlChar *)req->req_data.pair[i]->container) ==
2579 NULL) {
2580 return (ERR_XML_SETPROP_FAILED);
2581 }
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);
2588 }
2589 if (xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR,
2590 (xmlChar *)req->req_data.pair[i]->container) ==
2591 NULL) {
2592 return (ERR_XML_SETPROP_FAILED);
2593 }
2594 }
2595 if (xmlAddChild(n_obj, n_node) == NULL) {
2596 return (ERR_XML_ADDCHILD_FAILED);
2597 }
2598 ret_save = ret;
2599 }
2600 i++;
2601 }
2602
2603 return (handle_partial_failure(doc, ret_save,
2604 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2605 }
2606
2607 /*
2608 * ****************************************************************************
2609 *
2610 * rename_dd_ddset_op:
2611 * removes a list of dd memeber or dd seti member.
2612 *
2613 * req - contains delete request info.
2614 * doc - response doc to fill up
2615 * type - object type(either dd or dd set)
2616 *
2617 * ****************************************************************************
2618 */
2619 static int
rename_dd_ddset_op(request_t * req,xmlDocPtr doc,object_type type)2620 rename_dd_ddset_op(
2621 request_t *req,
2622 xmlDocPtr doc,
2623 object_type type
2624 /* any additional arguments go here */
2625 )
2626 {
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;
2636
2637 lc_type = get_lc_type(type);
2638 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2639 return (ERR_INVALID_MGMT_REQUEST);
2640 }
2641
2642 /* prepare lookup ctrl data for looking for the node object */
2643 SET_UID_LCP(&lc, lc_type, 0);
2644
2645 root = xmlDocGetRootElement(doc);
2646 if (root == NULL) {
2647 return (ERR_SYNTAX_MISSING_ROOT);
2648 }
2649
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);
2653
2654 /* get the dd_id/dds_id */
2655 (void) cache_lock_write();
2656
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);
2663
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);
2668
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;
2676 }
2677 if (ret != 0) {
2678 /* keep track if there are different errors encountered. */
2679 if (ret_save != 0 && ret != ret_save) {
2680 different_err++;
2681 }
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);
2688 }
2689 } else {
2690 return (ERR_XML_NEWNODE_FAILED);
2691 }
2692
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);
2704 }
2705 }
2706 } else {
2707 return (ERR_XML_NEWNODE_FAILED);
2708 }
2709
2710 }
2711 i++;
2712 }
2713
2714 return (handle_partial_failure(doc, ret_save,
2715 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2716 }
2717
2718 /*
2719 * ****************************************************************************
2720 *
2721 * update_dd_ddset_op:
2722 * removes a list of dd memeber or dd seti member.
2723 *
2724 * req - contains delete request info.
2725 * doc - response doc to fill up
2726 * type - object type(either dd or dd set)
2727 *
2728 * ****************************************************************************
2729 */
2730 static int
update_dd_ddset_op(request_t * req,xmlDocPtr doc,object_type type)2731 update_dd_ddset_op(
2732 request_t *req,
2733 xmlDocPtr doc,
2734 object_type type
2735 /* any additional arguments go here */
2736 )
2737 {
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;
2745
2746 lc_type = get_lc_type(type);
2747 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2748 return (ERR_INVALID_MGMT_REQUEST);
2749 }
2750
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;
2757
2758 root = xmlDocGetRootElement(doc);
2759 if (root == NULL) {
2760 return (ERR_SYNTAX_MISSING_ROOT);
2761 }
2762
2763 while (i < req->count) {
2764 lc.data[0].ptr = req->req_data.attrlist[i]->name;
2765
2766 /* lock the cache for writing */
2767 (void) cache_lock_write();
2768
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;
2782 }
2783 if (ret != 0) {
2784 /* keep track if there are different errors encountered. */
2785 if (ret_save != 0 && ret != ret_save) {
2786 different_err++;
2787 }
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);
2794 }
2795 } else {
2796 return (ERR_XML_NEWNODE_FAILED);
2797 }
2798
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);
2810 }
2811 }
2812 } else {
2813 return (ERR_XML_NEWNODE_FAILED);
2814 }
2815 }
2816 i++;
2817 }
2818
2819 return (handle_partial_failure(doc, ret_save,
2820 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2821 }
2822
2823 /*
2824 * ****************************************************************************
2825 *
2826 * createModify_dd_ddset_op:
2827 * removes a list of dd memeber or dd seti member.
2828 *
2829 * req - contains delete request info.
2830 * doc - response doc to fill up
2831 *
2832 * ****************************************************************************
2833 */
2834 static int
create_dd_ddset_op(request_t * req,xmlDocPtr doc,object_type type)2835 create_dd_ddset_op(
2836 request_t *req,
2837 xmlDocPtr doc,
2838 object_type type
2839 /* any additional arguments go here */
2840 )
2841 {
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;
2850
2851 lc_type = get_lc_type(type);
2852 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2853 return (ERR_INVALID_MGMT_REQUEST);
2854 }
2855
2856 root = xmlDocGetRootElement(doc);
2857 if (root == NULL) {
2858 return (ERR_SYNTAX_MISSING_ROOT);
2859 }
2860 lc_type = get_lc_type(type);
2861 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
2862 return (ERR_INVALID_MGMT_REQUEST);
2863 }
2864
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();
2876
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);
2888 }
2889 /* release the lock and sync the cache and data store */
2890 ret = cache_unlock_sync(ret);
2891 }
2892 } else {
2893 /* release the lock and no need to sync the data */
2894 (void) cache_unlock_nosync();
2895 ret = ERR_NAME_IN_USE;
2896 }
2897
2898 if (ret != 0) {
2899 /* keep track if there are different errors encountered. */
2900 if (ret_save != 0 && ret != ret_save) {
2901 different_err++;
2902 }
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);
2909 }
2910 } else {
2911 return (ERR_XML_ADDCHILD_FAILED);
2912 }
2913
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);
2925 }
2926 }
2927 } else {
2928 return (ERR_XML_NEWNODE_FAILED);
2929 }
2930 }
2931 i++;
2932 }
2933
2934 return (handle_partial_failure(doc, ret_save,
2935 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
2936 }
2937
2938 /*
2939 * ****************************************************************************
2940 *
2941 * createModify_dd_ddset_op:
2942 * removes a list of dd memeber or dd seti member.
2943 *
2944 * req - contains delete request info.
2945 * doc - response doc to fill up
2946 *
2947 * ****************************************************************************
2948 */
2949 int
createModify_dd_ddset_op(request_t * req,xmlDocPtr doc)2950 createModify_dd_ddset_op(
2951 request_t *req,
2952 xmlDocPtr doc
2953 /* any additional arguments go here */
2954 )
2955 {
2956 result_code_t ret = 0;
2957
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);
2964 }
2965
2966 return (ret);
2967 }
2968