confdb.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524
  1. /*
  2. * Copyright (c) 2008-2009 Red Hat, Inc.
  3. *
  4. * All rights reserved.
  5. *
  6. * Author: Christine Caulfield (ccaulfie@redhat.com)
  7. *
  8. * This software licensed under BSD license, the text of which follows:
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * - Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. * - Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  32. * THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. /*
  35. * Provides access to data in the corosync object database
  36. */
  37. #include <config.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <unistd.h>
  41. #include <pthread.h>
  42. #include <sys/types.h>
  43. #include <errno.h>
  44. #include <corosync/corotypes.h>
  45. #include <corosync/coroipc_types.h>
  46. #include <corosync/coroipcc.h>
  47. #include <corosync/corodefs.h>
  48. #include <corosync/hdb.h>
  49. #include <corosync/list.h>
  50. #include <corosync/confdb.h>
  51. #include <corosync/ipc_confdb.h>
  52. #include "util.h"
  53. #include "sa-confdb.h"
  54. #undef MIN
  55. #define MIN(x,y) ((x) < (y) ? (x) : (y))
  56. /* Hold the information for iterators so that
  57. callers can do recursive tree traversals.
  58. each object_handle can have its own iterator */
  59. struct iter_context {
  60. struct list_head list;
  61. hdb_handle_t parent_object_handle;
  62. hdb_handle_t find_handle;
  63. hdb_handle_t next_entry;
  64. };
  65. struct confdb_inst {
  66. hdb_handle_t handle;
  67. int finalize;
  68. int standalone;
  69. confdb_callbacks_t callbacks;
  70. const void *context;
  71. struct list_head object_find_head;
  72. struct list_head object_iter_head;
  73. struct list_head key_iter_head;
  74. };
  75. DECLARE_HDB_DATABASE(confdb_handle_t_db,NULL);
  76. static cs_error_t do_find_destroy(struct confdb_inst *confdb_inst, hdb_handle_t find_handle);
  77. /* Safely tidy one iterator context list */
  78. static void free_context_list(struct confdb_inst *confdb_inst, struct list_head *list)
  79. {
  80. struct iter_context *context;
  81. struct list_head *iter, *tmp;
  82. for (iter = list->next, tmp = iter->next;
  83. iter != list; iter = tmp, tmp = iter->next) {
  84. context = list_entry (iter, struct iter_context, list);
  85. (void)do_find_destroy(confdb_inst, context->find_handle);
  86. free(context);
  87. }
  88. }
  89. static struct iter_context *find_iter_context(struct list_head *list, hdb_handle_t object_handle)
  90. {
  91. struct iter_context *context;
  92. struct list_head *iter;
  93. for (iter = list->next;
  94. iter != list; iter = iter->next) {
  95. context = list_entry (iter, struct iter_context, list);
  96. if (context->parent_object_handle == object_handle)
  97. return context;
  98. }
  99. return NULL;
  100. }
  101. /**
  102. * @defgroup confdb_corosync
  103. * @ingroup corosync
  104. *
  105. * @{
  106. */
  107. cs_error_t confdb_initialize (
  108. confdb_handle_t *handle,
  109. confdb_callbacks_t *callbacks)
  110. {
  111. cs_error_t error;
  112. struct confdb_inst *confdb_inst;
  113. error = hdb_error_to_cs(hdb_handle_create (&confdb_handle_t_db, sizeof (struct confdb_inst), handle));
  114. if (error != CS_OK) {
  115. goto error_no_destroy;
  116. }
  117. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, *handle, (void *)&confdb_inst));
  118. if (error != CS_OK) {
  119. goto error_destroy;
  120. }
  121. if (getenv("COROSYNC_DEFAULT_CONFIG_IFACE")) {
  122. error = confdb_sa_init();
  123. confdb_inst->standalone = 1;
  124. }
  125. else {
  126. error = coroipcc_service_connect (
  127. COROSYNC_SOCKET_NAME,
  128. CONFDB_SERVICE,
  129. IPC_REQUEST_SIZE,
  130. IPC_RESPONSE_SIZE,
  131. IPC_DISPATCH_SIZE,
  132. &confdb_inst->handle);
  133. }
  134. if (error != CS_OK)
  135. goto error_put_destroy;
  136. memcpy (&confdb_inst->callbacks, callbacks, sizeof (confdb_callbacks_t));
  137. list_init (&confdb_inst->object_find_head);
  138. list_init (&confdb_inst->object_iter_head);
  139. list_init (&confdb_inst->key_iter_head);
  140. (void)hdb_handle_put (&confdb_handle_t_db, *handle);
  141. return (CS_OK);
  142. error_put_destroy:
  143. (void)hdb_handle_put (&confdb_handle_t_db, *handle);
  144. error_destroy:
  145. (void)hdb_handle_destroy (&confdb_handle_t_db, *handle);
  146. error_no_destroy:
  147. return (error);
  148. }
  149. cs_error_t confdb_finalize (
  150. confdb_handle_t handle)
  151. {
  152. struct confdb_inst *confdb_inst;
  153. cs_error_t error;
  154. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  155. if (error != CS_OK) {
  156. return (error);
  157. }
  158. /*
  159. * Another thread has already started finalizing
  160. */
  161. if (confdb_inst->finalize) {
  162. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  163. return (CS_ERR_BAD_HANDLE);
  164. }
  165. confdb_inst->finalize = 1;
  166. /* Free saved context handles */
  167. free_context_list(confdb_inst, &confdb_inst->object_find_head);
  168. free_context_list(confdb_inst, &confdb_inst->object_iter_head);
  169. free_context_list(confdb_inst, &confdb_inst->key_iter_head);
  170. if (!confdb_inst->standalone) {
  171. coroipcc_service_disconnect (confdb_inst->handle);
  172. }
  173. (void)hdb_handle_destroy (&confdb_handle_t_db, handle);
  174. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  175. return (CS_OK);
  176. }
  177. cs_error_t confdb_fd_get (
  178. confdb_handle_t handle,
  179. int *fd)
  180. {
  181. cs_error_t error;
  182. struct confdb_inst *confdb_inst;
  183. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  184. if (error != CS_OK) {
  185. return (error);
  186. }
  187. error = coroipcc_fd_get (confdb_inst->handle, fd);
  188. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  189. return (error);
  190. }
  191. cs_error_t confdb_context_get (
  192. confdb_handle_t handle,
  193. const void **context)
  194. {
  195. cs_error_t error;
  196. struct confdb_inst *confdb_inst;
  197. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  198. if (error != CS_OK) {
  199. return (error);
  200. }
  201. *context = confdb_inst->context;
  202. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  203. return (CS_OK);
  204. }
  205. cs_error_t confdb_context_set (
  206. confdb_handle_t handle,
  207. const void *context)
  208. {
  209. cs_error_t error;
  210. struct confdb_inst *confdb_inst;
  211. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  212. if (error != CS_OK) {
  213. return (error);
  214. }
  215. confdb_inst->context = context;
  216. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  217. return (CS_OK);
  218. }
  219. cs_error_t confdb_dispatch (
  220. confdb_handle_t handle,
  221. cs_dispatch_flags_t dispatch_types)
  222. {
  223. int timeout = -1;
  224. cs_error_t error;
  225. int cont = 1; /* always continue do loop except when set to 0 */
  226. struct confdb_inst *confdb_inst;
  227. confdb_callbacks_t callbacks;
  228. struct res_lib_confdb_key_change_callback *res_key_changed_pt;
  229. struct res_lib_confdb_object_create_callback *res_object_created_pt;
  230. struct res_lib_confdb_object_destroy_callback *res_object_destroyed_pt;
  231. coroipc_response_header_t *dispatch_data;
  232. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  233. if (error != CS_OK) {
  234. return (error);
  235. }
  236. if (confdb_inst->standalone) {
  237. error = CS_ERR_NOT_SUPPORTED;
  238. goto error_put;
  239. }
  240. /*
  241. * Timeout instantly for SA_DISPATCH_ONE or SA_DISPATCH_ALL and
  242. * wait indefinately for SA_DISPATCH_BLOCKING
  243. */
  244. if (dispatch_types == CONFDB_DISPATCH_ALL) {
  245. timeout = 0;
  246. }
  247. do {
  248. error = coroipcc_dispatch_get (
  249. confdb_inst->handle,
  250. (void **)&dispatch_data,
  251. timeout);
  252. if (error != CS_OK) {
  253. goto error_put;
  254. }
  255. /*
  256. * Make copy of callbacks, message data, unlock instance, and call callback
  257. * A risk of this dispatch method is that the callback routines may
  258. * operate at the same time that confdbFinalize has been called.
  259. */
  260. memcpy (&callbacks, &confdb_inst->callbacks, sizeof (confdb_callbacks_t));
  261. /*
  262. * Dispatch incoming message
  263. */
  264. switch (dispatch_data->id) {
  265. case MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK:
  266. res_key_changed_pt = (struct res_lib_confdb_key_change_callback *)dispatch_data;
  267. callbacks.confdb_key_change_notify_fn(handle,
  268. res_key_changed_pt->change_type,
  269. res_key_changed_pt->object_handle,
  270. res_key_changed_pt->parent_object_handle,
  271. res_key_changed_pt->object_name.value,
  272. res_key_changed_pt->object_name.length,
  273. res_key_changed_pt->key_name.value,
  274. res_key_changed_pt->key_name.length,
  275. res_key_changed_pt->key_value.value,
  276. res_key_changed_pt->key_value.length);
  277. break;
  278. case MESSAGE_RES_CONFDB_OBJECT_CREATE_CALLBACK:
  279. res_object_created_pt = (struct res_lib_confdb_object_create_callback *)dispatch_data;
  280. callbacks.confdb_object_create_change_notify_fn(handle,
  281. res_object_created_pt->object_handle,
  282. res_object_created_pt->parent_object_handle,
  283. res_object_created_pt->name.value,
  284. res_object_created_pt->name.length);
  285. break;
  286. case MESSAGE_RES_CONFDB_OBJECT_DESTROY_CALLBACK:
  287. res_object_destroyed_pt = (struct res_lib_confdb_object_destroy_callback *)dispatch_data;
  288. callbacks.confdb_object_delete_change_notify_fn(handle,
  289. res_object_destroyed_pt->parent_object_handle,
  290. res_object_destroyed_pt->name.value,
  291. res_object_destroyed_pt->name.length);
  292. break;
  293. default:
  294. coroipcc_dispatch_put (confdb_inst->handle);
  295. error = CS_ERR_LIBRARY;
  296. goto error_noput;
  297. break;
  298. }
  299. coroipcc_dispatch_put (confdb_inst->handle);
  300. /*
  301. * Determine if more messages should be processed
  302. * */
  303. switch (dispatch_types) {
  304. case CONFDB_DISPATCH_ONE:
  305. cont = 0;
  306. break;
  307. case CONFDB_DISPATCH_ALL:
  308. break;
  309. case CONFDB_DISPATCH_BLOCKING:
  310. break;
  311. }
  312. } while (cont);
  313. error_put:
  314. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  315. error_noput:
  316. return (error);
  317. }
  318. cs_error_t confdb_object_create (
  319. confdb_handle_t handle,
  320. hdb_handle_t parent_object_handle,
  321. const void *object_name,
  322. size_t object_name_len,
  323. hdb_handle_t *object_handle)
  324. {
  325. cs_error_t error;
  326. struct confdb_inst *confdb_inst;
  327. struct iovec iov;
  328. struct req_lib_confdb_object_create req_lib_confdb_object_create;
  329. struct res_lib_confdb_object_create res_lib_confdb_object_create;
  330. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  331. if (error != CS_OK) {
  332. return (error);
  333. }
  334. if (confdb_inst->standalone) {
  335. error = CS_OK;
  336. if (confdb_sa_object_create(parent_object_handle,
  337. object_name, object_name_len,
  338. object_handle))
  339. error = CS_ERR_ACCESS;
  340. goto error_exit;
  341. }
  342. req_lib_confdb_object_create.header.size = sizeof (struct req_lib_confdb_object_create);
  343. req_lib_confdb_object_create.header.id = MESSAGE_REQ_CONFDB_OBJECT_CREATE;
  344. req_lib_confdb_object_create.parent_object_handle = parent_object_handle;
  345. memcpy(req_lib_confdb_object_create.object_name.value, object_name, object_name_len);
  346. req_lib_confdb_object_create.object_name.length = object_name_len;
  347. iov.iov_base = (char *)&req_lib_confdb_object_create;
  348. iov.iov_len = sizeof (struct req_lib_confdb_object_create);
  349. error = coroipcc_msg_send_reply_receive (
  350. confdb_inst->handle,
  351. &iov,
  352. 1,
  353. &res_lib_confdb_object_create,
  354. sizeof (struct res_lib_confdb_object_create));
  355. if (error != CS_OK) {
  356. goto error_exit;
  357. }
  358. error = res_lib_confdb_object_create.header.error;
  359. *object_handle = res_lib_confdb_object_create.object_handle;
  360. error_exit:
  361. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  362. return (error);
  363. }
  364. cs_error_t confdb_object_destroy (
  365. confdb_handle_t handle,
  366. hdb_handle_t object_handle)
  367. {
  368. cs_error_t error;
  369. struct confdb_inst *confdb_inst;
  370. struct iovec iov;
  371. struct req_lib_confdb_object_destroy req_lib_confdb_object_destroy;
  372. coroipc_response_header_t res;
  373. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  374. if (error != CS_OK) {
  375. return (error);
  376. }
  377. if (confdb_inst->standalone) {
  378. error = CS_OK;
  379. if (confdb_sa_object_destroy(object_handle))
  380. error = CS_ERR_ACCESS;
  381. goto error_exit;
  382. }
  383. req_lib_confdb_object_destroy.header.size = sizeof (struct req_lib_confdb_object_destroy);
  384. req_lib_confdb_object_destroy.header.id = MESSAGE_REQ_CONFDB_OBJECT_DESTROY;
  385. req_lib_confdb_object_destroy.object_handle = object_handle;
  386. iov.iov_base = (char *)&req_lib_confdb_object_destroy;
  387. iov.iov_len = sizeof (struct req_lib_confdb_object_destroy);
  388. error = coroipcc_msg_send_reply_receive (
  389. confdb_inst->handle,
  390. &iov,
  391. 1,
  392. &res,
  393. sizeof (coroipc_response_header_t));
  394. if (error != CS_OK) {
  395. goto error_exit;
  396. }
  397. error = res.error;
  398. error_exit:
  399. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  400. return (error);
  401. }
  402. cs_error_t confdb_object_parent_get (
  403. confdb_handle_t handle,
  404. hdb_handle_t object_handle,
  405. hdb_handle_t *parent_object_handle)
  406. {
  407. cs_error_t error;
  408. struct confdb_inst *confdb_inst;
  409. struct iovec iov;
  410. struct req_lib_confdb_object_parent_get req_lib_confdb_object_parent_get;
  411. struct res_lib_confdb_object_parent_get res_lib_confdb_object_parent_get;
  412. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  413. if (error != CS_OK) {
  414. return (error);
  415. }
  416. if (confdb_inst->standalone) {
  417. error = CS_OK;
  418. if (confdb_sa_object_parent_get(object_handle, parent_object_handle))
  419. error = CS_ERR_ACCESS;
  420. goto error_exit;
  421. }
  422. req_lib_confdb_object_parent_get.header.size = sizeof (struct req_lib_confdb_object_parent_get);
  423. req_lib_confdb_object_parent_get.header.id = MESSAGE_REQ_CONFDB_OBJECT_PARENT_GET;
  424. req_lib_confdb_object_parent_get.object_handle = object_handle;
  425. iov.iov_base = (char *)&req_lib_confdb_object_parent_get;
  426. iov.iov_len = sizeof (struct req_lib_confdb_object_parent_get);
  427. error = coroipcc_msg_send_reply_receive (
  428. confdb_inst->handle,
  429. &iov,
  430. 1,
  431. &res_lib_confdb_object_parent_get,
  432. sizeof (struct res_lib_confdb_object_parent_get));
  433. if (error != CS_OK) {
  434. goto error_exit;
  435. }
  436. error = res_lib_confdb_object_parent_get.header.error;
  437. *parent_object_handle = res_lib_confdb_object_parent_get.parent_object_handle;
  438. error_exit:
  439. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  440. return (error);
  441. }
  442. static cs_error_t do_find_destroy(
  443. struct confdb_inst *confdb_inst,
  444. hdb_handle_t find_handle)
  445. {
  446. cs_error_t error;
  447. struct iovec iov;
  448. struct req_lib_confdb_object_find_destroy req_lib_confdb_object_find_destroy;
  449. coroipc_response_header_t res;
  450. if (!find_handle)
  451. return CS_OK;
  452. if (confdb_inst->standalone) {
  453. error = CS_OK;
  454. if (confdb_sa_find_destroy(find_handle))
  455. error = CS_ERR_ACCESS;
  456. goto error_exit;
  457. }
  458. req_lib_confdb_object_find_destroy.header.size = sizeof (struct req_lib_confdb_object_find_destroy);
  459. req_lib_confdb_object_find_destroy.header.id = MESSAGE_REQ_CONFDB_OBJECT_FIND_DESTROY;
  460. req_lib_confdb_object_find_destroy.find_handle = find_handle;
  461. iov.iov_base = (char *)&req_lib_confdb_object_find_destroy;
  462. iov.iov_len = sizeof (struct req_lib_confdb_object_find_destroy);
  463. error = coroipcc_msg_send_reply_receive (
  464. confdb_inst->handle,
  465. &iov,
  466. 1,
  467. &res,
  468. sizeof (coroipc_response_header_t));
  469. if (error != CS_OK) {
  470. goto error_exit;
  471. }
  472. error = res.error;
  473. error_exit:
  474. return (error);
  475. }
  476. cs_error_t confdb_object_find_destroy(
  477. confdb_handle_t handle,
  478. hdb_handle_t parent_object_handle)
  479. {
  480. struct iter_context *context;
  481. cs_error_t error;
  482. struct confdb_inst *confdb_inst;
  483. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  484. if (error != CS_OK) {
  485. return (error);
  486. }
  487. context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle);
  488. error = do_find_destroy(confdb_inst, context->find_handle);
  489. if (error == CS_OK) {
  490. list_del(&context->list);
  491. free(context);
  492. }
  493. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  494. return error;
  495. }
  496. cs_error_t confdb_object_iter_destroy(
  497. confdb_handle_t handle,
  498. hdb_handle_t parent_object_handle)
  499. {
  500. struct iter_context *context;
  501. cs_error_t error;
  502. struct confdb_inst *confdb_inst;
  503. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  504. if (error != CS_OK) {
  505. return (error);
  506. }
  507. context = find_iter_context(&confdb_inst->object_iter_head, parent_object_handle);
  508. error = do_find_destroy(confdb_inst, context->find_handle);
  509. if (error == CS_OK) {
  510. list_del(&context->list);
  511. free(context);
  512. }
  513. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  514. return error;
  515. }
  516. cs_error_t confdb_key_create (
  517. confdb_handle_t handle,
  518. hdb_handle_t parent_object_handle,
  519. const void *key_name,
  520. size_t key_name_len,
  521. const void *value,
  522. size_t value_len)
  523. {
  524. cs_error_t error;
  525. struct confdb_inst *confdb_inst;
  526. struct iovec iov;
  527. struct req_lib_confdb_key_create req_lib_confdb_key_create;
  528. coroipc_response_header_t res;
  529. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  530. if (error != CS_OK) {
  531. return (error);
  532. }
  533. if (confdb_inst->standalone) {
  534. error = CS_OK;
  535. if (confdb_sa_key_create(parent_object_handle,
  536. key_name, key_name_len,
  537. value, value_len))
  538. error = CS_ERR_ACCESS;
  539. goto error_exit;
  540. }
  541. req_lib_confdb_key_create.header.size = sizeof (struct req_lib_confdb_key_create);
  542. req_lib_confdb_key_create.header.id = MESSAGE_REQ_CONFDB_KEY_CREATE;
  543. req_lib_confdb_key_create.object_handle = parent_object_handle;
  544. memcpy(req_lib_confdb_key_create.key_name.value, key_name, key_name_len);
  545. req_lib_confdb_key_create.key_name.length = key_name_len;
  546. memcpy(req_lib_confdb_key_create.value.value, value, value_len);
  547. req_lib_confdb_key_create.value.length = value_len;
  548. iov.iov_base = (char *)&req_lib_confdb_key_create;
  549. iov.iov_len = sizeof (struct req_lib_confdb_key_create);
  550. error = coroipcc_msg_send_reply_receive (
  551. confdb_inst->handle,
  552. &iov,
  553. 1,
  554. &res,
  555. sizeof (res));
  556. if (error != CS_OK) {
  557. goto error_exit;
  558. }
  559. error = res.error;
  560. error_exit:
  561. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  562. return (error);
  563. }
  564. cs_error_t confdb_key_delete (
  565. confdb_handle_t handle,
  566. hdb_handle_t parent_object_handle,
  567. const void *key_name,
  568. size_t key_name_len,
  569. const void *value,
  570. size_t value_len)
  571. {
  572. cs_error_t error;
  573. struct confdb_inst *confdb_inst;
  574. struct iovec iov;
  575. struct req_lib_confdb_key_delete req_lib_confdb_key_delete;
  576. coroipc_response_header_t res;
  577. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  578. if (error != CS_OK) {
  579. return (error);
  580. }
  581. if (confdb_inst->standalone) {
  582. error = CS_OK;
  583. if (confdb_sa_key_delete(parent_object_handle,
  584. key_name, key_name_len,
  585. value, value_len))
  586. error = CS_ERR_ACCESS;
  587. goto error_exit;
  588. }
  589. req_lib_confdb_key_delete.header.size = sizeof (struct req_lib_confdb_key_delete);
  590. req_lib_confdb_key_delete.header.id = MESSAGE_REQ_CONFDB_KEY_DELETE;
  591. req_lib_confdb_key_delete.object_handle = parent_object_handle;
  592. memcpy(req_lib_confdb_key_delete.key_name.value, key_name, key_name_len);
  593. req_lib_confdb_key_delete.key_name.length = key_name_len;
  594. memcpy(req_lib_confdb_key_delete.value.value, value, value_len);
  595. req_lib_confdb_key_delete.value.length = value_len;
  596. iov.iov_base = (char *)&req_lib_confdb_key_delete;
  597. iov.iov_len = sizeof (struct req_lib_confdb_key_delete);
  598. error = coroipcc_msg_send_reply_receive (
  599. confdb_inst->handle,
  600. &iov,
  601. 1,
  602. &res,
  603. sizeof (res));
  604. if (error != CS_OK) {
  605. goto error_exit;
  606. }
  607. error = res.error;
  608. error_exit:
  609. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  610. return (error);
  611. }
  612. cs_error_t confdb_key_get (
  613. confdb_handle_t handle,
  614. hdb_handle_t parent_object_handle,
  615. const void *key_name,
  616. size_t key_name_len,
  617. void *value,
  618. size_t *value_len)
  619. {
  620. cs_error_t error;
  621. struct confdb_inst *confdb_inst;
  622. struct iovec iov;
  623. struct req_lib_confdb_key_get req_lib_confdb_key_get;
  624. struct res_lib_confdb_key_get res_lib_confdb_key_get;
  625. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  626. if (error != CS_OK) {
  627. return (error);
  628. }
  629. if (confdb_inst->standalone) {
  630. error = CS_OK;
  631. if (confdb_sa_key_get(parent_object_handle,
  632. key_name, key_name_len,
  633. value, value_len))
  634. error = CS_ERR_ACCESS;
  635. goto error_exit;
  636. }
  637. req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
  638. req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_GET;
  639. req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
  640. memcpy(req_lib_confdb_key_get.key_name.value, key_name, key_name_len);
  641. req_lib_confdb_key_get.key_name.length = key_name_len;
  642. iov.iov_base = (char *)&req_lib_confdb_key_get;
  643. iov.iov_len = sizeof (struct req_lib_confdb_key_get);
  644. error = coroipcc_msg_send_reply_receive (
  645. confdb_inst->handle,
  646. &iov,
  647. 1,
  648. &res_lib_confdb_key_get,
  649. sizeof (struct res_lib_confdb_key_get));
  650. if (error != CS_OK) {
  651. goto error_exit;
  652. }
  653. error = res_lib_confdb_key_get.header.error;
  654. if (error == CS_OK) {
  655. *value_len = res_lib_confdb_key_get.value.length;
  656. memcpy(value, res_lib_confdb_key_get.value.value, *value_len);
  657. }
  658. error_exit:
  659. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  660. return (error);
  661. }
  662. cs_error_t confdb_key_increment (
  663. confdb_handle_t handle,
  664. hdb_handle_t parent_object_handle,
  665. const void *key_name,
  666. size_t key_name_len,
  667. unsigned int *value)
  668. {
  669. cs_error_t error;
  670. struct confdb_inst *confdb_inst;
  671. struct iovec iov;
  672. struct req_lib_confdb_key_get req_lib_confdb_key_get;
  673. struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec;
  674. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  675. if (error != CS_OK) {
  676. return (error);
  677. }
  678. if (confdb_inst->standalone) {
  679. error = CS_OK;
  680. if (confdb_sa_key_increment(parent_object_handle,
  681. key_name, key_name_len,
  682. value))
  683. error = CS_ERR_ACCESS;
  684. goto error_exit;
  685. }
  686. req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
  687. req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_INCREMENT;
  688. req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
  689. memcpy(req_lib_confdb_key_get.key_name.value, key_name, key_name_len);
  690. req_lib_confdb_key_get.key_name.length = key_name_len;
  691. iov.iov_base = (char *)&req_lib_confdb_key_get;
  692. iov.iov_len = sizeof (struct req_lib_confdb_key_get);
  693. error = coroipcc_msg_send_reply_receive (
  694. confdb_inst->handle,
  695. &iov,
  696. 1,
  697. &res_lib_confdb_key_incdec,
  698. sizeof (struct res_lib_confdb_key_incdec));
  699. if (error != CS_OK) {
  700. goto error_exit;
  701. }
  702. error = res_lib_confdb_key_incdec.header.error;
  703. if (error == CS_OK) {
  704. *value = res_lib_confdb_key_incdec.value;
  705. }
  706. error_exit:
  707. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  708. return (error);
  709. }
  710. cs_error_t confdb_key_decrement (
  711. confdb_handle_t handle,
  712. hdb_handle_t parent_object_handle,
  713. const void *key_name,
  714. size_t key_name_len,
  715. unsigned int *value)
  716. {
  717. cs_error_t error;
  718. struct confdb_inst *confdb_inst;
  719. struct iovec iov;
  720. struct req_lib_confdb_key_get req_lib_confdb_key_get;
  721. struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec;
  722. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  723. if (error != CS_OK) {
  724. return (error);
  725. }
  726. if (confdb_inst->standalone) {
  727. error = CS_OK;
  728. if (confdb_sa_key_decrement(parent_object_handle,
  729. key_name, key_name_len,
  730. value))
  731. error = CS_ERR_ACCESS;
  732. goto error_exit;
  733. }
  734. req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
  735. req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_DECREMENT;
  736. req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
  737. memcpy(req_lib_confdb_key_get.key_name.value, key_name, key_name_len);
  738. req_lib_confdb_key_get.key_name.length = key_name_len;
  739. iov.iov_base = (char *)&req_lib_confdb_key_get;
  740. iov.iov_len = sizeof (struct req_lib_confdb_key_get);
  741. error = coroipcc_msg_send_reply_receive (
  742. confdb_inst->handle,
  743. &iov,
  744. 1,
  745. &res_lib_confdb_key_incdec,
  746. sizeof (struct res_lib_confdb_key_incdec));
  747. if (error != CS_OK) {
  748. goto error_exit;
  749. }
  750. error = res_lib_confdb_key_incdec.header.error;
  751. if (error == CS_OK) {
  752. *value = res_lib_confdb_key_incdec.value;
  753. }
  754. error_exit:
  755. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  756. return (error);
  757. }
  758. cs_error_t confdb_key_replace (
  759. confdb_handle_t handle,
  760. hdb_handle_t parent_object_handle,
  761. const void *key_name,
  762. size_t key_name_len,
  763. const void *old_value,
  764. size_t old_value_len,
  765. const void *new_value,
  766. size_t new_value_len)
  767. {
  768. cs_error_t error;
  769. struct confdb_inst *confdb_inst;
  770. struct iovec iov;
  771. struct req_lib_confdb_key_replace req_lib_confdb_key_replace;
  772. coroipc_response_header_t res;
  773. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  774. if (error != CS_OK) {
  775. return (error);
  776. }
  777. if (confdb_inst->standalone) {
  778. error = CS_OK;
  779. if (confdb_sa_key_replace(parent_object_handle,
  780. key_name, key_name_len,
  781. old_value, old_value_len,
  782. new_value, new_value_len))
  783. error = CS_ERR_ACCESS;
  784. goto error_exit;
  785. }
  786. req_lib_confdb_key_replace.header.size = sizeof (struct req_lib_confdb_key_replace);
  787. req_lib_confdb_key_replace.header.id = MESSAGE_REQ_CONFDB_KEY_REPLACE;
  788. req_lib_confdb_key_replace.object_handle = parent_object_handle;
  789. memcpy(req_lib_confdb_key_replace.key_name.value, key_name, key_name_len);
  790. req_lib_confdb_key_replace.key_name.length = key_name_len;
  791. memcpy(req_lib_confdb_key_replace.old_value.value, old_value, old_value_len);
  792. req_lib_confdb_key_replace.old_value.length = old_value_len;
  793. memcpy(req_lib_confdb_key_replace.new_value.value, new_value, new_value_len);
  794. req_lib_confdb_key_replace.new_value.length = new_value_len;
  795. iov.iov_base = (char *)&req_lib_confdb_key_replace;
  796. iov.iov_len = sizeof (struct req_lib_confdb_key_replace);
  797. error = coroipcc_msg_send_reply_receive (
  798. confdb_inst->handle,
  799. &iov,
  800. 1,
  801. &res,
  802. sizeof (res));
  803. if (error != CS_OK) {
  804. goto error_exit;
  805. }
  806. error = res.error;
  807. error_exit:
  808. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  809. return (error);
  810. }
  811. cs_error_t confdb_object_iter_start (
  812. confdb_handle_t handle,
  813. hdb_handle_t object_handle)
  814. {
  815. struct confdb_inst *confdb_inst;
  816. cs_error_t error = CS_OK;
  817. struct iter_context *context;
  818. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  819. if (error != CS_OK) {
  820. return (error);
  821. }
  822. context = find_iter_context(&confdb_inst->object_iter_head, object_handle);
  823. if (!context) {
  824. context = malloc(sizeof(struct iter_context));
  825. if (!context) {
  826. error = CS_ERR_NO_MEMORY;
  827. goto ret;
  828. }
  829. context->parent_object_handle = object_handle;
  830. context->find_handle = 0;
  831. list_add(&context->list, &confdb_inst->object_iter_head);
  832. }
  833. /* Start a new find context */
  834. if (context->find_handle) {
  835. (void)do_find_destroy(confdb_inst, context->find_handle);
  836. context->find_handle = 0;
  837. }
  838. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  839. ret:
  840. return error;
  841. }
  842. cs_error_t confdb_key_iter_start (
  843. confdb_handle_t handle,
  844. hdb_handle_t object_handle)
  845. {
  846. struct confdb_inst *confdb_inst;
  847. cs_error_t error = CS_OK;
  848. struct iter_context *context;
  849. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  850. if (error != CS_OK) {
  851. return (error);
  852. }
  853. context = find_iter_context(&confdb_inst->key_iter_head, object_handle);
  854. if (!context) {
  855. context = malloc(sizeof(struct iter_context));
  856. if (!context) {
  857. error = CS_ERR_NO_MEMORY;
  858. goto ret;
  859. }
  860. context->parent_object_handle = object_handle;
  861. list_add(&context->list, &confdb_inst->key_iter_head);
  862. }
  863. context->find_handle = 0;
  864. context->next_entry = 0;
  865. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  866. ret:
  867. return error;
  868. }
  869. cs_error_t confdb_object_find_start (
  870. confdb_handle_t handle,
  871. hdb_handle_t parent_object_handle)
  872. {
  873. struct confdb_inst *confdb_inst;
  874. cs_error_t error = CS_OK;
  875. struct iter_context *context;
  876. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  877. if (error != CS_OK) {
  878. return (error);
  879. }
  880. context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle);
  881. if (!context) {
  882. context = malloc(sizeof(struct iter_context));
  883. if (!context) {
  884. error = CS_ERR_NO_MEMORY;
  885. goto ret;
  886. }
  887. context->find_handle = 0;
  888. context->parent_object_handle = parent_object_handle;
  889. list_add(&context->list, &confdb_inst->object_find_head);
  890. }
  891. /* Start a new find context */
  892. if (context->find_handle) {
  893. (void)do_find_destroy(confdb_inst, context->find_handle);
  894. context->find_handle = 0;
  895. }
  896. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  897. ret:
  898. return error;
  899. }
  900. cs_error_t confdb_object_find (
  901. confdb_handle_t handle,
  902. hdb_handle_t parent_object_handle,
  903. const void *object_name,
  904. size_t object_name_len,
  905. hdb_handle_t *object_handle)
  906. {
  907. cs_error_t error;
  908. struct confdb_inst *confdb_inst;
  909. struct iovec iov;
  910. struct iter_context *context;
  911. struct req_lib_confdb_object_find req_lib_confdb_object_find;
  912. struct res_lib_confdb_object_find res_lib_confdb_object_find;
  913. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  914. if (error != CS_OK) {
  915. return (error);
  916. }
  917. /* You MUST call confdb_object_find_start first */
  918. context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle);
  919. if (!context) {
  920. error = CS_ERR_CONTEXT_NOT_FOUND;
  921. goto error_exit;
  922. }
  923. if (confdb_inst->standalone) {
  924. error = CS_OK;
  925. if (confdb_sa_object_find(parent_object_handle,
  926. &context->find_handle,
  927. object_handle,
  928. object_name, object_name_len))
  929. error = CS_ERR_ACCESS;
  930. goto error_exit;
  931. }
  932. req_lib_confdb_object_find.header.size = sizeof (struct req_lib_confdb_object_find);
  933. req_lib_confdb_object_find.header.id = MESSAGE_REQ_CONFDB_OBJECT_FIND;
  934. req_lib_confdb_object_find.parent_object_handle = parent_object_handle;
  935. req_lib_confdb_object_find.find_handle = context->find_handle;
  936. memcpy(req_lib_confdb_object_find.object_name.value, object_name, object_name_len);
  937. req_lib_confdb_object_find.object_name.length = object_name_len;
  938. iov.iov_base = (char *)&req_lib_confdb_object_find;
  939. iov.iov_len = sizeof (struct req_lib_confdb_object_find);
  940. error = coroipcc_msg_send_reply_receive (
  941. confdb_inst->handle,
  942. &iov,
  943. 1,
  944. &res_lib_confdb_object_find,
  945. sizeof (struct res_lib_confdb_object_find));
  946. if (error != CS_OK) {
  947. goto error_exit;
  948. }
  949. error = res_lib_confdb_object_find.header.error;
  950. *object_handle = res_lib_confdb_object_find.object_handle;
  951. context->find_handle = res_lib_confdb_object_find.find_handle;
  952. error_exit:
  953. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  954. return (error);
  955. }
  956. cs_error_t confdb_object_iter (
  957. confdb_handle_t handle,
  958. hdb_handle_t parent_object_handle,
  959. hdb_handle_t *object_handle,
  960. void *object_name,
  961. size_t *object_name_len)
  962. {
  963. cs_error_t error;
  964. struct confdb_inst *confdb_inst;
  965. struct iovec iov;
  966. struct iter_context *context;
  967. struct req_lib_confdb_object_iter req_lib_confdb_object_iter;
  968. struct res_lib_confdb_object_iter res_lib_confdb_object_iter;
  969. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  970. if (error != CS_OK) {
  971. return (error);
  972. }
  973. /* You MUST call confdb_object_iter_start first */
  974. context = find_iter_context(&confdb_inst->object_iter_head, parent_object_handle);
  975. if (!context) {
  976. error = CS_ERR_CONTEXT_NOT_FOUND;
  977. goto error_exit;
  978. }
  979. if (confdb_inst->standalone) {
  980. error = CS_OK;
  981. *object_name_len = 0;
  982. if (confdb_sa_object_iter(parent_object_handle,
  983. &context->find_handle,
  984. object_handle,
  985. NULL, 0,
  986. object_name, object_name_len))
  987. error = CS_ERR_ACCESS;
  988. goto sa_exit;
  989. }
  990. req_lib_confdb_object_iter.header.size = sizeof (struct req_lib_confdb_object_iter);
  991. req_lib_confdb_object_iter.header.id = MESSAGE_REQ_CONFDB_OBJECT_ITER;
  992. req_lib_confdb_object_iter.parent_object_handle = parent_object_handle;
  993. req_lib_confdb_object_iter.find_handle = context->find_handle;
  994. iov.iov_base = (char *)&req_lib_confdb_object_iter;
  995. iov.iov_len = sizeof (struct req_lib_confdb_object_iter);
  996. error = coroipcc_msg_send_reply_receive (
  997. confdb_inst->handle,
  998. &iov,
  999. 1,
  1000. &res_lib_confdb_object_iter,
  1001. sizeof (struct res_lib_confdb_object_iter));
  1002. if (error != CS_OK) {
  1003. goto error_exit;
  1004. }
  1005. error = res_lib_confdb_object_iter.header.error;
  1006. if (error == CS_OK) {
  1007. *object_name_len = res_lib_confdb_object_iter.object_name.length;
  1008. memcpy(object_name, res_lib_confdb_object_iter.object_name.value, *object_name_len);
  1009. *object_handle = res_lib_confdb_object_iter.object_handle;
  1010. context->find_handle = res_lib_confdb_object_iter.find_handle;
  1011. }
  1012. sa_exit:
  1013. error_exit:
  1014. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  1015. return (error);
  1016. }
  1017. cs_error_t confdb_key_iter (
  1018. confdb_handle_t handle,
  1019. hdb_handle_t parent_object_handle,
  1020. void *key_name,
  1021. size_t *key_name_len,
  1022. void *value,
  1023. size_t *value_len)
  1024. {
  1025. cs_error_t error;
  1026. struct confdb_inst *confdb_inst;
  1027. struct iovec iov;
  1028. struct iter_context *context;
  1029. struct req_lib_confdb_key_iter req_lib_confdb_key_iter;
  1030. struct res_lib_confdb_key_iter res_lib_confdb_key_iter;
  1031. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  1032. if (error != CS_OK) {
  1033. return (error);
  1034. }
  1035. /* You MUST call confdb_key_iter_start first */
  1036. context = find_iter_context(&confdb_inst->key_iter_head, parent_object_handle);
  1037. if (!context) {
  1038. error = CS_ERR_CONTEXT_NOT_FOUND;
  1039. goto error_exit;
  1040. }
  1041. if (confdb_inst->standalone) {
  1042. error = CS_OK;
  1043. if (confdb_sa_key_iter(parent_object_handle,
  1044. context->next_entry,
  1045. key_name, key_name_len,
  1046. value, value_len))
  1047. error = CS_ERR_ACCESS;
  1048. goto sa_exit;
  1049. }
  1050. req_lib_confdb_key_iter.header.size = sizeof (struct req_lib_confdb_key_iter);
  1051. req_lib_confdb_key_iter.header.id = MESSAGE_REQ_CONFDB_KEY_ITER;
  1052. req_lib_confdb_key_iter.parent_object_handle = parent_object_handle;
  1053. req_lib_confdb_key_iter.next_entry= context->next_entry;
  1054. iov.iov_base = (char *)&req_lib_confdb_key_iter;
  1055. iov.iov_len = sizeof (struct req_lib_confdb_key_iter);
  1056. error = coroipcc_msg_send_reply_receive (
  1057. confdb_inst->handle,
  1058. &iov,
  1059. 1,
  1060. &res_lib_confdb_key_iter,
  1061. sizeof (struct res_lib_confdb_key_iter));
  1062. if (error != CS_OK) {
  1063. goto error_exit;
  1064. }
  1065. error = res_lib_confdb_key_iter.header.error;
  1066. if (error == CS_OK) {
  1067. *key_name_len = res_lib_confdb_key_iter.key_name.length;
  1068. memcpy(key_name, res_lib_confdb_key_iter.key_name.value, *key_name_len);
  1069. *value_len = res_lib_confdb_key_iter.value.length;
  1070. memcpy(value, res_lib_confdb_key_iter.value.value, *value_len);
  1071. }
  1072. sa_exit:
  1073. context->next_entry++;
  1074. error_exit:
  1075. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  1076. return (error);
  1077. }
  1078. cs_error_t confdb_write (
  1079. confdb_handle_t handle,
  1080. char *error_text,
  1081. size_t errbuf_len)
  1082. {
  1083. cs_error_t error;
  1084. struct confdb_inst *confdb_inst;
  1085. struct iovec iov;
  1086. coroipc_request_header_t req;
  1087. struct res_lib_confdb_write res_lib_confdb_write;
  1088. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  1089. if (error != CS_OK) {
  1090. /* FIXME: set error_text */
  1091. return (error);
  1092. }
  1093. if (confdb_inst->standalone) {
  1094. error = CS_OK;
  1095. if (confdb_sa_write(error_text, errbuf_len))
  1096. error = CS_ERR_ACCESS;
  1097. goto error_exit;
  1098. }
  1099. req.size = sizeof (coroipc_request_header_t);
  1100. req.id = MESSAGE_REQ_CONFDB_WRITE;
  1101. iov.iov_base = (char *)&req;
  1102. iov.iov_len = sizeof (coroipc_request_header_t);
  1103. error = coroipcc_msg_send_reply_receive (
  1104. confdb_inst->handle,
  1105. &iov,
  1106. 1,
  1107. &res_lib_confdb_write,
  1108. sizeof (struct res_lib_confdb_write));
  1109. if (error != CS_OK) {
  1110. /* FIXME: set error_text */
  1111. goto error_exit;
  1112. }
  1113. error = res_lib_confdb_write.header.error;
  1114. if (res_lib_confdb_write.error.length) {
  1115. memcpy(error_text, res_lib_confdb_write.error.value,
  1116. MIN(res_lib_confdb_write.error.length,errbuf_len));
  1117. error_text[errbuf_len-1] = '\0';
  1118. }
  1119. error_exit:
  1120. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  1121. return (error);
  1122. }
  1123. cs_error_t confdb_reload (
  1124. confdb_handle_t handle,
  1125. int flush,
  1126. char *error_text,
  1127. size_t errbuf_len)
  1128. {
  1129. cs_error_t error;
  1130. struct confdb_inst *confdb_inst;
  1131. struct iovec iov;
  1132. struct res_lib_confdb_reload res_lib_confdb_reload;
  1133. struct req_lib_confdb_reload req_lib_confdb_reload;
  1134. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  1135. if (error != CS_OK) {
  1136. /* FIXME: set error_text */
  1137. return (error);
  1138. }
  1139. if (confdb_inst->standalone) {
  1140. error = CS_OK;
  1141. if (confdb_sa_reload(flush, error_text, errbuf_len))
  1142. error = CS_ERR_ACCESS;
  1143. goto error_exit;
  1144. }
  1145. req_lib_confdb_reload.header.size = sizeof (req_lib_confdb_reload);
  1146. req_lib_confdb_reload.header.id = MESSAGE_REQ_CONFDB_RELOAD;
  1147. req_lib_confdb_reload.flush = flush;
  1148. iov.iov_base = (char *)&req_lib_confdb_reload;
  1149. iov.iov_len = sizeof (req_lib_confdb_reload);
  1150. error = coroipcc_msg_send_reply_receive (
  1151. confdb_inst->handle,
  1152. &iov,
  1153. 1,
  1154. &res_lib_confdb_reload,
  1155. sizeof (struct res_lib_confdb_reload));
  1156. if (error != CS_OK) {
  1157. /* FIXME: set error_text */
  1158. goto error_exit;
  1159. }
  1160. error = res_lib_confdb_reload.header.error;
  1161. if(res_lib_confdb_reload.error.length) {
  1162. memcpy(error_text, res_lib_confdb_reload.error.value,
  1163. MIN(res_lib_confdb_reload.error.length,errbuf_len));
  1164. error_text[errbuf_len-1] = '\0';
  1165. }
  1166. error_exit:
  1167. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  1168. return (error);
  1169. }
  1170. cs_error_t confdb_track_changes (
  1171. confdb_handle_t handle,
  1172. hdb_handle_t object_handle,
  1173. unsigned int flags)
  1174. {
  1175. cs_error_t error;
  1176. struct confdb_inst *confdb_inst;
  1177. struct iovec iov;
  1178. struct req_lib_confdb_object_track_start req;
  1179. coroipc_response_header_t res;
  1180. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  1181. if (error != CS_OK) {
  1182. return (error);
  1183. }
  1184. if (confdb_inst->standalone) {
  1185. error = CS_ERR_NOT_SUPPORTED;
  1186. goto error_exit;
  1187. }
  1188. req.header.size = sizeof (struct req_lib_confdb_object_track_start);
  1189. req.header.id = MESSAGE_REQ_CONFDB_TRACK_START;
  1190. req.object_handle = object_handle;
  1191. req.flags = flags;
  1192. iov.iov_base = (char *)&req;
  1193. iov.iov_len = sizeof (struct req_lib_confdb_object_track_start);
  1194. error = coroipcc_msg_send_reply_receive (
  1195. confdb_inst->handle,
  1196. &iov,
  1197. 1,
  1198. &res,
  1199. sizeof (coroipc_response_header_t));
  1200. if (error != CS_OK) {
  1201. goto error_exit;
  1202. }
  1203. error = res.error;
  1204. error_exit:
  1205. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  1206. return (error);
  1207. }
  1208. cs_error_t confdb_stop_track_changes (confdb_handle_t handle)
  1209. {
  1210. cs_error_t error;
  1211. struct confdb_inst *confdb_inst;
  1212. struct iovec iov;
  1213. coroipc_request_header_t req;
  1214. coroipc_response_header_t res;
  1215. error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
  1216. if (error != CS_OK) {
  1217. return (error);
  1218. }
  1219. if (confdb_inst->standalone) {
  1220. error = CS_ERR_NOT_SUPPORTED;
  1221. goto error_exit;
  1222. }
  1223. req.size = sizeof (coroipc_request_header_t);
  1224. req.id = MESSAGE_REQ_CONFDB_TRACK_STOP;
  1225. iov.iov_base = (char *)&req;
  1226. iov.iov_len = sizeof (coroipc_request_header_t);
  1227. error = coroipcc_msg_send_reply_receive (
  1228. confdb_inst->handle,
  1229. &iov,
  1230. 1,
  1231. &res,
  1232. sizeof (coroipc_response_header_t));
  1233. if (error != CS_OK) {
  1234. goto error_exit;
  1235. }
  1236. error = res.error;
  1237. error_exit:
  1238. (void)hdb_handle_put (&confdb_handle_t_db, handle);
  1239. return (error);
  1240. }