cmap.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /*
  2. * Copyright (c) 2011 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 <sys/types.h>
  36. #include <unistd.h>
  37. #include <fcntl.h>
  38. #include <stdlib.h>
  39. #include <errno.h>
  40. #include <unistd.h>
  41. #include <poll.h>
  42. #include <assert.h>
  43. #include <qb/qbloop.h>
  44. #include <qb/qbipc_common.h>
  45. #include <corosync/corotypes.h>
  46. #include <corosync/corodefs.h>
  47. #include <corosync/list.h>
  48. #include <corosync/mar_gen.h>
  49. #include <corosync/ipc_cmap.h>
  50. #include <corosync/lcr/lcr_comp.h>
  51. #include <corosync/engine/logsys.h>
  52. #include <corosync/engine/coroapi.h>
  53. #include <corosync/engine/icmap.h>
  54. #define hdb_error_to_cs(_result_) qb_to_cs_error(_result_)
  55. LOGSYS_DECLARE_SUBSYS ("CMAP");
  56. struct cmap_conn_info {
  57. struct hdb_handle_database iter_db;
  58. struct hdb_handle_database track_db;
  59. };
  60. typedef uint64_t cmap_iter_handle_t;
  61. typedef uint64_t cmap_track_handle_t;
  62. struct cmap_track_user_data {
  63. void *conn;
  64. cmap_track_handle_t track_handle;
  65. uint64_t track_inst_handle;
  66. };
  67. static struct corosync_api_v1 *api;
  68. static int cmap_exec_init_fn (struct corosync_api_v1 *corosync_api);
  69. static int cmap_exec_exit_fn(void);
  70. static int cmap_lib_init_fn (void *conn);
  71. static int cmap_lib_exit_fn (void *conn);
  72. static void message_handler_req_lib_cmap_set(void *conn, const void *message);
  73. static void message_handler_req_lib_cmap_delete(void *conn, const void *message);
  74. static void message_handler_req_lib_cmap_get(void *conn, const void *message);
  75. static void message_handler_req_lib_cmap_adjust_int(void *conn, const void *message);
  76. static void message_handler_req_lib_cmap_iter_init(void *conn, const void *message);
  77. static void message_handler_req_lib_cmap_iter_next(void *conn, const void *message);
  78. static void message_handler_req_lib_cmap_iter_finalize(void *conn, const void *message);
  79. static void message_handler_req_lib_cmap_track_add(void *conn, const void *message);
  80. static void message_handler_req_lib_cmap_track_delete(void *conn, const void *message);
  81. static void cmap_notify_fn(int32_t event,
  82. const char *key_name,
  83. struct icmap_notify_value new_val,
  84. struct icmap_notify_value old_val,
  85. void *user_data);
  86. /*
  87. * Library Handler Definition
  88. */
  89. static struct corosync_lib_handler cmap_lib_engine[] =
  90. {
  91. { /* 0 */
  92. .lib_handler_fn = message_handler_req_lib_cmap_set,
  93. .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
  94. },
  95. { /* 1 */
  96. .lib_handler_fn = message_handler_req_lib_cmap_delete,
  97. .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
  98. },
  99. { /* 2 */
  100. .lib_handler_fn = message_handler_req_lib_cmap_get,
  101. .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
  102. },
  103. { /* 3 */
  104. .lib_handler_fn = message_handler_req_lib_cmap_adjust_int,
  105. .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
  106. },
  107. { /* 4 */
  108. .lib_handler_fn = message_handler_req_lib_cmap_iter_init,
  109. .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
  110. },
  111. { /* 5 */
  112. .lib_handler_fn = message_handler_req_lib_cmap_iter_next,
  113. .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
  114. },
  115. { /* 6 */
  116. .lib_handler_fn = message_handler_req_lib_cmap_iter_finalize,
  117. .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
  118. },
  119. { /* 7 */
  120. .lib_handler_fn = message_handler_req_lib_cmap_track_add,
  121. .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
  122. },
  123. { /* 8 */
  124. .lib_handler_fn = message_handler_req_lib_cmap_track_delete,
  125. .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
  126. },
  127. };
  128. struct corosync_service_engine cmap_service_engine = {
  129. .name = "corosync configuration map access",
  130. .id = CMAP_SERVICE,
  131. .priority = 1,
  132. .private_data_size = sizeof(struct cmap_conn_info),
  133. .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED,
  134. .allow_inquorate = CS_LIB_ALLOW_INQUORATE,
  135. .lib_init_fn = cmap_lib_init_fn,
  136. .lib_exit_fn = cmap_lib_exit_fn,
  137. .lib_engine = cmap_lib_engine,
  138. .lib_engine_count = sizeof (cmap_lib_engine) / sizeof (struct corosync_lib_handler),
  139. .exec_init_fn = cmap_exec_init_fn,
  140. .exec_exit_fn = cmap_exec_exit_fn,
  141. };
  142. /*
  143. * Dynamic loader definition
  144. */
  145. static struct corosync_service_engine *cmap_get_service_engine_ver0 (void);
  146. static struct corosync_service_engine_iface_ver0 cmap_service_engine_iface = {
  147. .corosync_get_service_engine_ver0 = cmap_get_service_engine_ver0
  148. };
  149. static struct lcr_iface corosync_cmap_ver0[1] = {
  150. {
  151. .name = "corosync_cmap",
  152. .version = 0,
  153. .versions_replace = 0,
  154. .versions_replace_count = 0,
  155. .dependencies = 0,
  156. .dependency_count = 0,
  157. .constructor = NULL,
  158. .destructor = NULL,
  159. .interfaces = NULL
  160. }
  161. };
  162. static struct lcr_comp cmap_comp_ver0 = {
  163. .iface_count = 1,
  164. .ifaces = corosync_cmap_ver0
  165. };
  166. static struct corosync_service_engine *cmap_get_service_engine_ver0 (void)
  167. {
  168. return (&cmap_service_engine);
  169. }
  170. #ifdef COROSYNC_SOLARIS
  171. void corosync_lcr_component_register (void);
  172. void corosync_lcr_component_register (void) {
  173. #else
  174. __attribute__ ((constructor)) static void corosync_lcr_component_register (void) {
  175. #endif
  176. lcr_interfaces_set (&corosync_cmap_ver0[0], &cmap_service_engine_iface);
  177. lcr_component_register (&cmap_comp_ver0);
  178. }
  179. static int cmap_exec_exit_fn(void)
  180. {
  181. return 0;
  182. }
  183. static int cmap_exec_init_fn (
  184. struct corosync_api_v1 *corosync_api)
  185. {
  186. #ifdef COROSYNC_SOLARIS
  187. logsys_subsys_init();
  188. #endif
  189. api = corosync_api;
  190. return (0);
  191. }
  192. static int cmap_lib_init_fn (void *conn)
  193. {
  194. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  195. log_printf(LOGSYS_LEVEL_DEBUG, "lib_init_fn: conn=%p\n", conn);
  196. api->ipc_refcnt_inc(conn);
  197. memset(conn_info, 0, sizeof(*conn_info));
  198. hdb_create(&conn_info->iter_db);
  199. hdb_create(&conn_info->track_db);
  200. return (0);
  201. }
  202. static int cmap_lib_exit_fn (void *conn)
  203. {
  204. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  205. hdb_handle_t iter_handle = 0;
  206. icmap_iter_t *iter;
  207. hdb_handle_t track_handle = 0;
  208. icmap_track_t *track;
  209. log_printf(LOGSYS_LEVEL_DEBUG, "exit_fn for conn=%p\n", conn);
  210. hdb_iterator_reset(&conn_info->iter_db);
  211. while (hdb_iterator_next(&conn_info->iter_db,
  212. (void*)&iter, &iter_handle) == 0) {
  213. icmap_iter_finalize(*iter);
  214. (void)hdb_handle_put (&conn_info->iter_db, iter_handle);
  215. }
  216. hdb_destroy(&conn_info->iter_db);
  217. hdb_iterator_reset(&conn_info->track_db);
  218. while (hdb_iterator_next(&conn_info->track_db,
  219. (void*)&track, &track_handle) == 0) {
  220. free(icmap_track_get_user_data(*track));
  221. icmap_track_delete(*track);
  222. (void)hdb_handle_put (&conn_info->track_db, track_handle);
  223. }
  224. hdb_destroy(&conn_info->track_db);
  225. api->ipc_refcnt_dec(conn);
  226. return (0);
  227. }
  228. static void message_handler_req_lib_cmap_set(void *conn, const void *message)
  229. {
  230. const struct req_lib_cmap_set *req_lib_cmap_set = message;
  231. struct res_lib_cmap_set res_lib_cmap_set;
  232. cs_error_t ret;
  233. if (icmap_is_key_ro((char *)req_lib_cmap_set->key_name.value)) {
  234. ret = CS_ERR_ACCESS;
  235. } else {
  236. ret = icmap_set((char *)req_lib_cmap_set->key_name.value, &req_lib_cmap_set->value,
  237. req_lib_cmap_set->value_len, req_lib_cmap_set->type);
  238. }
  239. memset(&res_lib_cmap_set, 0, sizeof(res_lib_cmap_set));
  240. res_lib_cmap_set.header.size = sizeof(res_lib_cmap_set);
  241. res_lib_cmap_set.header.id = MESSAGE_RES_CMAP_SET;
  242. res_lib_cmap_set.header.error = ret;
  243. api->ipc_response_send(conn, &res_lib_cmap_set, sizeof(res_lib_cmap_set));
  244. }
  245. static void message_handler_req_lib_cmap_delete(void *conn, const void *message)
  246. {
  247. const struct req_lib_cmap_set *req_lib_cmap_set = message;
  248. struct res_lib_cmap_delete res_lib_cmap_delete;
  249. cs_error_t ret;
  250. if (icmap_is_key_ro((char *)req_lib_cmap_set->key_name.value)) {
  251. ret = CS_ERR_ACCESS;
  252. } else {
  253. ret = icmap_delete((char *)req_lib_cmap_set->key_name.value);
  254. }
  255. memset(&res_lib_cmap_delete, 0, sizeof(res_lib_cmap_delete));
  256. res_lib_cmap_delete.header.size = sizeof(res_lib_cmap_delete);
  257. res_lib_cmap_delete.header.id = MESSAGE_RES_CMAP_DELETE;
  258. res_lib_cmap_delete.header.error = ret;
  259. api->ipc_response_send(conn, &res_lib_cmap_delete, sizeof(res_lib_cmap_delete));
  260. }
  261. static void message_handler_req_lib_cmap_get(void *conn, const void *message)
  262. {
  263. const struct req_lib_cmap_get *req_lib_cmap_get = message;
  264. struct res_lib_cmap_get *res_lib_cmap_get;
  265. struct res_lib_cmap_get error_res_lib_cmap_get;
  266. cs_error_t ret;
  267. size_t value_len;
  268. size_t res_lib_cmap_get_size;
  269. icmap_value_types_t type;
  270. void *value;
  271. value_len = req_lib_cmap_get->value_len;
  272. res_lib_cmap_get_size = sizeof(*res_lib_cmap_get) + value_len;
  273. res_lib_cmap_get = malloc(res_lib_cmap_get_size);
  274. if (res_lib_cmap_get == NULL) {
  275. ret = CS_ERR_NO_MEMORY;
  276. goto error_exit;
  277. }
  278. memset(res_lib_cmap_get, 0, res_lib_cmap_get_size);
  279. if (value_len > 0) {
  280. value = res_lib_cmap_get->value;
  281. } else {
  282. value = NULL;
  283. }
  284. ret = icmap_get((char *)req_lib_cmap_get->key_name.value,
  285. value,
  286. &value_len,
  287. &type);
  288. if (ret != CS_OK) {
  289. free(res_lib_cmap_get);
  290. goto error_exit;
  291. }
  292. res_lib_cmap_get->header.size = res_lib_cmap_get_size;
  293. res_lib_cmap_get->header.id = MESSAGE_RES_CMAP_GET;
  294. res_lib_cmap_get->header.error = ret;
  295. res_lib_cmap_get->type = type;
  296. res_lib_cmap_get->value_len = value_len;
  297. api->ipc_response_send(conn, res_lib_cmap_get, res_lib_cmap_get_size);
  298. free(res_lib_cmap_get);
  299. return ;
  300. error_exit:
  301. memset(&error_res_lib_cmap_get, 0, sizeof(error_res_lib_cmap_get));
  302. error_res_lib_cmap_get.header.size = sizeof(error_res_lib_cmap_get);
  303. error_res_lib_cmap_get.header.id = MESSAGE_RES_CMAP_GET;
  304. error_res_lib_cmap_get.header.error = ret;
  305. api->ipc_response_send(conn, &error_res_lib_cmap_get, sizeof(error_res_lib_cmap_get));
  306. }
  307. static void message_handler_req_lib_cmap_adjust_int(void *conn, const void *message)
  308. {
  309. const struct req_lib_cmap_adjust_int *req_lib_cmap_adjust_int = message;
  310. struct res_lib_cmap_adjust_int res_lib_cmap_adjust_int;
  311. cs_error_t ret;
  312. ret = icmap_adjust_int((char *)req_lib_cmap_adjust_int->key_name.value, req_lib_cmap_adjust_int->step);
  313. memset(&res_lib_cmap_adjust_int, 0, sizeof(res_lib_cmap_adjust_int));
  314. res_lib_cmap_adjust_int.header.size = sizeof(res_lib_cmap_adjust_int);
  315. res_lib_cmap_adjust_int.header.id = MESSAGE_RES_CMAP_ADJUST_INT;
  316. res_lib_cmap_adjust_int.header.error = ret;
  317. api->ipc_response_send(conn, &res_lib_cmap_adjust_int, sizeof(res_lib_cmap_adjust_int));
  318. }
  319. static void message_handler_req_lib_cmap_iter_init(void *conn, const void *message)
  320. {
  321. const struct req_lib_cmap_iter_init *req_lib_cmap_iter_init = message;
  322. struct res_lib_cmap_iter_init res_lib_cmap_iter_init;
  323. cs_error_t ret;
  324. icmap_iter_t iter;
  325. icmap_iter_t *hdb_iter;
  326. cmap_iter_handle_t handle;
  327. const char *prefix;
  328. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  329. if (req_lib_cmap_iter_init->prefix.length > 0) {
  330. prefix = (char *)req_lib_cmap_iter_init->prefix.value;
  331. } else {
  332. prefix = NULL;
  333. }
  334. iter = icmap_iter_init(prefix);
  335. if (iter == NULL) {
  336. ret = CS_ERR_NO_SECTIONS;
  337. goto reply_send;
  338. }
  339. ret = hdb_error_to_cs(hdb_handle_create(&conn_info->iter_db, sizeof(iter), &handle));
  340. if (ret != CS_OK) {
  341. goto reply_send;
  342. }
  343. ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db, handle, (void *)&hdb_iter));
  344. if (ret != CS_OK) {
  345. goto reply_send;
  346. }
  347. *hdb_iter = iter;
  348. (void)hdb_handle_put (&conn_info->iter_db, handle);
  349. reply_send:
  350. memset(&res_lib_cmap_iter_init, 0, sizeof(res_lib_cmap_iter_init));
  351. res_lib_cmap_iter_init.header.size = sizeof(res_lib_cmap_iter_init);
  352. res_lib_cmap_iter_init.header.id = MESSAGE_RES_CMAP_ITER_INIT;
  353. res_lib_cmap_iter_init.header.error = ret;
  354. res_lib_cmap_iter_init.iter_handle = handle;
  355. api->ipc_response_send(conn, &res_lib_cmap_iter_init, sizeof(res_lib_cmap_iter_init));
  356. }
  357. static void message_handler_req_lib_cmap_iter_next(void *conn, const void *message)
  358. {
  359. const struct req_lib_cmap_iter_next *req_lib_cmap_iter_next = message;
  360. struct res_lib_cmap_iter_next res_lib_cmap_iter_next;
  361. cs_error_t ret;
  362. icmap_iter_t *iter;
  363. size_t value_len;
  364. icmap_value_types_t type;
  365. const char *res = NULL;
  366. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  367. ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db,
  368. req_lib_cmap_iter_next->iter_handle, (void *)&iter));
  369. if (ret != CS_OK) {
  370. goto reply_send;
  371. }
  372. res = icmap_iter_next(*iter, &value_len, &type);
  373. if (res == NULL) {
  374. ret = CS_ERR_NO_SECTIONS;
  375. }
  376. (void)hdb_handle_put (&conn_info->iter_db, req_lib_cmap_iter_next->iter_handle);
  377. reply_send:
  378. memset(&res_lib_cmap_iter_next, 0, sizeof(res_lib_cmap_iter_next));
  379. res_lib_cmap_iter_next.header.size = sizeof(res_lib_cmap_iter_next);
  380. res_lib_cmap_iter_next.header.id = MESSAGE_RES_CMAP_ITER_NEXT;
  381. res_lib_cmap_iter_next.header.error = ret;
  382. if (res != NULL) {
  383. res_lib_cmap_iter_next.value_len = value_len;
  384. res_lib_cmap_iter_next.type = type;
  385. memcpy(res_lib_cmap_iter_next.key_name.value, res, strlen(res));
  386. res_lib_cmap_iter_next.key_name.length = strlen(res);
  387. }
  388. api->ipc_response_send(conn, &res_lib_cmap_iter_next, sizeof(res_lib_cmap_iter_next));
  389. }
  390. static void message_handler_req_lib_cmap_iter_finalize(void *conn, const void *message)
  391. {
  392. const struct req_lib_cmap_iter_finalize *req_lib_cmap_iter_finalize = message;
  393. struct res_lib_cmap_iter_finalize res_lib_cmap_iter_finalize;
  394. cs_error_t ret;
  395. icmap_iter_t *iter;
  396. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  397. ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db,
  398. req_lib_cmap_iter_finalize->iter_handle, (void *)&iter));
  399. if (ret != CS_OK) {
  400. goto reply_send;
  401. }
  402. icmap_iter_finalize(*iter);
  403. (void)hdb_handle_destroy(&conn_info->iter_db, req_lib_cmap_iter_finalize->iter_handle);
  404. (void)hdb_handle_put (&conn_info->iter_db, req_lib_cmap_iter_finalize->iter_handle);
  405. reply_send:
  406. memset(&res_lib_cmap_iter_finalize, 0, sizeof(res_lib_cmap_iter_finalize));
  407. res_lib_cmap_iter_finalize.header.size = sizeof(res_lib_cmap_iter_finalize);
  408. res_lib_cmap_iter_finalize.header.id = MESSAGE_RES_CMAP_ITER_FINALIZE;
  409. res_lib_cmap_iter_finalize.header.error = ret;
  410. api->ipc_response_send(conn, &res_lib_cmap_iter_finalize, sizeof(res_lib_cmap_iter_finalize));
  411. }
  412. static void cmap_notify_fn(int32_t event,
  413. const char *key_name,
  414. struct icmap_notify_value new_val,
  415. struct icmap_notify_value old_val,
  416. void *user_data)
  417. {
  418. struct cmap_track_user_data *cmap_track_user_data = (struct cmap_track_user_data *)user_data;
  419. struct res_lib_cmap_notify_callback res_lib_cmap_notify_callback;
  420. struct iovec iov[3];
  421. memset(&res_lib_cmap_notify_callback, 0, sizeof(res_lib_cmap_notify_callback));
  422. res_lib_cmap_notify_callback.header.size = sizeof(res_lib_cmap_notify_callback) + new_val.len + old_val.len;
  423. res_lib_cmap_notify_callback.header.id = MESSAGE_RES_CMAP_NOTIFY_CALLBACK;
  424. res_lib_cmap_notify_callback.header.error = CS_OK;
  425. res_lib_cmap_notify_callback.new_value_type = new_val.type;
  426. res_lib_cmap_notify_callback.old_value_type = old_val.type;
  427. res_lib_cmap_notify_callback.new_value_len = new_val.len;
  428. res_lib_cmap_notify_callback.old_value_len = old_val.len;
  429. res_lib_cmap_notify_callback.event = event;
  430. res_lib_cmap_notify_callback.key_name.length = strlen(key_name);
  431. res_lib_cmap_notify_callback.track_inst_handle = cmap_track_user_data->track_inst_handle;
  432. memcpy(res_lib_cmap_notify_callback.key_name.value, key_name, strlen(key_name));
  433. iov[0].iov_base = (char *)&res_lib_cmap_notify_callback;
  434. iov[0].iov_len = sizeof(res_lib_cmap_notify_callback);
  435. iov[1].iov_base = (char *)new_val.data;
  436. iov[1].iov_len = new_val.len;
  437. iov[2].iov_base = (char *)old_val.data;
  438. iov[2].iov_len = old_val.len;
  439. api->ipc_dispatch_iov_send(cmap_track_user_data->conn, iov, 3);
  440. }
  441. static void message_handler_req_lib_cmap_track_add(void *conn, const void *message)
  442. {
  443. const struct req_lib_cmap_track_add *req_lib_cmap_track_add = message;
  444. struct res_lib_cmap_track_add res_lib_cmap_track_add;
  445. cs_error_t ret;
  446. cmap_track_handle_t handle;
  447. icmap_track_t track;
  448. icmap_track_t *hdb_track;
  449. struct cmap_track_user_data *cmap_track_user_data;
  450. const char *key_name;
  451. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  452. cmap_track_user_data = malloc(sizeof(*cmap_track_user_data));
  453. if (cmap_track_user_data == NULL) {
  454. ret = CS_ERR_NO_MEMORY;
  455. goto reply_send;
  456. }
  457. memset(cmap_track_user_data, 0, sizeof(*cmap_track_user_data));
  458. if (req_lib_cmap_track_add->key_name.length > 0) {
  459. key_name = (char *)req_lib_cmap_track_add->key_name.value;
  460. } else {
  461. key_name = NULL;
  462. }
  463. ret = icmap_track_add(key_name,
  464. req_lib_cmap_track_add->track_type,
  465. cmap_notify_fn,
  466. cmap_track_user_data,
  467. &track);
  468. if (ret != CS_OK) {
  469. free(cmap_track_user_data);
  470. goto reply_send;
  471. }
  472. ret = hdb_error_to_cs(hdb_handle_create(&conn_info->track_db, sizeof(track), &handle));
  473. if (ret != CS_OK) {
  474. free(cmap_track_user_data);
  475. goto reply_send;
  476. }
  477. ret = hdb_error_to_cs(hdb_handle_get(&conn_info->track_db, handle, (void *)&hdb_track));
  478. if (ret != CS_OK) {
  479. free(cmap_track_user_data);
  480. goto reply_send;
  481. }
  482. *hdb_track = track;
  483. cmap_track_user_data->conn = conn;
  484. cmap_track_user_data->track_handle = handle;
  485. cmap_track_user_data->track_inst_handle = req_lib_cmap_track_add->track_inst_handle;
  486. (void)hdb_handle_put (&conn_info->track_db, handle);
  487. reply_send:
  488. memset(&res_lib_cmap_track_add, 0, sizeof(res_lib_cmap_track_add));
  489. res_lib_cmap_track_add.header.size = sizeof(res_lib_cmap_track_add);
  490. res_lib_cmap_track_add.header.id = MESSAGE_RES_CMAP_TRACK_ADD;
  491. res_lib_cmap_track_add.header.error = ret;
  492. res_lib_cmap_track_add.track_handle = handle;
  493. api->ipc_response_send(conn, &res_lib_cmap_track_add, sizeof(res_lib_cmap_track_add));
  494. }
  495. static void message_handler_req_lib_cmap_track_delete(void *conn, const void *message)
  496. {
  497. const struct req_lib_cmap_track_delete *req_lib_cmap_track_delete = message;
  498. struct res_lib_cmap_track_delete res_lib_cmap_track_delete;
  499. cs_error_t ret;
  500. icmap_track_t *track;
  501. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  502. uint64_t track_inst_handle = 0;
  503. ret = hdb_error_to_cs(hdb_handle_get(&conn_info->track_db,
  504. req_lib_cmap_track_delete->track_handle, (void *)&track));
  505. if (ret != CS_OK) {
  506. goto reply_send;
  507. }
  508. track_inst_handle = ((struct cmap_track_user_data *)icmap_track_get_user_data(*track))->track_inst_handle;
  509. free(icmap_track_get_user_data(*track));
  510. ret = icmap_track_delete(*track);
  511. (void)hdb_handle_put (&conn_info->track_db, req_lib_cmap_track_delete->track_handle);
  512. (void)hdb_handle_destroy(&conn_info->track_db, req_lib_cmap_track_delete->track_handle);
  513. reply_send:
  514. memset(&res_lib_cmap_track_delete, 0, sizeof(res_lib_cmap_track_delete));
  515. res_lib_cmap_track_delete.header.size = sizeof(res_lib_cmap_track_delete);
  516. res_lib_cmap_track_delete.header.id = MESSAGE_RES_CMAP_TRACK_DELETE;
  517. res_lib_cmap_track_delete.header.error = ret;
  518. res_lib_cmap_track_delete.track_inst_handle = track_inst_handle;
  519. api->ipc_response_send(conn, &res_lib_cmap_track_delete, sizeof(res_lib_cmap_track_delete));
  520. }