cmap.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  1. /*
  2. * Copyright (c) 2011-2012 Red Hat, Inc.
  3. *
  4. * All rights reserved.
  5. *
  6. * Author: Jan Friesse (jfriesse@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 Red Hat, 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. #include <config.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <unistd.h>
  38. #include <pthread.h>
  39. #include <sys/types.h>
  40. #include <sys/uio.h>
  41. #include <errno.h>
  42. #include <corosync/corotypes.h>
  43. #include <corosync/corodefs.h>
  44. #include <corosync/hdb.h>
  45. #include <corosync/list.h>
  46. #include <qb/qbipcc.h>
  47. #include <corosync/cmap.h>
  48. #include <corosync/ipc_cmap.h>
  49. #include "util.h"
  50. #include <stdio.h>
  51. struct cmap_inst {
  52. int finalize;
  53. qb_ipcc_connection_t *c;
  54. const void *context;
  55. };
  56. struct cmap_track_inst {
  57. void *user_data;
  58. cmap_notify_fn_t notify_fn;
  59. qb_ipcc_connection_t *c;
  60. cmap_track_handle_t track_handle;
  61. };
  62. static void cmap_inst_free (void *inst);
  63. DECLARE_HDB_DATABASE(cmap_handle_t_db, cmap_inst_free);
  64. DECLARE_HDB_DATABASE(cmap_track_handle_t_db,NULL);
  65. /*
  66. * Function prototypes
  67. */
  68. static cs_error_t cmap_get_int(
  69. cmap_handle_t handle,
  70. const char *key_name,
  71. void *value,
  72. size_t value_size,
  73. cmap_value_types_t type);
  74. static cs_error_t cmap_adjust_int(cmap_handle_t handle, const char *key_name, int32_t step);
  75. /*
  76. * Function implementations
  77. */
  78. cs_error_t cmap_initialize (cmap_handle_t *handle)
  79. {
  80. cs_error_t error;
  81. struct cmap_inst *cmap_inst;
  82. error = hdb_error_to_cs(hdb_handle_create(&cmap_handle_t_db, sizeof(*cmap_inst), handle));
  83. if (error != CS_OK) {
  84. goto error_no_destroy;
  85. }
  86. error = hdb_error_to_cs(hdb_handle_get(&cmap_handle_t_db, *handle, (void *)&cmap_inst));
  87. if (error != CS_OK) {
  88. goto error_destroy;
  89. }
  90. error = CS_OK;
  91. cmap_inst->finalize = 0;
  92. cmap_inst->c = qb_ipcc_connect("cmap", IPC_REQUEST_SIZE);
  93. if (cmap_inst->c == NULL) {
  94. error = qb_to_cs_error(-errno);
  95. goto error_put_destroy;
  96. }
  97. (void)hdb_handle_put(&cmap_handle_t_db, *handle);
  98. return (CS_OK);
  99. error_put_destroy:
  100. (void)hdb_handle_put(&cmap_handle_t_db, *handle);
  101. error_destroy:
  102. (void)hdb_handle_destroy(&cmap_handle_t_db, *handle);
  103. error_no_destroy:
  104. return (error);
  105. }
  106. static void cmap_inst_free (void *inst)
  107. {
  108. struct cmap_inst *cmap_inst = (struct cmap_inst *)inst;
  109. qb_ipcc_disconnect(cmap_inst->c);
  110. }
  111. cs_error_t cmap_finalize(cmap_handle_t handle)
  112. {
  113. struct cmap_inst *cmap_inst;
  114. cs_error_t error;
  115. hdb_handle_t track_inst_handle = 0;
  116. struct cmap_track_inst *cmap_track_inst;
  117. error = hdb_error_to_cs(hdb_handle_get(&cmap_handle_t_db, handle, (void *)&cmap_inst));
  118. if (error != CS_OK) {
  119. return (error);
  120. }
  121. if (cmap_inst->finalize) {
  122. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  123. return (CS_ERR_BAD_HANDLE);
  124. }
  125. cmap_inst->finalize = 1;
  126. /*
  127. * Destroy all track instances for given connection
  128. */
  129. hdb_iterator_reset(&cmap_track_handle_t_db);
  130. while (hdb_iterator_next(&cmap_track_handle_t_db,
  131. (void*)&cmap_track_inst, &track_inst_handle) == 0) {
  132. if (cmap_track_inst->c == cmap_inst->c) {
  133. (void)hdb_handle_destroy(&cmap_track_handle_t_db, track_inst_handle);
  134. }
  135. (void)hdb_handle_put (&cmap_track_handle_t_db, track_inst_handle);
  136. }
  137. (void)hdb_handle_destroy(&cmap_handle_t_db, handle);
  138. (void)hdb_handle_put(&cmap_handle_t_db, handle);
  139. return (CS_OK);
  140. }
  141. cs_error_t cmap_fd_get(cmap_handle_t handle, int *fd)
  142. {
  143. cs_error_t error;
  144. struct cmap_inst *cmap_inst;
  145. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  146. if (error != CS_OK) {
  147. return (error);
  148. }
  149. error = qb_to_cs_error (qb_ipcc_fd_get (cmap_inst->c, fd));
  150. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  151. return (error);
  152. }
  153. cs_error_t cmap_dispatch (
  154. cmap_handle_t handle,
  155. cs_dispatch_flags_t dispatch_types)
  156. {
  157. int timeout = -1;
  158. cs_error_t error;
  159. int cont = 1; /* always continue do loop except when set to 0 */
  160. struct cmap_inst *cmap_inst;
  161. struct qb_ipc_response_header *dispatch_data;
  162. char dispatch_buf[IPC_DISPATCH_SIZE];
  163. struct res_lib_cmap_notify_callback *res_lib_cmap_notify_callback;
  164. struct cmap_track_inst *cmap_track_inst;
  165. struct cmap_notify_value old_val;
  166. struct cmap_notify_value new_val;
  167. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  168. if (error != CS_OK) {
  169. return (error);
  170. }
  171. /*
  172. * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
  173. * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
  174. */
  175. if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
  176. timeout = 0;
  177. }
  178. dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
  179. do {
  180. error = qb_to_cs_error(qb_ipcc_event_recv (
  181. cmap_inst->c,
  182. dispatch_buf,
  183. IPC_DISPATCH_SIZE,
  184. timeout));
  185. if (error == CS_ERR_BAD_HANDLE) {
  186. error = CS_OK;
  187. goto error_put;
  188. }
  189. if (error == CS_ERR_TRY_AGAIN) {
  190. if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
  191. /*
  192. * Don't mask error
  193. */
  194. goto error_put;
  195. }
  196. error = CS_OK;
  197. if (dispatch_types == CS_DISPATCH_ALL) {
  198. break; /* exit do while cont is 1 loop */
  199. } else {
  200. continue; /* next poll */
  201. }
  202. }
  203. if (error != CS_OK) {
  204. goto error_put;
  205. }
  206. /*
  207. * Dispatch incoming message
  208. */
  209. switch (dispatch_data->id) {
  210. case MESSAGE_RES_CMAP_NOTIFY_CALLBACK:
  211. res_lib_cmap_notify_callback = (struct res_lib_cmap_notify_callback *)dispatch_data;
  212. error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
  213. res_lib_cmap_notify_callback->track_inst_handle,
  214. (void *)&cmap_track_inst));
  215. if (error == CS_ERR_BAD_HANDLE) {
  216. /*
  217. * User deleted tracker -> ignore error
  218. */
  219. break;
  220. }
  221. if (error != CS_OK) {
  222. goto error_put;
  223. }
  224. new_val.type = res_lib_cmap_notify_callback->new_value_type;
  225. old_val.type = res_lib_cmap_notify_callback->old_value_type;
  226. new_val.len = res_lib_cmap_notify_callback->new_value_len;
  227. old_val.len = res_lib_cmap_notify_callback->old_value_len;
  228. new_val.data = res_lib_cmap_notify_callback->new_value;
  229. old_val.data = (((const char *)res_lib_cmap_notify_callback->new_value) + new_val.len);
  230. cmap_track_inst->notify_fn(handle,
  231. cmap_track_inst->track_handle,
  232. res_lib_cmap_notify_callback->event,
  233. (char *)res_lib_cmap_notify_callback->key_name.value,
  234. new_val,
  235. old_val,
  236. cmap_track_inst->user_data);
  237. (void)hdb_handle_put(&cmap_track_handle_t_db, res_lib_cmap_notify_callback->track_inst_handle);
  238. break;
  239. default:
  240. error = CS_ERR_LIBRARY;
  241. goto error_put;
  242. break;
  243. }
  244. if (cmap_inst->finalize) {
  245. /*
  246. * If the finalize has been called then get out of the dispatch.
  247. */
  248. error = CS_ERR_BAD_HANDLE;
  249. goto error_put;
  250. }
  251. /*
  252. * Determine if more messages should be processed
  253. */
  254. if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
  255. cont = 0;
  256. }
  257. } while (cont);
  258. error_put:
  259. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  260. return (error);
  261. }
  262. cs_error_t cmap_context_get (
  263. cmap_handle_t handle,
  264. const void **context)
  265. {
  266. cs_error_t error;
  267. struct cmap_inst *cmap_inst;
  268. error = hdb_error_to_cs(hdb_handle_get(&cmap_handle_t_db, handle, (void *)&cmap_inst));
  269. if (error != CS_OK) {
  270. return (error);
  271. }
  272. *context = cmap_inst->context;
  273. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  274. return (CS_OK);
  275. }
  276. cs_error_t cmap_context_set (
  277. cmap_handle_t handle,
  278. const void *context)
  279. {
  280. cs_error_t error;
  281. struct cmap_inst *cmap_inst;
  282. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  283. if (error != CS_OK) {
  284. return (error);
  285. }
  286. cmap_inst->context = context;
  287. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  288. return (CS_OK);
  289. }
  290. cs_error_t cmap_set (
  291. cmap_handle_t handle,
  292. const char *key_name,
  293. const void *value,
  294. size_t value_len,
  295. cmap_value_types_t type)
  296. {
  297. cs_error_t error;
  298. struct iovec iov[2];
  299. struct cmap_inst *cmap_inst;
  300. struct req_lib_cmap_set req_lib_cmap_set;
  301. struct res_lib_cmap_set res_lib_cmap_set;
  302. if (key_name == NULL) {
  303. return (CS_ERR_INVALID_PARAM);
  304. }
  305. if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
  306. return (CS_ERR_NAME_TOO_LONG);
  307. }
  308. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  309. if (error != CS_OK) {
  310. return (error);
  311. }
  312. memset(&req_lib_cmap_set, 0, sizeof(req_lib_cmap_set));
  313. req_lib_cmap_set.header.size = sizeof(req_lib_cmap_set) + value_len;
  314. req_lib_cmap_set.header.id = MESSAGE_REQ_CMAP_SET;
  315. memcpy(req_lib_cmap_set.key_name.value, key_name, strlen(key_name));
  316. req_lib_cmap_set.key_name.length = strlen(key_name);
  317. req_lib_cmap_set.value_len = value_len;
  318. req_lib_cmap_set.type = type;
  319. iov[0].iov_base = (char *)&req_lib_cmap_set;
  320. iov[0].iov_len = sizeof(req_lib_cmap_set);
  321. iov[1].iov_base = (void *)value;
  322. iov[1].iov_len = value_len;
  323. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  324. cmap_inst->c,
  325. iov,
  326. 2,
  327. &res_lib_cmap_set,
  328. sizeof (struct res_lib_cmap_set), CS_IPC_TIMEOUT_MS));
  329. if (error == CS_OK) {
  330. error = res_lib_cmap_set.header.error;
  331. }
  332. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  333. return (error);
  334. }
  335. cs_error_t cmap_set_int8(cmap_handle_t handle, const char *key_name, int8_t value)
  336. {
  337. return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_INT8));
  338. }
  339. cs_error_t cmap_set_uint8(cmap_handle_t handle, const char *key_name, uint8_t value)
  340. {
  341. return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_UINT8));
  342. }
  343. cs_error_t cmap_set_int16(cmap_handle_t handle, const char *key_name, int16_t value)
  344. {
  345. return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_INT16));
  346. }
  347. cs_error_t cmap_set_uint16(cmap_handle_t handle, const char *key_name, uint16_t value)
  348. {
  349. return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_UINT16));
  350. }
  351. cs_error_t cmap_set_int32(cmap_handle_t handle, const char *key_name, int32_t value)
  352. {
  353. return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_INT32));
  354. }
  355. cs_error_t cmap_set_uint32(cmap_handle_t handle, const char *key_name, uint32_t value)
  356. {
  357. return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_UINT32));
  358. }
  359. cs_error_t cmap_set_int64(cmap_handle_t handle, const char *key_name, int64_t value)
  360. {
  361. return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_INT64));
  362. }
  363. cs_error_t cmap_set_uint64(cmap_handle_t handle, const char *key_name, uint64_t value)
  364. {
  365. return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_UINT64));
  366. }
  367. cs_error_t cmap_set_float(cmap_handle_t handle, const char *key_name, float value)
  368. {
  369. return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_FLOAT));
  370. }
  371. cs_error_t cmap_set_double(cmap_handle_t handle, const char *key_name, double value)
  372. {
  373. return (cmap_set(handle, key_name, &value, sizeof(value), CMAP_VALUETYPE_DOUBLE));
  374. }
  375. cs_error_t cmap_set_string(cmap_handle_t handle, const char *key_name, const char *value)
  376. {
  377. if (value == NULL) {
  378. return (CS_ERR_INVALID_PARAM);
  379. }
  380. return (cmap_set(handle, key_name, value, strlen(value), CMAP_VALUETYPE_STRING));
  381. }
  382. cs_error_t cmap_delete(cmap_handle_t handle, const char *key_name)
  383. {
  384. cs_error_t error;
  385. struct iovec iov;
  386. struct cmap_inst *cmap_inst;
  387. struct req_lib_cmap_delete req_lib_cmap_delete;
  388. struct res_lib_cmap_delete res_lib_cmap_delete;
  389. if (key_name == NULL) {
  390. return (CS_ERR_INVALID_PARAM);
  391. }
  392. if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
  393. return (CS_ERR_NAME_TOO_LONG);
  394. }
  395. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  396. if (error != CS_OK) {
  397. return (error);
  398. }
  399. memset(&req_lib_cmap_delete, 0, sizeof(req_lib_cmap_delete));
  400. req_lib_cmap_delete.header.size = sizeof(req_lib_cmap_delete);
  401. req_lib_cmap_delete.header.id = MESSAGE_REQ_CMAP_DELETE;
  402. memcpy(req_lib_cmap_delete.key_name.value, key_name, strlen(key_name));
  403. req_lib_cmap_delete.key_name.length = strlen(key_name);
  404. iov.iov_base = (char *)&req_lib_cmap_delete;
  405. iov.iov_len = sizeof(req_lib_cmap_delete);
  406. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  407. cmap_inst->c,
  408. &iov,
  409. 1,
  410. &res_lib_cmap_delete,
  411. sizeof (struct res_lib_cmap_delete), CS_IPC_TIMEOUT_MS));
  412. if (error == CS_OK) {
  413. error = res_lib_cmap_delete.header.error;
  414. }
  415. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  416. return (error);
  417. }
  418. cs_error_t cmap_get(
  419. cmap_handle_t handle,
  420. const char *key_name,
  421. void *value,
  422. size_t *value_len,
  423. cmap_value_types_t *type)
  424. {
  425. cs_error_t error;
  426. struct cmap_inst *cmap_inst;
  427. struct iovec iov;
  428. struct req_lib_cmap_get req_lib_cmap_get;
  429. struct res_lib_cmap_get *res_lib_cmap_get;
  430. size_t res_size;
  431. if (key_name == NULL) {
  432. return (CS_ERR_INVALID_PARAM);
  433. }
  434. if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
  435. return (CS_ERR_NAME_TOO_LONG);
  436. }
  437. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  438. if (error != CS_OK) {
  439. return (error);
  440. }
  441. memset(&req_lib_cmap_get, 0, sizeof(req_lib_cmap_get));
  442. req_lib_cmap_get.header.size = sizeof(req_lib_cmap_get);
  443. req_lib_cmap_get.header.id = MESSAGE_REQ_CMAP_GET;
  444. memcpy(req_lib_cmap_get.key_name.value, key_name, strlen(key_name));
  445. req_lib_cmap_get.key_name.length = strlen(key_name);
  446. if (value != NULL && value_len != NULL) {
  447. req_lib_cmap_get.value_len = *value_len;
  448. } else {
  449. req_lib_cmap_get.value_len = 0;
  450. }
  451. iov.iov_base = (char *)&req_lib_cmap_get;
  452. iov.iov_len = sizeof(req_lib_cmap_get);
  453. res_size = sizeof(struct res_lib_cmap_get) + req_lib_cmap_get.value_len;
  454. res_lib_cmap_get = malloc(res_size);
  455. if (res_lib_cmap_get == NULL) {
  456. return (CS_ERR_NO_MEMORY);
  457. }
  458. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  459. cmap_inst->c,
  460. &iov,
  461. 1,
  462. res_lib_cmap_get,
  463. res_size, CS_IPC_TIMEOUT_MS));
  464. if (error == CS_OK) {
  465. error = res_lib_cmap_get->header.error;
  466. }
  467. if (error == CS_OK) {
  468. if (type != NULL) {
  469. *type = res_lib_cmap_get->type;
  470. }
  471. if (value_len != NULL) {
  472. *value_len = res_lib_cmap_get->value_len;
  473. }
  474. if (value != NULL) {
  475. memcpy(value, res_lib_cmap_get->value, res_lib_cmap_get->value_len);
  476. }
  477. }
  478. free(res_lib_cmap_get);
  479. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  480. return (error);
  481. }
  482. static cs_error_t cmap_get_int(
  483. cmap_handle_t handle,
  484. const char *key_name,
  485. void *value,
  486. size_t value_size,
  487. cmap_value_types_t type)
  488. {
  489. char key_value[16];
  490. size_t key_size;
  491. cs_error_t err;
  492. cmap_value_types_t key_type;
  493. key_size = sizeof(key_value);
  494. memset(key_value, 0, key_size);
  495. err = cmap_get(handle, key_name, key_value, &key_size, &key_type);
  496. if (err != CS_OK)
  497. return (err);
  498. if (key_type != type) {
  499. return (CS_ERR_INVALID_PARAM);
  500. }
  501. memcpy(value, key_value, value_size);
  502. return (CS_OK);
  503. }
  504. cs_error_t cmap_get_int8(cmap_handle_t handle, const char *key_name, int8_t *i8)
  505. {
  506. return (cmap_get_int(handle, key_name, i8, sizeof(*i8), CMAP_VALUETYPE_INT8));
  507. }
  508. cs_error_t cmap_get_uint8(cmap_handle_t handle, const char *key_name, uint8_t *u8)
  509. {
  510. return (cmap_get_int(handle, key_name, u8, sizeof(*u8), CMAP_VALUETYPE_UINT8));
  511. }
  512. cs_error_t cmap_get_int16(cmap_handle_t handle, const char *key_name, int16_t *i16)
  513. {
  514. return (cmap_get_int(handle, key_name, i16, sizeof(*i16), CMAP_VALUETYPE_INT16));
  515. }
  516. cs_error_t cmap_get_uint16(cmap_handle_t handle, const char *key_name, uint16_t *u16)
  517. {
  518. return (cmap_get_int(handle, key_name, u16, sizeof(*u16), CMAP_VALUETYPE_UINT16));
  519. }
  520. cs_error_t cmap_get_int32(cmap_handle_t handle, const char *key_name, int32_t *i32)
  521. {
  522. return (cmap_get_int(handle, key_name, i32, sizeof(*i32), CMAP_VALUETYPE_INT32));
  523. }
  524. cs_error_t cmap_get_uint32(cmap_handle_t handle, const char *key_name, uint32_t *u32)
  525. {
  526. return (cmap_get_int(handle, key_name, u32, sizeof(*u32), CMAP_VALUETYPE_UINT32));
  527. }
  528. cs_error_t cmap_get_int64(cmap_handle_t handle, const char *key_name, int64_t *i64)
  529. {
  530. return (cmap_get_int(handle, key_name, i64, sizeof(*i64), CMAP_VALUETYPE_INT64));
  531. }
  532. cs_error_t cmap_get_uint64(cmap_handle_t handle, const char *key_name, uint64_t *u64)
  533. {
  534. return (cmap_get_int(handle, key_name, u64, sizeof(*u64), CMAP_VALUETYPE_UINT64));
  535. }
  536. cs_error_t cmap_get_float(cmap_handle_t handle, const char *key_name, float *flt)
  537. {
  538. return (cmap_get_int(handle, key_name, flt, sizeof(*flt), CMAP_VALUETYPE_FLOAT));
  539. }
  540. cs_error_t cmap_get_double(cmap_handle_t handle, const char *key_name, double *dbl)
  541. {
  542. return (cmap_get_int(handle, key_name, dbl, sizeof(*dbl), CMAP_VALUETYPE_DOUBLE));
  543. }
  544. cs_error_t cmap_get_string(cmap_handle_t handle, const char *key_name, char **str)
  545. {
  546. cs_error_t res;
  547. size_t str_len;
  548. cmap_value_types_t type;
  549. res = cmap_get(handle, key_name, NULL, &str_len, &type);
  550. if (res != CS_OK || type != CMAP_VALUETYPE_STRING) {
  551. if (res == CS_OK) {
  552. res = CS_ERR_INVALID_PARAM;
  553. }
  554. goto return_error;
  555. }
  556. *str = malloc(str_len);
  557. if (*str == NULL) {
  558. res = CS_ERR_NO_MEMORY;
  559. goto return_error;
  560. }
  561. res = cmap_get(handle, key_name, *str, &str_len, &type);
  562. if (res != CS_OK) {
  563. free(*str);
  564. goto return_error;
  565. }
  566. return (CS_OK);
  567. return_error:
  568. return (res);
  569. }
  570. static cs_error_t cmap_adjust_int(cmap_handle_t handle, const char *key_name, int32_t step)
  571. {
  572. cs_error_t error;
  573. struct iovec iov;
  574. struct cmap_inst *cmap_inst;
  575. struct req_lib_cmap_adjust_int req_lib_cmap_adjust_int;
  576. struct res_lib_cmap_adjust_int res_lib_cmap_adjust_int;
  577. if (key_name == NULL) {
  578. return (CS_ERR_INVALID_PARAM);
  579. }
  580. if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
  581. return (CS_ERR_NAME_TOO_LONG);
  582. }
  583. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  584. if (error != CS_OK) {
  585. return (error);
  586. }
  587. memset(&req_lib_cmap_adjust_int, 0, sizeof(req_lib_cmap_adjust_int));
  588. req_lib_cmap_adjust_int.header.size = sizeof(req_lib_cmap_adjust_int);
  589. req_lib_cmap_adjust_int.header.id = MESSAGE_REQ_CMAP_ADJUST_INT;
  590. memcpy(req_lib_cmap_adjust_int.key_name.value, key_name, strlen(key_name));
  591. req_lib_cmap_adjust_int.key_name.length = strlen(key_name);
  592. req_lib_cmap_adjust_int.step = step;
  593. iov.iov_base = (char *)&req_lib_cmap_adjust_int;
  594. iov.iov_len = sizeof(req_lib_cmap_adjust_int);
  595. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  596. cmap_inst->c,
  597. &iov,
  598. 1,
  599. &res_lib_cmap_adjust_int,
  600. sizeof (struct res_lib_cmap_adjust_int), CS_IPC_TIMEOUT_MS));
  601. if (error == CS_OK) {
  602. error = res_lib_cmap_adjust_int.header.error;
  603. }
  604. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  605. return (error);
  606. }
  607. cs_error_t cmap_inc(cmap_handle_t handle, const char *key_name)
  608. {
  609. return (cmap_adjust_int(handle, key_name, 1));
  610. }
  611. cs_error_t cmap_dec(cmap_handle_t handle, const char *key_name)
  612. {
  613. return (cmap_adjust_int(handle, key_name, -1));
  614. }
  615. cs_error_t cmap_iter_init(
  616. cmap_handle_t handle,
  617. const char *prefix,
  618. cmap_iter_handle_t *cmap_iter_handle)
  619. {
  620. cs_error_t error;
  621. struct iovec iov;
  622. struct cmap_inst *cmap_inst;
  623. struct req_lib_cmap_iter_init req_lib_cmap_iter_init;
  624. struct res_lib_cmap_iter_init res_lib_cmap_iter_init;
  625. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  626. if (error != CS_OK) {
  627. return (error);
  628. }
  629. memset(&req_lib_cmap_iter_init, 0, sizeof(req_lib_cmap_iter_init));
  630. req_lib_cmap_iter_init.header.size = sizeof(req_lib_cmap_iter_init);
  631. req_lib_cmap_iter_init.header.id = MESSAGE_REQ_CMAP_ITER_INIT;
  632. if (prefix) {
  633. if (strlen(prefix) >= CS_MAX_NAME_LENGTH) {
  634. return (CS_ERR_NAME_TOO_LONG);
  635. }
  636. memcpy(req_lib_cmap_iter_init.prefix.value, prefix, strlen(prefix));
  637. req_lib_cmap_iter_init.prefix.length = strlen(prefix);
  638. }
  639. iov.iov_base = (char *)&req_lib_cmap_iter_init;
  640. iov.iov_len = sizeof(req_lib_cmap_iter_init);
  641. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  642. cmap_inst->c,
  643. &iov,
  644. 1,
  645. &res_lib_cmap_iter_init,
  646. sizeof (struct res_lib_cmap_iter_init), CS_IPC_TIMEOUT_MS));
  647. if (error == CS_OK) {
  648. error = res_lib_cmap_iter_init.header.error;
  649. }
  650. if (error == CS_OK) {
  651. *cmap_iter_handle = res_lib_cmap_iter_init.iter_handle;
  652. }
  653. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  654. return (error);
  655. }
  656. cs_error_t cmap_iter_next(
  657. cmap_handle_t handle,
  658. cmap_iter_handle_t iter_handle,
  659. char key_name[],
  660. size_t *value_len,
  661. cmap_value_types_t *type)
  662. {
  663. cs_error_t error;
  664. struct iovec iov;
  665. struct cmap_inst *cmap_inst;
  666. struct req_lib_cmap_iter_next req_lib_cmap_iter_next;
  667. struct res_lib_cmap_iter_next res_lib_cmap_iter_next;
  668. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  669. if (error != CS_OK) {
  670. return (error);
  671. }
  672. memset(&req_lib_cmap_iter_next, 0, sizeof(req_lib_cmap_iter_next));
  673. req_lib_cmap_iter_next.header.size = sizeof(req_lib_cmap_iter_next);
  674. req_lib_cmap_iter_next.header.id = MESSAGE_REQ_CMAP_ITER_NEXT;
  675. req_lib_cmap_iter_next.iter_handle = iter_handle;
  676. iov.iov_base = (char *)&req_lib_cmap_iter_next;
  677. iov.iov_len = sizeof(req_lib_cmap_iter_next);
  678. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  679. cmap_inst->c,
  680. &iov,
  681. 1,
  682. &res_lib_cmap_iter_next,
  683. sizeof (struct res_lib_cmap_iter_next), CS_IPC_TIMEOUT_MS));
  684. if (error == CS_OK) {
  685. error = res_lib_cmap_iter_next.header.error;
  686. }
  687. if (error == CS_OK) {
  688. strncpy(key_name, (const char *)res_lib_cmap_iter_next.key_name.value, CMAP_KEYNAME_MAXLEN);
  689. if (value_len != NULL) {
  690. *value_len = res_lib_cmap_iter_next.value_len;
  691. }
  692. if (type != NULL) {
  693. *type = res_lib_cmap_iter_next.type;
  694. }
  695. }
  696. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  697. return (error);
  698. }
  699. cs_error_t cmap_iter_finalize(
  700. cmap_handle_t handle,
  701. cmap_iter_handle_t iter_handle)
  702. {
  703. cs_error_t error;
  704. struct iovec iov;
  705. struct cmap_inst *cmap_inst;
  706. struct req_lib_cmap_iter_finalize req_lib_cmap_iter_finalize;
  707. struct res_lib_cmap_iter_finalize res_lib_cmap_iter_finalize;
  708. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  709. if (error != CS_OK) {
  710. return (error);
  711. }
  712. memset(&req_lib_cmap_iter_finalize, 0, sizeof(req_lib_cmap_iter_finalize));
  713. req_lib_cmap_iter_finalize.header.size = sizeof(req_lib_cmap_iter_finalize);
  714. req_lib_cmap_iter_finalize.header.id = MESSAGE_REQ_CMAP_ITER_FINALIZE;
  715. req_lib_cmap_iter_finalize.iter_handle = iter_handle;
  716. iov.iov_base = (char *)&req_lib_cmap_iter_finalize;
  717. iov.iov_len = sizeof(req_lib_cmap_iter_finalize);
  718. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  719. cmap_inst->c,
  720. &iov,
  721. 1,
  722. &res_lib_cmap_iter_finalize,
  723. sizeof (struct res_lib_cmap_iter_finalize), CS_IPC_TIMEOUT_MS));
  724. if (error == CS_OK) {
  725. error = res_lib_cmap_iter_finalize.header.error;
  726. }
  727. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  728. return (error);
  729. }
  730. cs_error_t cmap_track_add(
  731. cmap_handle_t handle,
  732. const char *key_name,
  733. int32_t track_type,
  734. cmap_notify_fn_t notify_fn,
  735. void *user_data,
  736. cmap_track_handle_t *cmap_track_handle)
  737. {
  738. cs_error_t error;
  739. struct iovec iov;
  740. struct cmap_inst *cmap_inst;
  741. struct req_lib_cmap_track_add req_lib_cmap_track_add;
  742. struct res_lib_cmap_track_add res_lib_cmap_track_add;
  743. struct cmap_track_inst *cmap_track_inst;
  744. cmap_track_handle_t cmap_track_inst_handle;
  745. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  746. if (error != CS_OK) {
  747. return (error);
  748. }
  749. error = hdb_error_to_cs(hdb_handle_create(&cmap_track_handle_t_db,
  750. sizeof(*cmap_track_inst), &cmap_track_inst_handle));
  751. if (error != CS_OK) {
  752. goto error_put;
  753. }
  754. error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
  755. cmap_track_inst_handle, (void *)&cmap_track_inst));
  756. if (error != CS_OK) {
  757. goto error_put_destroy;
  758. }
  759. cmap_track_inst->user_data = user_data;
  760. cmap_track_inst->notify_fn = notify_fn;
  761. cmap_track_inst->c = cmap_inst->c;
  762. memset(&req_lib_cmap_track_add, 0, sizeof(req_lib_cmap_track_add));
  763. req_lib_cmap_track_add.header.size = sizeof(req_lib_cmap_track_add);
  764. req_lib_cmap_track_add.header.id = MESSAGE_REQ_CMAP_TRACK_ADD;
  765. if (key_name) {
  766. if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
  767. return (CS_ERR_NAME_TOO_LONG);
  768. }
  769. memcpy(req_lib_cmap_track_add.key_name.value, key_name, strlen(key_name));
  770. req_lib_cmap_track_add.key_name.length = strlen(key_name);
  771. }
  772. req_lib_cmap_track_add.track_type = track_type;
  773. req_lib_cmap_track_add.track_inst_handle = cmap_track_inst_handle;
  774. iov.iov_base = (char *)&req_lib_cmap_track_add;
  775. iov.iov_len = sizeof(req_lib_cmap_track_add);
  776. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  777. cmap_inst->c,
  778. &iov,
  779. 1,
  780. &res_lib_cmap_track_add,
  781. sizeof (struct res_lib_cmap_track_add), CS_IPC_TIMEOUT_MS));
  782. if (error == CS_OK) {
  783. error = res_lib_cmap_track_add.header.error;
  784. }
  785. if (error == CS_OK) {
  786. *cmap_track_handle = res_lib_cmap_track_add.track_handle;
  787. cmap_track_inst->track_handle = *cmap_track_handle;
  788. }
  789. (void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle);
  790. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  791. return (error);
  792. error_put_destroy:
  793. (void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle);
  794. (void)hdb_handle_destroy (&cmap_track_handle_t_db, cmap_track_inst_handle);
  795. error_put:
  796. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  797. return (error);
  798. }
  799. cs_error_t cmap_track_delete(
  800. cmap_handle_t handle,
  801. cmap_track_handle_t track_handle)
  802. {
  803. cs_error_t error;
  804. struct iovec iov;
  805. struct cmap_inst *cmap_inst;
  806. struct cmap_track_inst *cmap_track_inst;
  807. struct req_lib_cmap_track_delete req_lib_cmap_track_delete;
  808. struct res_lib_cmap_track_delete res_lib_cmap_track_delete;
  809. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  810. if (error != CS_OK) {
  811. return (error);
  812. }
  813. memset(&req_lib_cmap_track_delete, 0, sizeof(req_lib_cmap_track_delete));
  814. req_lib_cmap_track_delete.header.size = sizeof(req_lib_cmap_track_delete);
  815. req_lib_cmap_track_delete.header.id = MESSAGE_REQ_CMAP_TRACK_DELETE;
  816. req_lib_cmap_track_delete.track_handle = track_handle;
  817. iov.iov_base = (char *)&req_lib_cmap_track_delete;
  818. iov.iov_len = sizeof(req_lib_cmap_track_delete);
  819. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  820. cmap_inst->c,
  821. &iov,
  822. 1,
  823. &res_lib_cmap_track_delete,
  824. sizeof (struct res_lib_cmap_track_delete), CS_IPC_TIMEOUT_MS));
  825. if (error == CS_OK) {
  826. error = res_lib_cmap_track_delete.header.error;
  827. }
  828. if (error == CS_OK) {
  829. error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
  830. res_lib_cmap_track_delete.track_inst_handle,
  831. (void *)&cmap_track_inst));
  832. if (error != CS_OK) {
  833. goto error_put;
  834. }
  835. (void)hdb_handle_put(&cmap_track_handle_t_db, res_lib_cmap_track_delete.track_inst_handle);
  836. (void)hdb_handle_destroy(&cmap_track_handle_t_db, res_lib_cmap_track_delete.track_inst_handle);
  837. }
  838. error_put:
  839. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  840. return (error);
  841. }