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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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