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 2008 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 /* pass ip addr from cb_get_pg_info. */ 1574 lc3.data[0].ip = lc2.data[1].ip; 1575 /* pass port num from cb_get_pg_info. */ 1576 lc3.data[1].ui = lc2.data[2].ui; 1577 /* pass pgt from cb_get_pg_info. */ 1578 lc3.id[2] = lc2.id[2]; 1579 ret = cache_lookup(&lc3, &uid, 1580 cb_get_portal_info); 1581 } else { 1582 /* 1583 * no more portal group which is 1584 * tied to this stroage node object. 1585 */ 1586 break; 1587 } 1588 } 1589 } 1590 /* save error for this iteration */ 1591 if (ret != 0) { 1592 ret_save = ret; 1593 } 1594 ret = 0; 1595 i++; 1596 } 1597 1598 return (handle_partial_success(doc, ret_save)); 1599 } 1600 1601 /* 1602 * **************************************************************************** 1603 * 1604 * i_get_dd_dds_op: 1605 * serves get operatrion on dd or dds. 1606 * 1607 * req - contains all info for a request. 1608 * doc - response doc to fill up 1609 * obj_type - object type(either dd or dd set) 1610 * 1611 * **************************************************************************** 1612 */ 1613 static int 1614 i_get_dd_dds_op( 1615 request_t *req, 1616 xmlDocPtr doc, 1617 isns_type_t obj_type 1618 /* any additional arguments go here */ 1619 ) 1620 { 1621 result_code_t ret = 0, ret_save = 0; 1622 int i = 0; 1623 lookup_ctrl_t lc; 1624 uint32_t uid; 1625 1626 if ((obj_type != OBJ_DD) && (obj_type != OBJ_DDS)) { 1627 return (ERR_INVALID_MGMT_REQUEST); 1628 } 1629 1630 /* prepare lookup ctrl data for looking for the node object */ 1631 lc.curr_uid = 0; 1632 lc.type = obj_type; 1633 lc.id[0] = get_lc_id(req->op_info.obj); 1634 lc.op[0] = OP_STRING; 1635 lc.op[1] = 0; 1636 lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */ 1637 while (i < req->count) { 1638 if (obj_type == OBJ_DD) { 1639 lc.data[0].ptr = (uchar_t *)req->req_data.data[i]; 1640 ret = cache_lookup(&lc, &uid, cb_get_dd_info); 1641 if (uid == 0) { 1642 /* set an error and continue. */ 1643 ret = ERR_MATCHING_DD_NOT_FOUND; 1644 } 1645 } else { 1646 lc.data[0].ptr = (uchar_t *)req->req_data.data[i]; 1647 ret = cache_lookup(&lc, &uid, cb_get_ddset_info); 1648 if (uid == 0) { 1649 /* set an error and continue. */ 1650 ret = ERR_MATCHING_DDSET_NOT_FOUND; 1651 } 1652 } 1653 /* save error for this iteration */ 1654 if (ret != 0) { 1655 ret_save = ret; 1656 } 1657 ret = 0; 1658 i++; 1659 } 1660 1661 return (handle_partial_success(doc, ret_save)); 1662 } 1663 1664 /* 1665 * **************************************************************************** 1666 * 1667 * i_delete_ddmember_op: 1668 * serves delete member operatrion on dd. 1669 * 1670 * container - dd name 1671 * member - node name 1672 * 1673 * **************************************************************************** 1674 */ 1675 static int 1676 i_delete_ddmember_op( 1677 uchar_t *container, 1678 uchar_t *member 1679 ) 1680 { 1681 int ret = 0; 1682 1683 isns_assoc_iscsi_t aiscsi; 1684 isns_obj_t *assoc; 1685 isns_attr_t *attr; 1686 int len; 1687 1688 lookup_ctrl_t lc; 1689 uint32_t dd_id; 1690 1691 /* prepare lookup ctrl data for looking for the dd object */ 1692 lc.curr_uid = 0; 1693 lc.type = OBJ_DD; 1694 lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID); 1695 lc.op[0] = OP_STRING; 1696 lc.data[0].ptr = container; 1697 lc.op[1] = 0; 1698 1699 if ((dd_id = is_obj_there(&lc)) != 0) { 1700 aiscsi.type = OBJ_ASSOC_ISCSI; 1701 aiscsi.puid = dd_id; 1702 1703 len = strlen((char *)member) + 1; 1704 len += 4 - (len % 4); 1705 1706 attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI( 1707 ISNS_DD_ISCSI_NAME_ATTR_ID)]; 1708 attr->tag = ISNS_DD_ISCSI_NAME_ATTR_ID; 1709 attr->len = len; 1710 attr->value.ptr = (uchar_t *)member; 1711 attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI( 1712 ISNS_DD_ISCSI_INDEX_ATTR_ID)]; 1713 attr->tag = 0; /* clear it */ 1714 assoc = (isns_obj_t *)&aiscsi; 1715 ret = remove_dd_member(assoc); 1716 } else { 1717 ret = ERR_MATCHING_DD_NOT_FOUND; 1718 } 1719 1720 return (ret); 1721 } 1722 1723 /* 1724 * **************************************************************************** 1725 * 1726 * i_delete_ddsetmember_op: 1727 * serves delete member operatrion on dd set. 1728 * 1729 * container - dd set name 1730 * member - dd name 1731 * 1732 * **************************************************************************** 1733 */ 1734 static int 1735 i_delete_ddsetmember_op( 1736 uchar_t *container, 1737 uchar_t *member 1738 ) 1739 { 1740 int ret = 0; 1741 1742 lookup_ctrl_t lc, lc2; 1743 uint32_t container_id, member_id; 1744 1745 /* prepare lookup ctrl data for looking for the dd-set object */ 1746 lc.curr_uid = 0; 1747 lc.type = OBJ_DDS; 1748 lc.id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID); 1749 lc.op[0] = OP_STRING; 1750 lc.data[0].ptr = container; 1751 lc.op[1] = 0; 1752 1753 /* prepare lookup ctrl data for looking for the dd object */ 1754 lc2.curr_uid = 0; 1755 lc2.type = OBJ_DD; 1756 lc2.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID); 1757 lc2.op[0] = OP_STRING; 1758 lc2.data[0].ptr = member; 1759 lc2.op[1] = 0; 1760 1761 if ((container_id = is_obj_there(&lc)) != 0) { 1762 if ((member_id = is_obj_there(&lc2)) != 0) { 1763 ret = remove_dds_member(container_id, member_id); 1764 } else { 1765 ret = ERR_MATCHING_DD_NOT_FOUND; 1766 } 1767 } else { 1768 ret = ERR_MATCHING_DDSET_NOT_FOUND; 1769 } 1770 1771 return (ret); 1772 } 1773 1774 /* 1775 * **************************************************************************** 1776 * 1777 * get_dd_op: 1778 * service get operation on given dd(s). 1779 * 1780 * req - contains all info for a request. 1781 * doc - response doc to fill up 1782 * 1783 * **************************************************************************** 1784 */ 1785 int 1786 get_dd_op( 1787 request_t *req, 1788 xmlDocPtr doc 1789 /* any additional arguments go here */ 1790 ) 1791 { 1792 return (i_get_dd_dds_op(req, doc, OBJ_DD)); 1793 } 1794 1795 /* 1796 * **************************************************************************** 1797 * 1798 * get_ddset_op: 1799 * service get operation on given dd set(s). 1800 * 1801 * req - contains all info for a request. 1802 * doc - response doc to fill up 1803 * 1804 * **************************************************************************** 1805 */ 1806 int 1807 get_ddset_op( 1808 request_t *req, 1809 xmlDocPtr doc 1810 /* any additional arguments go here */ 1811 ) 1812 { 1813 return (i_get_dd_dds_op(req, doc, OBJ_DDS)); 1814 } 1815 1816 /* 1817 * **************************************************************************** 1818 * 1819 * enumerate_node_op: 1820 * services enumerate node op. 1821 * 1822 * req - contains enumerate request info. 1823 * doc - response doc to fill up 1824 * 1825 * **************************************************************************** 1826 */ 1827 int 1828 enumerate_node_op( 1829 xmlDocPtr doc 1830 /* any additional arguments go here */ 1831 ) 1832 { 1833 htab_t *htab = cache_get_htab(OBJ_ISCSI); 1834 uint32_t uid = 0; 1835 lookup_ctrl_t lc; 1836 int ret = 0, ret_save = 0; 1837 1838 SET_UID_LCP(&lc, OBJ_ISCSI, 0); 1839 1840 lc.data[1].ptr = (uchar_t *)doc; 1841 lc.data[2].ui = 0; 1842 1843 FOR_EACH_ITEM(htab, uid, { 1844 lc.data[0].ui = uid; 1845 ret = cache_lookup(&lc, NULL, cb_enumerate_node_info); 1846 if (ret != 0) { 1847 ret_save = ret; 1848 } 1849 }); 1850 1851 return (handle_partial_success(doc, ret_save)); 1852 } 1853 1854 /* 1855 * **************************************************************************** 1856 * 1857 * enumerate_dd_op: 1858 * services enumerate discovery domain op. 1859 * 1860 * req - contains enumerate request info. 1861 * doc - response doc to fill up 1862 * 1863 * **************************************************************************** 1864 */ 1865 int 1866 enumerate_dd_op( 1867 xmlDocPtr doc 1868 /* any additional arguments go here */ 1869 ) 1870 { 1871 1872 htab_t *htab = cache_get_htab(OBJ_DD); 1873 uint32_t uid = 0; 1874 lookup_ctrl_t lc; 1875 int ret = 0, ret_save = 0; 1876 1877 SET_UID_LCP(&lc, OBJ_DD, 0); 1878 1879 lc.data[1].ptr = (uchar_t *)doc; 1880 lc.data[2].ui = 0; 1881 1882 FOR_EACH_ITEM(htab, uid, { 1883 lc.data[0].ui = uid; 1884 ret = cache_lookup(&lc, NULL, cb_enumerate_dd_info); 1885 if (ret != 0) { 1886 ret_save = ret; 1887 } 1888 }); 1889 1890 return (handle_partial_success(doc, ret_save)); 1891 } 1892 1893 /* 1894 * **************************************************************************** 1895 * 1896 * enumerate_ddset_op: 1897 * services enumerate discovery domain set op. 1898 * 1899 * req - contains enumerate request info. 1900 * doc - response doc to fill up 1901 * 1902 * **************************************************************************** 1903 */ 1904 int 1905 enumerate_ddset_op( 1906 xmlDocPtr doc 1907 /* any additional arguments go here */ 1908 ) 1909 { 1910 htab_t *htab = cache_get_htab(OBJ_DDS); 1911 uint32_t uid = 0; 1912 lookup_ctrl_t lc; 1913 int ret = 0, ret_save = 0; 1914 1915 SET_UID_LCP(&lc, OBJ_DDS, 0); 1916 1917 lc.data[1].ptr = (uchar_t *)doc; 1918 lc.data[2].ui = 0; 1919 1920 FOR_EACH_ITEM(htab, uid, { 1921 lc.data[0].ui = uid; 1922 ret = cache_lookup(&lc, NULL, cb_enumerate_ddset_info); 1923 if (ret != 0) { 1924 ret_save = ret; 1925 } 1926 }); 1927 1928 return (handle_partial_success(doc, ret_save)); 1929 } 1930 1931 /* 1932 * **************************************************************************** 1933 * 1934 * getassociated_dd_to_node_op: 1935 * construct a list of node that is associated with a given Discovery 1936 * Domain. 1937 * 1938 * req - contains getAssociated request info. 1939 * doc - response doc to fill up 1940 * 1941 * **************************************************************************** 1942 */ 1943 int 1944 getAssociated_dd_to_node_op( 1945 request_t *req, 1946 xmlDocPtr doc 1947 /* any additional arguments go here */ 1948 ) 1949 { 1950 uint32_t uid = 0, n; 1951 lookup_ctrl_t lc, lc2; 1952 int i = 0, ret = 0, ret_save = 0; 1953 bmp_t *p; 1954 1955 lc.curr_uid = 0; 1956 lc.type = OBJ_DD; 1957 lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID); 1958 lc.op[0] = OP_STRING; 1959 lc.op[1] = 0; 1960 1961 SET_UID_LCP(&lc2, OBJ_ISCSI, 0); 1962 1963 lc2.data[1].ptr = (uchar_t *)doc; 1964 1965 while (i < req->count) { 1966 lc.data[0].ptr = (uchar_t *)req->req_data.data[i]; 1967 if ((uid = is_obj_there(&lc)) != 0) { 1968 ret = get_dd_matrix(uid, &p, &n); 1969 FOR_EACH_MEMBER(p, n, uid, { 1970 lc2.data[0].ui = uid; 1971 lc2.data[2].ptr = (uchar_t *)req->req_data.data[i]; 1972 ret = cache_lookup(&lc2, NULL, 1973 cb_getAssociated_node_info); 1974 }); 1975 free(p); 1976 } else { 1977 ret = ERR_MATCHING_DD_NOT_FOUND; 1978 } 1979 /* save error for this iteration */ 1980 if (ret != 0) { 1981 ret_save = ret; 1982 } 1983 ret = 0; 1984 i++; 1985 } 1986 1987 return (handle_partial_success(doc, ret_save)); 1988 } 1989 1990 /* 1991 * **************************************************************************** 1992 * 1993 * getassociated_node_to_dd_op: 1994 * construct a list of Discovery Doamins that is associated with a given 1995 * node. 1996 * 1997 * req - contains getAssociated request info. 1998 * doc - response doc to fill up 1999 * 2000 * **************************************************************************** 2001 */ 2002 int 2003 getAssociated_node_to_dd_op( 2004 request_t *req, 2005 xmlDocPtr doc 2006 /* any additional arguments go here */ 2007 ) 2008 { 2009 uint32_t uid = 0, dd_id; 2010 lookup_ctrl_t lc, lc2; 2011 int i = 0, ret = 0, ret_save = 0; 2012 2013 lc.curr_uid = 0; 2014 lc.type = OBJ_ISCSI; 2015 lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID); 2016 lc.op[0] = OP_STRING; 2017 lc.op[1] = 0; 2018 2019 SET_UID_LCP(&lc2, OBJ_DD, 0); 2020 2021 lc2.data[1].ptr = (uchar_t *)doc; 2022 2023 while (i < req->count) { 2024 lc.data[0].ptr = (uchar_t *)req->req_data.data[i]; 2025 if ((uid = is_obj_there(&lc)) != 0) { 2026 if ((dd_id = get_dd_id(uid, 0)) == 0) { 2027 ret = ERR_NO_ASSOCIATED_DD_FOUND; 2028 i++; 2029 continue; 2030 } else { 2031 do { 2032 lc2.data[0].ui = dd_id; 2033 lc2.data[2].ptr = (uchar_t *)req->req_data.data[i]; 2034 ret = cache_lookup(&lc2, NULL, 2035 cb_getAssociated_node_to_dd_info); 2036 dd_id = get_dd_id(uid, dd_id); 2037 } while (dd_id != 0); 2038 }; 2039 } else { 2040 ret = ERR_MATCHING_NODE_NOT_FOUND; 2041 } 2042 /* save error for this iteration */ 2043 if (ret != 0) { 2044 ret_save = ret; 2045 } 2046 ret = 0; 2047 i++; 2048 } 2049 2050 return (handle_partial_success(doc, ret_save)); 2051 } 2052 2053 /* 2054 * **************************************************************************** 2055 * 2056 * getassociated_ddset_to_dd_op: 2057 * construct a list of Discovery Doamins that is associated with a given 2058 * Discover Domain set. 2059 * 2060 * req - contains getAssociated request info. 2061 * doc - response doc to fill up 2062 * 2063 * **************************************************************************** 2064 */ 2065 int 2066 getAssociated_ddset_to_dd_op( 2067 request_t *req, 2068 xmlDocPtr doc 2069 /* any additional arguments go here */ 2070 ) 2071 { 2072 uint32_t uid = 0, n; 2073 lookup_ctrl_t lc, lc2; 2074 int i = 0, ret = 0, ret_save = 0; 2075 bmp_t *p; 2076 2077 lc.curr_uid = 0; 2078 lc.type = OBJ_DDS; 2079 lc.id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID); 2080 lc.op[0] = OP_STRING; 2081 lc.op[1] = 0; 2082 2083 SET_UID_LCP(&lc2, OBJ_DD, 0); 2084 2085 lc2.data[1].ptr = (uchar_t *)doc; 2086 2087 while (i < req->count) { 2088 lc.data[0].ptr = (uchar_t *)req->req_data.data[i]; 2089 if ((uid = is_obj_there(&lc)) != 0) { 2090 ret = get_dds_matrix(uid, &p, &n); 2091 FOR_EACH_MEMBER(p, n, uid, { 2092 lc2.data[0].ui = uid; 2093 lc2.data[2].ptr = (uchar_t *)req->req_data.data[i]; 2094 ret = cache_lookup(&lc2, NULL, 2095 cb_getAssociated_dd_info); 2096 }); 2097 free(p); 2098 } else { 2099 ret = ERR_MATCHING_DDSET_NOT_FOUND; 2100 } 2101 /* save error for this iteration */ 2102 if (ret != 0) { 2103 ret_save = ret; 2104 } 2105 ret = 0; 2106 i++; 2107 } 2108 2109 return (handle_partial_success(doc, ret_save)); 2110 } 2111 2112 /* 2113 * **************************************************************************** 2114 * 2115 * getassociated_dd_to_ddset_op: 2116 * construct a list of Discovery Doamin sets that is associated with a 2117 * given Discovery Domain. 2118 * 2119 * req - contains getAssociated request info. 2120 * doc - response doc to fill up 2121 * 2122 * **************************************************************************** 2123 */ 2124 int 2125 getAssociated_dd_to_ddset_op( 2126 request_t *req, 2127 xmlDocPtr doc 2128 /* any additional arguments go here */ 2129 ) 2130 { 2131 uint32_t uid = 0, ddset_id; 2132 lookup_ctrl_t lc, lc2; 2133 int i = 0, ret = 0, ret_save = 0; 2134 2135 lc.curr_uid = 0; 2136 lc.type = OBJ_DD; 2137 lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID); 2138 lc.op[0] = OP_STRING; 2139 lc.op[1] = 0; 2140 2141 SET_UID_LCP(&lc2, OBJ_DDS, 0); 2142 2143 lc2.data[1].ptr = (uchar_t *)doc; 2144 2145 while (i < req->count) { 2146 lc.data[0].ptr = (uchar_t *)req->req_data.data[i]; 2147 if ((uid = is_obj_there(&lc)) != 0) { 2148 lc2.data[2].ui = 0; 2149 if ((ddset_id = get_dds_id(uid, 0)) == 0) { 2150 ret = ERR_NO_ASSOCIATED_DDSET_FOUND; 2151 i++; 2152 continue; 2153 } else { 2154 do { 2155 lc2.data[0].ui = ddset_id; 2156 lc2.data[2].ptr = (uchar_t *)req->req_data.data[i]; 2157 ret = cache_lookup(&lc2, NULL, 2158 cb_getAssociated_dd_to_ddset_info); 2159 ddset_id = get_dds_id(uid, ddset_id); 2160 } while (ddset_id != 0); 2161 }; 2162 } else { 2163 ret = ERR_MATCHING_DD_NOT_FOUND; 2164 } 2165 if (ret != 0) { 2166 ret_save = ret; 2167 } 2168 i++; 2169 } 2170 2171 return (handle_partial_success(doc, ret_save)); 2172 } 2173 2174 /* 2175 * **************************************************************************** 2176 * 2177 * delete_dd_ddset_op: 2178 * removes a list of dd or dd set. 2179 * 2180 * req - contains delete request info. 2181 * doc - response doc to fill up 2182 * obj_type - object type(either dd or dd set) 2183 * 2184 * **************************************************************************** 2185 */ 2186 int 2187 delete_dd_ddset_op( 2188 request_t *req, 2189 xmlDocPtr doc, 2190 object_type type 2191 /* any additional arguments go here */ 2192 ) 2193 { 2194 result_code_t ret = 0, ret_save = 0; 2195 isns_type_t lc_type; 2196 int i = 0, err_count = 0; 2197 lookup_ctrl_t lc; 2198 uint32_t uid; 2199 xmlNodePtr n_obj, n_node, root; 2200 xmlAttrPtr n_attr; 2201 int different_err = 0; 2202 2203 root = xmlDocGetRootElement(doc); 2204 if (root == NULL) { 2205 return (ERR_SYNTAX_MISSING_ROOT); 2206 } 2207 lc_type = get_lc_type(type); 2208 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) { 2209 return (ERR_INVALID_MGMT_REQUEST); 2210 } 2211 2212 /* prepare lookup ctrl data for looking for the node object */ 2213 lc.curr_uid = 0; 2214 lc.type = lc_type; 2215 lc.id[0] = get_lc_id(req->op_info.obj); 2216 lc.op[0] = OP_STRING; 2217 lc.op[1] = 0; 2218 lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */ 2219 while (i < req->count) { 2220 lc.data[0].ptr = (uchar_t *)req->req_data.data[i]; 2221 2222 /* lock the cache for writing */ 2223 (void) cache_lock_write(); 2224 2225 if ((uid = is_obj_there(&lc)) != 0) { 2226 /* remove the dd/ddset */ 2227 ret = (lc_type == OBJ_DD) ? 2228 remove_dd_object(uid) : 2229 remove_dds_object(uid); 2230 /* unlock the cache and sync the data */ 2231 ret = cache_unlock_sync(ret); 2232 } else { 2233 /* unlock the cache and no need to sync data */ 2234 (void) cache_unlock_nosync(); 2235 /* set an error and continue. */ 2236 ret = ERR_MATCHING_DD_NOT_FOUND; 2237 } 2238 2239 if (ret != 0) { 2240 /* keep track if there are different errors encountered. */ 2241 if (ret_save != 0 && ret != ret_save) { 2242 different_err++; 2243 } 2244 err_count++; 2245 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT); 2246 if (n_obj) { 2247 if ((n_obj = xmlAddChild(root, n_obj)) == NULL) { 2248 return (ERR_XML_ADDCHILD_FAILED); 2249 } 2250 } else { 2251 return (ERR_XML_NEWNODE_FAILED); 2252 } 2253 2254 n_node = (lc_type == OBJ_DD) ? 2255 xmlNewNode(NULL, (xmlChar *)DDOBJECT) : 2256 xmlNewNode(NULL, (xmlChar *)DDSETOBJECT); 2257 if (n_node) { 2258 if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) { 2259 return (ERR_XML_ADDCHILD_FAILED); 2260 } 2261 n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR, 2262 (xmlChar *)req->req_data.data[i]); 2263 if (n_attr == NULL) { 2264 return (ERR_XML_SETPROP_FAILED); 2265 } 2266 } else { 2267 return (ERR_XML_NEWNODE_FAILED); 2268 } 2269 ret_save = ret; 2270 } 2271 i ++; 2272 } 2273 2274 return (handle_partial_failure(doc, ret_save, 2275 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE)); 2276 } 2277 2278 /* 2279 * **************************************************************************** 2280 * 2281 * delete_ddmember_ddsetmember_op: 2282 * removes a list of dd memeber or dd seti member. 2283 * 2284 * req - contains delete request info. 2285 * doc - response doc to fill up 2286 * type - object type(either dd or dd set) 2287 * 2288 * **************************************************************************** 2289 */ 2290 int 2291 delete_ddmember_ddsetmember_op( 2292 request_t *req, 2293 xmlDocPtr doc, 2294 object_type type 2295 /* any additional arguments go here */ 2296 ) 2297 { 2298 result_code_t ret = 0, ret_save = 0; 2299 isns_type_t lc_type; 2300 int i = 0, err_count = 0; 2301 lookup_ctrl_t lc, lc2; 2302 uint32_t container_id, member_id; 2303 xmlNodePtr n_node, n_obj, root; 2304 xmlAttrPtr n_attr; 2305 int different_err = 0; 2306 int is_a_member; 2307 2308 lc_type = get_lc_type(type); 2309 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) { 2310 return (ERR_INVALID_MGMT_REQUEST); 2311 } 2312 2313 /* prepare lookup ctrl data for looking for the node object */ 2314 lc.curr_uid = 0; 2315 lc.type = lc_type; 2316 lc.id[0] = get_lc_id(req->op_info.obj); 2317 lc.op[0] = OP_STRING; 2318 lc.op[1] = 0; 2319 2320 lc2.curr_uid = 0; 2321 if (lc_type == OBJ_DD) { 2322 lc2.type = OBJ_ISCSI; 2323 lc2.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID); 2324 } else { 2325 lc2.type = OBJ_DD; 2326 lc2.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID); 2327 } 2328 lc2.op[0] = OP_STRING; 2329 lc2.op[1] = 0; 2330 2331 root = xmlDocGetRootElement(doc); 2332 if (root == NULL) { 2333 return (ERR_SYNTAX_MISSING_ROOT); 2334 } 2335 2336 while (i < req->count) { 2337 lc.data[0].ptr = (uchar_t *)req->req_data.pair[i]->container; 2338 2339 /* get the dd_id/dds_id */ 2340 (void) cache_lock_write(); 2341 container_id = is_obj_there(&lc); 2342 2343 if (container_id != 0) { 2344 lc2.data[0].ptr = (uchar_t *)req->req_data.pair[i]->member; 2345 2346 member_id = is_obj_there(&lc2); 2347 if (member_id != 0) { 2348 is_a_member = 2349 (container_id == 2350 ((lc_type == OBJ_DD) ? 2351 get_dd_id(member_id, container_id - 1) : 2352 get_dds_id(member_id, container_id - 1))); 2353 } 2354 if (member_id != 0 && is_a_member != 0) { 2355 /* delete the dd member */ 2356 ret = (lc_type == OBJ_DD) ? 2357 i_delete_ddmember_op( 2358 (uchar_t *)req->req_data.pair[i]->container, 2359 (uchar_t *)req->req_data.pair[i]->member) : 2360 i_delete_ddsetmember_op( 2361 (uchar_t *)req->req_data.pair[i]->container, 2362 (uchar_t *)req->req_data.pair[i]->member); 2363 /* unlock the cache and sync the data */ 2364 ret = cache_unlock_sync(ret); 2365 } else { 2366 /* unlock the cache and no need to sync */ 2367 (void) cache_unlock_nosync(); 2368 ret = ERR_NO_SUCH_ASSOCIATION; 2369 } 2370 } else { 2371 /* unlock the cache and no need to sync */ 2372 (void) cache_unlock_nosync(); 2373 ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND : 2374 ERR_MATCHING_DDSET_NOT_FOUND; 2375 } 2376 2377 if (ret != 0) { 2378 /* keep track if there are different errors encountered. */ 2379 if (ret_save != 0 && ret != ret_save) { 2380 different_err++; 2381 } 2382 ret_save = ret; 2383 err_count++; 2384 n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION); 2385 if (n_obj) { 2386 n_obj = xmlAddChild(root, n_obj); 2387 if (n_obj == NULL) { 2388 return (ERR_XML_ADDCHILD_FAILED); 2389 } 2390 } else { 2391 return (ERR_XML_NEWNODE_FAILED); 2392 } 2393 if (lc_type == OBJ_DD) { 2394 n_node = 2395 xmlNewNode(NULL, (xmlChar *)DDOBJECTMEMBER); 2396 n_attr = xmlSetProp(n_node, (xmlChar *)NODENAMEATTR, 2397 (xmlChar *)req->req_data.pair[i]->member); 2398 if (n_attr == NULL) { 2399 return (ERR_XML_SETPROP_FAILED); 2400 } 2401 n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR, 2402 (xmlChar *)req->req_data.pair[i]->container); 2403 if (n_attr == NULL) { 2404 return (ERR_XML_SETPROP_FAILED); 2405 } 2406 } else { 2407 n_node = 2408 xmlNewNode(NULL, (xmlChar *)DDSETOBJECTMEMBER); 2409 n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR, 2410 (xmlChar *)req->req_data.pair[i]->member); 2411 if (n_attr == NULL) { 2412 return (ERR_XML_SETPROP_FAILED); 2413 } 2414 n_attr = xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR, 2415 (xmlChar *)req->req_data.pair[i]->container); 2416 if (n_attr == NULL) { 2417 return (ERR_XML_SETPROP_FAILED); 2418 } 2419 } 2420 if (xmlAddChild(n_obj, n_node) == NULL) { 2421 return (ERR_XML_ADDCHILD_FAILED); 2422 } 2423 } 2424 i++; 2425 } 2426 2427 return (handle_partial_failure(doc, ret_save, 2428 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE)); 2429 } 2430 2431 /* 2432 * **************************************************************************** 2433 * 2434 * create_ddmember_ddsetmember_op: 2435 * removes a list of dd memeber or dd seti member. 2436 * 2437 * req - contains delete request info. 2438 * doc - response doc to fill up 2439 * type - object type(either dd or dd set) 2440 * 2441 * **************************************************************************** 2442 */ 2443 int 2444 create_ddmember_ddsetmember_op( 2445 request_t *req, 2446 xmlDocPtr doc, 2447 object_type type 2448 /* any additional arguments go here */ 2449 ) 2450 { 2451 result_code_t ret = 0, ret_save = 0; 2452 isns_type_t lc_type; 2453 int i = 0, err_count = 0; 2454 lookup_ctrl_t lc, lc2; 2455 uint32_t container_id, member_id; 2456 xmlNodePtr n_node, n_obj, root; 2457 isns_assoc_iscsi_t aiscsi = { 0 }; 2458 isns_assoc_dd_t add = { 0 }; 2459 isns_obj_t *assoc; 2460 isns_attr_t *attr; 2461 uint32_t len; 2462 int different_err = 0; 2463 2464 lc_type = get_lc_type(type); 2465 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) { 2466 return (ERR_INVALID_MGMT_REQUEST); 2467 } 2468 2469 /* prepare lookup ctrl data for looking for the node object */ 2470 lc.curr_uid = 0; 2471 lc.type = lc_type; 2472 lc.id[0] = get_lc_id(req->op_info.obj); 2473 lc.op[0] = OP_STRING; 2474 lc.op[1] = 0; 2475 2476 lc2.curr_uid = 0; 2477 if (lc_type == OBJ_DD) { 2478 lc2.type = OBJ_ISCSI; 2479 lc2.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID); 2480 } else { 2481 lc2.type = OBJ_DD; 2482 lc2.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID); 2483 } 2484 lc2.op[0] = OP_STRING; 2485 lc2.op[1] = 0; 2486 2487 root = xmlDocGetRootElement(doc); 2488 if (root == NULL) { 2489 return (ERR_SYNTAX_MISSING_ROOT); 2490 } 2491 2492 while (i < req->count) { 2493 lc.data[0].ptr = (uchar_t *)req->req_data.pair[i]->container; 2494 2495 /* get the dd_id/dds_id */ 2496 (void) cache_lock_write(); 2497 container_id = is_obj_there(&lc); 2498 2499 if (container_id != 0) { 2500 (void) memset(&aiscsi, 0, sizeof (aiscsi)); 2501 if (lc_type == OBJ_DD) { 2502 aiscsi.puid = container_id; 2503 aiscsi.type = OBJ_ASSOC_ISCSI; 2504 attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI( 2505 ISNS_DD_ISCSI_NAME_ATTR_ID)]; 2506 attr->tag = ISNS_DD_ISCSI_NAME_ATTR_ID; 2507 len = xmlStrlen( 2508 (xmlChar *)req->req_data.pair[i]->member) + 1; 2509 len += 4 - (len % 4); /* on 4 bytes aligned */ 2510 attr->len = len; 2511 attr->value.ptr = 2512 (uchar_t *)req->req_data.pair[i]->member; 2513 assoc = (isns_obj_t *)&aiscsi; 2514 2515 /* add the dd member */ 2516 ret = add_dd_member(assoc); 2517 2518 /* unlock the cache and sync the data */ 2519 ret = cache_unlock_sync(ret); 2520 } else { 2521 lc2.data[0].ptr = 2522 (uchar_t *)req->req_data.pair[i]->member; 2523 2524 if ((member_id = is_obj_there(&lc2)) != 0) { 2525 add.puid = container_id; 2526 add.type = OBJ_ASSOC_DD; 2527 attr = &add.attrs[ATTR_INDEX_ASSOC_DD( 2528 ISNS_DD_ID_ATTR_ID)]; 2529 attr->tag = ISNS_DD_ID_ATTR_ID; 2530 attr->len = 4; 2531 attr->value.ui = member_id; 2532 assoc = (isns_obj_t *)&add; 2533 2534 /* add the dd-set member */ 2535 ret = add_dds_member(assoc); 2536 2537 /* unlock the cache and sync the data */ 2538 ret = cache_unlock_sync(ret); 2539 } else { 2540 /* unlock the cache and no need to sync */ 2541 (void) cache_unlock_nosync(); 2542 ret = ERR_MATCHING_DD_NOT_FOUND; 2543 } 2544 } 2545 } else { 2546 /* unlock the cache and no need to sync */ 2547 (void) cache_unlock_nosync(); 2548 ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND : 2549 ERR_MATCHING_DDSET_NOT_FOUND; 2550 } 2551 if (ret != 0) { 2552 /* keep track if there are different errors encountered. */ 2553 if (ret_save != 0 && ret != ret_save) { 2554 different_err++; 2555 } 2556 err_count++; 2557 n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION); 2558 if (n_obj) { 2559 n_obj = xmlAddChild(root, n_obj); 2560 if (n_obj == NULL) { 2561 return (ERR_XML_ADDCHILD_FAILED); 2562 } 2563 } else { 2564 return (ERR_XML_NEWNODE_FAILED); 2565 } 2566 if (lc_type == OBJ_DD) { 2567 n_node = 2568 xmlNewNode(NULL, (xmlChar *)DDOBJECTMEMBER); 2569 if (xmlSetProp(n_node, (xmlChar *)NODENAMEATTR, 2570 (xmlChar *)req->req_data.pair[i]->member) == NULL) { 2571 return (ERR_XML_SETPROP_FAILED); 2572 } 2573 if (xmlSetProp(n_node, (xmlChar *)DDNAMEATTR, 2574 (xmlChar *)req->req_data.pair[i]->container) == 2575 NULL) { 2576 return (ERR_XML_SETPROP_FAILED); 2577 } 2578 } else { 2579 n_node = 2580 xmlNewNode(NULL, (xmlChar *)DDSETOBJECTMEMBER); 2581 if (xmlSetProp(n_node, (xmlChar *)DDNAMEATTR, 2582 (xmlChar *)req->req_data.pair[i]->member) == NULL) { 2583 return (ERR_XML_SETPROP_FAILED); 2584 } 2585 if (xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR, 2586 (xmlChar *)req->req_data.pair[i]->container) == 2587 NULL) { 2588 return (ERR_XML_SETPROP_FAILED); 2589 } 2590 } 2591 if (xmlAddChild(n_obj, n_node) == NULL) { 2592 return (ERR_XML_ADDCHILD_FAILED); 2593 } 2594 ret_save = ret; 2595 } 2596 i++; 2597 } 2598 2599 return (handle_partial_failure(doc, ret_save, 2600 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE)); 2601 } 2602 2603 /* 2604 * **************************************************************************** 2605 * 2606 * rename_dd_ddset_op: 2607 * removes a list of dd memeber or dd seti member. 2608 * 2609 * req - contains delete request info. 2610 * doc - response doc to fill up 2611 * type - object type(either dd or dd set) 2612 * 2613 * **************************************************************************** 2614 */ 2615 static int 2616 rename_dd_ddset_op( 2617 request_t *req, 2618 xmlDocPtr doc, 2619 object_type type 2620 /* any additional arguments go here */ 2621 ) 2622 { 2623 result_code_t ret = 0, ret_save = 0; 2624 isns_type_t lc_type; 2625 int i = 0, err_count = 0; 2626 lookup_ctrl_t lc; 2627 uint32_t container_id; 2628 xmlNodePtr n_node, n_obj, root; 2629 uchar_t *name; 2630 uint32_t len; 2631 int different_err = 0; 2632 2633 lc_type = get_lc_type(type); 2634 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) { 2635 return (ERR_INVALID_MGMT_REQUEST); 2636 } 2637 2638 /* prepare lookup ctrl data for looking for the node object */ 2639 SET_UID_LCP(&lc, lc_type, 0); 2640 2641 root = xmlDocGetRootElement(doc); 2642 if (root == NULL) { 2643 return (ERR_SYNTAX_MISSING_ROOT); 2644 } 2645 2646 while (i < req->count) { 2647 /* id is checked to be not NULL before calling this routine. */ 2648 lc.data[0].ui = *(req->req_data.attrlist[i]->id); 2649 2650 /* get the dd_id/dds_id */ 2651 (void) cache_lock_write(); 2652 2653 if ((container_id = is_obj_there(&lc)) != 0) { 2654 name = (uchar_t *)req->req_data.attrlist[i]->name; 2655 /* the length of the name need to include the */ 2656 /* null terminator and be on 4 bytes aligned */ 2657 len = xmlStrlen(name) + 1; 2658 len += 4 - (len % 4); 2659 2660 /* rename the dd/dds */ 2661 ret = (lc_type == OBJ_DD) ? 2662 update_dd_name(container_id, len, name) : 2663 update_dds_name(container_id, len, name); 2664 2665 /* release the lock and sync the data */ 2666 ret = cache_unlock_sync(ret); 2667 } else { 2668 /* release the lock and no need to sync */ 2669 (void) cache_unlock_nosync(); 2670 ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND : 2671 ERR_MATCHING_DDSET_NOT_FOUND; 2672 } 2673 if (ret != 0) { 2674 /* keep track if there are different errors encountered. */ 2675 if (ret_save != 0 && ret != ret_save) { 2676 different_err++; 2677 } 2678 ret_save = ret; 2679 err_count++; 2680 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT); 2681 if (n_obj) { 2682 if ((n_obj = xmlAddChild(root, n_obj)) == NULL) { 2683 return (ERR_XML_ADDCHILD_FAILED); 2684 } 2685 } else { 2686 return (ERR_XML_NEWNODE_FAILED); 2687 } 2688 2689 n_node = (lc_type == OBJ_DD) ? 2690 xmlNewNode(NULL, (xmlChar *)DDOBJECT) : 2691 xmlNewNode(NULL, (xmlChar *)DDSETOBJECT); 2692 if (n_node) { 2693 if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) { 2694 return (ERR_XML_ADDCHILD_FAILED); 2695 } else { 2696 if (xmlSetProp(n_node, (xmlChar *)NAMEATTR, 2697 (xmlChar *)req->req_data.attrlist[i]->name) == 2698 NULL) { 2699 return (ERR_XML_SETPROP_FAILED); 2700 } 2701 } 2702 } else { 2703 return (ERR_XML_NEWNODE_FAILED); 2704 } 2705 2706 } 2707 i++; 2708 } 2709 2710 return (handle_partial_failure(doc, ret_save, 2711 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE)); 2712 } 2713 2714 /* 2715 * **************************************************************************** 2716 * 2717 * update_dd_ddset_op: 2718 * removes a list of dd memeber or dd seti member. 2719 * 2720 * req - contains delete request info. 2721 * doc - response doc to fill up 2722 * type - object type(either dd or dd set) 2723 * 2724 * **************************************************************************** 2725 */ 2726 static int 2727 update_dd_ddset_op( 2728 request_t *req, 2729 xmlDocPtr doc, 2730 object_type type 2731 /* any additional arguments go here */ 2732 ) 2733 { 2734 result_code_t ret = 0, ret_save = 0; 2735 isns_type_t lc_type; 2736 int i = 0, err_count = 0; 2737 lookup_ctrl_t lc; 2738 uint32_t container_id; 2739 xmlNodePtr n_node, n_obj, root; 2740 int different_err = 0; 2741 2742 lc_type = get_lc_type(type); 2743 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) { 2744 return (ERR_INVALID_MGMT_REQUEST); 2745 } 2746 2747 /* prepare lookup ctrl data for looking for the node object */ 2748 lc.curr_uid = 0; 2749 lc.type = lc_type; 2750 lc.id[0] = get_lc_id(req->op_info.obj); 2751 lc.op[0] = OP_STRING; 2752 lc.op[1] = 0; 2753 2754 root = xmlDocGetRootElement(doc); 2755 if (root == NULL) { 2756 return (ERR_SYNTAX_MISSING_ROOT); 2757 } 2758 2759 while (i < req->count) { 2760 lc.data[0].ptr = req->req_data.attrlist[i]->name; 2761 2762 /* lock the cache for writing */ 2763 (void) cache_lock_write(); 2764 2765 if ((container_id = is_obj_there(&lc)) != 0) { 2766 ret = (lc_type == OBJ_DD) ? 2767 /* enabled is checked to be not NULL before calling. */ 2768 update_dd_features(container_id, 2769 *(req->req_data.attrlist[i]->enabled) ? 1 : 0): 2770 update_dds_status(container_id, 2771 *(req->req_data.attrlist[i]->enabled) ? 1 : 0); 2772 /* unlock the cache and sync the data */ 2773 ret = cache_unlock_sync(ret); 2774 } else { 2775 (void) cache_unlock_nosync(); 2776 ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND : 2777 ERR_MATCHING_DDSET_NOT_FOUND; 2778 } 2779 if (ret != 0) { 2780 /* keep track if there are different errors encountered. */ 2781 if (ret_save != 0 && ret != ret_save) { 2782 different_err++; 2783 } 2784 ret_save = ret; 2785 err_count++; 2786 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT); 2787 if (n_obj) { 2788 if ((n_obj = xmlAddChild(root, n_obj)) == NULL) { 2789 return (ERR_XML_ADDCHILD_FAILED); 2790 } 2791 } else { 2792 return (ERR_XML_NEWNODE_FAILED); 2793 } 2794 2795 n_node = (lc_type == OBJ_DD) ? 2796 xmlNewNode(NULL, (xmlChar *)DDOBJECT) : 2797 xmlNewNode(NULL, (xmlChar *)DDSETOBJECT); 2798 if (n_node) { 2799 if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) { 2800 return (ERR_XML_ADDCHILD_FAILED); 2801 } else { 2802 if (xmlSetProp(n_node, (xmlChar *)NAMEATTR, 2803 (xmlChar *)req->req_data.attrlist[i]->name) == 2804 NULL) { 2805 return (ERR_XML_SETPROP_FAILED); 2806 } 2807 } 2808 } else { 2809 return (ERR_XML_NEWNODE_FAILED); 2810 } 2811 } 2812 i++; 2813 } 2814 2815 return (handle_partial_failure(doc, ret_save, 2816 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE)); 2817 } 2818 2819 /* 2820 * **************************************************************************** 2821 * 2822 * createModify_dd_ddset_op: 2823 * removes a list of dd memeber or dd seti member. 2824 * 2825 * req - contains delete request info. 2826 * doc - response doc to fill up 2827 * 2828 * **************************************************************************** 2829 */ 2830 static int 2831 create_dd_ddset_op( 2832 request_t *req, 2833 xmlDocPtr doc, 2834 object_type type 2835 /* any additional arguments go here */ 2836 ) 2837 { 2838 isns_obj_t *obj; 2839 result_code_t ret = 0, ret_save = 0; 2840 isns_type_t lc_type; 2841 lookup_ctrl_t lc; 2842 uint32_t uid; 2843 int i = 0, err_count = 0; 2844 xmlNodePtr n_obj, n_node, root; 2845 int different_err = 0; 2846 2847 lc_type = get_lc_type(type); 2848 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) { 2849 return (ERR_INVALID_MGMT_REQUEST); 2850 } 2851 2852 root = xmlDocGetRootElement(doc); 2853 if (root == NULL) { 2854 return (ERR_SYNTAX_MISSING_ROOT); 2855 } 2856 lc_type = get_lc_type(type); 2857 if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) { 2858 return (ERR_INVALID_MGMT_REQUEST); 2859 } 2860 2861 /* prepare lookup ctrl data for looking for the node object */ 2862 lc.curr_uid = 0; 2863 lc.type = lc_type; 2864 lc.id[0] = get_lc_id(req->op_info.obj); 2865 lc.op[0] = OP_STRING; 2866 lc.op[1] = 0; 2867 lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */ 2868 while (i < req->count) { 2869 lc.data[0].ptr = req->req_data.attrlist[i]->name, 2870 /* grab the write lock */ 2871 (void) cache_lock_write(); 2872 2873 uid = is_obj_there(&lc); 2874 if (uid == 0) { 2875 ret = (lc_type == OBJ_DD) ? 2876 adm_create_dd(&obj, req->req_data.attrlist[i]->name, 2877 0, 0) : 2878 adm_create_dds(&obj, req->req_data.attrlist[i]->name, 2879 0, 0); 2880 if (ret == 0) { 2881 ret = register_object(obj, NULL, NULL); 2882 if (ret != 0) { 2883 free_object(obj); 2884 } 2885 /* release the lock and sync the cache and data store */ 2886 ret = cache_unlock_sync(ret); 2887 } 2888 } else { 2889 /* release the lock and no need to sync the data */ 2890 (void) cache_unlock_nosync(); 2891 ret = ERR_NAME_IN_USE; 2892 } 2893 2894 if (ret != 0) { 2895 /* keep track if there are different errors encountered. */ 2896 if (ret_save != 0 && ret != ret_save) { 2897 different_err++; 2898 } 2899 ret_save = ret; 2900 err_count++; 2901 n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT); 2902 if (n_obj) { 2903 if ((n_obj = xmlAddChild(root, n_obj)) == NULL) { 2904 return (ERR_XML_ADDCHILD_FAILED); 2905 } 2906 } else { 2907 return (ERR_XML_ADDCHILD_FAILED); 2908 } 2909 2910 n_node = (lc_type == OBJ_DD) ? 2911 xmlNewNode(NULL, (xmlChar *)DDOBJECT) : 2912 xmlNewNode(NULL, (xmlChar *)DDSETOBJECT); 2913 if (n_node) { 2914 if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) { 2915 return (ERR_XML_ADDCHILD_FAILED); 2916 } else { 2917 if (xmlSetProp(n_node, (xmlChar *)NAMEATTR, 2918 (xmlChar *)req->req_data.attrlist[i]->name) == 2919 NULL) { 2920 return (ERR_XML_SETPROP_FAILED); 2921 } 2922 } 2923 } else { 2924 return (ERR_XML_NEWNODE_FAILED); 2925 } 2926 } 2927 i++; 2928 } 2929 2930 return (handle_partial_failure(doc, ret_save, 2931 (req->count == err_count && !different_err) ? B_TRUE : B_FALSE)); 2932 } 2933 2934 /* 2935 * **************************************************************************** 2936 * 2937 * createModify_dd_ddset_op: 2938 * removes a list of dd memeber or dd seti member. 2939 * 2940 * req - contains delete request info. 2941 * doc - response doc to fill up 2942 * 2943 * **************************************************************************** 2944 */ 2945 int 2946 createModify_dd_ddset_op( 2947 request_t *req, 2948 xmlDocPtr doc 2949 /* any additional arguments go here */ 2950 ) 2951 { 2952 result_code_t ret = 0; 2953 2954 if (req->req_data.attrlist[0]->id != NULL) { 2955 ret = rename_dd_ddset_op(req, doc, req->op_info.obj); 2956 } else if (req->req_data.attrlist[0]->enabled != NULL) { 2957 ret = update_dd_ddset_op(req, doc, req->op_info.obj); 2958 } else { 2959 ret = create_dd_ddset_op(req, doc, req->op_info.obj); 2960 } 2961 2962 return (ret); 2963 } 2964