PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/usr/src/cmd/isns/isnsd/admintf.c

https://bitbucket.org/buffyg/illumos-gate-1514
C | 2967 lines | 2149 code | 233 blank | 585 comment | 634 complexity | 3b2b81063b3255c33df1330254214026 MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-3.0, GPL-2.0, GPL-3.0, LGPL-3.0, 0BSD, AGPL-1.0, BSD-3-Clause, LGPL-2.1, LGPL-2.0, BSD-2-Clause
  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. * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
  23. * Use is subject to license terms.
  24. */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <libxml/xmlreader.h>
  29. #include <libxml/xmlwriter.h>
  30. #include <libxml/tree.h>
  31. #include <sys/types.h>
  32. #include <sys/socket.h>
  33. #include <netinet/in.h>
  34. #include <arpa/inet.h>
  35. #include <pthread.h>
  36. #include "isns_server.h"
  37. #include "isns_cfg.h"
  38. #include "isns_htab.h"
  39. #include "isns_cache.h"
  40. #include "isns_obj.h"
  41. #include "isns_dd.h"
  42. #include "isns_utils.h"
  43. #include "isns_mgmt.h"
  44. #include "isns_protocol.h"
  45. #include "admintf.h"
  46. extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE];
  47. static isns_type_t
  48. get_lc_type(
  49. object_type obj
  50. )
  51. {
  52. isns_type_t type;
  53. switch (obj) {
  54. case Node:
  55. type = OBJ_ISCSI;
  56. break;
  57. case DiscoveryDomain:
  58. case DiscoveryDomainMember:
  59. type = OBJ_DD;
  60. break;
  61. case DiscoveryDomainSet:
  62. case DiscoveryDomainSetMember:
  63. type = OBJ_DDS;
  64. break;
  65. default:
  66. ASSERT(0);
  67. break;
  68. }
  69. return (type);
  70. }
  71. static uint32_t
  72. get_lc_id(
  73. object_type obj
  74. )
  75. {
  76. uint32_t id;
  77. switch (obj) {
  78. case Node:
  79. id = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
  80. break;
  81. case DiscoveryDomain:
  82. case DiscoveryDomainMember:
  83. id = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
  84. break;
  85. case DiscoveryDomainSet:
  86. case DiscoveryDomainSetMember:
  87. id = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
  88. break;
  89. default:
  90. ASSERT(0);
  91. break;
  92. }
  93. return (id);
  94. }
  95. /*
  96. * ****************************************************************************
  97. *
  98. * cb_get_node_info: callback for get_node_op
  99. * The routine process matching node and add a Node object elements
  100. * to the response doc.
  101. *
  102. * p1 - matching node object
  103. * p2 - lookup control data that was used for node look up
  104. * returns parent index(newtork entity) in look up control.
  105. * return - error code
  106. *
  107. * ****************************************************************************
  108. */
  109. static int
  110. cb_get_node_info(
  111. void *p1,
  112. void *p2
  113. )
  114. {
  115. xmlNodePtr n_obj, n_node, sub_node, root;
  116. xmlAttrPtr n_attr;
  117. isns_attr_t *attr;
  118. isns_obj_t *obj = (isns_obj_t *)p1;
  119. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  120. xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
  121. root = xmlDocGetRootElement(doc);
  122. if (root == NULL) {
  123. return (ERR_XML_ADDCHILD_FAILED);
  124. }
  125. n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
  126. if (n_obj) {
  127. n_obj = xmlAddChild(root, n_obj);
  128. if (n_obj == NULL) {
  129. return (ERR_XML_ADDCHILD_FAILED);
  130. }
  131. } else {
  132. return (ERR_XML_ADDCHILD_FAILED);
  133. }
  134. n_node = xmlNewNode(NULL, (xmlChar *)NODEOBJECT);
  135. if (n_node) {
  136. n_node = xmlAddChild(n_obj, n_node);
  137. if (n_node == NULL) {
  138. return (ERR_XML_ADDCHILD_FAILED);
  139. }
  140. } else {
  141. return (ERR_XML_ADDCHILD_FAILED);
  142. }
  143. /* get node name, alias, type and generate xml info */
  144. attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
  145. n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
  146. (xmlChar *)attr->value.ptr);
  147. if (n_attr == NULL) {
  148. return (ERR_XML_SETPROP_FAILED);
  149. }
  150. attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_TYPE_ATTR_ID)];
  151. switch (attr->value.ui) {
  152. case ISNS_CONTROL_NODE_TYPE | ISNS_INITIATOR_NODE_TYPE:
  153. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  154. (xmlChar *)CONTROLNODEINITIATORTYPE);
  155. break;
  156. case ISNS_CONTROL_NODE_TYPE | ISNS_TARGET_NODE_TYPE:
  157. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  158. (xmlChar *)CONTROLNODETARGETTYPE);
  159. break;
  160. case ISNS_TARGET_NODE_TYPE:
  161. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  162. (xmlChar *)TARGETTYPE);
  163. break;
  164. case ISNS_INITIATOR_NODE_TYPE:
  165. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  166. (xmlChar *)INITIATORTYPE);
  167. break;
  168. case ISNS_CONTROL_NODE_TYPE:
  169. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  170. (xmlChar *)CONTROLNODETYPE);
  171. break;
  172. default:
  173. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  174. (xmlChar *)UNKNOWNTYPE);
  175. }
  176. if (n_attr == NULL) {
  177. return (ERR_XML_SETPROP_FAILED);
  178. }
  179. attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_ALIAS_ATTR_ID)];
  180. n_attr = xmlSetProp(n_node, (xmlChar *)ALIASATTR,
  181. (xmlChar *)attr->value.ptr);
  182. if (n_attr == NULL) {
  183. return (ERR_XML_SETPROP_FAILED);
  184. }
  185. /*
  186. * A node can have all or no SCN subsribtion.
  187. * May avoid redundant code with scsusrciption table.
  188. */
  189. attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_SCN_BITMAP_ATTR_ID)];
  190. if (IS_SCN_INIT_SELF_INFO_ONLY(attr->value.ui)) {
  191. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
  192. (xmlChar *)SCNINITSELFONLY);
  193. if (sub_node == NULL) {
  194. return (ERR_XML_NEWCHILD_FAILED);
  195. }
  196. }
  197. if (IS_SCN_TARGET_SELF_INFO_ONLY(attr->value.ui)) {
  198. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
  199. (xmlChar *)SCNTARGETSELFONLY);
  200. if (sub_node == NULL) {
  201. return (ERR_XML_NEWCHILD_FAILED);
  202. }
  203. }
  204. if (IS_SCN_MGMT_REG(attr->value.ui)) {
  205. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
  206. (xmlChar *)SCNTARGETSELFONLY);
  207. if (sub_node == NULL) {
  208. return (ERR_XML_NEWCHILD_FAILED);
  209. }
  210. }
  211. if (IS_SCN_OBJ_REMOVED(attr->value.ui)) {
  212. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
  213. (xmlChar *)SCNOBJECTREMOVED);
  214. if (sub_node == NULL) {
  215. return (ERR_XML_NEWCHILD_FAILED);
  216. }
  217. }
  218. if (IS_SCN_OBJ_ADDED(attr->value.ui)) {
  219. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
  220. (xmlChar *)SCNOBJECTADDED);
  221. if (sub_node == NULL) {
  222. return (ERR_XML_NEWCHILD_FAILED);
  223. }
  224. }
  225. if (IS_SCN_OBJ_UPDATED(attr->value.ui)) {
  226. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
  227. (xmlChar *)SCNOBJECTUPDATED);
  228. if (sub_node == NULL) {
  229. return (ERR_XML_NEWCHILD_FAILED);
  230. }
  231. }
  232. if (IS_SCN_MEMBER_REMOVED(attr->value.ui)) {
  233. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
  234. (xmlChar *)SCNMEMBERREMOVED);
  235. if (sub_node == NULL) {
  236. return (ERR_XML_NEWCHILD_FAILED);
  237. }
  238. }
  239. if (IS_SCN_MEMBER_ADDED(attr->value.ui)) {
  240. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)SCNSUBSCRIPTION,
  241. (xmlChar *)SCNMEMBERADDED);
  242. if (sub_node == NULL) {
  243. return (ERR_XML_NEWCHILD_FAILED);
  244. }
  245. }
  246. /* set the parent object id, i.e. the network entity object id */
  247. lcp->id[2] = get_parent_uid(obj);
  248. /* pass back the node object element to add entity, portal info to it */
  249. lcp->data[2].ptr = (uchar_t *)n_node;
  250. /* successful */
  251. return (0);
  252. }
  253. /*
  254. * ****************************************************************************
  255. *
  256. * cb_get_entity_info: callback for get_node_op
  257. * The routine process matching network entity and add children elements
  258. * to a Node object for given entity.
  259. *
  260. * p1 - matching entity object
  261. * p2 - lookup control data that was used for node look up
  262. * returns parent index(newtork entity) in look up control.
  263. * return - error code
  264. *
  265. * ****************************************************************************
  266. */
  267. static int
  268. cb_get_entity_info(
  269. void *p1,
  270. void *p2
  271. )
  272. {
  273. isns_obj_t *obj = (isns_obj_t *)p1;
  274. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  275. xmlNodePtr n_node = (xmlNodePtr)lcp->data[2].ptr;
  276. xmlNodePtr sub_node, subchild_node, subgrandchild_node;
  277. char numbuf[32];
  278. char buff[INET6_ADDRSTRLEN + 1] = { 0 };
  279. isns_attr_t *attr;
  280. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)NETWORKENTITY, NULL);
  281. if (sub_node) {
  282. attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)];
  283. subchild_node = xmlNewChild(sub_node, NULL,
  284. (xmlChar *)ENTITYID, (xmlChar *)attr->value.ptr);
  285. if (subchild_node == NULL) {
  286. return (ERR_XML_NEWCHILD_FAILED);
  287. }
  288. attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_ENTITY_PROTOCOL_ATTR_ID)];
  289. (void) sprintf(numbuf, "%u", attr->value.ui);
  290. subchild_node = xmlNewChild(sub_node, NULL,
  291. (xmlChar *)ENTITYPROTOCOL, (xmlChar *)numbuf);
  292. if (subchild_node == NULL) {
  293. return (ERR_XML_NEWCHILD_FAILED);
  294. }
  295. attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_MGMT_IP_ADDR_ATTR_ID)];
  296. if (attr->value.ip) {
  297. /* convert the ipv6 to ipv4 */
  298. if (((int *)attr->value.ip)[0] == 0x00 &&
  299. ((int *)attr->value.ip)[1] == 0x00 &&
  300. ((uchar_t *)attr->value.ip)[8] == 0x00 &&
  301. ((uchar_t *)attr->value.ip)[9] == 0x00 &&
  302. ((uchar_t *)attr->value.ip)[10] == 0xFF &&
  303. ((uchar_t *)attr->value.ip)[11] == 0xFF) {
  304. subchild_node = xmlNewChild(sub_node, NULL,
  305. (xmlChar *)MANAGEMENTIPADDR,
  306. (xmlChar *)inet_ntop(AF_INET,
  307. (void *)&(((uint32_t *)attr->value.ip)[3]),
  308. buff, sizeof (buff)));
  309. } else {
  310. subchild_node = xmlNewChild(sub_node, NULL,
  311. (xmlChar *)MANAGEMENTIPADDR,
  312. (xmlChar *)inet_ntop(AF_INET6,
  313. (void *)attr->value.ip, buff, sizeof (buff)));
  314. }
  315. if (subchild_node == NULL) {
  316. return (ERR_XML_NEWCHILD_FAILED);
  317. }
  318. }
  319. attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_TIMESTAMP_ATTR_ID)];
  320. if (attr->value.ui) {
  321. (void) sprintf(numbuf, "%u", attr->value.ui);
  322. subchild_node = xmlNewChild(sub_node, NULL,
  323. (xmlChar *)ENTITYREGTIMESTAMP, (xmlChar *)numbuf);
  324. if (subchild_node == NULL) {
  325. return (ERR_XML_NEWCHILD_FAILED);
  326. }
  327. }
  328. attr = &obj->attrs[ATTR_INDEX_ENTITY(ISNS_VERSION_RANGE_ATTR_ID)];
  329. if (attr->value.ui) {
  330. subchild_node = xmlNewNode(NULL,
  331. (xmlChar *)PROTOCOLVERSIONRANGE);
  332. subchild_node = xmlAddChild(sub_node, subchild_node);
  333. if (subchild_node == NULL) {
  334. return (ERR_XML_NEWCHILD_FAILED);
  335. }
  336. (void) sprintf(numbuf, "%u",
  337. (attr->value.ui >> ISNS_VER_SHIFT) & ISNS_VERSION);
  338. subgrandchild_node = xmlNewChild(subchild_node, NULL,
  339. (xmlChar *)PROTOCOLMAXVERSION, (xmlChar *)numbuf);
  340. if (subgrandchild_node == NULL) {
  341. return (ERR_XML_NEWCHILD_FAILED);
  342. }
  343. (void) sprintf(numbuf, "%u", attr->value.ui & ISNS_VERSION);
  344. subgrandchild_node = xmlNewChild(subchild_node, NULL,
  345. (xmlChar *)PROTOCOLMINVERSION, (xmlChar *)numbuf);
  346. if (subgrandchild_node == NULL) {
  347. return (ERR_XML_NEWCHILD_FAILED);
  348. }
  349. }
  350. attr =
  351. &obj->attrs[ATTR_INDEX_ENTITY(ISNS_ENTITY_REG_PERIOD_ATTR_ID)];
  352. if (attr->value.ui) {
  353. (void) sprintf(numbuf, "%u", attr->value.ui);
  354. subchild_node = xmlNewChild(sub_node, NULL,
  355. (xmlChar *)REGISTRATIONPERIOD, (xmlChar *)numbuf);
  356. if (subchild_node == NULL) {
  357. return (ERR_XML_NEWCHILD_FAILED);
  358. }
  359. }
  360. } else {
  361. return (ERR_XML_NEWCHILD_FAILED);
  362. }
  363. /* successful */
  364. return (0);
  365. }
  366. /*
  367. * ****************************************************************************
  368. *
  369. * cb_get_pg_info: callback for get_node_op
  370. * The routine process matching portal group and returns ip address
  371. * and port number for further portal processing.
  372. *
  373. * p1 - matching portal group object
  374. * p2 - lookup control data that was used for portal group look up
  375. * returns portal ip address, port and group tag in look up control.
  376. * return - error code
  377. *
  378. * ****************************************************************************
  379. */
  380. static int
  381. cb_get_pg_info(
  382. void *p1,
  383. void *p2
  384. )
  385. {
  386. isns_obj_t *obj = (isns_obj_t *)p1;
  387. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  388. isns_attr_t *attr;
  389. /* get pg portal ip address and port attributes */
  390. attr = &obj->attrs[ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)];
  391. (void) memcpy(lcp->data[1].ip, attr->value.ip, sizeof (in6_addr_t));
  392. attr = &obj->attrs[ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID)];
  393. lcp->data[2].ui = attr->value.ui;
  394. attr = &obj->attrs[ATTR_INDEX_PG(ISNS_PG_TAG_ATTR_ID)];
  395. lcp->id[2] = attr->value.ui;
  396. /* successful */
  397. return (0);
  398. }
  399. /*
  400. * ****************************************************************************
  401. *
  402. * cb_get_portal_info: callback for get_node_op
  403. * The routine process matching portal and add portal object info to
  404. * the node object.
  405. *
  406. * p1 - matching portal object
  407. * p2 - lookup control data that was used for portal look up
  408. * return - error code
  409. *
  410. * ****************************************************************************
  411. */
  412. static int
  413. cb_get_portal_info(
  414. void *p1,
  415. void *p2
  416. )
  417. {
  418. isns_obj_t *obj = (isns_obj_t *)p1;
  419. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  420. xmlNodePtr n_node = (xmlNodePtr)lcp->data[2].ptr;
  421. uint32_t tag = lcp->id[2];
  422. xmlNodePtr sub_node, subchild_node, subgrandchild_node;
  423. char numbuf[32];
  424. char buff[INET6_ADDRSTRLEN + 1] = { 0 };
  425. isns_attr_t *attr;
  426. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)PORTAL, NULL);
  427. /* get portal object attributes. */
  428. if (sub_node) {
  429. attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID)];
  430. if (attr->value.ip) {
  431. /* convert the ipv6 to ipv4 */
  432. if (((int *)attr->value.ip)[0] == 0x00 &&
  433. ((int *)attr->value.ip)[1] == 0x00 &&
  434. ((uchar_t *)attr->value.ip)[8] == 0x00 &&
  435. ((uchar_t *)attr->value.ip)[9] == 0x00 &&
  436. ((uchar_t *)attr->value.ip)[10] == 0xFF &&
  437. ((uchar_t *)attr->value.ip)[11] == 0xFF) {
  438. subchild_node = xmlNewChild(sub_node, NULL,
  439. (xmlChar *)IPADDR,
  440. (xmlChar *)inet_ntop(AF_INET,
  441. (void *)&(((uint32_t *)attr->value.ip)[3]),
  442. buff, sizeof (buff)));
  443. } else {
  444. subchild_node = xmlNewChild(sub_node, NULL,
  445. (xmlChar *)IPADDR,
  446. (xmlChar *)inet_ntop(AF_INET6,
  447. (void *)attr->value.ip, buff, sizeof (buff)));
  448. }
  449. if (subchild_node == NULL) {
  450. return (ERR_XML_NEWCHILD_FAILED);
  451. }
  452. }
  453. subchild_node = xmlNewChild(sub_node, NULL, (xmlChar *)UDPTCPPORT,
  454. NULL);
  455. if (subchild_node) {
  456. attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID)];
  457. subgrandchild_node = xmlNewChild(subchild_node, NULL,
  458. (xmlChar *)PORTTYPE, IS_PORT_UDP(attr->value.ui) ?
  459. (xmlChar *)UDPPORT : (xmlChar *)TCPPORT);
  460. if (subgrandchild_node == NULL) {
  461. return (ERR_XML_NEWCHILD_FAILED);
  462. }
  463. (void) sprintf(numbuf, "%u", PORT_NUMBER(attr->value.ui));
  464. subgrandchild_node = xmlNewChild(subchild_node, NULL,
  465. (xmlChar *)PORTNUMBER, (xmlChar *)numbuf);
  466. if (subgrandchild_node == NULL) {
  467. return (ERR_XML_NEWCHILD_FAILED);
  468. }
  469. } else {
  470. return (ERR_XML_NEWCHILD_FAILED);
  471. }
  472. (void) sprintf(numbuf, "%u", tag);
  473. subchild_node = xmlNewChild(sub_node, NULL, (xmlChar *)GROUPTAG,
  474. (xmlChar *)numbuf);
  475. if (subchild_node == NULL) {
  476. return (ERR_XML_NEWCHILD_FAILED);
  477. }
  478. attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_PORTAL_NAME_ATTR_ID)];
  479. if (attr->value.ptr) {
  480. subchild_node = xmlNewChild(sub_node, NULL,
  481. (xmlChar *)SYMBOLICNAME, (xmlChar *)attr->value.ptr);
  482. if (subchild_node == NULL) {
  483. return (ERR_XML_NEWCHILD_FAILED);
  484. }
  485. }
  486. attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_ESI_INTERVAL_ATTR_ID)];
  487. if (attr->value.ui) {
  488. (void) sprintf(numbuf, "%u", attr->value.ui);
  489. subchild_node = xmlNewChild(sub_node, NULL,
  490. (xmlChar *)ESIINTERVAL, (xmlChar *)numbuf);
  491. if (subchild_node == NULL) {
  492. return (ERR_XML_NEWCHILD_FAILED);
  493. }
  494. }
  495. attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_ESI_PORT_ATTR_ID)];
  496. if (attr->value.ui) {
  497. subchild_node = xmlNewChild(sub_node, NULL,
  498. (xmlChar *)ESIPORT, NULL);
  499. if (subchild_node) {
  500. subgrandchild_node = xmlNewChild(subchild_node, NULL,
  501. (xmlChar *)PORTTYPE, IS_PORT_UDP(attr->value.ui) ?
  502. (xmlChar *)UDPPORT : (xmlChar *)TCPPORT);
  503. if (subgrandchild_node == NULL) {
  504. return (ERR_XML_NEWCHILD_FAILED);
  505. }
  506. (void) sprintf(numbuf, "%u", PORT_NUMBER(attr->value.ui));
  507. subgrandchild_node = xmlNewChild(subchild_node, NULL,
  508. (xmlChar *)PORTNUMBER, (xmlChar *)numbuf);
  509. if (subgrandchild_node == NULL) {
  510. return (ERR_XML_NEWCHILD_FAILED);
  511. }
  512. } else {
  513. return (ERR_XML_NEWCHILD_FAILED);
  514. }
  515. }
  516. attr = &obj->attrs[ATTR_INDEX_PORTAL(ISNS_SCN_PORT_ATTR_ID)];
  517. if (attr->value.ui) {
  518. subchild_node = xmlNewChild(sub_node, NULL,
  519. (xmlChar *)SCNPORT, NULL);
  520. if (subchild_node) {
  521. subgrandchild_node = xmlNewChild(subchild_node, NULL,
  522. (xmlChar *)PORTTYPE, IS_PORT_UDP(attr->value.ui) ?
  523. (xmlChar *)UDPPORT : (xmlChar *)TCPPORT);
  524. (void) sprintf(numbuf, "%u", PORT_NUMBER(attr->value.ui));
  525. if (subgrandchild_node == NULL) {
  526. return (ERR_XML_NEWCHILD_FAILED);
  527. }
  528. subgrandchild_node = xmlNewChild(subchild_node, NULL,
  529. (xmlChar *)PORTNUMBER, (xmlChar *)numbuf);
  530. if (subgrandchild_node == NULL) {
  531. return (ERR_XML_NEWCHILD_FAILED);
  532. }
  533. } else {
  534. return (ERR_XML_NEWCHILD_FAILED);
  535. }
  536. }
  537. } else if (sub_node == NULL) {
  538. return (ERR_XML_NEWCHILD_FAILED);
  539. }
  540. /* successful */
  541. return (0);
  542. }
  543. /*
  544. * ****************************************************************************
  545. *
  546. * cb_get_dd_info: callback for get_dd_op
  547. * The routine process matching dd object
  548. *
  549. * p1 - matching dd object
  550. * p2 - lookup control data that was used for dd look up
  551. * return - error code
  552. *
  553. * ****************************************************************************
  554. */
  555. static int
  556. cb_get_dd_info(
  557. void *p1,
  558. void *p2
  559. )
  560. {
  561. xmlNodePtr n_obj, n_node, sub_node, root;
  562. xmlAttrPtr n_attr;
  563. isns_attr_t *attr;
  564. char numbuf[32];
  565. isns_obj_t *obj = (isns_obj_t *)p1;
  566. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  567. xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
  568. root = xmlDocGetRootElement(doc);
  569. if (root == NULL) {
  570. return (ERR_SYNTAX_MISSING_ROOT);
  571. }
  572. n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
  573. if (n_obj) {
  574. n_obj = xmlAddChild(root, n_obj);
  575. if (n_obj == NULL) {
  576. return (ERR_XML_ADDCHILD_FAILED);
  577. }
  578. } else {
  579. return (ERR_XML_ADDCHILD_FAILED);
  580. }
  581. n_node = xmlNewNode(NULL, (xmlChar *)DDOBJECT);
  582. if (n_node) {
  583. n_node = xmlAddChild(n_obj, n_node);
  584. if (n_node == NULL) {
  585. return (ERR_XML_ADDCHILD_FAILED);
  586. }
  587. } else {
  588. return (ERR_XML_ADDCHILD_FAILED);
  589. }
  590. attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)];
  591. n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
  592. (xmlChar *)attr->value.ptr);
  593. if (n_attr == NULL) {
  594. return (ERR_XML_SETPROP_FAILED);
  595. }
  596. attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_ID_ATTR_ID)];
  597. (void) sprintf(numbuf, "%u", attr->value.ui);
  598. n_attr = xmlSetProp(n_node, (xmlChar *)IDATTR,
  599. (xmlChar *)numbuf);
  600. if (n_attr == NULL) {
  601. return (ERR_XML_SETPROP_FAILED);
  602. }
  603. attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_FEATURES_ATTR_ID)];
  604. if (DD_BOOTLIST_ENABLED(attr->value.ui)) {
  605. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)BOOTLISTENABLEDELEM,
  606. (xmlChar *)XMLTRUE);
  607. if (sub_node == NULL) {
  608. return (ERR_XML_NEWCHILD_FAILED);
  609. }
  610. } else {
  611. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)BOOTLISTENABLEDELEM,
  612. (xmlChar *)XMLFALSE);
  613. if (sub_node == NULL) {
  614. return (ERR_XML_NEWCHILD_FAILED);
  615. }
  616. }
  617. /* successful */
  618. return (0);
  619. }
  620. /*
  621. * ****************************************************************************
  622. *
  623. * cb_get_ddset_info: callback for get_ddset_op
  624. * The routine process matching dd object
  625. *
  626. * p1 - matching dds object
  627. * p2 - lookup control data that was used for dd set look up
  628. * return - error code
  629. *
  630. * ****************************************************************************
  631. */
  632. static int
  633. cb_get_ddset_info(
  634. void *p1,
  635. void *p2
  636. )
  637. {
  638. xmlNodePtr n_obj, n_node, sub_node, root;
  639. xmlAttrPtr n_attr;
  640. isns_attr_t *attr;
  641. char numbuf[32];
  642. isns_obj_t *obj = (isns_obj_t *)p1;
  643. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  644. xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
  645. root = xmlDocGetRootElement(doc);
  646. if (root == NULL) {
  647. return (ERR_SYNTAX_MISSING_ROOT);
  648. }
  649. n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
  650. if (n_obj) {
  651. n_obj = xmlAddChild(root, n_obj);
  652. if (n_obj == NULL) {
  653. return (ERR_XML_NEWCHILD_FAILED);
  654. }
  655. } else {
  656. return (ERR_XML_NEWNODE_FAILED);
  657. }
  658. n_node = xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
  659. if (n_node) {
  660. n_node = xmlAddChild(n_obj, n_node);
  661. if (n_node == NULL) {
  662. return (ERR_XML_ADDCHILD_FAILED);
  663. }
  664. } else {
  665. return (ERR_XML_NEWNODE_FAILED);
  666. }
  667. /* get node name, alias, type and generate xml info */
  668. attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID)];
  669. n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
  670. (xmlChar *)attr->value.ptr);
  671. if (n_attr == NULL) {
  672. return (ERR_XML_SETPROP_FAILED);
  673. }
  674. attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_ID_ATTR_ID)];
  675. (void) sprintf(numbuf, "%u", attr->value.ui);
  676. n_attr = xmlSetProp(n_node, (xmlChar *)IDATTR,
  677. (xmlChar *)numbuf);
  678. if (n_attr == NULL) {
  679. return (ERR_XML_SETPROP_FAILED);
  680. }
  681. attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID)];
  682. if (DDS_ENABLED(attr->value.ui)) {
  683. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)ENABLEDELEM,
  684. (xmlChar *)XMLTRUE);
  685. if (sub_node == NULL) {
  686. return (ERR_XML_NEWCHILD_FAILED);
  687. }
  688. } else {
  689. sub_node = xmlNewChild(n_node, NULL, (xmlChar *)ENABLEDELEM,
  690. (xmlChar *)XMLFALSE);
  691. if (sub_node == NULL) {
  692. return (ERR_XML_NEWCHILD_FAILED);
  693. }
  694. }
  695. /* successful */
  696. return (0);
  697. }
  698. /*
  699. * ****************************************************************************
  700. *
  701. * cb_enumerate_node_info: callback for enumerate_node_op
  702. * The routine is invoked for each node object.
  703. *
  704. * p1 - node object
  705. * p2 - lookup control data that was used for node look up
  706. * return - error code
  707. *
  708. * ****************************************************************************
  709. */
  710. static int
  711. cb_enumerate_node_info(
  712. void *p1,
  713. void *p2
  714. )
  715. {
  716. xmlNodePtr n_obj, n_node, root;
  717. xmlAttrPtr n_attr;
  718. isns_attr_t *attr;
  719. isns_obj_t *obj = (isns_obj_t *)p1;
  720. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  721. xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
  722. root = xmlDocGetRootElement(doc);
  723. if (root == NULL) {
  724. return (ERR_SYNTAX_MISSING_ROOT);
  725. }
  726. n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
  727. if (n_obj) {
  728. n_obj = xmlAddChild(root, n_obj);
  729. if (n_obj == NULL) {
  730. return (ERR_XML_ADDCHILD_FAILED);
  731. }
  732. } else {
  733. return (ERR_XML_NEWNODE_FAILED);
  734. }
  735. n_node = xmlNewNode(NULL, (xmlChar *)NODEOBJECT);
  736. if (n_node) {
  737. n_node = xmlAddChild(n_obj, n_node);
  738. if (n_node == NULL) {
  739. return (ERR_XML_ADDCHILD_FAILED);
  740. }
  741. } else {
  742. return (ERR_XML_NEWNODE_FAILED);
  743. }
  744. /* get node name, alias, type and generate xml info */
  745. attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
  746. n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
  747. (xmlChar *)attr->value.ptr);
  748. if (n_attr == NULL) {
  749. return (ERR_XML_SETPROP_FAILED);
  750. }
  751. attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_TYPE_ATTR_ID)];
  752. switch (attr->value.ui) {
  753. case ISNS_CONTROL_NODE_TYPE | ISNS_INITIATOR_NODE_TYPE:
  754. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  755. (xmlChar *)CONTROLNODEINITIATORTYPE);
  756. break;
  757. case ISNS_CONTROL_NODE_TYPE | ISNS_TARGET_NODE_TYPE:
  758. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  759. (xmlChar *)CONTROLNODETARGETTYPE);
  760. break;
  761. case ISNS_TARGET_NODE_TYPE:
  762. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  763. (xmlChar *)TARGETTYPE);
  764. break;
  765. case ISNS_INITIATOR_NODE_TYPE:
  766. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  767. (xmlChar *)INITIATORTYPE);
  768. break;
  769. case ISNS_CONTROL_NODE_TYPE:
  770. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  771. (xmlChar *)CONTROLNODETYPE);
  772. break;
  773. default:
  774. n_attr = xmlSetProp(n_node, (xmlChar *)TYPEATTR,
  775. (xmlChar *)UNKNOWNTYPE);
  776. }
  777. if (n_attr == NULL) {
  778. return (ERR_XML_SETPROP_FAILED);
  779. }
  780. attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_ALIAS_ATTR_ID)];
  781. n_attr = xmlSetProp(n_node, (xmlChar *)ALIASATTR,
  782. (xmlChar *)attr->value.ptr);
  783. if (n_attr == NULL) {
  784. return (ERR_XML_SETPROP_FAILED);
  785. }
  786. /* successful */
  787. return (0);
  788. }
  789. /*
  790. * ****************************************************************************
  791. *
  792. * i_enumerate_dd_dds_info:
  793. * The routine is implemnetation for enumerate dd and enumerate dds.
  794. *
  795. * p1 - dd or dd set object
  796. * p2 - lookup control data that was used for dd and dd set look up
  797. * return - error code
  798. *
  799. * ****************************************************************************
  800. */
  801. static int
  802. i_enumerate_dd_dds_info(
  803. void *p1,
  804. void *p2,
  805. isns_type_t obj_type
  806. )
  807. {
  808. xmlNodePtr n_obj, n_node, sub_node, root;
  809. xmlAttrPtr n_attr;
  810. isns_attr_t *attr;
  811. char numbuf[32];
  812. isns_obj_t *obj = (isns_obj_t *)p1;
  813. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  814. xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
  815. root = xmlDocGetRootElement(doc);
  816. if (root == NULL) {
  817. return (ERR_SYNTAX_MISSING_ROOT);
  818. }
  819. n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
  820. if (n_obj) {
  821. n_obj = xmlAddChild(root, n_obj);
  822. if (n_obj == NULL) {
  823. return (ERR_XML_ADDCHILD_FAILED);
  824. }
  825. } else {
  826. return (ERR_XML_NEWNODE_FAILED);
  827. }
  828. if (obj_type == OBJ_DD) {
  829. n_node = xmlNewNode(NULL, (xmlChar *)DDOBJECT);
  830. } else {
  831. n_node = xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
  832. }
  833. if (n_node) {
  834. n_node = xmlAddChild(n_obj, n_node);
  835. if (n_node == NULL) {
  836. return (ERR_XML_ADDCHILD_FAILED);
  837. }
  838. } else {
  839. return (ERR_XML_NEWNODE_FAILED);
  840. }
  841. if (obj_type == OBJ_DD) {
  842. /* get name, id, feaure and generate xml info */
  843. attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)];
  844. n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
  845. (xmlChar *)attr->value.ptr);
  846. if (n_attr == NULL) {
  847. return (ERR_XML_SETPROP_FAILED);
  848. }
  849. attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_ID_ATTR_ID)];
  850. (void) sprintf(numbuf, "%u", attr->value.ui);
  851. n_attr = xmlSetProp(n_node, (xmlChar *)IDATTR,
  852. (xmlChar *)numbuf);
  853. if (n_attr == NULL) {
  854. return (ERR_XML_SETPROP_FAILED);
  855. }
  856. attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_FEATURES_ATTR_ID)];
  857. if (DD_BOOTLIST_ENABLED(attr->value.ui)) {
  858. sub_node = xmlNewChild(n_node, NULL,
  859. (xmlChar *)BOOTLISTENABLEDELEM, (xmlChar *)XMLTRUE);
  860. if (sub_node == NULL) {
  861. return (ERR_XML_NEWCHILD_FAILED);
  862. }
  863. } else {
  864. sub_node = xmlNewChild(n_node, NULL,
  865. (xmlChar *)BOOTLISTENABLEDELEM, (xmlChar *)XMLFALSE);
  866. if (sub_node == NULL) {
  867. return (ERR_XML_NEWCHILD_FAILED);
  868. }
  869. }
  870. } else {
  871. /* get name, id, status and generate xml info */
  872. attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID)];
  873. n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
  874. (xmlChar *)attr->value.ptr);
  875. if (n_attr == NULL) {
  876. return (ERR_XML_SETPROP_FAILED);
  877. }
  878. attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_ID_ATTR_ID)];
  879. (void) sprintf(numbuf, "%u", attr->value.ui);
  880. n_attr = xmlSetProp(n_node, (xmlChar *)IDATTR,
  881. (xmlChar *)numbuf);
  882. if (n_attr == NULL) {
  883. return (ERR_XML_SETPROP_FAILED);
  884. }
  885. attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_STATUS_ATTR_ID)];
  886. if (DDS_ENABLED(attr->value.ui)) {
  887. sub_node = xmlNewChild(n_node, NULL,
  888. (xmlChar *)ENABLEDELEM, (xmlChar *)XMLTRUE);
  889. if (sub_node == NULL) {
  890. return (ERR_XML_NEWCHILD_FAILED);
  891. }
  892. } else {
  893. sub_node = xmlNewChild(n_node, NULL,
  894. (xmlChar *)ENABLEDELEM, (xmlChar *)XMLFALSE);
  895. if (sub_node == NULL) {
  896. return (ERR_XML_NEWCHILD_FAILED);
  897. }
  898. }
  899. }
  900. /* successful */
  901. return (0);
  902. }
  903. /*
  904. * ****************************************************************************
  905. *
  906. * cb_enumerate_dd_info: callback for enumerate_dd_op
  907. * The routine is invoked for each dd object.
  908. *
  909. * p1 - dd object
  910. * p2 - lookup control data that was used for dd look up
  911. * return - error code
  912. *
  913. * ****************************************************************************
  914. */
  915. static int
  916. cb_enumerate_dd_info(
  917. void *p1,
  918. void *p2
  919. )
  920. {
  921. return (i_enumerate_dd_dds_info(p1, p2, OBJ_DD));
  922. }
  923. /*
  924. * ****************************************************************************
  925. *
  926. * cb_enumerate_ddset_info: callback for enumerate_dd_op
  927. * The routine is invoked for each dd object.
  928. *
  929. * p1 - dd object
  930. * p2 - lookup control data that was used for dd set look up
  931. * return - error code
  932. *
  933. * ****************************************************************************
  934. */
  935. static int
  936. cb_enumerate_ddset_info(
  937. void *p1,
  938. void *p2
  939. )
  940. {
  941. return (i_enumerate_dd_dds_info(p1, p2, OBJ_DDS));
  942. }
  943. /*
  944. * ****************************************************************************
  945. *
  946. * cb_getAssociated_node_info:
  947. * The routine is implemnetation for enumerate dd and enumerate dds.
  948. *
  949. * p1 - dd or dd set object
  950. * p2 - lookup control data that was used for dd and dd set look up
  951. * return - error code
  952. *
  953. * ****************************************************************************
  954. */
  955. static int
  956. cb_getAssociated_node_info(
  957. void *p1,
  958. void *p2
  959. )
  960. {
  961. xmlNodePtr n_obj, n_node, root;
  962. xmlAttrPtr n_attr;
  963. isns_attr_t *attr;
  964. isns_obj_t *obj = (isns_obj_t *)p1;
  965. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  966. xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
  967. uchar_t *ddname = lcp->data[2].ptr;
  968. root = xmlDocGetRootElement(doc);
  969. if (root == NULL) {
  970. return (ERR_SYNTAX_MISSING_ROOT);
  971. }
  972. n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
  973. if (n_obj) {
  974. n_obj = xmlAddChild(root, n_obj);
  975. if (n_obj == NULL) {
  976. return (ERR_XML_ADDCHILD_FAILED);
  977. }
  978. } else {
  979. return (ERR_XML_NEWNODE_FAILED);
  980. }
  981. n_node = xmlNewNode(NULL, (xmlChar *)DDOBJECTMEMBER);
  982. if (n_node) {
  983. n_node = xmlAddChild(n_obj, n_node);
  984. if (n_node == NULL) {
  985. return (ERR_XML_ADDCHILD_FAILED);
  986. }
  987. } else {
  988. return (ERR_XML_NEWNODE_FAILED);
  989. }
  990. /* get node name, alias, type and generate xml info */
  991. attr = &obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)];
  992. n_attr = xmlSetProp(n_node, (xmlChar *)NODENAMEATTR,
  993. (xmlChar *)attr->value.ptr);
  994. if (n_attr == NULL) {
  995. return (ERR_XML_SETPROP_FAILED);
  996. }
  997. n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
  998. (xmlChar *)ddname);
  999. if (n_attr == NULL) {
  1000. return (ERR_XML_SETPROP_FAILED);
  1001. }
  1002. /* successful */
  1003. return (0);
  1004. }
  1005. /*
  1006. * ****************************************************************************
  1007. *
  1008. * cb_getAssociated_node_to_dd_info:
  1009. * The routine is implemnetation for enumerate dd and enumerate dds.
  1010. *
  1011. * p1 - dd or dd set object
  1012. * p2 - lookup control data that was used for dd and dd set look up
  1013. * return - error code
  1014. *
  1015. * ****************************************************************************
  1016. */
  1017. static int
  1018. cb_getAssociated_node_to_dd_info(
  1019. void *p1,
  1020. void *p2
  1021. )
  1022. {
  1023. xmlNodePtr n_obj, n_node, root;
  1024. xmlAttrPtr n_attr;
  1025. isns_attr_t *attr;
  1026. isns_obj_t *obj = (isns_obj_t *)p1;
  1027. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  1028. xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
  1029. uchar_t *nodename = lcp->data[2].ptr;
  1030. root = xmlDocGetRootElement(doc);
  1031. if (root == NULL) {
  1032. return (ERR_SYNTAX_MISSING_ROOT);
  1033. }
  1034. n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
  1035. if (n_obj) {
  1036. n_obj = xmlAddChild(root, n_obj);
  1037. if (n_obj == NULL) {
  1038. return (ERR_XML_ADDCHILD_FAILED);
  1039. }
  1040. } else {
  1041. return (ERR_XML_NEWNODE_FAILED);
  1042. }
  1043. n_node = xmlNewNode(NULL, (xmlChar *)DDOBJECTMEMBER);
  1044. if (n_node) {
  1045. n_node = xmlAddChild(n_obj, n_node);
  1046. if (n_node == NULL) {
  1047. return (ERR_XML_ADDCHILD_FAILED);
  1048. }
  1049. } else {
  1050. return (ERR_XML_NEWNODE_FAILED);
  1051. }
  1052. /* get node name, alias, type and generate xml info */
  1053. n_attr = xmlSetProp(n_node, (xmlChar *)NODENAMEATTR,
  1054. (xmlChar *)nodename);
  1055. if (n_attr == NULL) {
  1056. return (ERR_XML_SETPROP_FAILED);
  1057. }
  1058. attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)];
  1059. n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
  1060. (xmlChar *)attr->value.ptr);
  1061. if (n_attr == NULL) {
  1062. return (ERR_XML_SETPROP_FAILED);
  1063. }
  1064. /* successful */
  1065. return (0);
  1066. }
  1067. /*
  1068. * ****************************************************************************
  1069. *
  1070. * cb_getAssociated_dd_info:
  1071. * The routine is implemnetation for getting dds membership.
  1072. *
  1073. * p1 - dd or dd set object
  1074. * p2 - lookup control data that was used for dd and dd set look up
  1075. * return - error code
  1076. *
  1077. * ****************************************************************************
  1078. */
  1079. static int
  1080. cb_getAssociated_dd_info(
  1081. void *p1,
  1082. void *p2
  1083. )
  1084. {
  1085. xmlNodePtr n_obj, n_node, root;
  1086. xmlAttrPtr n_attr;
  1087. isns_attr_t *attr;
  1088. isns_obj_t *obj = (isns_obj_t *)p1;
  1089. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  1090. xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
  1091. uchar_t *ddsetname = lcp->data[2].ptr;
  1092. root = xmlDocGetRootElement(doc);
  1093. if (root == NULL) {
  1094. return (ERR_SYNTAX_MISSING_ROOT);
  1095. }
  1096. n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
  1097. if (n_obj) {
  1098. n_obj = xmlAddChild(root, n_obj);
  1099. if (n_obj == NULL) {
  1100. return (ERR_XML_ADDCHILD_FAILED);
  1101. }
  1102. } else {
  1103. return (ERR_XML_NEWNODE_FAILED);
  1104. }
  1105. n_node = xmlNewNode(NULL, (xmlChar *)DDSETOBJECTMEMBER);
  1106. if (n_node) {
  1107. n_node = xmlAddChild(n_obj, n_node);
  1108. if (n_node == NULL) {
  1109. return (ERR_XML_ADDCHILD_FAILED);
  1110. }
  1111. } else {
  1112. return (ERR_XML_NEWNODE_FAILED);
  1113. }
  1114. /* get node name, alias, type and generate xml info */
  1115. attr = &obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)];
  1116. n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
  1117. (xmlChar *)attr->value.ptr);
  1118. if (n_attr == NULL) {
  1119. return (ERR_XML_SETPROP_FAILED);
  1120. }
  1121. n_attr = xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR,
  1122. (xmlChar *)ddsetname);
  1123. if (n_attr == NULL) {
  1124. return (ERR_XML_SETPROP_FAILED);
  1125. }
  1126. /* successful */
  1127. return (0);
  1128. }
  1129. /*
  1130. * ****************************************************************************
  1131. *
  1132. * cb_getAssociated_dd_to_ddset_info:
  1133. * The routine is implemnetation for enumerate dd and enumerate dds.
  1134. *
  1135. * p1 - dd or dd set object
  1136. * p2 - lookup control data that was used for dd and dd set look up
  1137. * return - error code
  1138. *
  1139. * ****************************************************************************
  1140. */
  1141. static int
  1142. cb_getAssociated_dd_to_ddset_info(
  1143. void *p1,
  1144. void *p2
  1145. )
  1146. {
  1147. xmlNodePtr n_obj, n_node, root;
  1148. xmlAttrPtr n_attr;
  1149. isns_attr_t *attr;
  1150. isns_obj_t *obj = (isns_obj_t *)p1;
  1151. lookup_ctrl_t *lcp = (lookup_ctrl_t *)p2;
  1152. xmlDocPtr doc = (xmlDocPtr)lcp->data[1].ptr;
  1153. uchar_t *ddname = lcp->data[2].ptr;
  1154. root = xmlDocGetRootElement(doc);
  1155. if (root == NULL) {
  1156. return (ERR_SYNTAX_MISSING_ROOT);
  1157. }
  1158. n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
  1159. if (n_obj) {
  1160. n_obj = xmlAddChild(root, n_obj);
  1161. if (n_obj == NULL) {
  1162. return (ERR_XML_ADDCHILD_FAILED);
  1163. }
  1164. } else {
  1165. return (ERR_XML_NEWNODE_FAILED);
  1166. }
  1167. n_node = xmlNewNode(NULL, (xmlChar *)DDSETOBJECTMEMBER);
  1168. if (n_node) {
  1169. n_node = xmlAddChild(n_obj, n_node);
  1170. if (n_node == NULL) {
  1171. return (ERR_XML_ADDCHILD_FAILED);
  1172. }
  1173. } else {
  1174. return (ERR_XML_NEWNODE_FAILED);
  1175. }
  1176. /* get node name, alias, type and generate xml info */
  1177. n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
  1178. (xmlChar *)ddname);
  1179. if (n_attr == NULL) {
  1180. return (ERR_XML_SETPROP_FAILED);
  1181. }
  1182. attr = &obj->attrs[ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID)];
  1183. n_attr = xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR,
  1184. (xmlChar *)attr->value.ptr);
  1185. if (n_attr == NULL) {
  1186. return (ERR_XML_SETPROP_FAILED);
  1187. }
  1188. /* successful */
  1189. return (0);
  1190. }
  1191. /*
  1192. * ****************************************************************************
  1193. *
  1194. * handle_partial_success:
  1195. *
  1196. * doc - response doc to fill up
  1197. * ret - return code from the caller.
  1198. *
  1199. * ****************************************************************************
  1200. */
  1201. static int
  1202. handle_partial_success(
  1203. xmlDocPtr doc,
  1204. int ret
  1205. )
  1206. {
  1207. xmlNodePtr n_obj, n_node, root;
  1208. char numbuf[32];
  1209. root = xmlDocGetRootElement(doc);
  1210. if (root == NULL) {
  1211. return (ERR_SYNTAX_MISSING_ROOT);
  1212. }
  1213. n_obj = xmlNewNode(NULL, (xmlChar *)RESULTELEMENT);
  1214. if (n_obj) {
  1215. if (root->children) {
  1216. n_obj = xmlAddPrevSibling(root->children, n_obj);
  1217. (void) sprintf(numbuf, "%d", (ret != 0) ? PARTIAL_SUCCESS : 0);
  1218. n_node = xmlNewChild(n_obj, NULL, (xmlChar *)STATUSELEMENT,
  1219. (xmlChar *)numbuf);
  1220. if (n_node == NULL) {
  1221. return (ERR_XML_NEWCHILD_FAILED);
  1222. }
  1223. n_node = xmlNewChild(n_obj, NULL, (xmlChar *)MESSAGEELEMENT,
  1224. (xmlChar *)result_code_to_str((ret != 0) ?
  1225. PARTIAL_SUCCESS : 0));
  1226. if (n_node == NULL) {
  1227. return (ERR_XML_NEWCHILD_FAILED);
  1228. }
  1229. } else {
  1230. n_obj = xmlAddChild(root, n_obj);
  1231. if (n_obj == NULL) {
  1232. return (ERR_XML_ADDCHILD_FAILED);
  1233. }
  1234. (void) sprintf(numbuf, "%d", ret);
  1235. n_node = xmlNewChild(n_obj, NULL, (xmlChar *)STATUSELEMENT,
  1236. (xmlChar *)numbuf);
  1237. if (n_node == NULL) {
  1238. return (ERR_XML_NEWCHILD_FAILED);
  1239. }
  1240. n_node = xmlNewChild(n_obj, NULL, (xmlChar *)MESSAGEELEMENT,
  1241. (xmlChar *)result_code_to_str(ret));
  1242. if (n_node == NULL) {
  1243. return (ERR_XML_NEWCHILD_FAILED);
  1244. }
  1245. }
  1246. } else {
  1247. return (ERR_XML_NEWNODE_FAILED);
  1248. }
  1249. return (0);
  1250. }
  1251. /*
  1252. * ****************************************************************************
  1253. *
  1254. * handle_partial_failure:
  1255. *
  1256. * doc - response doc to fill up
  1257. * ret - return code from the caller.
  1258. *
  1259. * ****************************************************************************
  1260. */
  1261. static int
  1262. handle_partial_failure(
  1263. xmlDocPtr doc,
  1264. int ret,
  1265. boolean_t all_failed
  1266. )
  1267. {
  1268. xmlNodePtr n_obj, n_node, root;
  1269. char numbuf[32];
  1270. root = xmlDocGetRootElement(doc);
  1271. if (root == NULL) {
  1272. return (ERR_SYNTAX_MISSING_ROOT);
  1273. }
  1274. n_obj = xmlNewNode(NULL, (xmlChar *)RESULTELEMENT);
  1275. if (n_obj) {
  1276. if (root->children) {
  1277. /* some or all associations failed to create */
  1278. n_obj = xmlAddPrevSibling(root->children, n_obj);
  1279. /* capture last error. should come up with all failed?? */
  1280. (void) sprintf(numbuf, "%d",
  1281. all_failed ? ret : PARTIAL_FAILURE);
  1282. n_node = xmlNewChild(n_obj, NULL, (xmlChar *)STATUSELEMENT,
  1283. (xmlChar *)numbuf);
  1284. if (n_node == NULL) {
  1285. return (ERR_XML_NEWCHILD_FAILED);
  1286. }
  1287. n_node = xmlNewChild(n_obj, NULL, (xmlChar *)MESSAGEELEMENT,
  1288. (xmlChar *)result_code_to_str(all_failed ? ret :
  1289. PARTIAL_FAILURE));
  1290. if (n_node == NULL) {
  1291. return (ERR_XML_NEWCHILD_FAILED);
  1292. }
  1293. } else {
  1294. n_obj = xmlAddChild(root, n_obj);
  1295. if (n_obj == NULL) {
  1296. return (ERR_XML_ADDCHILD_FAILED);
  1297. }
  1298. (void) sprintf(numbuf, "%d", (ret != 0) ? ret : 0);
  1299. n_node = xmlNewChild(n_obj, NULL, (xmlChar *)STATUSELEMENT,
  1300. (xmlChar *)numbuf);
  1301. if (n_node == NULL) {
  1302. return (ERR_XML_NEWCHILD_FAILED);
  1303. }
  1304. n_node = xmlNewChild(n_obj, NULL, (xmlChar *)MESSAGEELEMENT,
  1305. (xmlChar *)result_code_to_str((ret != 0) ? ret : 0));
  1306. if (n_node == NULL) {
  1307. return (ERR_XML_NEWCHILD_FAILED);
  1308. }
  1309. }
  1310. } else {
  1311. return (ERR_XML_NEWNODE_FAILED);
  1312. }
  1313. return (0);
  1314. }
  1315. /*
  1316. * ****************************************************************************
  1317. *
  1318. * get_serverconfig_op:
  1319. * The routine process server administrative setting.
  1320. *
  1321. * doc - response doc to fill up.
  1322. *
  1323. * ****************************************************************************
  1324. */
  1325. int
  1326. get_serverconfig_op(
  1327. xmlDocPtr doc
  1328. )
  1329. {
  1330. extern uint64_t esi_threshold;
  1331. extern uint8_t mgmt_scn;
  1332. extern ctrl_node_t *control_nodes;
  1333. extern pthread_mutex_t ctrl_node_mtx;
  1334. extern char data_store[MAXPATHLEN];
  1335. xmlNodePtr n_obj, root;
  1336. char numbuf[32];
  1337. ctrl_node_t *ctrl_node_p;
  1338. int ret = 0;
  1339. root = xmlDocGetRootElement(doc);
  1340. if (root == NULL) {
  1341. return (ERR_SYNTAX_MISSING_ROOT);
  1342. }
  1343. n_obj = xmlNewNode(NULL, (xmlChar *)ISNSSERVER);
  1344. if (n_obj) {
  1345. n_obj = xmlAddChild(root, n_obj);
  1346. if (n_obj == NULL) {
  1347. return (ERR_XML_ADDCHILD_FAILED);
  1348. }
  1349. } else {
  1350. return (ERR_XML_ADDCHILD_FAILED);
  1351. }
  1352. if (xmlNewChild(n_obj, NULL, (xmlChar *)DATASTORELOCATION,
  1353. (xmlChar *)data_store) == NULL) {
  1354. return (ERR_XML_NEWCHILD_FAILED);
  1355. }
  1356. (void) sprintf(numbuf, "%llu", esi_threshold);
  1357. if (xmlNewChild(n_obj, NULL, (xmlChar *)ESIRETRYTHRESHOLD,
  1358. (xmlChar *)numbuf) == NULL) {
  1359. return (ERR_XML_NEWCHILD_FAILED);
  1360. }
  1361. if (xmlNewChild(n_obj, NULL, (xmlChar *)MANAGEMENTSCNENABLED,
  1362. (mgmt_scn) ? (uchar_t *)XMLTRUE : (uchar_t *)XMLFALSE) == NULL) {
  1363. return (ERR_XML_NEWCHILD_FAILED);
  1364. }
  1365. (void) pthread_mutex_lock(&ctrl_node_mtx);
  1366. if (control_nodes == NULL) {
  1367. if (xmlNewChild(n_obj, NULL, (xmlChar *)CONTROLNODENAME,
  1368. (xmlChar *)NULL) == NULL) {
  1369. (void) pthread_mutex_unlock(&ctrl_node_mtx);
  1370. return (ERR_XML_NEWCHILD_FAILED);
  1371. }
  1372. } else {
  1373. ctrl_node_p = control_nodes;
  1374. while (ctrl_node_p != NULL) {
  1375. if (xmlNewChild(n_obj, NULL, (xmlChar *)CONTROLNODENAME,
  1376. (xmlChar *)ctrl_node_p->name) == NULL) {
  1377. (void) pthread_mutex_unlock(&ctrl_node_mtx);
  1378. return (ERR_XML_NEWCHILD_FAILED);
  1379. }
  1380. ctrl_node_p = ctrl_node_p->next;
  1381. }
  1382. }
  1383. (void) pthread_mutex_unlock(&ctrl_node_mtx);
  1384. return (handle_partial_success(doc, ret));
  1385. }
  1386. /*
  1387. * ****************************************************************************
  1388. *
  1389. * get_node_op:
  1390. * service get operation on a given node.
  1391. *
  1392. * req - contains all info for a request.
  1393. * doc - response doc to fill up
  1394. *
  1395. * ****************************************************************************
  1396. */
  1397. int
  1398. get_node_op(
  1399. request_t *req,
  1400. xmlDocPtr doc
  1401. /* any additional arguments go here */
  1402. )
  1403. {
  1404. int ret = 0, ret_save = 0;
  1405. int i = 0;
  1406. lookup_ctrl_t lc, lc2, lc3;
  1407. uint32_t uid;
  1408. char buff2[INET6_ADDRSTRLEN];
  1409. /* prepare lookup ctrl data for looking for the node object */
  1410. lc.curr_uid = 0;
  1411. lc.type = get_lc_type(req->op_info.obj);
  1412. lc.id[0] = get_lc_id(req->op_info.obj);
  1413. lc.op[0] = OP_STRING;
  1414. lc.op[1] = 0;
  1415. lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */
  1416. while (i < req->count) {
  1417. lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
  1418. ret = cache_lookup(&lc, &uid, cb_get_node_info);
  1419. if (uid == 0) {
  1420. ret = ERR_MATCHING_ISCSI_NODE_NOT_FOUND;
  1421. }
  1422. /* generate network entity object information */
  1423. if (ret == 0 && lc.id[2] != 0) {
  1424. /*
  1425. * !!! there might be no entity and portal info for
  1426. * !!! the node if it is not a registered node
  1427. */
  1428. /* prepare lookup ctrl data for looking for entity */
  1429. SET_UID_LCP(&lc2, OBJ_ENTITY, lc.id[2]);
  1430. lc2.data[1].ptr = (uchar_t *)doc;
  1431. /* cb_get_node_info callback returned Node object. */
  1432. lc2.data[2].ptr = lc.data[2].ptr;
  1433. ret = cache_lookup(&lc2, &uid, cb_get_entity_info);
  1434. if (uid == 0) {
  1435. ret = ERR_MATCHING_NETWORK_ENTITY_NOT_FOUND;
  1436. }
  1437. }
  1438. /* generate portal information */
  1439. if (ret == 0 && lc.id[2] != 0) {
  1440. /* prepare lookup ctrl data for looking for pg */
  1441. lc2.curr_uid = 0;
  1442. lc2.type = OBJ_PG;
  1443. lc2.id[0] = ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID);
  1444. lc2.op[0] = OP_STRING;
  1445. /* lc.data[0].ptr contains node name */
  1446. lc2.data[0].ptr = lc.data[0].ptr;
  1447. lc2.op[1] = 0;
  1448. lc2.data[1].ip = (in6_addr_t *)buff2;
  1449. /* prepare lookup ctrl data for looking for portal */
  1450. lc3.curr_uid = 0;
  1451. lc3.type = OBJ_PORTAL;
  1452. lc3.id[0] = ATTR_INDEX_PORTAL(
  1453. ISNS_PORTAL_IP_ADDR_ATTR_ID);
  1454. lc3.op[0] = OP_MEMORY_IP6;
  1455. lc3.id[1] = ATTR_INDEX_PORTAL(
  1456. ISNS_PORTAL_PORT_ATTR_ID);
  1457. lc3.op[1] = OP_INTEGER;
  1458. lc3.op[2] = 0;
  1459. /* cb_get_node_info callback returned Node object. */
  1460. lc3.data[2].ptr = lc.data[2].ptr;
  1461. for (;;) {
  1462. ret = cache_lookup(&lc2, &uid, cb_get_pg_info);
  1463. if (uid != 0) {
  1464. /* we found a portal group */
  1465. lc2.curr_uid = uid;
  1466. /* it is a null pg if pgt is zero. */
  1467. if (lc2.id[2] != 0) {
  1468. /* pass ip addr */
  1469. lc3.data[0].ip = lc2.data[1].ip;
  1470. /* pass port num */
  1471. lc3.data[1].ui = lc2.data[2].ui;
  1472. /* pass pgt */
  1473. lc3.id[2] = lc2.id[2];
  1474. ret = cache_lookup(&lc3, &uid,
  1475. cb_get_portal_info);
  1476. }
  1477. } else {
  1478. /*
  1479. * no more portal group which is
  1480. * tied to this stroage node object.
  1481. */
  1482. break;
  1483. }
  1484. }
  1485. }
  1486. /* save error for this iteration */
  1487. if (ret != 0) {
  1488. ret_save = ret;
  1489. }
  1490. ret = 0;
  1491. i++;
  1492. }
  1493. return (handle_partial_success(doc, ret_save));
  1494. }
  1495. /*
  1496. * ****************************************************************************
  1497. *
  1498. * i_get_dd_dds_op:
  1499. * serves get operatrion on dd or dds.
  1500. *
  1501. * req - contains all info for a request.
  1502. * doc - response doc to fill up
  1503. * obj_type - object type(either dd or dd set)
  1504. *
  1505. * ****************************************************************************
  1506. */
  1507. static int
  1508. i_get_dd_dds_op(
  1509. request_t *req,
  1510. xmlDocPtr doc,
  1511. isns_type_t obj_type
  1512. /* any additional arguments go here */
  1513. )
  1514. {
  1515. result_code_t ret = 0, ret_save = 0;
  1516. int i = 0;
  1517. lookup_ctrl_t lc;
  1518. uint32_t uid;
  1519. if ((obj_type != OBJ_DD) && (obj_type != OBJ_DDS)) {
  1520. return (ERR_INVALID_MGMT_REQUEST);
  1521. }
  1522. /* prepare lookup ctrl data for looking for the node object */
  1523. lc.curr_uid = 0;
  1524. lc.type = obj_type;
  1525. lc.id[0] = get_lc_id(req->op_info.obj);
  1526. lc.op[0] = OP_STRING;
  1527. lc.op[1] = 0;
  1528. lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */
  1529. while (i < req->count) {
  1530. if (obj_type == OBJ_DD) {
  1531. lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
  1532. ret = cache_lookup(&lc, &uid, cb_get_dd_info);
  1533. if (uid == 0) {
  1534. /* set an error and continue. */
  1535. ret = ERR_MATCHING_DD_NOT_FOUND;
  1536. }
  1537. } else {
  1538. lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
  1539. ret = cache_lookup(&lc, &uid, cb_get_ddset_info);
  1540. if (uid == 0) {
  1541. /* set an error and continue. */
  1542. ret = ERR_MATCHING_DDSET_NOT_FOUND;
  1543. }
  1544. }
  1545. /* save error for this iteration */
  1546. if (ret != 0) {
  1547. ret_save = ret;
  1548. }
  1549. ret = 0;
  1550. i++;
  1551. }
  1552. return (handle_partial_success(doc, ret_save));
  1553. }
  1554. /*
  1555. * ****************************************************************************
  1556. *
  1557. * i_delete_ddmember_op:
  1558. * serves delete member operatrion on dd.
  1559. *
  1560. * container - dd name
  1561. * member - node name
  1562. *
  1563. * ****************************************************************************
  1564. */
  1565. static int
  1566. i_delete_ddmember_op(
  1567. uchar_t *container,
  1568. uchar_t *member
  1569. )
  1570. {
  1571. int ret = 0;
  1572. isns_assoc_iscsi_t aiscsi;
  1573. isns_obj_t *assoc;
  1574. isns_attr_t *attr;
  1575. int len;
  1576. lookup_ctrl_t lc;
  1577. uint32_t dd_id;
  1578. /* prepare lookup ctrl data for looking for the dd object */
  1579. lc.curr_uid = 0;
  1580. lc.type = OBJ_DD;
  1581. lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
  1582. lc.op[0] = OP_STRING;
  1583. lc.data[0].ptr = container;
  1584. lc.op[1] = 0;
  1585. if ((dd_id = is_obj_there(&lc)) != 0) {
  1586. aiscsi.type = OBJ_ASSOC_ISCSI;
  1587. aiscsi.puid = dd_id;
  1588. len = strlen((char *)member) + 1;
  1589. len += 4 - (len % 4);
  1590. attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
  1591. ISNS_DD_ISCSI_NAME_ATTR_ID)];
  1592. attr->tag = ISNS_DD_ISCSI_NAME_ATTR_ID;
  1593. attr->len = len;
  1594. attr->value.ptr = (uchar_t *)member;
  1595. attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
  1596. ISNS_DD_ISCSI_INDEX_ATTR_ID)];
  1597. attr->tag = 0; /* clear it */
  1598. assoc = (isns_obj_t *)&aiscsi;
  1599. ret = remove_dd_member(assoc);
  1600. } else {
  1601. ret = ERR_MATCHING_DD_NOT_FOUND;
  1602. }
  1603. return (ret);
  1604. }
  1605. /*
  1606. * ****************************************************************************
  1607. *
  1608. * i_delete_ddsetmember_op:
  1609. * serves delete member operatrion on dd set.
  1610. *
  1611. * container - dd set name
  1612. * member - dd name
  1613. *
  1614. * ****************************************************************************
  1615. */
  1616. static int
  1617. i_delete_ddsetmember_op(
  1618. uchar_t *container,
  1619. uchar_t *member
  1620. )
  1621. {
  1622. int ret = 0;
  1623. lookup_ctrl_t lc, lc2;
  1624. uint32_t container_id, member_id;
  1625. /* prepare lookup ctrl data for looking for the dd-set object */
  1626. lc.curr_uid = 0;
  1627. lc.type = OBJ_DDS;
  1628. lc.id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
  1629. lc.op[0] = OP_STRING;
  1630. lc.data[0].ptr = container;
  1631. lc.op[1] = 0;
  1632. /* prepare lookup ctrl data for looking for the dd object */
  1633. lc2.curr_uid = 0;
  1634. lc2.type = OBJ_DD;
  1635. lc2.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
  1636. lc2.op[0] = OP_STRING;
  1637. lc2.data[0].ptr = member;
  1638. lc2.op[1] = 0;
  1639. if ((container_id = is_obj_there(&lc)) != 0) {
  1640. if ((member_id = is_obj_there(&lc2)) != 0) {
  1641. ret = remove_dds_member(container_id, member_id);
  1642. } else {
  1643. ret = ERR_MATCHING_DD_NOT_FOUND;
  1644. }
  1645. } else {
  1646. ret = ERR_MATCHING_DDSET_NOT_FOUND;
  1647. }
  1648. return (ret);
  1649. }
  1650. /*
  1651. * ****************************************************************************
  1652. *
  1653. * get_dd_op:
  1654. * service get operation on given dd(s).
  1655. *
  1656. * req - contains all info for a request.
  1657. * doc - response doc to fill up
  1658. *
  1659. * ****************************************************************************
  1660. */
  1661. int
  1662. get_dd_op(
  1663. request_t *req,
  1664. xmlDocPtr doc
  1665. /* any additional arguments go here */
  1666. )
  1667. {
  1668. return (i_get_dd_dds_op(req, doc, OBJ_DD));
  1669. }
  1670. /*
  1671. * ****************************************************************************
  1672. *
  1673. * get_ddset_op:
  1674. * service get operation on given dd set(s).
  1675. *
  1676. * req - contains all info for a request.
  1677. * doc - response doc to fill up
  1678. *
  1679. * ****************************************************************************
  1680. */
  1681. int
  1682. get_ddset_op(
  1683. request_t *req,
  1684. xmlDocPtr doc
  1685. /* any additional arguments go here */
  1686. )
  1687. {
  1688. return (i_get_dd_dds_op(req, doc, OBJ_DDS));
  1689. }
  1690. /*
  1691. * ****************************************************************************
  1692. *
  1693. * enumerate_node_op:
  1694. * services enumerate node op.
  1695. *
  1696. * req - contains enumerate request info.
  1697. * doc - response doc to fill up
  1698. *
  1699. * ****************************************************************************
  1700. */
  1701. int
  1702. enumerate_node_op(
  1703. xmlDocPtr doc
  1704. /* any additional arguments go here */
  1705. )
  1706. {
  1707. htab_t *htab = cache_get_htab(OBJ_ISCSI);
  1708. uint32_t uid = 0;
  1709. lookup_ctrl_t lc;
  1710. int ret = 0, ret_save = 0;
  1711. SET_UID_LCP(&lc, OBJ_ISCSI, 0);
  1712. lc.data[1].ptr = (uchar_t *)doc;
  1713. lc.data[2].ui = 0;
  1714. FOR_EACH_ITEM(htab, uid, {
  1715. lc.data[0].ui = uid;
  1716. ret = cache_lookup(&lc, NULL, cb_enumerate_node_info);
  1717. if (ret != 0) {
  1718. ret_save = ret;
  1719. }
  1720. });
  1721. return (handle_partial_success(doc, ret_save));
  1722. }
  1723. /*
  1724. * ****************************************************************************
  1725. *
  1726. * enumerate_dd_op:
  1727. * services enumerate discovery domain op.
  1728. *
  1729. * req - contains enumerate request info.
  1730. * doc - response doc to fill up
  1731. *
  1732. * ****************************************************************************
  1733. */
  1734. int
  1735. enumerate_dd_op(
  1736. xmlDocPtr doc
  1737. /* any additional arguments go here */
  1738. )
  1739. {
  1740. htab_t *htab = cache_get_htab(OBJ_DD);
  1741. uint32_t uid = 0;
  1742. lookup_ctrl_t lc;
  1743. int ret = 0, ret_save = 0;
  1744. SET_UID_LCP(&lc, OBJ_DD, 0);
  1745. lc.data[1].ptr = (uchar_t *)doc;
  1746. lc.data[2].ui = 0;
  1747. FOR_EACH_ITEM(htab, uid, {
  1748. lc.data[0].ui = uid;
  1749. ret = cache_lookup(&lc, NULL, cb_enumerate_dd_info);
  1750. if (ret != 0) {
  1751. ret_save = ret;
  1752. }
  1753. });
  1754. return (handle_partial_success(doc, ret_save));
  1755. }
  1756. /*
  1757. * ****************************************************************************
  1758. *
  1759. * enumerate_ddset_op:
  1760. * services enumerate discovery domain set op.
  1761. *
  1762. * req - contains enumerate request info.
  1763. * doc - response doc to fill up
  1764. *
  1765. * ****************************************************************************
  1766. */
  1767. int
  1768. enumerate_ddset_op(
  1769. xmlDocPtr doc
  1770. /* any additional arguments go here */
  1771. )
  1772. {
  1773. htab_t *htab = cache_get_htab(OBJ_DDS);
  1774. uint32_t uid = 0;
  1775. lookup_ctrl_t lc;
  1776. int ret = 0, ret_save = 0;
  1777. SET_UID_LCP(&lc, OBJ_DDS, 0);
  1778. lc.data[1].ptr = (uchar_t *)doc;
  1779. lc.data[2].ui = 0;
  1780. FOR_EACH_ITEM(htab, uid, {
  1781. lc.data[0].ui = uid;
  1782. ret = cache_lookup(&lc, NULL, cb_enumerate_ddset_info);
  1783. if (ret != 0) {
  1784. ret_save = ret;
  1785. }
  1786. });
  1787. return (handle_partial_success(doc, ret_save));
  1788. }
  1789. /*
  1790. * ****************************************************************************
  1791. *
  1792. * getassociated_dd_to_node_op:
  1793. * construct a list of node that is associated with a given Discovery
  1794. * Domain.
  1795. *
  1796. * req - contains getAssociated request info.
  1797. * doc - response doc to fill up
  1798. *
  1799. * ****************************************************************************
  1800. */
  1801. int
  1802. getAssociated_dd_to_node_op(
  1803. request_t *req,
  1804. xmlDocPtr doc
  1805. /* any additional arguments go here */
  1806. )
  1807. {
  1808. uint32_t uid = 0, n;
  1809. lookup_ctrl_t lc, lc2;
  1810. int i = 0, ret = 0, ret_save = 0;
  1811. bmp_t *p;
  1812. lc.curr_uid = 0;
  1813. lc.type = OBJ_DD;
  1814. lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
  1815. lc.op[0] = OP_STRING;
  1816. lc.op[1] = 0;
  1817. SET_UID_LCP(&lc2, OBJ_ISCSI, 0);
  1818. lc2.data[1].ptr = (uchar_t *)doc;
  1819. while (i < req->count) {
  1820. lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
  1821. if ((uid = is_obj_there(&lc)) != 0) {
  1822. ret = get_dd_matrix(uid, &p, &n);
  1823. FOR_EACH_MEMBER(p, n, uid, {
  1824. lc2.data[0].ui = uid;
  1825. lc2.data[2].ptr = (uchar_t *)req->req_data.data[i];
  1826. ret = cache_lookup(&lc2, NULL,
  1827. cb_getAssociated_node_info);
  1828. });
  1829. free(p);
  1830. } else {
  1831. ret = ERR_MATCHING_DD_NOT_FOUND;
  1832. }
  1833. /* save error for this iteration */
  1834. if (ret != 0) {
  1835. ret_save = ret;
  1836. }
  1837. ret = 0;
  1838. i++;
  1839. }
  1840. return (handle_partial_success(doc, ret_save));
  1841. }
  1842. /*
  1843. * ****************************************************************************
  1844. *
  1845. * getassociated_node_to_dd_op:
  1846. * construct a list of Discovery Doamins that is associated with a given
  1847. * node.
  1848. *
  1849. * req - contains getAssociated request info.
  1850. * doc - response doc to fill up
  1851. *
  1852. * ****************************************************************************
  1853. */
  1854. int
  1855. getAssociated_node_to_dd_op(
  1856. request_t *req,
  1857. xmlDocPtr doc
  1858. /* any additional arguments go here */
  1859. )
  1860. {
  1861. uint32_t uid = 0, dd_id;
  1862. lookup_ctrl_t lc, lc2;
  1863. int i = 0, ret = 0, ret_save = 0;
  1864. lc.curr_uid = 0;
  1865. lc.type = OBJ_ISCSI;
  1866. lc.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
  1867. lc.op[0] = OP_STRING;
  1868. lc.op[1] = 0;
  1869. SET_UID_LCP(&lc2, OBJ_DD, 0);
  1870. lc2.data[1].ptr = (uchar_t *)doc;
  1871. while (i < req->count) {
  1872. lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
  1873. if ((uid = is_obj_there(&lc)) != 0) {
  1874. if ((dd_id = get_dd_id(uid, 0)) == 0) {
  1875. ret = ERR_NO_ASSOCIATED_DD_FOUND;
  1876. i++;
  1877. continue;
  1878. } else {
  1879. do {
  1880. lc2.data[0].ui = dd_id;
  1881. lc2.data[2].ptr = (uchar_t *)req->req_data.data[i];
  1882. ret = cache_lookup(&lc2, NULL,
  1883. cb_getAssociated_node_to_dd_info);
  1884. dd_id = get_dd_id(uid, dd_id);
  1885. } while (dd_id != 0);
  1886. };
  1887. } else {
  1888. ret = ERR_MATCHING_NODE_NOT_FOUND;
  1889. }
  1890. /* save error for this iteration */
  1891. if (ret != 0) {
  1892. ret_save = ret;
  1893. }
  1894. ret = 0;
  1895. i++;
  1896. }
  1897. return (handle_partial_success(doc, ret_save));
  1898. }
  1899. /*
  1900. * ****************************************************************************
  1901. *
  1902. * getassociated_ddset_to_dd_op:
  1903. * construct a list of Discovery Doamins that is associated with a given
  1904. * Discover Domain set.
  1905. *
  1906. * req - contains getAssociated request info.
  1907. * doc - response doc to fill up
  1908. *
  1909. * ****************************************************************************
  1910. */
  1911. int
  1912. getAssociated_ddset_to_dd_op(
  1913. request_t *req,
  1914. xmlDocPtr doc
  1915. /* any additional arguments go here */
  1916. )
  1917. {
  1918. uint32_t uid = 0, n;
  1919. lookup_ctrl_t lc, lc2;
  1920. int i = 0, ret = 0, ret_save = 0;
  1921. bmp_t *p;
  1922. lc.curr_uid = 0;
  1923. lc.type = OBJ_DDS;
  1924. lc.id[0] = ATTR_INDEX_DDS(ISNS_DD_SET_NAME_ATTR_ID);
  1925. lc.op[0] = OP_STRING;
  1926. lc.op[1] = 0;
  1927. SET_UID_LCP(&lc2, OBJ_DD, 0);
  1928. lc2.data[1].ptr = (uchar_t *)doc;
  1929. while (i < req->count) {
  1930. lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
  1931. if ((uid = is_obj_there(&lc)) != 0) {
  1932. ret = get_dds_matrix(uid, &p, &n);
  1933. FOR_EACH_MEMBER(p, n, uid, {
  1934. lc2.data[0].ui = uid;
  1935. lc2.data[2].ptr = (uchar_t *)req->req_data.data[i];
  1936. ret = cache_lookup(&lc2, NULL,
  1937. cb_getAssociated_dd_info);
  1938. });
  1939. free(p);
  1940. } else {
  1941. ret = ERR_MATCHING_DDSET_NOT_FOUND;
  1942. }
  1943. /* save error for this iteration */
  1944. if (ret != 0) {
  1945. ret_save = ret;
  1946. }
  1947. ret = 0;
  1948. i++;
  1949. }
  1950. return (handle_partial_success(doc, ret_save));
  1951. }
  1952. /*
  1953. * ****************************************************************************
  1954. *
  1955. * getassociated_dd_to_ddset_op:
  1956. * construct a list of Discovery Doamin sets that is associated with a
  1957. * given Discovery Domain.
  1958. *
  1959. * req - contains getAssociated request info.
  1960. * doc - response doc to fill up
  1961. *
  1962. * ****************************************************************************
  1963. */
  1964. int
  1965. getAssociated_dd_to_ddset_op(
  1966. request_t *req,
  1967. xmlDocPtr doc
  1968. /* any additional arguments go here */
  1969. )
  1970. {
  1971. uint32_t uid = 0, ddset_id;
  1972. lookup_ctrl_t lc, lc2;
  1973. int i = 0, ret = 0, ret_save = 0;
  1974. lc.curr_uid = 0;
  1975. lc.type = OBJ_DD;
  1976. lc.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
  1977. lc.op[0] = OP_STRING;
  1978. lc.op[1] = 0;
  1979. SET_UID_LCP(&lc2, OBJ_DDS, 0);
  1980. lc2.data[1].ptr = (uchar_t *)doc;
  1981. while (i < req->count) {
  1982. lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
  1983. if ((uid = is_obj_there(&lc)) != 0) {
  1984. lc2.data[2].ui = 0;
  1985. if ((ddset_id = get_dds_id(uid, 0)) == 0) {
  1986. ret = ERR_NO_ASSOCIATED_DDSET_FOUND;
  1987. i++;
  1988. continue;
  1989. } else {
  1990. do {
  1991. lc2.data[0].ui = ddset_id;
  1992. lc2.data[2].ptr = (uchar_t *)req->req_data.data[i];
  1993. ret = cache_lookup(&lc2, NULL,
  1994. cb_getAssociated_dd_to_ddset_info);
  1995. ddset_id = get_dds_id(uid, ddset_id);
  1996. } while (ddset_id != 0);
  1997. };
  1998. } else {
  1999. ret = ERR_MATCHING_DD_NOT_FOUND;
  2000. }
  2001. if (ret != 0) {
  2002. ret_save = ret;
  2003. }
  2004. i++;
  2005. }
  2006. return (handle_partial_success(doc, ret_save));
  2007. }
  2008. /*
  2009. * ****************************************************************************
  2010. *
  2011. * delete_dd_ddset_op:
  2012. * removes a list of dd or dd set.
  2013. *
  2014. * req - contains delete request info.
  2015. * doc - response doc to fill up
  2016. * obj_type - object type(either dd or dd set)
  2017. *
  2018. * ****************************************************************************
  2019. */
  2020. int
  2021. delete_dd_ddset_op(
  2022. request_t *req,
  2023. xmlDocPtr doc,
  2024. object_type type
  2025. /* any additional arguments go here */
  2026. )
  2027. {
  2028. result_code_t ret = 0, ret_save = 0;
  2029. isns_type_t lc_type;
  2030. int i = 0, err_count = 0;
  2031. lookup_ctrl_t lc;
  2032. uint32_t uid;
  2033. xmlNodePtr n_obj, n_node, root;
  2034. xmlAttrPtr n_attr;
  2035. int different_err = 0;
  2036. root = xmlDocGetRootElement(doc);
  2037. if (root == NULL) {
  2038. return (ERR_SYNTAX_MISSING_ROOT);
  2039. }
  2040. lc_type = get_lc_type(type);
  2041. if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
  2042. return (ERR_INVALID_MGMT_REQUEST);
  2043. }
  2044. /* prepare lookup ctrl data for looking for the node object */
  2045. lc.curr_uid = 0;
  2046. lc.type = lc_type;
  2047. lc.id[0] = get_lc_id(req->op_info.obj);
  2048. lc.op[0] = OP_STRING;
  2049. lc.op[1] = 0;
  2050. lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */
  2051. while (i < req->count) {
  2052. lc.data[0].ptr = (uchar_t *)req->req_data.data[i];
  2053. /* lock the cache for writing */
  2054. (void) cache_lock_write();
  2055. if ((uid = is_obj_there(&lc)) != 0) {
  2056. /* remove the dd/ddset */
  2057. ret = (lc_type == OBJ_DD) ?
  2058. remove_dd_object(uid) :
  2059. remove_dds_object(uid);
  2060. /* unlock the cache and sync the data */
  2061. ret = cache_unlock_sync(ret);
  2062. } else {
  2063. /* unlock the cache and no need to sync data */
  2064. (void) cache_unlock_nosync();
  2065. /* set an error and continue. */
  2066. ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND :
  2067. ERR_MATCHING_DDSET_NOT_FOUND;
  2068. }
  2069. if (ret != 0) {
  2070. /* keep track if there are different errors encountered. */
  2071. if (ret_save != 0 && ret != ret_save) {
  2072. different_err++;
  2073. }
  2074. err_count++;
  2075. n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
  2076. if (n_obj) {
  2077. if ((n_obj = xmlAddChild(root, n_obj)) == NULL) {
  2078. return (ERR_XML_ADDCHILD_FAILED);
  2079. }
  2080. } else {
  2081. return (ERR_XML_NEWNODE_FAILED);
  2082. }
  2083. n_node = (lc_type == OBJ_DD) ?
  2084. xmlNewNode(NULL, (xmlChar *)DDOBJECT) :
  2085. xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
  2086. if (n_node) {
  2087. if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) {
  2088. return (ERR_XML_ADDCHILD_FAILED);
  2089. }
  2090. n_attr = xmlSetProp(n_node, (xmlChar *)NAMEATTR,
  2091. (xmlChar *)req->req_data.data[i]);
  2092. if (n_attr == NULL) {
  2093. return (ERR_XML_SETPROP_FAILED);
  2094. }
  2095. } else {
  2096. return (ERR_XML_NEWNODE_FAILED);
  2097. }
  2098. ret_save = ret;
  2099. }
  2100. i ++;
  2101. }
  2102. return (handle_partial_failure(doc, ret_save,
  2103. (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
  2104. }
  2105. /*
  2106. * ****************************************************************************
  2107. *
  2108. * delete_ddmember_ddsetmember_op:
  2109. * removes a list of dd memeber or dd seti member.
  2110. *
  2111. * req - contains delete request info.
  2112. * doc - response doc to fill up
  2113. * type - object type(either dd or dd set)
  2114. *
  2115. * ****************************************************************************
  2116. */
  2117. int
  2118. delete_ddmember_ddsetmember_op(
  2119. request_t *req,
  2120. xmlDocPtr doc,
  2121. object_type type
  2122. /* any additional arguments go here */
  2123. )
  2124. {
  2125. result_code_t ret = 0, ret_save = 0;
  2126. isns_type_t lc_type;
  2127. int i = 0, err_count = 0;
  2128. lookup_ctrl_t lc, lc2;
  2129. uint32_t container_id, member_id;
  2130. xmlNodePtr n_node, n_obj, root;
  2131. xmlAttrPtr n_attr;
  2132. int different_err = 0;
  2133. int is_a_member;
  2134. lc_type = get_lc_type(type);
  2135. if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
  2136. return (ERR_INVALID_MGMT_REQUEST);
  2137. }
  2138. /* prepare lookup ctrl data for looking for the node object */
  2139. lc.curr_uid = 0;
  2140. lc.type = lc_type;
  2141. lc.id[0] = get_lc_id(req->op_info.obj);
  2142. lc.op[0] = OP_STRING;
  2143. lc.op[1] = 0;
  2144. lc2.curr_uid = 0;
  2145. if (lc_type == OBJ_DD) {
  2146. lc2.type = OBJ_ISCSI;
  2147. lc2.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
  2148. } else {
  2149. lc2.type = OBJ_DD;
  2150. lc2.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
  2151. }
  2152. lc2.op[0] = OP_STRING;
  2153. lc2.op[1] = 0;
  2154. root = xmlDocGetRootElement(doc);
  2155. if (root == NULL) {
  2156. return (ERR_SYNTAX_MISSING_ROOT);
  2157. }
  2158. while (i < req->count) {
  2159. lc.data[0].ptr = (uchar_t *)req->req_data.pair[i]->container;
  2160. /* get the dd_id/dds_id */
  2161. (void) cache_lock_write();
  2162. container_id = is_obj_there(&lc);
  2163. if (container_id != 0) {
  2164. lc2.data[0].ptr = (uchar_t *)req->req_data.pair[i]->member;
  2165. member_id = is_obj_there(&lc2);
  2166. if (member_id != 0) {
  2167. is_a_member =
  2168. (container_id ==
  2169. ((lc_type == OBJ_DD) ?
  2170. get_dd_id(member_id, container_id - 1) :
  2171. get_dds_id(member_id, container_id - 1)));
  2172. }
  2173. if (member_id != 0 && is_a_member != 0) {
  2174. /* delete the dd member */
  2175. ret = (lc_type == OBJ_DD) ?
  2176. i_delete_ddmember_op(
  2177. (uchar_t *)req->req_data.pair[i]->container,
  2178. (uchar_t *)req->req_data.pair[i]->member) :
  2179. i_delete_ddsetmember_op(
  2180. (uchar_t *)req->req_data.pair[i]->container,
  2181. (uchar_t *)req->req_data.pair[i]->member);
  2182. /* unlock the cache and sync the data */
  2183. ret = cache_unlock_sync(ret);
  2184. } else {
  2185. /* unlock the cache and no need to sync */
  2186. (void) cache_unlock_nosync();
  2187. ret = ERR_NO_SUCH_ASSOCIATION;
  2188. }
  2189. } else {
  2190. /* unlock the cache and no need to sync */
  2191. (void) cache_unlock_nosync();
  2192. ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND :
  2193. ERR_MATCHING_DDSET_NOT_FOUND;
  2194. }
  2195. if (ret != 0) {
  2196. /* keep track if there are different errors encountered. */
  2197. if (ret_save != 0 && ret != ret_save) {
  2198. different_err++;
  2199. }
  2200. ret_save = ret;
  2201. err_count++;
  2202. n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
  2203. if (n_obj) {
  2204. n_obj = xmlAddChild(root, n_obj);
  2205. if (n_obj == NULL) {
  2206. return (ERR_XML_ADDCHILD_FAILED);
  2207. }
  2208. } else {
  2209. return (ERR_XML_NEWNODE_FAILED);
  2210. }
  2211. if (lc_type == OBJ_DD) {
  2212. n_node =
  2213. xmlNewNode(NULL, (xmlChar *)DDOBJECTMEMBER);
  2214. n_attr = xmlSetProp(n_node, (xmlChar *)NODENAMEATTR,
  2215. (xmlChar *)req->req_data.pair[i]->member);
  2216. if (n_attr == NULL) {
  2217. return (ERR_XML_SETPROP_FAILED);
  2218. }
  2219. n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
  2220. (xmlChar *)req->req_data.pair[i]->container);
  2221. if (n_attr == NULL) {
  2222. return (ERR_XML_SETPROP_FAILED);
  2223. }
  2224. } else {
  2225. n_node =
  2226. xmlNewNode(NULL, (xmlChar *)DDSETOBJECTMEMBER);
  2227. n_attr = xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
  2228. (xmlChar *)req->req_data.pair[i]->member);
  2229. if (n_attr == NULL) {
  2230. return (ERR_XML_SETPROP_FAILED);
  2231. }
  2232. n_attr = xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR,
  2233. (xmlChar *)req->req_data.pair[i]->container);
  2234. if (n_attr == NULL) {
  2235. return (ERR_XML_SETPROP_FAILED);
  2236. }
  2237. }
  2238. if (xmlAddChild(n_obj, n_node) == NULL) {
  2239. return (ERR_XML_ADDCHILD_FAILED);
  2240. }
  2241. }
  2242. i++;
  2243. }
  2244. return (handle_partial_failure(doc, ret_save,
  2245. (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
  2246. }
  2247. /*
  2248. * ****************************************************************************
  2249. *
  2250. * create_ddmember_ddsetmember_op:
  2251. * removes a list of dd memeber or dd seti member.
  2252. *
  2253. * req - contains delete request info.
  2254. * doc - response doc to fill up
  2255. * type - object type(either dd or dd set)
  2256. *
  2257. * ****************************************************************************
  2258. */
  2259. int
  2260. create_ddmember_ddsetmember_op(
  2261. request_t *req,
  2262. xmlDocPtr doc,
  2263. object_type type
  2264. /* any additional arguments go here */
  2265. )
  2266. {
  2267. result_code_t ret = 0, ret_save = 0;
  2268. isns_type_t lc_type;
  2269. int i = 0, err_count = 0;
  2270. lookup_ctrl_t lc, lc2;
  2271. uint32_t container_id, member_id;
  2272. xmlNodePtr n_node, n_obj, root;
  2273. isns_assoc_iscsi_t aiscsi = { 0 };
  2274. isns_assoc_dd_t add = { 0 };
  2275. isns_obj_t *assoc;
  2276. isns_attr_t *attr;
  2277. uint32_t len;
  2278. int different_err = 0;
  2279. lc_type = get_lc_type(type);
  2280. if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
  2281. return (ERR_INVALID_MGMT_REQUEST);
  2282. }
  2283. /* prepare lookup ctrl data for looking for the node object */
  2284. lc.curr_uid = 0;
  2285. lc.type = lc_type;
  2286. lc.id[0] = get_lc_id(req->op_info.obj);
  2287. lc.op[0] = OP_STRING;
  2288. lc.op[1] = 0;
  2289. lc2.curr_uid = 0;
  2290. if (lc_type == OBJ_DD) {
  2291. lc2.type = OBJ_ISCSI;
  2292. lc2.id[0] = ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID);
  2293. } else {
  2294. lc2.type = OBJ_DD;
  2295. lc2.id[0] = ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID);
  2296. }
  2297. lc2.op[0] = OP_STRING;
  2298. lc2.op[1] = 0;
  2299. root = xmlDocGetRootElement(doc);
  2300. if (root == NULL) {
  2301. return (ERR_SYNTAX_MISSING_ROOT);
  2302. }
  2303. while (i < req->count) {
  2304. lc.data[0].ptr = (uchar_t *)req->req_data.pair[i]->container;
  2305. /* get the dd_id/dds_id */
  2306. (void) cache_lock_write();
  2307. container_id = is_obj_there(&lc);
  2308. if (container_id != 0) {
  2309. (void) memset(&aiscsi, 0, sizeof (aiscsi));
  2310. if (lc_type == OBJ_DD) {
  2311. aiscsi.puid = container_id;
  2312. aiscsi.type = OBJ_ASSOC_ISCSI;
  2313. attr = &aiscsi.attrs[ATTR_INDEX_ASSOC_ISCSI(
  2314. ISNS_DD_ISCSI_NAME_ATTR_ID)];
  2315. attr->tag = ISNS_DD_ISCSI_NAME_ATTR_ID;
  2316. len = xmlStrlen(
  2317. (xmlChar *)req->req_data.pair[i]->member) + 1;
  2318. len += 4 - (len % 4); /* on 4 bytes aligned */
  2319. attr->len = len;
  2320. attr->value.ptr =
  2321. (uchar_t *)req->req_data.pair[i]->member;
  2322. assoc = (isns_obj_t *)&aiscsi;
  2323. /* add the dd member */
  2324. ret = add_dd_member(assoc);
  2325. /* unlock the cache and sync the data */
  2326. ret = cache_unlock_sync(ret);
  2327. } else {
  2328. lc2.data[0].ptr =
  2329. (uchar_t *)req->req_data.pair[i]->member;
  2330. if ((member_id = is_obj_there(&lc2)) != 0) {
  2331. add.puid = container_id;
  2332. add.type = OBJ_ASSOC_DD;
  2333. attr = &add.attrs[ATTR_INDEX_ASSOC_DD(
  2334. ISNS_DD_ID_ATTR_ID)];
  2335. attr->tag = ISNS_DD_ID_ATTR_ID;
  2336. attr->len = 4;
  2337. attr->value.ui = member_id;
  2338. assoc = (isns_obj_t *)&add;
  2339. /* add the dd-set member */
  2340. ret = add_dds_member(assoc);
  2341. /* unlock the cache and sync the data */
  2342. ret = cache_unlock_sync(ret);
  2343. } else {
  2344. /* unlock the cache and no need to sync */
  2345. (void) cache_unlock_nosync();
  2346. ret = ERR_MATCHING_DD_NOT_FOUND;
  2347. }
  2348. }
  2349. } else {
  2350. /* unlock the cache and no need to sync */
  2351. (void) cache_unlock_nosync();
  2352. ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND :
  2353. ERR_MATCHING_DDSET_NOT_FOUND;
  2354. }
  2355. if (ret != 0) {
  2356. /* keep track if there are different errors encountered. */
  2357. if (ret_save != 0 && ret != ret_save) {
  2358. different_err++;
  2359. }
  2360. err_count++;
  2361. n_obj = xmlNewNode(NULL, (xmlChar *)ASSOCIATION);
  2362. if (n_obj) {
  2363. n_obj = xmlAddChild(root, n_obj);
  2364. if (n_obj == NULL) {
  2365. return (ERR_XML_ADDCHILD_FAILED);
  2366. }
  2367. } else {
  2368. return (ERR_XML_NEWNODE_FAILED);
  2369. }
  2370. if (lc_type == OBJ_DD) {
  2371. n_node =
  2372. xmlNewNode(NULL, (xmlChar *)DDOBJECTMEMBER);
  2373. if (xmlSetProp(n_node, (xmlChar *)NODENAMEATTR,
  2374. (xmlChar *)req->req_data.pair[i]->member) == NULL) {
  2375. return (ERR_XML_SETPROP_FAILED);
  2376. }
  2377. if (xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
  2378. (xmlChar *)req->req_data.pair[i]->container) ==
  2379. NULL) {
  2380. return (ERR_XML_SETPROP_FAILED);
  2381. }
  2382. } else {
  2383. n_node =
  2384. xmlNewNode(NULL, (xmlChar *)DDSETOBJECTMEMBER);
  2385. if (xmlSetProp(n_node, (xmlChar *)DDNAMEATTR,
  2386. (xmlChar *)req->req_data.pair[i]->member) == NULL) {
  2387. return (ERR_XML_SETPROP_FAILED);
  2388. }
  2389. if (xmlSetProp(n_node, (xmlChar *)DDSETNAMEATTR,
  2390. (xmlChar *)req->req_data.pair[i]->container) ==
  2391. NULL) {
  2392. return (ERR_XML_SETPROP_FAILED);
  2393. }
  2394. }
  2395. if (xmlAddChild(n_obj, n_node) == NULL) {
  2396. return (ERR_XML_ADDCHILD_FAILED);
  2397. }
  2398. ret_save = ret;
  2399. }
  2400. i++;
  2401. }
  2402. return (handle_partial_failure(doc, ret_save,
  2403. (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
  2404. }
  2405. /*
  2406. * ****************************************************************************
  2407. *
  2408. * rename_dd_ddset_op:
  2409. * removes a list of dd memeber or dd seti member.
  2410. *
  2411. * req - contains delete request info.
  2412. * doc - response doc to fill up
  2413. * type - object type(either dd or dd set)
  2414. *
  2415. * ****************************************************************************
  2416. */
  2417. static int
  2418. rename_dd_ddset_op(
  2419. request_t *req,
  2420. xmlDocPtr doc,
  2421. object_type type
  2422. /* any additional arguments go here */
  2423. )
  2424. {
  2425. result_code_t ret = 0, ret_save = 0;
  2426. isns_type_t lc_type;
  2427. int i = 0, err_count = 0;
  2428. lookup_ctrl_t lc;
  2429. uint32_t container_id;
  2430. xmlNodePtr n_node, n_obj, root;
  2431. uchar_t *name;
  2432. uint32_t len;
  2433. int different_err = 0;
  2434. lc_type = get_lc_type(type);
  2435. if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
  2436. return (ERR_INVALID_MGMT_REQUEST);
  2437. }
  2438. /* prepare lookup ctrl data for looking for the node object */
  2439. SET_UID_LCP(&lc, lc_type, 0);
  2440. root = xmlDocGetRootElement(doc);
  2441. if (root == NULL) {
  2442. return (ERR_SYNTAX_MISSING_ROOT);
  2443. }
  2444. while (i < req->count) {
  2445. /* id is checked to be not NULL before calling this routine. */
  2446. lc.data[0].ui = *(req->req_data.attrlist[i]->id);
  2447. /* get the dd_id/dds_id */
  2448. (void) cache_lock_write();
  2449. if ((container_id = is_obj_there(&lc)) != 0) {
  2450. name = (uchar_t *)req->req_data.attrlist[i]->name;
  2451. /* the length of the name need to include the */
  2452. /* null terminator and be on 4 bytes aligned */
  2453. len = xmlStrlen(name) + 1;
  2454. len += 4 - (len % 4);
  2455. /* rename the dd/dds */
  2456. ret = (lc_type == OBJ_DD) ?
  2457. update_dd_name(container_id, len, name) :
  2458. update_dds_name(container_id, len, name);
  2459. /* release the lock and sync the data */
  2460. ret = cache_unlock_sync(ret);
  2461. } else {
  2462. /* release the lock and no need to sync */
  2463. (void) cache_unlock_nosync();
  2464. ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND :
  2465. ERR_MATCHING_DDSET_NOT_FOUND;
  2466. }
  2467. if (ret != 0) {
  2468. /* keep track if there are different errors encountered. */
  2469. if (ret_save != 0 && ret != ret_save) {
  2470. different_err++;
  2471. }
  2472. ret_save = ret;
  2473. err_count++;
  2474. n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
  2475. if (n_obj) {
  2476. if ((n_obj = xmlAddChild(root, n_obj)) == NULL) {
  2477. return (ERR_XML_ADDCHILD_FAILED);
  2478. }
  2479. } else {
  2480. return (ERR_XML_NEWNODE_FAILED);
  2481. }
  2482. n_node = (lc_type == OBJ_DD) ?
  2483. xmlNewNode(NULL, (xmlChar *)DDOBJECT) :
  2484. xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
  2485. if (n_node) {
  2486. if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) {
  2487. return (ERR_XML_ADDCHILD_FAILED);
  2488. } else {
  2489. if (xmlSetProp(n_node, (xmlChar *)NAMEATTR,
  2490. (xmlChar *)req->req_data.attrlist[i]->name) ==
  2491. NULL) {
  2492. return (ERR_XML_SETPROP_FAILED);
  2493. }
  2494. }
  2495. } else {
  2496. return (ERR_XML_NEWNODE_FAILED);
  2497. }
  2498. }
  2499. i++;
  2500. }
  2501. return (handle_partial_failure(doc, ret_save,
  2502. (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
  2503. }
  2504. /*
  2505. * ****************************************************************************
  2506. *
  2507. * update_dd_ddset_op:
  2508. * removes a list of dd memeber or dd seti member.
  2509. *
  2510. * req - contains delete request info.
  2511. * doc - response doc to fill up
  2512. * type - object type(either dd or dd set)
  2513. *
  2514. * ****************************************************************************
  2515. */
  2516. static int
  2517. update_dd_ddset_op(
  2518. request_t *req,
  2519. xmlDocPtr doc,
  2520. object_type type
  2521. /* any additional arguments go here */
  2522. )
  2523. {
  2524. result_code_t ret = 0, ret_save = 0;
  2525. isns_type_t lc_type;
  2526. int i = 0, err_count = 0;
  2527. lookup_ctrl_t lc;
  2528. uint32_t container_id;
  2529. xmlNodePtr n_node, n_obj, root;
  2530. int different_err = 0;
  2531. lc_type = get_lc_type(type);
  2532. if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
  2533. return (ERR_INVALID_MGMT_REQUEST);
  2534. }
  2535. /* prepare lookup ctrl data for looking for the node object */
  2536. lc.curr_uid = 0;
  2537. lc.type = lc_type;
  2538. lc.id[0] = get_lc_id(req->op_info.obj);
  2539. lc.op[0] = OP_STRING;
  2540. lc.op[1] = 0;
  2541. root = xmlDocGetRootElement(doc);
  2542. if (root == NULL) {
  2543. return (ERR_SYNTAX_MISSING_ROOT);
  2544. }
  2545. while (i < req->count) {
  2546. lc.data[0].ptr = req->req_data.attrlist[i]->name;
  2547. /* lock the cache for writing */
  2548. (void) cache_lock_write();
  2549. if ((container_id = is_obj_there(&lc)) != 0) {
  2550. ret = (lc_type == OBJ_DD) ?
  2551. /* enabled is checked to be not NULL before calling. */
  2552. update_dd_features(container_id,
  2553. *(req->req_data.attrlist[i]->enabled) ? 1 : 0):
  2554. update_dds_status(container_id,
  2555. *(req->req_data.attrlist[i]->enabled) ? 1 : 0);
  2556. /* unlock the cache and sync the data */
  2557. ret = cache_unlock_sync(ret);
  2558. } else {
  2559. (void) cache_unlock_nosync();
  2560. ret = (lc_type == OBJ_DD) ? ERR_MATCHING_DD_NOT_FOUND :
  2561. ERR_MATCHING_DDSET_NOT_FOUND;
  2562. }
  2563. if (ret != 0) {
  2564. /* keep track if there are different errors encountered. */
  2565. if (ret_save != 0 && ret != ret_save) {
  2566. different_err++;
  2567. }
  2568. ret_save = ret;
  2569. err_count++;
  2570. n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
  2571. if (n_obj) {
  2572. if ((n_obj = xmlAddChild(root, n_obj)) == NULL) {
  2573. return (ERR_XML_ADDCHILD_FAILED);
  2574. }
  2575. } else {
  2576. return (ERR_XML_NEWNODE_FAILED);
  2577. }
  2578. n_node = (lc_type == OBJ_DD) ?
  2579. xmlNewNode(NULL, (xmlChar *)DDOBJECT) :
  2580. xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
  2581. if (n_node) {
  2582. if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) {
  2583. return (ERR_XML_ADDCHILD_FAILED);
  2584. } else {
  2585. if (xmlSetProp(n_node, (xmlChar *)NAMEATTR,
  2586. (xmlChar *)req->req_data.attrlist[i]->name) ==
  2587. NULL) {
  2588. return (ERR_XML_SETPROP_FAILED);
  2589. }
  2590. }
  2591. } else {
  2592. return (ERR_XML_NEWNODE_FAILED);
  2593. }
  2594. }
  2595. i++;
  2596. }
  2597. return (handle_partial_failure(doc, ret_save,
  2598. (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
  2599. }
  2600. /*
  2601. * ****************************************************************************
  2602. *
  2603. * createModify_dd_ddset_op:
  2604. * removes a list of dd memeber or dd seti member.
  2605. *
  2606. * req - contains delete request info.
  2607. * doc - response doc to fill up
  2608. *
  2609. * ****************************************************************************
  2610. */
  2611. static int
  2612. create_dd_ddset_op(
  2613. request_t *req,
  2614. xmlDocPtr doc,
  2615. object_type type
  2616. /* any additional arguments go here */
  2617. )
  2618. {
  2619. isns_obj_t *obj;
  2620. result_code_t ret = 0, ret_save = 0;
  2621. isns_type_t lc_type;
  2622. lookup_ctrl_t lc;
  2623. uint32_t uid;
  2624. int i = 0, err_count = 0;
  2625. xmlNodePtr n_obj, n_node, root;
  2626. int different_err = 0;
  2627. lc_type = get_lc_type(type);
  2628. if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
  2629. return (ERR_INVALID_MGMT_REQUEST);
  2630. }
  2631. root = xmlDocGetRootElement(doc);
  2632. if (root == NULL) {
  2633. return (ERR_SYNTAX_MISSING_ROOT);
  2634. }
  2635. lc_type = get_lc_type(type);
  2636. if ((lc_type != OBJ_DD) && (lc_type != OBJ_DDS)) {
  2637. return (ERR_INVALID_MGMT_REQUEST);
  2638. }
  2639. /* prepare lookup ctrl data for looking for the node object */
  2640. lc.curr_uid = 0;
  2641. lc.type = lc_type;
  2642. lc.id[0] = get_lc_id(req->op_info.obj);
  2643. lc.op[0] = OP_STRING;
  2644. lc.op[1] = 0;
  2645. lc.data[1].ptr = (uchar_t *)doc; /* xml writer descriptor */
  2646. while (i < req->count) {
  2647. lc.data[0].ptr = req->req_data.attrlist[i]->name,
  2648. /* grab the write lock */
  2649. (void) cache_lock_write();
  2650. uid = is_obj_there(&lc);
  2651. if (uid == 0) {
  2652. ret = (lc_type == OBJ_DD) ?
  2653. adm_create_dd(&obj, req->req_data.attrlist[i]->name,
  2654. 0, 0) :
  2655. adm_create_dds(&obj, req->req_data.attrlist[i]->name,
  2656. 0, 0);
  2657. if (ret == 0) {
  2658. ret = register_object(obj, NULL, NULL);
  2659. if (ret != 0) {
  2660. free_object(obj);
  2661. }
  2662. /* release the lock and sync the cache and data store */
  2663. ret = cache_unlock_sync(ret);
  2664. }
  2665. } else {
  2666. /* release the lock and no need to sync the data */
  2667. (void) cache_unlock_nosync();
  2668. ret = ERR_NAME_IN_USE;
  2669. }
  2670. if (ret != 0) {
  2671. /* keep track if there are different errors encountered. */
  2672. if (ret_save != 0 && ret != ret_save) {
  2673. different_err++;
  2674. }
  2675. ret_save = ret;
  2676. err_count++;
  2677. n_obj = xmlNewNode(NULL, (xmlChar *)ISNSOBJECT);
  2678. if (n_obj) {
  2679. if ((n_obj = xmlAddChild(root, n_obj)) == NULL) {
  2680. return (ERR_XML_ADDCHILD_FAILED);
  2681. }
  2682. } else {
  2683. return (ERR_XML_ADDCHILD_FAILED);
  2684. }
  2685. n_node = (lc_type == OBJ_DD) ?
  2686. xmlNewNode(NULL, (xmlChar *)DDOBJECT) :
  2687. xmlNewNode(NULL, (xmlChar *)DDSETOBJECT);
  2688. if (n_node) {
  2689. if ((n_node = xmlAddChild(n_obj, n_node)) == NULL) {
  2690. return (ERR_XML_ADDCHILD_FAILED);
  2691. } else {
  2692. if (xmlSetProp(n_node, (xmlChar *)NAMEATTR,
  2693. (xmlChar *)req->req_data.attrlist[i]->name) ==
  2694. NULL) {
  2695. return (ERR_XML_SETPROP_FAILED);
  2696. }
  2697. }
  2698. } else {
  2699. return (ERR_XML_NEWNODE_FAILED);
  2700. }
  2701. }
  2702. i++;
  2703. }
  2704. return (handle_partial_failure(doc, ret_save,
  2705. (req->count == err_count && !different_err) ? B_TRUE : B_FALSE));
  2706. }
  2707. /*
  2708. * ****************************************************************************
  2709. *
  2710. * createModify_dd_ddset_op:
  2711. * removes a list of dd memeber or dd seti member.
  2712. *
  2713. * req - contains delete request info.
  2714. * doc - response doc to fill up
  2715. *
  2716. * ****************************************************************************
  2717. */
  2718. int
  2719. createModify_dd_ddset_op(
  2720. request_t *req,
  2721. xmlDocPtr doc
  2722. /* any additional arguments go here */
  2723. )
  2724. {
  2725. result_code_t ret = 0;
  2726. if (req->req_data.attrlist[0]->id != NULL) {
  2727. ret = rename_dd_ddset_op(req, doc, req->op_info.obj);
  2728. } else if (req->req_data.attrlist[0]->enabled != NULL) {
  2729. ret = update_dd_ddset_op(req, doc, req->op_info.obj);
  2730. } else {
  2731. ret = create_dd_ddset_op(req, doc, req->op_info.obj);
  2732. }
  2733. return (ret);
  2734. }