cmap.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  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. strncpy(key_name, (const char *)res_lib_cmap_iter_next.key_name.value, CMAP_KEYNAME_MAXLEN);
  698. if (value_len != NULL) {
  699. *value_len = res_lib_cmap_iter_next.value_len;
  700. }
  701. if (type != NULL) {
  702. *type = res_lib_cmap_iter_next.type;
  703. }
  704. }
  705. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  706. return (error);
  707. }
  708. cs_error_t cmap_iter_finalize(
  709. cmap_handle_t handle,
  710. cmap_iter_handle_t iter_handle)
  711. {
  712. cs_error_t error;
  713. struct iovec iov;
  714. struct cmap_inst *cmap_inst;
  715. struct req_lib_cmap_iter_finalize req_lib_cmap_iter_finalize;
  716. struct res_lib_cmap_iter_finalize res_lib_cmap_iter_finalize;
  717. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  718. if (error != CS_OK) {
  719. return (error);
  720. }
  721. memset(&req_lib_cmap_iter_finalize, 0, sizeof(req_lib_cmap_iter_finalize));
  722. req_lib_cmap_iter_finalize.header.size = sizeof(req_lib_cmap_iter_finalize);
  723. req_lib_cmap_iter_finalize.header.id = MESSAGE_REQ_CMAP_ITER_FINALIZE;
  724. req_lib_cmap_iter_finalize.iter_handle = iter_handle;
  725. iov.iov_base = (char *)&req_lib_cmap_iter_finalize;
  726. iov.iov_len = sizeof(req_lib_cmap_iter_finalize);
  727. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  728. cmap_inst->c,
  729. &iov,
  730. 1,
  731. &res_lib_cmap_iter_finalize,
  732. sizeof (struct res_lib_cmap_iter_finalize), CS_IPC_TIMEOUT_MS));
  733. if (error == CS_OK) {
  734. error = res_lib_cmap_iter_finalize.header.error;
  735. }
  736. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  737. return (error);
  738. }
  739. cs_error_t cmap_track_add(
  740. cmap_handle_t handle,
  741. const char *key_name,
  742. int32_t track_type,
  743. cmap_notify_fn_t notify_fn,
  744. void *user_data,
  745. cmap_track_handle_t *cmap_track_handle)
  746. {
  747. cs_error_t error;
  748. struct iovec iov;
  749. struct cmap_inst *cmap_inst;
  750. struct req_lib_cmap_track_add req_lib_cmap_track_add;
  751. struct res_lib_cmap_track_add res_lib_cmap_track_add;
  752. struct cmap_track_inst *cmap_track_inst;
  753. cmap_track_handle_t cmap_track_inst_handle;
  754. if (cmap_track_handle == NULL || notify_fn == NULL) {
  755. return (CS_ERR_INVALID_PARAM);
  756. }
  757. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  758. if (error != CS_OK) {
  759. return (error);
  760. }
  761. error = hdb_error_to_cs(hdb_handle_create(&cmap_track_handle_t_db,
  762. sizeof(*cmap_track_inst), &cmap_track_inst_handle));
  763. if (error != CS_OK) {
  764. goto error_put;
  765. }
  766. error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
  767. cmap_track_inst_handle, (void *)&cmap_track_inst));
  768. if (error != CS_OK) {
  769. goto error_put_destroy;
  770. }
  771. cmap_track_inst->user_data = user_data;
  772. cmap_track_inst->notify_fn = notify_fn;
  773. cmap_track_inst->c = cmap_inst->c;
  774. memset(&req_lib_cmap_track_add, 0, sizeof(req_lib_cmap_track_add));
  775. req_lib_cmap_track_add.header.size = sizeof(req_lib_cmap_track_add);
  776. req_lib_cmap_track_add.header.id = MESSAGE_REQ_CMAP_TRACK_ADD;
  777. if (key_name) {
  778. if (strlen(key_name) >= CS_MAX_NAME_LENGTH) {
  779. return (CS_ERR_NAME_TOO_LONG);
  780. }
  781. memcpy(req_lib_cmap_track_add.key_name.value, key_name, strlen(key_name));
  782. req_lib_cmap_track_add.key_name.length = strlen(key_name);
  783. }
  784. req_lib_cmap_track_add.track_type = track_type;
  785. req_lib_cmap_track_add.track_inst_handle = cmap_track_inst_handle;
  786. iov.iov_base = (char *)&req_lib_cmap_track_add;
  787. iov.iov_len = sizeof(req_lib_cmap_track_add);
  788. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  789. cmap_inst->c,
  790. &iov,
  791. 1,
  792. &res_lib_cmap_track_add,
  793. sizeof (struct res_lib_cmap_track_add), CS_IPC_TIMEOUT_MS));
  794. if (error == CS_OK) {
  795. error = res_lib_cmap_track_add.header.error;
  796. }
  797. if (error == CS_OK) {
  798. *cmap_track_handle = res_lib_cmap_track_add.track_handle;
  799. cmap_track_inst->track_handle = *cmap_track_handle;
  800. }
  801. (void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle);
  802. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  803. return (error);
  804. error_put_destroy:
  805. (void)hdb_handle_put (&cmap_track_handle_t_db, cmap_track_inst_handle);
  806. (void)hdb_handle_destroy (&cmap_track_handle_t_db, cmap_track_inst_handle);
  807. error_put:
  808. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  809. return (error);
  810. }
  811. cs_error_t cmap_track_delete(
  812. cmap_handle_t handle,
  813. cmap_track_handle_t track_handle)
  814. {
  815. cs_error_t error;
  816. struct iovec iov;
  817. struct cmap_inst *cmap_inst;
  818. struct cmap_track_inst *cmap_track_inst;
  819. struct req_lib_cmap_track_delete req_lib_cmap_track_delete;
  820. struct res_lib_cmap_track_delete res_lib_cmap_track_delete;
  821. error = hdb_error_to_cs(hdb_handle_get (&cmap_handle_t_db, handle, (void *)&cmap_inst));
  822. if (error != CS_OK) {
  823. return (error);
  824. }
  825. memset(&req_lib_cmap_track_delete, 0, sizeof(req_lib_cmap_track_delete));
  826. req_lib_cmap_track_delete.header.size = sizeof(req_lib_cmap_track_delete);
  827. req_lib_cmap_track_delete.header.id = MESSAGE_REQ_CMAP_TRACK_DELETE;
  828. req_lib_cmap_track_delete.track_handle = track_handle;
  829. iov.iov_base = (char *)&req_lib_cmap_track_delete;
  830. iov.iov_len = sizeof(req_lib_cmap_track_delete);
  831. error = qb_to_cs_error(qb_ipcc_sendv_recv(
  832. cmap_inst->c,
  833. &iov,
  834. 1,
  835. &res_lib_cmap_track_delete,
  836. sizeof (struct res_lib_cmap_track_delete), CS_IPC_TIMEOUT_MS));
  837. if (error == CS_OK) {
  838. error = res_lib_cmap_track_delete.header.error;
  839. }
  840. if (error == CS_OK) {
  841. error = hdb_error_to_cs(hdb_handle_get(&cmap_track_handle_t_db,
  842. res_lib_cmap_track_delete.track_inst_handle,
  843. (void *)&cmap_track_inst));
  844. if (error != CS_OK) {
  845. goto error_put;
  846. }
  847. (void)hdb_handle_put(&cmap_track_handle_t_db, res_lib_cmap_track_delete.track_inst_handle);
  848. (void)hdb_handle_destroy(&cmap_track_handle_t_db, res_lib_cmap_track_delete.track_inst_handle);
  849. }
  850. error_put:
  851. (void)hdb_handle_put (&cmap_handle_t_db, handle);
  852. return (error);
  853. }