cmap.c 19 KB

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