cmap.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  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/logsys.h>
  51. #include <corosync/coroapi.h>
  52. #include <corosync/icmap.h>
  53. #include "service.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. struct corosync_service_engine *cmap_get_service_engine_ver0 (void)
  143. {
  144. return (&cmap_service_engine);
  145. }
  146. static int cmap_exec_exit_fn(void)
  147. {
  148. return 0;
  149. }
  150. static int cmap_exec_init_fn (
  151. struct corosync_api_v1 *corosync_api)
  152. {
  153. #ifdef COROSYNC_SOLARIS
  154. logsys_subsys_init();
  155. #endif
  156. api = corosync_api;
  157. return (0);
  158. }
  159. static int cmap_lib_init_fn (void *conn)
  160. {
  161. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  162. log_printf(LOGSYS_LEVEL_DEBUG, "lib_init_fn: conn=%p\n", conn);
  163. api->ipc_refcnt_inc(conn);
  164. memset(conn_info, 0, sizeof(*conn_info));
  165. hdb_create(&conn_info->iter_db);
  166. hdb_create(&conn_info->track_db);
  167. return (0);
  168. }
  169. static int cmap_lib_exit_fn (void *conn)
  170. {
  171. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  172. hdb_handle_t iter_handle = 0;
  173. icmap_iter_t *iter;
  174. hdb_handle_t track_handle = 0;
  175. icmap_track_t *track;
  176. log_printf(LOGSYS_LEVEL_DEBUG, "exit_fn for conn=%p\n", conn);
  177. hdb_iterator_reset(&conn_info->iter_db);
  178. while (hdb_iterator_next(&conn_info->iter_db,
  179. (void*)&iter, &iter_handle) == 0) {
  180. icmap_iter_finalize(*iter);
  181. (void)hdb_handle_put (&conn_info->iter_db, iter_handle);
  182. }
  183. hdb_destroy(&conn_info->iter_db);
  184. hdb_iterator_reset(&conn_info->track_db);
  185. while (hdb_iterator_next(&conn_info->track_db,
  186. (void*)&track, &track_handle) == 0) {
  187. free(icmap_track_get_user_data(*track));
  188. icmap_track_delete(*track);
  189. (void)hdb_handle_put (&conn_info->track_db, track_handle);
  190. }
  191. hdb_destroy(&conn_info->track_db);
  192. api->ipc_refcnt_dec(conn);
  193. return (0);
  194. }
  195. static void message_handler_req_lib_cmap_set(void *conn, const void *message)
  196. {
  197. const struct req_lib_cmap_set *req_lib_cmap_set = message;
  198. struct res_lib_cmap_set res_lib_cmap_set;
  199. cs_error_t ret;
  200. if (icmap_is_key_ro((char *)req_lib_cmap_set->key_name.value)) {
  201. ret = CS_ERR_ACCESS;
  202. } else {
  203. ret = icmap_set((char *)req_lib_cmap_set->key_name.value, &req_lib_cmap_set->value,
  204. req_lib_cmap_set->value_len, req_lib_cmap_set->type);
  205. }
  206. memset(&res_lib_cmap_set, 0, sizeof(res_lib_cmap_set));
  207. res_lib_cmap_set.header.size = sizeof(res_lib_cmap_set);
  208. res_lib_cmap_set.header.id = MESSAGE_RES_CMAP_SET;
  209. res_lib_cmap_set.header.error = ret;
  210. api->ipc_response_send(conn, &res_lib_cmap_set, sizeof(res_lib_cmap_set));
  211. }
  212. static void message_handler_req_lib_cmap_delete(void *conn, const void *message)
  213. {
  214. const struct req_lib_cmap_set *req_lib_cmap_set = message;
  215. struct res_lib_cmap_delete res_lib_cmap_delete;
  216. cs_error_t ret;
  217. if (icmap_is_key_ro((char *)req_lib_cmap_set->key_name.value)) {
  218. ret = CS_ERR_ACCESS;
  219. } else {
  220. ret = icmap_delete((char *)req_lib_cmap_set->key_name.value);
  221. }
  222. memset(&res_lib_cmap_delete, 0, sizeof(res_lib_cmap_delete));
  223. res_lib_cmap_delete.header.size = sizeof(res_lib_cmap_delete);
  224. res_lib_cmap_delete.header.id = MESSAGE_RES_CMAP_DELETE;
  225. res_lib_cmap_delete.header.error = ret;
  226. api->ipc_response_send(conn, &res_lib_cmap_delete, sizeof(res_lib_cmap_delete));
  227. }
  228. static void message_handler_req_lib_cmap_get(void *conn, const void *message)
  229. {
  230. const struct req_lib_cmap_get *req_lib_cmap_get = message;
  231. struct res_lib_cmap_get *res_lib_cmap_get;
  232. struct res_lib_cmap_get error_res_lib_cmap_get;
  233. cs_error_t ret;
  234. size_t value_len;
  235. size_t res_lib_cmap_get_size;
  236. icmap_value_types_t type;
  237. void *value;
  238. value_len = req_lib_cmap_get->value_len;
  239. res_lib_cmap_get_size = sizeof(*res_lib_cmap_get) + value_len;
  240. res_lib_cmap_get = malloc(res_lib_cmap_get_size);
  241. if (res_lib_cmap_get == NULL) {
  242. ret = CS_ERR_NO_MEMORY;
  243. goto error_exit;
  244. }
  245. memset(res_lib_cmap_get, 0, res_lib_cmap_get_size);
  246. if (value_len > 0) {
  247. value = res_lib_cmap_get->value;
  248. } else {
  249. value = NULL;
  250. }
  251. ret = icmap_get((char *)req_lib_cmap_get->key_name.value,
  252. value,
  253. &value_len,
  254. &type);
  255. if (ret != CS_OK) {
  256. free(res_lib_cmap_get);
  257. goto error_exit;
  258. }
  259. res_lib_cmap_get->header.size = res_lib_cmap_get_size;
  260. res_lib_cmap_get->header.id = MESSAGE_RES_CMAP_GET;
  261. res_lib_cmap_get->header.error = ret;
  262. res_lib_cmap_get->type = type;
  263. res_lib_cmap_get->value_len = value_len;
  264. api->ipc_response_send(conn, res_lib_cmap_get, res_lib_cmap_get_size);
  265. free(res_lib_cmap_get);
  266. return ;
  267. error_exit:
  268. memset(&error_res_lib_cmap_get, 0, sizeof(error_res_lib_cmap_get));
  269. error_res_lib_cmap_get.header.size = sizeof(error_res_lib_cmap_get);
  270. error_res_lib_cmap_get.header.id = MESSAGE_RES_CMAP_GET;
  271. error_res_lib_cmap_get.header.error = ret;
  272. api->ipc_response_send(conn, &error_res_lib_cmap_get, sizeof(error_res_lib_cmap_get));
  273. }
  274. static void message_handler_req_lib_cmap_adjust_int(void *conn, const void *message)
  275. {
  276. const struct req_lib_cmap_adjust_int *req_lib_cmap_adjust_int = message;
  277. struct res_lib_cmap_adjust_int res_lib_cmap_adjust_int;
  278. cs_error_t ret;
  279. ret = icmap_adjust_int((char *)req_lib_cmap_adjust_int->key_name.value, req_lib_cmap_adjust_int->step);
  280. memset(&res_lib_cmap_adjust_int, 0, sizeof(res_lib_cmap_adjust_int));
  281. res_lib_cmap_adjust_int.header.size = sizeof(res_lib_cmap_adjust_int);
  282. res_lib_cmap_adjust_int.header.id = MESSAGE_RES_CMAP_ADJUST_INT;
  283. res_lib_cmap_adjust_int.header.error = ret;
  284. api->ipc_response_send(conn, &res_lib_cmap_adjust_int, sizeof(res_lib_cmap_adjust_int));
  285. }
  286. static void message_handler_req_lib_cmap_iter_init(void *conn, const void *message)
  287. {
  288. const struct req_lib_cmap_iter_init *req_lib_cmap_iter_init = message;
  289. struct res_lib_cmap_iter_init res_lib_cmap_iter_init;
  290. cs_error_t ret;
  291. icmap_iter_t iter;
  292. icmap_iter_t *hdb_iter;
  293. cmap_iter_handle_t handle;
  294. const char *prefix;
  295. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  296. if (req_lib_cmap_iter_init->prefix.length > 0) {
  297. prefix = (char *)req_lib_cmap_iter_init->prefix.value;
  298. } else {
  299. prefix = NULL;
  300. }
  301. iter = icmap_iter_init(prefix);
  302. if (iter == NULL) {
  303. ret = CS_ERR_NO_SECTIONS;
  304. goto reply_send;
  305. }
  306. ret = hdb_error_to_cs(hdb_handle_create(&conn_info->iter_db, sizeof(iter), &handle));
  307. if (ret != CS_OK) {
  308. goto reply_send;
  309. }
  310. ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db, handle, (void *)&hdb_iter));
  311. if (ret != CS_OK) {
  312. goto reply_send;
  313. }
  314. *hdb_iter = iter;
  315. (void)hdb_handle_put (&conn_info->iter_db, handle);
  316. reply_send:
  317. memset(&res_lib_cmap_iter_init, 0, sizeof(res_lib_cmap_iter_init));
  318. res_lib_cmap_iter_init.header.size = sizeof(res_lib_cmap_iter_init);
  319. res_lib_cmap_iter_init.header.id = MESSAGE_RES_CMAP_ITER_INIT;
  320. res_lib_cmap_iter_init.header.error = ret;
  321. res_lib_cmap_iter_init.iter_handle = handle;
  322. api->ipc_response_send(conn, &res_lib_cmap_iter_init, sizeof(res_lib_cmap_iter_init));
  323. }
  324. static void message_handler_req_lib_cmap_iter_next(void *conn, const void *message)
  325. {
  326. const struct req_lib_cmap_iter_next *req_lib_cmap_iter_next = message;
  327. struct res_lib_cmap_iter_next res_lib_cmap_iter_next;
  328. cs_error_t ret;
  329. icmap_iter_t *iter;
  330. size_t value_len;
  331. icmap_value_types_t type;
  332. const char *res = NULL;
  333. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  334. ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db,
  335. req_lib_cmap_iter_next->iter_handle, (void *)&iter));
  336. if (ret != CS_OK) {
  337. goto reply_send;
  338. }
  339. res = icmap_iter_next(*iter, &value_len, &type);
  340. if (res == NULL) {
  341. ret = CS_ERR_NO_SECTIONS;
  342. }
  343. (void)hdb_handle_put (&conn_info->iter_db, req_lib_cmap_iter_next->iter_handle);
  344. reply_send:
  345. memset(&res_lib_cmap_iter_next, 0, sizeof(res_lib_cmap_iter_next));
  346. res_lib_cmap_iter_next.header.size = sizeof(res_lib_cmap_iter_next);
  347. res_lib_cmap_iter_next.header.id = MESSAGE_RES_CMAP_ITER_NEXT;
  348. res_lib_cmap_iter_next.header.error = ret;
  349. if (res != NULL) {
  350. res_lib_cmap_iter_next.value_len = value_len;
  351. res_lib_cmap_iter_next.type = type;
  352. memcpy(res_lib_cmap_iter_next.key_name.value, res, strlen(res));
  353. res_lib_cmap_iter_next.key_name.length = strlen(res);
  354. }
  355. api->ipc_response_send(conn, &res_lib_cmap_iter_next, sizeof(res_lib_cmap_iter_next));
  356. }
  357. static void message_handler_req_lib_cmap_iter_finalize(void *conn, const void *message)
  358. {
  359. const struct req_lib_cmap_iter_finalize *req_lib_cmap_iter_finalize = message;
  360. struct res_lib_cmap_iter_finalize res_lib_cmap_iter_finalize;
  361. cs_error_t ret;
  362. icmap_iter_t *iter;
  363. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  364. ret = hdb_error_to_cs(hdb_handle_get(&conn_info->iter_db,
  365. req_lib_cmap_iter_finalize->iter_handle, (void *)&iter));
  366. if (ret != CS_OK) {
  367. goto reply_send;
  368. }
  369. icmap_iter_finalize(*iter);
  370. (void)hdb_handle_destroy(&conn_info->iter_db, req_lib_cmap_iter_finalize->iter_handle);
  371. (void)hdb_handle_put (&conn_info->iter_db, req_lib_cmap_iter_finalize->iter_handle);
  372. reply_send:
  373. memset(&res_lib_cmap_iter_finalize, 0, sizeof(res_lib_cmap_iter_finalize));
  374. res_lib_cmap_iter_finalize.header.size = sizeof(res_lib_cmap_iter_finalize);
  375. res_lib_cmap_iter_finalize.header.id = MESSAGE_RES_CMAP_ITER_FINALIZE;
  376. res_lib_cmap_iter_finalize.header.error = ret;
  377. api->ipc_response_send(conn, &res_lib_cmap_iter_finalize, sizeof(res_lib_cmap_iter_finalize));
  378. }
  379. static void cmap_notify_fn(int32_t event,
  380. const char *key_name,
  381. struct icmap_notify_value new_val,
  382. struct icmap_notify_value old_val,
  383. void *user_data)
  384. {
  385. struct cmap_track_user_data *cmap_track_user_data = (struct cmap_track_user_data *)user_data;
  386. struct res_lib_cmap_notify_callback res_lib_cmap_notify_callback;
  387. struct iovec iov[3];
  388. memset(&res_lib_cmap_notify_callback, 0, sizeof(res_lib_cmap_notify_callback));
  389. res_lib_cmap_notify_callback.header.size = sizeof(res_lib_cmap_notify_callback) + new_val.len + old_val.len;
  390. res_lib_cmap_notify_callback.header.id = MESSAGE_RES_CMAP_NOTIFY_CALLBACK;
  391. res_lib_cmap_notify_callback.header.error = CS_OK;
  392. res_lib_cmap_notify_callback.new_value_type = new_val.type;
  393. res_lib_cmap_notify_callback.old_value_type = old_val.type;
  394. res_lib_cmap_notify_callback.new_value_len = new_val.len;
  395. res_lib_cmap_notify_callback.old_value_len = old_val.len;
  396. res_lib_cmap_notify_callback.event = event;
  397. res_lib_cmap_notify_callback.key_name.length = strlen(key_name);
  398. res_lib_cmap_notify_callback.track_inst_handle = cmap_track_user_data->track_inst_handle;
  399. memcpy(res_lib_cmap_notify_callback.key_name.value, key_name, strlen(key_name));
  400. iov[0].iov_base = (char *)&res_lib_cmap_notify_callback;
  401. iov[0].iov_len = sizeof(res_lib_cmap_notify_callback);
  402. iov[1].iov_base = (char *)new_val.data;
  403. iov[1].iov_len = new_val.len;
  404. iov[2].iov_base = (char *)old_val.data;
  405. iov[2].iov_len = old_val.len;
  406. api->ipc_dispatch_iov_send(cmap_track_user_data->conn, iov, 3);
  407. }
  408. static void message_handler_req_lib_cmap_track_add(void *conn, const void *message)
  409. {
  410. const struct req_lib_cmap_track_add *req_lib_cmap_track_add = message;
  411. struct res_lib_cmap_track_add res_lib_cmap_track_add;
  412. cs_error_t ret;
  413. cmap_track_handle_t handle = 0;
  414. icmap_track_t track;
  415. icmap_track_t *hdb_track;
  416. struct cmap_track_user_data *cmap_track_user_data;
  417. const char *key_name;
  418. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  419. cmap_track_user_data = malloc(sizeof(*cmap_track_user_data));
  420. if (cmap_track_user_data == NULL) {
  421. ret = CS_ERR_NO_MEMORY;
  422. goto reply_send;
  423. }
  424. memset(cmap_track_user_data, 0, sizeof(*cmap_track_user_data));
  425. if (req_lib_cmap_track_add->key_name.length > 0) {
  426. key_name = (char *)req_lib_cmap_track_add->key_name.value;
  427. } else {
  428. key_name = NULL;
  429. }
  430. ret = icmap_track_add(key_name,
  431. req_lib_cmap_track_add->track_type,
  432. cmap_notify_fn,
  433. cmap_track_user_data,
  434. &track);
  435. if (ret != CS_OK) {
  436. free(cmap_track_user_data);
  437. goto reply_send;
  438. }
  439. ret = hdb_error_to_cs(hdb_handle_create(&conn_info->track_db, sizeof(track), &handle));
  440. if (ret != CS_OK) {
  441. free(cmap_track_user_data);
  442. goto reply_send;
  443. }
  444. ret = hdb_error_to_cs(hdb_handle_get(&conn_info->track_db, handle, (void *)&hdb_track));
  445. if (ret != CS_OK) {
  446. free(cmap_track_user_data);
  447. goto reply_send;
  448. }
  449. *hdb_track = track;
  450. cmap_track_user_data->conn = conn;
  451. cmap_track_user_data->track_handle = handle;
  452. cmap_track_user_data->track_inst_handle = req_lib_cmap_track_add->track_inst_handle;
  453. (void)hdb_handle_put (&conn_info->track_db, handle);
  454. reply_send:
  455. memset(&res_lib_cmap_track_add, 0, sizeof(res_lib_cmap_track_add));
  456. res_lib_cmap_track_add.header.size = sizeof(res_lib_cmap_track_add);
  457. res_lib_cmap_track_add.header.id = MESSAGE_RES_CMAP_TRACK_ADD;
  458. res_lib_cmap_track_add.header.error = ret;
  459. res_lib_cmap_track_add.track_handle = handle;
  460. api->ipc_response_send(conn, &res_lib_cmap_track_add, sizeof(res_lib_cmap_track_add));
  461. }
  462. static void message_handler_req_lib_cmap_track_delete(void *conn, const void *message)
  463. {
  464. const struct req_lib_cmap_track_delete *req_lib_cmap_track_delete = message;
  465. struct res_lib_cmap_track_delete res_lib_cmap_track_delete;
  466. cs_error_t ret;
  467. icmap_track_t *track;
  468. struct cmap_conn_info *conn_info = (struct cmap_conn_info *)api->ipc_private_data_get (conn);
  469. uint64_t track_inst_handle = 0;
  470. ret = hdb_error_to_cs(hdb_handle_get(&conn_info->track_db,
  471. req_lib_cmap_track_delete->track_handle, (void *)&track));
  472. if (ret != CS_OK) {
  473. goto reply_send;
  474. }
  475. track_inst_handle = ((struct cmap_track_user_data *)icmap_track_get_user_data(*track))->track_inst_handle;
  476. free(icmap_track_get_user_data(*track));
  477. ret = icmap_track_delete(*track);
  478. (void)hdb_handle_put (&conn_info->track_db, req_lib_cmap_track_delete->track_handle);
  479. (void)hdb_handle_destroy(&conn_info->track_db, req_lib_cmap_track_delete->track_handle);
  480. reply_send:
  481. memset(&res_lib_cmap_track_delete, 0, sizeof(res_lib_cmap_track_delete));
  482. res_lib_cmap_track_delete.header.size = sizeof(res_lib_cmap_track_delete);
  483. res_lib_cmap_track_delete.header.id = MESSAGE_RES_CMAP_TRACK_DELETE;
  484. res_lib_cmap_track_delete.header.error = ret;
  485. res_lib_cmap_track_delete.track_inst_handle = track_inst_handle;
  486. api->ipc_response_send(conn, &res_lib_cmap_track_delete, sizeof(res_lib_cmap_track_delete));
  487. }