4
0

cmap.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077
  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 || value == 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. if (value != NULL && value_len == NULL) {
  438. return (CS_ERR_INVALID_PARAM);
  439. }
  440. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  441. if (error != CS_OK) {
  442. return (error);
  443. }
  444. memset(&req_lib_cmap_get, 0, sizeof(req_lib_cmap_get));
  445. req_lib_cmap_get.header.size = sizeof(req_lib_cmap_get);
  446. req_lib_cmap_get.header.id = MESSAGE_REQ_CMAP_GET;
  447. memcpy(req_lib_cmap_get.key_name.value, key_name, strlen(key_name));
  448. req_lib_cmap_get.key_name.length = strlen(key_name);
  449. if (value != NULL && value_len != NULL) {
  450. req_lib_cmap_get.value_len = *value_len;
  451. } else {
  452. req_lib_cmap_get.value_len = 0;
  453. }
  454. iov.iov_base = (char *)&req_lib_cmap_get;
  455. iov.iov_len = sizeof(req_lib_cmap_get);
  456. res_size = sizeof(struct res_lib_cmap_get) + req_lib_cmap_get.value_len;
  457. res_lib_cmap_get = malloc(res_size);
  458. if (res_lib_cmap_get == NULL) {
  459. return (CS_ERR_NO_MEMORY);
  460. }
  461. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  462. cmap_inst->c,
  463. &iov,
  464. 1,
  465. res_lib_cmap_get,
  466. res_size, CS_IPC_TIMEOUT_MS));
  467. if (error == CS_OK) {
  468. error = res_lib_cmap_get->header.error;
  469. }
  470. if (error == CS_OK) {
  471. if (type != NULL) {
  472. *type = res_lib_cmap_get->type;
  473. }
  474. if (value_len != NULL) {
  475. *value_len = res_lib_cmap_get->value_len;
  476. }
  477. if (value != NULL && value_len != NULL) {
  478. memcpy(value, res_lib_cmap_get->value, res_lib_cmap_get->value_len);
  479. }
  480. }
  481. free(res_lib_cmap_get);
  482. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  483. return (error);
  484. }
  485. static cs_error_t cmap_get_int(
  486. cmap_handle_t handle,
  487. const char *key_name,
  488. void *value,
  489. size_t value_size,
  490. cmap_value_types_t type)
  491. {
  492. char key_value[16];
  493. size_t key_size;
  494. cs_error_t err;
  495. cmap_value_types_t key_type;
  496. key_size = sizeof(key_value);
  497. memset(key_value, 0, key_size);
  498. err = cmap_get(handle, key_name, key_value, &key_size, &key_type);
  499. if (err != CS_OK)
  500. return (err);
  501. if (key_type != type) {
  502. return (CS_ERR_INVALID_PARAM);
  503. }
  504. memcpy(value, key_value, value_size);
  505. return (CS_OK);
  506. }
  507. cs_error_t cmap_get_int8(cmap_handle_t handle, const char *key_name, int8_t *i8)
  508. {
  509. return (cmap_get_int(handle, key_name, i8, sizeof(*i8), CMAP_VALUETYPE_INT8));
  510. }
  511. cs_error_t cmap_get_uint8(cmap_handle_t handle, const char *key_name, uint8_t *u8)
  512. {
  513. return (cmap_get_int(handle, key_name, u8, sizeof(*u8), CMAP_VALUETYPE_UINT8));
  514. }
  515. cs_error_t cmap_get_int16(cmap_handle_t handle, const char *key_name, int16_t *i16)
  516. {
  517. return (cmap_get_int(handle, key_name, i16, sizeof(*i16), CMAP_VALUETYPE_INT16));
  518. }
  519. cs_error_t cmap_get_uint16(cmap_handle_t handle, const char *key_name, uint16_t *u16)
  520. {
  521. return (cmap_get_int(handle, key_name, u16, sizeof(*u16), CMAP_VALUETYPE_UINT16));
  522. }
  523. cs_error_t cmap_get_int32(cmap_handle_t handle, const char *key_name, int32_t *i32)
  524. {
  525. return (cmap_get_int(handle, key_name, i32, sizeof(*i32), CMAP_VALUETYPE_INT32));
  526. }
  527. cs_error_t cmap_get_uint32(cmap_handle_t handle, const char *key_name, uint32_t *u32)
  528. {
  529. return (cmap_get_int(handle, key_name, u32, sizeof(*u32), CMAP_VALUETYPE_UINT32));
  530. }
  531. cs_error_t cmap_get_int64(cmap_handle_t handle, const char *key_name, int64_t *i64)
  532. {
  533. return (cmap_get_int(handle, key_name, i64, sizeof(*i64), CMAP_VALUETYPE_INT64));
  534. }
  535. cs_error_t cmap_get_uint64(cmap_handle_t handle, const char *key_name, uint64_t *u64)
  536. {
  537. return (cmap_get_int(handle, key_name, u64, sizeof(*u64), CMAP_VALUETYPE_UINT64));
  538. }
  539. cs_error_t cmap_get_float(cmap_handle_t handle, const char *key_name, float *flt)
  540. {
  541. return (cmap_get_int(handle, key_name, flt, sizeof(*flt), CMAP_VALUETYPE_FLOAT));
  542. }
  543. cs_error_t cmap_get_double(cmap_handle_t handle, const char *key_name, double *dbl)
  544. {
  545. return (cmap_get_int(handle, key_name, dbl, sizeof(*dbl), CMAP_VALUETYPE_DOUBLE));
  546. }
  547. cs_error_t cmap_get_string(cmap_handle_t handle, const char *key_name, char **str)
  548. {
  549. cs_error_t res;
  550. size_t str_len;
  551. cmap_value_types_t type;
  552. res = cmap_get(handle, key_name, NULL, &str_len, &type);
  553. if (res != CS_OK || type != CMAP_VALUETYPE_STRING) {
  554. if (res == CS_OK) {
  555. res = CS_ERR_INVALID_PARAM;
  556. }
  557. goto return_error;
  558. }
  559. *str = malloc(str_len);
  560. if (*str == NULL) {
  561. res = CS_ERR_NO_MEMORY;
  562. goto return_error;
  563. }
  564. res = cmap_get(handle, key_name, *str, &str_len, &type);
  565. if (res != CS_OK) {
  566. free(*str);
  567. goto return_error;
  568. }
  569. return (CS_OK);
  570. return_error:
  571. return (res);
  572. }
  573. static cs_error_t cmap_adjust_int(cmap_handle_t handle, const char *key_name, int32_t step)
  574. {
  575. cs_error_t error;
  576. struct iovec iov;
  577. struct cmap_inst *cmap_inst;
  578. struct req_lib_cmap_adjust_int req_lib_cmap_adjust_int;
  579. struct res_lib_cmap_adjust_int res_lib_cmap_adjust_int;
  580. if (key_name == NULL) {
  581. return (CS_ERR_INVALID_PARAM);
  582. }
  583. if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
  584. return (CS_ERR_NAME_TOO_LONG);
  585. }
  586. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  587. if (error != CS_OK) {
  588. return (error);
  589. }
  590. memset(&req_lib_cmap_adjust_int, 0, sizeof(req_lib_cmap_adjust_int));
  591. req_lib_cmap_adjust_int.header.size = sizeof(req_lib_cmap_adjust_int);
  592. req_lib_cmap_adjust_int.header.id = MESSAGE_REQ_CMAP_ADJUST_INT;
  593. memcpy(req_lib_cmap_adjust_int.key_name.value, key_name, strlen(key_name));
  594. req_lib_cmap_adjust_int.key_name.length = strlen(key_name);
  595. req_lib_cmap_adjust_int.step = step;
  596. iov.iov_base = (char *)&req_lib_cmap_adjust_int;
  597. iov.iov_len = sizeof(req_lib_cmap_adjust_int);
  598. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  599. cmap_inst->c,
  600. &iov,
  601. 1,
  602. &res_lib_cmap_adjust_int,
  603. sizeof (struct res_lib_cmap_adjust_int), CS_IPC_TIMEOUT_MS));
  604. if (error == CS_OK) {
  605. error = res_lib_cmap_adjust_int.header.error;
  606. }
  607. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  608. return (error);
  609. }
  610. cs_error_t cmap_inc(cmap_handle_t handle, const char *key_name)
  611. {
  612. return (cmap_adjust_int(handle, key_name, 1));
  613. }
  614. cs_error_t cmap_dec(cmap_handle_t handle, const char *key_name)
  615. {
  616. return (cmap_adjust_int(handle, key_name, -1));
  617. }
  618. cs_error_t cmap_iter_init(
  619. cmap_handle_t handle,
  620. const char *prefix,
  621. cmap_iter_handle_t *cmap_iter_handle)
  622. {
  623. cs_error_t error;
  624. struct iovec iov;
  625. struct cmap_inst *cmap_inst;
  626. struct req_lib_cmap_iter_init req_lib_cmap_iter_init;
  627. struct res_lib_cmap_iter_init res_lib_cmap_iter_init;
  628. if (cmap_iter_handle == NULL) {
  629. return (CS_ERR_INVALID_PARAM);
  630. }
  631. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  632. if (error != CS_OK) {
  633. return (error);
  634. }
  635. memset(&req_lib_cmap_iter_init, 0, sizeof(req_lib_cmap_iter_init));
  636. req_lib_cmap_iter_init.header.size = sizeof(req_lib_cmap_iter_init);
  637. req_lib_cmap_iter_init.header.id = MESSAGE_REQ_CMAP_ITER_INIT;
  638. if (prefix) {
  639. if (strlen(prefix) >= CS_MAX_NAME_LENGTH) {
  640. return (CS_ERR_NAME_TOO_LONG);
  641. }
  642. memcpy(req_lib_cmap_iter_init.prefix.value, prefix, strlen(prefix));
  643. req_lib_cmap_iter_init.prefix.length = strlen(prefix);
  644. }
  645. iov.iov_base = (char *)&req_lib_cmap_iter_init;
  646. iov.iov_len = sizeof(req_lib_cmap_iter_init);
  647. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  648. cmap_inst->c,
  649. &iov,
  650. 1,
  651. &res_lib_cmap_iter_init,
  652. sizeof (struct res_lib_cmap_iter_init), CS_IPC_TIMEOUT_MS));
  653. if (error == CS_OK) {
  654. error = res_lib_cmap_iter_init.header.error;
  655. }
  656. if (error == CS_OK) {
  657. *cmap_iter_handle = res_lib_cmap_iter_init.iter_handle;
  658. }
  659. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  660. return (error);
  661. }
  662. cs_error_t cmap_iter_next(
  663. cmap_handle_t handle,
  664. cmap_iter_handle_t iter_handle,
  665. char key_name[],
  666. size_t *value_len,
  667. cmap_value_types_t *type)
  668. {
  669. cs_error_t error;
  670. struct iovec iov;
  671. struct cmap_inst *cmap_inst;
  672. struct req_lib_cmap_iter_next req_lib_cmap_iter_next;
  673. struct res_lib_cmap_iter_next res_lib_cmap_iter_next;
  674. if (key_name == NULL) {
  675. return (CS_ERR_INVALID_PARAM);
  676. }
  677. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  678. if (error != CS_OK) {
  679. return (error);
  680. }
  681. memset(&req_lib_cmap_iter_next, 0, sizeof(req_lib_cmap_iter_next));
  682. req_lib_cmap_iter_next.header.size = sizeof(req_lib_cmap_iter_next);
  683. req_lib_cmap_iter_next.header.id = MESSAGE_REQ_CMAP_ITER_NEXT;
  684. req_lib_cmap_iter_next.iter_handle = iter_handle;
  685. iov.iov_base = (char *)&req_lib_cmap_iter_next;
  686. iov.iov_len = sizeof(req_lib_cmap_iter_next);
  687. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  688. cmap_inst->c,
  689. &iov,
  690. 1,
  691. &res_lib_cmap_iter_next,
  692. sizeof (struct res_lib_cmap_iter_next), CS_IPC_TIMEOUT_MS));
  693. if (error == CS_OK) {
  694. error = res_lib_cmap_iter_next.header.error;
  695. }
  696. if (error == CS_OK) {
  697. memcpy(key_name, (const char *)res_lib_cmap_iter_next.key_name.value,
  698. res_lib_cmap_iter_next.key_name.length);
  699. key_name[res_lib_cmap_iter_next.key_name.length] = '\0';
  700. if (value_len != NULL) {
  701. *value_len = res_lib_cmap_iter_next.value_len;
  702. }
  703. if (type != NULL) {
  704. *type = res_lib_cmap_iter_next.type;
  705. }
  706. }
  707. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  708. return (error);
  709. }
  710. cs_error_t cmap_iter_finalize(
  711. cmap_handle_t handle,
  712. cmap_iter_handle_t iter_handle)
  713. {
  714. cs_error_t error;
  715. struct iovec iov;
  716. struct cmap_inst *cmap_inst;
  717. struct req_lib_cmap_iter_finalize req_lib_cmap_iter_finalize;
  718. struct res_lib_cmap_iter_finalize res_lib_cmap_iter_finalize;
  719. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  720. if (error != CS_OK) {
  721. return (error);
  722. }
  723. memset(&req_lib_cmap_iter_finalize, 0, sizeof(req_lib_cmap_iter_finalize));
  724. req_lib_cmap_iter_finalize.header.size = sizeof(req_lib_cmap_iter_finalize);
  725. req_lib_cmap_iter_finalize.header.id = MESSAGE_REQ_CMAP_ITER_FINALIZE;
  726. req_lib_cmap_iter_finalize.iter_handle = iter_handle;
  727. iov.iov_base = (char *)&req_lib_cmap_iter_finalize;
  728. iov.iov_len = sizeof(req_lib_cmap_iter_finalize);
  729. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  730. cmap_inst->c,
  731. &iov,
  732. 1,
  733. &res_lib_cmap_iter_finalize,
  734. sizeof (struct res_lib_cmap_iter_finalize), CS_IPC_TIMEOUT_MS));
  735. if (error == CS_OK) {
  736. error = res_lib_cmap_iter_finalize.header.error;
  737. }
  738. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  739. return (error);
  740. }
  741. cs_error_t cmap_track_add(
  742. cmap_handle_t handle,
  743. const char *key_name,
  744. int32_t track_type,
  745. cmap_notify_fn_t notify_fn,
  746. void *user_data,
  747. cmap_track_handle_t *cmap_track_handle)
  748. {
  749. cs_error_t error;
  750. struct iovec iov;
  751. struct cmap_inst *cmap_inst;
  752. struct req_lib_cmap_track_add req_lib_cmap_track_add;
  753. struct res_lib_cmap_track_add res_lib_cmap_track_add;
  754. struct cmap_track_inst *cmap_track_inst;
  755. cmap_track_handle_t cmap_track_inst_handle;
  756. if (cmap_track_handle == NULL || notify_fn == NULL) {
  757. return (CS_ERR_INVALID_PARAM);
  758. }
  759. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  760. if (error != CS_OK) {
  761. return (error);
  762. }
  763. error = hdb_error_to_cs(hdb_handle_create(&cmap_track_handle_t_db,
  764. sizeof(*cmap_track_inst), &cmap_track_inst_handle));
  765. if (error != CS_OK) {
  766. goto error_put;
  767. }
  768. error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
  769. cmap_track_inst_handle, (void *)&cmap_track_inst));
  770. if (error != CS_OK) {
  771. goto error_put_destroy;
  772. }
  773. cmap_track_inst->user_data = user_data;
  774. cmap_track_inst->notify_fn = notify_fn;
  775. cmap_track_inst->c = cmap_inst->c;
  776. memset(&req_lib_cmap_track_add, 0, sizeof(req_lib_cmap_track_add));
  777. req_lib_cmap_track_add.header.size = sizeof(req_lib_cmap_track_add);
  778. req_lib_cmap_track_add.header.id = MESSAGE_REQ_CMAP_TRACK_ADD;
  779. if (key_name) {
  780. if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
  781. return (CS_ERR_NAME_TOO_LONG);
  782. }
  783. memcpy(req_lib_cmap_track_add.key_name.value, key_name, strlen(key_name));
  784. req_lib_cmap_track_add.key_name.length = strlen(key_name);
  785. }
  786. req_lib_cmap_track_add.track_type = track_type;
  787. req_lib_cmap_track_add.track_inst_handle = cmap_track_inst_handle;
  788. iov.iov_base = (char *)&req_lib_cmap_track_add;
  789. iov.iov_len = sizeof(req_lib_cmap_track_add);
  790. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  791. cmap_inst->c,
  792. &iov,
  793. 1,
  794. &res_lib_cmap_track_add,
  795. sizeof (struct res_lib_cmap_track_add), CS_IPC_TIMEOUT_MS));
  796. if (error == CS_OK) {
  797. error = res_lib_cmap_track_add.header.error;
  798. }
  799. if (error == CS_OK) {
  800. *cmap_track_handle = res_lib_cmap_track_add.track_handle;
  801. cmap_track_inst->track_handle = *cmap_track_handle;
  802. }
  803. (void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle);
  804. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  805. return (error);
  806. error_put_destroy:
  807. (void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle);
  808. (void)hdb_handle_destroy (&cmap_track_handle_t_db, cmap_track_inst_handle);
  809. error_put:
  810. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  811. return (error);
  812. }
  813. cs_error_t cmap_track_delete(
  814. cmap_handle_t handle,
  815. cmap_track_handle_t track_handle)
  816. {
  817. cs_error_t error;
  818. struct iovec iov;
  819. struct cmap_inst *cmap_inst;
  820. struct cmap_track_inst *cmap_track_inst;
  821. struct req_lib_cmap_track_delete req_lib_cmap_track_delete;
  822. struct res_lib_cmap_track_delete res_lib_cmap_track_delete;
  823. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  824. if (error != CS_OK) {
  825. return (error);
  826. }
  827. memset(&req_lib_cmap_track_delete, 0, sizeof(req_lib_cmap_track_delete));
  828. req_lib_cmap_track_delete.header.size = sizeof(req_lib_cmap_track_delete);
  829. req_lib_cmap_track_delete.header.id = MESSAGE_REQ_CMAP_TRACK_DELETE;
  830. req_lib_cmap_track_delete.track_handle = track_handle;
  831. iov.iov_base = (char *)&req_lib_cmap_track_delete;
  832. iov.iov_len = sizeof(req_lib_cmap_track_delete);
  833. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  834. cmap_inst->c,
  835. &iov,
  836. 1,
  837. &res_lib_cmap_track_delete,
  838. sizeof (struct res_lib_cmap_track_delete), CS_IPC_TIMEOUT_MS));
  839. if (error == CS_OK) {
  840. error = res_lib_cmap_track_delete.header.error;
  841. }
  842. if (error == CS_OK) {
  843. error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
  844. res_lib_cmap_track_delete.track_inst_handle,
  845. (void *)&cmap_track_inst));
  846. if (error != CS_OK) {
  847. goto error_put;
  848. }
  849. (void)hdb_handle_put(&cmap_track_handle_t_db, res_lib_cmap_track_delete.track_inst_handle);
  850. (void)hdb_handle_destroy(&cmap_track_handle_t_db, res_lib_cmap_track_delete.track_inst_handle);
  851. }
  852. error_put:
  853. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  854. return (error);
  855. }