cfg.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. /*
  2. * Copyright (c) 2002-2005 MontaVista Software, Inc.
  3. * Copyright (c) 2006-2009 Red Hat, Inc.
  4. *
  5. * All rights reserved.
  6. *
  7. * Author: Steven Dake (sdake@redhat.com)
  8. *
  9. * This software licensed under BSD license, the text of which follows:
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above copyright notice,
  15. * this list of conditions and the following disclaimer.
  16. * - Redistributions in binary form must reproduce the above copyright notice,
  17. * this list of conditions and the following disclaimer in the documentation
  18. * and/or other materials provided with the distribution.
  19. * - Neither the name of the MontaVista Software, Inc. nor the names of its
  20. * contributors may be used to endorse or promote products derived from this
  21. * software without specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  33. * THE POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. #include <config.h>
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <stdlib.h>
  39. #include <unistd.h>
  40. #include <errno.h>
  41. #include <signal.h>
  42. #include <pthread.h>
  43. #include <limits.h>
  44. #include <sys/types.h>
  45. #include <sys/socket.h>
  46. #include <sys/select.h>
  47. #include <sys/un.h>
  48. #include <corosync/corotypes.h>
  49. #include <corosync/coroipc_types.h>
  50. #include <corosync/coroipcc.h>
  51. #include <corosync/corodefs.h>
  52. #include <corosync/cfg.h>
  53. #include <corosync/mar_gen.h>
  54. #include <corosync/ipc_cfg.h>
  55. #include <corosync/hdb.h>
  56. #include <corosync/totem/totemip.h>
  57. #include "util.h"
  58. /*
  59. * Data structure for instance data
  60. */
  61. struct cfg_instance {
  62. void *ipc_ctx;
  63. corosync_cfg_callbacks_t callbacks;
  64. cs_name_t comp_name;
  65. int comp_registered;
  66. int finalize;
  67. pthread_mutex_t response_mutex;
  68. pthread_mutex_t dispatch_mutex;
  69. };
  70. static void cfg_handle_instance_destructor (void *);
  71. /*
  72. * All instances in one database
  73. */
  74. DECLARE_HDB_DATABASE (cfg_hdb,cfg_handle_instance_destructor);
  75. /*
  76. * Implementation
  77. */
  78. void cfg_handle_instance_destructor (void *instance)
  79. {
  80. struct cfg_instance *cfg_instance = instance;
  81. pthread_mutex_destroy (&cfg_instance->response_mutex);
  82. pthread_mutex_destroy (&cfg_instance->dispatch_mutex);
  83. }
  84. cs_error_t
  85. corosync_cfg_initialize (
  86. corosync_cfg_handle_t *cfg_handle,
  87. const corosync_cfg_callbacks_t *cfg_callbacks)
  88. {
  89. struct cfg_instance *cfg_instance;
  90. cs_error_t error = CS_OK;
  91. error = hdb_error_to_cs (hdb_handle_create (&cfg_hdb, sizeof (struct cfg_instance), cfg_handle));
  92. if (error != CS_OK) {
  93. goto error_no_destroy;
  94. }
  95. error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, *cfg_handle, (void *)&cfg_instance));
  96. if (error != CS_OK) {
  97. goto error_destroy;
  98. }
  99. error = coroipcc_service_connect (
  100. COROSYNC_SOCKET_NAME,
  101. CFG_SERVICE,
  102. IPC_REQUEST_SIZE,
  103. IPC_RESPONSE_SIZE,
  104. IPC_DISPATCH_SIZE,
  105. &cfg_instance->ipc_ctx);
  106. if (error != CS_OK) {
  107. goto error_put_destroy;
  108. }
  109. if (cfg_callbacks) {
  110. memcpy (&cfg_instance->callbacks, cfg_callbacks, sizeof (corosync_cfg_callbacks_t));
  111. }
  112. pthread_mutex_init (&cfg_instance->response_mutex, NULL);
  113. pthread_mutex_init (&cfg_instance->dispatch_mutex, NULL);
  114. (void)hdb_handle_put (&cfg_hdb, *cfg_handle);
  115. return (CS_OK);
  116. error_put_destroy:
  117. (void)hdb_handle_put (&cfg_hdb, *cfg_handle);
  118. error_destroy:
  119. (void)hdb_handle_destroy (&cfg_hdb, *cfg_handle);
  120. error_no_destroy:
  121. return (error);
  122. }
  123. cs_error_t
  124. corosync_cfg_fd_get (
  125. corosync_cfg_handle_t cfg_handle,
  126. int32_t *selection_fd)
  127. {
  128. struct cfg_instance *cfg_instance;
  129. cs_error_t error;
  130. error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_instance));
  131. if (error != CS_OK) {
  132. return (error);
  133. }
  134. *selection_fd = coroipcc_fd_get (cfg_instance->ipc_ctx);
  135. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  136. return (CS_OK);
  137. }
  138. cs_error_t
  139. corosync_cfg_dispatch (
  140. corosync_cfg_handle_t cfg_handle,
  141. cs_dispatch_flags_t dispatch_flags)
  142. {
  143. int timeout = -1;
  144. cs_error_t error;
  145. int cont = 1; /* always continue do loop except when set to 0 */
  146. int dispatch_avail;
  147. struct cfg_instance *cfg_instance;
  148. struct res_lib_cfg_testshutdown *res_lib_cfg_testshutdown;
  149. corosync_cfg_callbacks_t callbacks;
  150. coroipc_response_header_t *dispatch_data;
  151. error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle,
  152. (void *)&cfg_instance));
  153. if (error != CS_OK) {
  154. return (error);
  155. }
  156. /*
  157. * Timeout instantly for CS_DISPATCH_ALL
  158. */
  159. if (dispatch_flags == CS_DISPATCH_ALL) {
  160. timeout = 0;
  161. }
  162. do {
  163. pthread_mutex_lock (&cfg_instance->dispatch_mutex);
  164. dispatch_avail = coroipcc_dispatch_get (
  165. cfg_instance->ipc_ctx,
  166. (void **)&dispatch_data,
  167. timeout);
  168. /*
  169. * Handle has been finalized in another thread
  170. */
  171. if (cfg_instance->finalize == 1) {
  172. error = CS_OK;
  173. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  174. goto error_put;
  175. }
  176. if (dispatch_avail == 0 && dispatch_flags == CS_DISPATCH_ALL) {
  177. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  178. break; /* exit do while cont is 1 loop */
  179. } else
  180. if (dispatch_avail == 0) {
  181. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  182. continue; /* next poll */
  183. }
  184. /*
  185. * Make copy of callbacks, message data, unlock instance, and call callback
  186. * A risk of this dispatch method is that the callback routines may
  187. * operate at the same time that cfgFinalize has been called in another thread.
  188. */
  189. memcpy (&callbacks, &cfg_instance->callbacks, sizeof (corosync_cfg_callbacks_t));
  190. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  191. /*
  192. * Dispatch incoming response
  193. */
  194. switch (dispatch_data->id) {
  195. case MESSAGE_RES_CFG_TESTSHUTDOWN:
  196. if (callbacks.corosync_cfg_shutdown_callback) {
  197. res_lib_cfg_testshutdown = (struct res_lib_cfg_testshutdown *)dispatch_data;
  198. callbacks.corosync_cfg_shutdown_callback(cfg_handle, res_lib_cfg_testshutdown->flags);
  199. }
  200. break;
  201. default:
  202. coroipcc_dispatch_put (cfg_instance->ipc_ctx);
  203. error = CS_ERR_LIBRARY;
  204. goto error_nounlock;
  205. break;
  206. }
  207. coroipcc_dispatch_put (cfg_instance->ipc_ctx);
  208. /*
  209. * Determine if more messages should be processed
  210. */
  211. switch (dispatch_flags) {
  212. case CS_DISPATCH_ONE:
  213. cont = 0;
  214. break;
  215. case CS_DISPATCH_ALL:
  216. break;
  217. case CS_DISPATCH_BLOCKING:
  218. break;
  219. }
  220. } while (cont);
  221. error_put:
  222. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  223. error_nounlock:
  224. return (error);
  225. }
  226. cs_error_t
  227. corosync_cfg_finalize (
  228. corosync_cfg_handle_t cfg_handle)
  229. {
  230. struct cfg_instance *cfg_instance;
  231. cs_error_t error;
  232. error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_instance));
  233. if (error != CS_OK) {
  234. return (error);
  235. }
  236. pthread_mutex_lock (&cfg_instance->dispatch_mutex);
  237. pthread_mutex_lock (&cfg_instance->response_mutex);
  238. /*
  239. * Another thread has already started finalizing
  240. */
  241. if (cfg_instance->finalize) {
  242. pthread_mutex_unlock (&cfg_instance->response_mutex);
  243. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  244. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  245. return (CS_ERR_BAD_HANDLE);
  246. }
  247. cfg_instance->finalize = 1;
  248. coroipcc_service_disconnect (cfg_instance->ipc_ctx);
  249. pthread_mutex_unlock (&cfg_instance->response_mutex);
  250. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  251. pthread_mutex_destroy (&cfg_instance->response_mutex);
  252. pthread_mutex_destroy (&cfg_instance->dispatch_mutex);
  253. (void)hdb_handle_destroy (&cfg_hdb, cfg_handle);
  254. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  255. return (error);
  256. }
  257. cs_error_t
  258. corosync_cfg_ring_status_get (
  259. corosync_cfg_handle_t cfg_handle,
  260. char ***interface_names,
  261. char ***status,
  262. unsigned int *interface_count)
  263. {
  264. struct cfg_instance *cfg_instance;
  265. struct req_lib_cfg_ringstatusget req_lib_cfg_ringstatusget;
  266. struct res_lib_cfg_ringstatusget res_lib_cfg_ringstatusget;
  267. unsigned int i;
  268. cs_error_t error;
  269. struct iovec iov;
  270. error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_instance));
  271. if (error != CS_OK) {
  272. return (error);
  273. }
  274. req_lib_cfg_ringstatusget.header.size = sizeof (struct req_lib_cfg_ringstatusget);
  275. req_lib_cfg_ringstatusget.header.id = MESSAGE_REQ_CFG_RINGSTATUSGET;
  276. iov.iov_base = &req_lib_cfg_ringstatusget,
  277. iov.iov_len = sizeof (struct req_lib_cfg_ringstatusget),
  278. pthread_mutex_lock (&cfg_instance->response_mutex);
  279. error = coroipcc_msg_send_reply_receive(cfg_instance->ipc_ctx,
  280. &iov,
  281. 1,
  282. &res_lib_cfg_ringstatusget,
  283. sizeof (struct res_lib_cfg_ringstatusget));
  284. pthread_mutex_unlock (&cfg_instance->response_mutex);
  285. *interface_count = res_lib_cfg_ringstatusget.interface_count;
  286. *interface_names = malloc (sizeof (char *) * *interface_count);
  287. if (*interface_names == NULL) {
  288. return (CS_ERR_NO_MEMORY);
  289. }
  290. memset (*interface_names, 0, sizeof (char *) * *interface_count);
  291. *status = malloc (sizeof (char *) * *interface_count);
  292. if (*status == NULL) {
  293. error = CS_ERR_NO_MEMORY;
  294. goto error_free_interface_names;
  295. }
  296. memset (*status, 0, sizeof (char *) * *interface_count);
  297. for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) {
  298. (*(interface_names))[i] = strdup (res_lib_cfg_ringstatusget.interface_name[i]);
  299. if ((*(interface_names))[i] == NULL) {
  300. error = CS_ERR_NO_MEMORY;
  301. goto error_free_contents;
  302. }
  303. (*(status))[i] = strdup (res_lib_cfg_ringstatusget.interface_status[i]);
  304. if ((*(status))[i] == NULL) {
  305. error = CS_ERR_NO_MEMORY;
  306. goto error_free_contents;
  307. }
  308. }
  309. goto no_error;
  310. error_free_contents:
  311. for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) {
  312. if ((*(interface_names))[i]) {
  313. free ((*(interface_names))[i]);
  314. }
  315. if ((*(status))[i]) {
  316. free ((*(status))[i]);
  317. }
  318. }
  319. free (*status);
  320. error_free_interface_names:
  321. free (*interface_names);
  322. no_error:
  323. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  324. return (error);
  325. }
  326. cs_error_t
  327. corosync_cfg_ring_reenable (
  328. corosync_cfg_handle_t cfg_handle)
  329. {
  330. struct cfg_instance *cfg_instance;
  331. struct req_lib_cfg_ringreenable req_lib_cfg_ringreenable;
  332. struct res_lib_cfg_ringreenable res_lib_cfg_ringreenable;
  333. cs_error_t error;
  334. struct iovec iov;
  335. error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_instance));
  336. if (error != CS_OK) {
  337. return (error);
  338. }
  339. req_lib_cfg_ringreenable.header.size = sizeof (struct req_lib_cfg_ringreenable);
  340. req_lib_cfg_ringreenable.header.id = MESSAGE_REQ_CFG_RINGREENABLE;
  341. iov.iov_base = &req_lib_cfg_ringreenable,
  342. iov.iov_len = sizeof (struct req_lib_cfg_ringreenable);
  343. pthread_mutex_lock (&cfg_instance->response_mutex);
  344. error = coroipcc_msg_send_reply_receive (cfg_instance->ipc_ctx,
  345. &iov,
  346. 1,
  347. &res_lib_cfg_ringreenable,
  348. sizeof (struct res_lib_cfg_ringreenable));
  349. pthread_mutex_unlock (&cfg_instance->response_mutex);
  350. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  351. return (error);
  352. }
  353. cs_error_t
  354. corosync_cfg_service_load (
  355. corosync_cfg_handle_t cfg_handle,
  356. const char *service_name,
  357. unsigned int service_ver)
  358. {
  359. struct cfg_instance *cfg_instance;
  360. struct req_lib_cfg_serviceload req_lib_cfg_serviceload;
  361. struct res_lib_cfg_serviceload res_lib_cfg_serviceload;
  362. cs_error_t error;
  363. struct iovec iov;
  364. error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_instance));
  365. if (error != CS_OK) {
  366. return (error);
  367. }
  368. req_lib_cfg_serviceload.header.size = sizeof (struct req_lib_cfg_serviceload);
  369. req_lib_cfg_serviceload.header.id = MESSAGE_REQ_CFG_SERVICELOAD;
  370. memset (&req_lib_cfg_serviceload.service_name, 0,
  371. sizeof (req_lib_cfg_serviceload.service_name));
  372. strncpy (req_lib_cfg_serviceload.service_name, service_name,
  373. sizeof (req_lib_cfg_serviceload.service_name) - 1);
  374. req_lib_cfg_serviceload.service_ver = service_ver;
  375. iov.iov_base = &req_lib_cfg_serviceload;
  376. iov.iov_len = sizeof (req_lib_cfg_serviceload);
  377. pthread_mutex_lock (&cfg_instance->response_mutex);
  378. error = coroipcc_msg_send_reply_receive (cfg_instance->ipc_ctx,
  379. &iov,
  380. 1,
  381. &res_lib_cfg_serviceload,
  382. sizeof (struct res_lib_cfg_serviceload));
  383. pthread_mutex_unlock (&cfg_instance->response_mutex);
  384. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  385. return (error);
  386. }
  387. cs_error_t
  388. corosync_cfg_service_unload (
  389. corosync_cfg_handle_t cfg_handle,
  390. const char *service_name,
  391. unsigned int service_ver)
  392. {
  393. struct cfg_instance *cfg_instance;
  394. struct req_lib_cfg_serviceunload req_lib_cfg_serviceunload;
  395. struct res_lib_cfg_serviceunload res_lib_cfg_serviceunload;
  396. cs_error_t error;
  397. struct iovec iov;
  398. error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_instance));
  399. if (error != CS_OK) {
  400. return (error);
  401. }
  402. req_lib_cfg_serviceunload.header.size = sizeof (struct req_lib_cfg_serviceunload);
  403. req_lib_cfg_serviceunload.header.id = MESSAGE_REQ_CFG_SERVICEUNLOAD;
  404. memset (&req_lib_cfg_serviceunload.service_name, 0,
  405. sizeof (req_lib_cfg_serviceunload.service_name));
  406. strncpy (req_lib_cfg_serviceunload.service_name, service_name,
  407. sizeof (req_lib_cfg_serviceunload.service_name) - 1);
  408. req_lib_cfg_serviceunload.service_ver = service_ver;
  409. iov.iov_base = &req_lib_cfg_serviceunload;
  410. iov.iov_len = sizeof (req_lib_cfg_serviceunload);
  411. pthread_mutex_lock (&cfg_instance->response_mutex);
  412. error = coroipcc_msg_send_reply_receive (cfg_instance->ipc_ctx,
  413. &iov,
  414. 1,
  415. &res_lib_cfg_serviceunload,
  416. sizeof (struct res_lib_cfg_serviceunload));
  417. pthread_mutex_unlock (&cfg_instance->response_mutex);
  418. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  419. return (error);
  420. }
  421. cs_error_t
  422. corosync_cfg_state_track (
  423. corosync_cfg_handle_t cfg_handle,
  424. uint8_t track_flags,
  425. const corosync_cfg_state_notification_t *notification_buffer)
  426. {
  427. struct cfg_instance *cfg_instance;
  428. struct req_lib_cfg_statetrack req_lib_cfg_statetrack;
  429. struct res_lib_cfg_statetrack res_lib_cfg_statetrack;
  430. cs_error_t error;
  431. struct iovec iov;
  432. req_lib_cfg_statetrack.header.size = sizeof (struct req_lib_cfg_statetrack);
  433. req_lib_cfg_statetrack.header.id = MESSAGE_REQ_CFG_STATETRACKSTART;
  434. req_lib_cfg_statetrack.track_flags = track_flags;
  435. req_lib_cfg_statetrack.notification_buffer_address = (corosync_cfg_state_notification_t *)notification_buffer;
  436. error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle,
  437. (void *)&cfg_instance));
  438. if (error != CS_OK) {
  439. return (error);
  440. }
  441. iov.iov_base = &req_lib_cfg_statetrack,
  442. iov.iov_len = sizeof (struct req_lib_cfg_statetrack),
  443. pthread_mutex_lock (&cfg_instance->response_mutex);
  444. error = coroipcc_msg_send_reply_receive (cfg_instance->ipc_ctx,
  445. &iov,
  446. 1,
  447. &res_lib_cfg_statetrack,
  448. sizeof (struct res_lib_cfg_statetrack));
  449. pthread_mutex_unlock (&cfg_instance->response_mutex);
  450. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  451. return (error == CS_OK ? res_lib_cfg_statetrack.header.error : error);
  452. }
  453. cs_error_t
  454. corosync_cfg_state_track_stop (
  455. corosync_cfg_handle_t cfg_handle)
  456. {
  457. struct cfg_instance *cfg_instance;
  458. struct req_lib_cfg_statetrackstop req_lib_cfg_statetrackstop;
  459. struct res_lib_cfg_statetrackstop res_lib_cfg_statetrackstop;
  460. cs_error_t error;
  461. struct iovec iov;
  462. error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle,
  463. (void *)&cfg_instance));
  464. if (error != CS_OK) {
  465. return (error);
  466. }
  467. req_lib_cfg_statetrackstop.header.size = sizeof (struct req_lib_cfg_statetrackstop);
  468. req_lib_cfg_statetrackstop.header.id = MESSAGE_REQ_CFG_STATETRACKSTOP;
  469. iov.iov_base = &req_lib_cfg_statetrackstop,
  470. iov.iov_len = sizeof (struct req_lib_cfg_statetrackstop),
  471. pthread_mutex_lock (&cfg_instance->response_mutex);
  472. error = coroipcc_msg_send_reply_receive (cfg_instance->ipc_ctx,
  473. &iov,
  474. 1,
  475. &res_lib_cfg_statetrackstop,
  476. sizeof (struct res_lib_cfg_statetrackstop));
  477. pthread_mutex_unlock (&cfg_instance->response_mutex);
  478. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  479. return (error == CS_OK ? res_lib_cfg_statetrackstop.header.error : error);
  480. }
  481. cs_error_t
  482. corosync_cfg_kill_node (
  483. corosync_cfg_handle_t cfg_handle,
  484. unsigned int nodeid,
  485. const char *reason)
  486. {
  487. struct cfg_instance *cfg_instance;
  488. struct req_lib_cfg_killnode req_lib_cfg_killnode;
  489. struct res_lib_cfg_killnode res_lib_cfg_killnode;
  490. cs_error_t error;
  491. struct iovec iov;
  492. if (strlen(reason) >= CS_MAX_NAME_LENGTH)
  493. return CS_ERR_NAME_TOO_LONG;
  494. error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle,
  495. (void *)&cfg_instance));
  496. if (error != CS_OK) {
  497. return (error);
  498. }
  499. req_lib_cfg_killnode.header.id = MESSAGE_REQ_CFG_KILLNODE;
  500. req_lib_cfg_killnode.header.size = sizeof (struct req_lib_cfg_killnode);
  501. req_lib_cfg_killnode.nodeid = nodeid;
  502. strcpy((char *)req_lib_cfg_killnode.reason.value, reason);
  503. req_lib_cfg_killnode.reason.length = strlen(reason)+1;
  504. iov.iov_base = &req_lib_cfg_killnode;
  505. iov.iov_len = sizeof (struct req_lib_cfg_killnode);
  506. pthread_mutex_lock (&cfg_instance->response_mutex);
  507. error = coroipcc_msg_send_reply_receive (cfg_instance->ipc_ctx,
  508. &iov,
  509. 1,
  510. &res_lib_cfg_killnode,
  511. sizeof (struct res_lib_cfg_killnode));
  512. error = res_lib_cfg_killnode.header.error;
  513. pthread_mutex_unlock (&cfg_instance->response_mutex);
  514. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  515. return (error == CS_OK ? res_lib_cfg_killnode.header.error : error);
  516. }
  517. cs_error_t
  518. corosync_cfg_try_shutdown (
  519. corosync_cfg_handle_t cfg_handle,
  520. corosync_cfg_shutdown_flags_t flags)
  521. {
  522. struct cfg_instance *cfg_instance;
  523. struct req_lib_cfg_tryshutdown req_lib_cfg_tryshutdown;
  524. struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown;
  525. cs_error_t error;
  526. struct iovec iov;
  527. error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle,
  528. (void *)&cfg_instance));
  529. if (error != CS_OK) {
  530. return (error);
  531. }
  532. req_lib_cfg_tryshutdown.header.id = MESSAGE_REQ_CFG_TRYSHUTDOWN;
  533. req_lib_cfg_tryshutdown.header.size = sizeof (struct req_lib_cfg_tryshutdown);
  534. req_lib_cfg_tryshutdown.flags = flags;
  535. iov.iov_base = &req_lib_cfg_tryshutdown;
  536. iov.iov_len = sizeof (req_lib_cfg_tryshutdown);
  537. pthread_mutex_lock (&cfg_instance->response_mutex);
  538. error = coroipcc_msg_send_reply_receive (cfg_instance->ipc_ctx,
  539. &iov,
  540. 1,
  541. &res_lib_cfg_tryshutdown,
  542. sizeof (struct res_lib_cfg_tryshutdown));
  543. pthread_mutex_unlock (&cfg_instance->response_mutex);
  544. (void)hdb_handle_put (&cfg_hdb, cfg_handle);
  545. return (error == CS_OK ? res_lib_cfg_tryshutdown.header.error : error);
  546. }
  547. cs_error_t
  548. corosync_cfg_replyto_shutdown (
  549. corosync_cfg_handle_t cfg_handle,
  550. corosync_cfg_shutdown_reply_flags_t response)
  551. {
  552. struct cfg_instance *cfg_instance;
  553. struct req_lib_cfg_replytoshutdown req_lib_cfg_replytoshutdown;
  554. struct res_lib_cfg_replytoshutdown res_lib_cfg_replytoshutdown;
  555. struct iovec iov;
  556. cs_error_t error;
  557. error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle,
  558. (void *)&cfg_instance));
  559. if (error != CS_OK) {
  560. return (error);
  561. }
  562. req_lib_cfg_replytoshutdown.header.id = MESSAGE_REQ_CFG_REPLYTOSHUTDOWN;
  563. req_lib_cfg_replytoshutdown.header.size = sizeof (struct req_lib_cfg_replytoshutdown);
  564. req_lib_cfg_replytoshutdown.response = response;
  565. iov.iov_base = &req_lib_cfg_replytoshutdown;
  566. iov.iov_len = sizeof (struct req_lib_cfg_replytoshutdown);
  567. pthread_mutex_lock (&cfg_instance->response_mutex);
  568. error = coroipcc_msg_send_reply_receive (cfg_instance->ipc_ctx,
  569. &iov,
  570. 1,
  571. &res_lib_cfg_replytoshutdown,
  572. sizeof (struct res_lib_cfg_replytoshutdown));
  573. pthread_mutex_unlock (&cfg_instance->response_mutex);
  574. return (error);
  575. }
  576. cs_error_t corosync_cfg_get_node_addrs (
  577. corosync_cfg_handle_t cfg_handle,
  578. int nodeid,
  579. size_t max_addrs,
  580. int *num_addrs,
  581. corosync_cfg_node_address_t *addrs)
  582. {
  583. cs_error_t error;
  584. struct req_lib_cfg_get_node_addrs req_lib_cfg_get_node_addrs;
  585. struct res_lib_cfg_get_node_addrs *res_lib_cfg_get_node_addrs;
  586. struct cfg_instance *cfg_instance;
  587. int addrlen;
  588. int i;
  589. struct iovec iov;
  590. void *return_address;
  591. error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle,
  592. (void *)&cfg_instance));
  593. if (error != CS_OK) {
  594. return (error);
  595. }
  596. req_lib_cfg_get_node_addrs.header.size = sizeof (req_lib_cfg_get_node_addrs);
  597. req_lib_cfg_get_node_addrs.header.id = MESSAGE_REQ_CFG_GET_NODE_ADDRS;
  598. req_lib_cfg_get_node_addrs.nodeid = nodeid;
  599. iov.iov_base = (char *)&req_lib_cfg_get_node_addrs;
  600. iov.iov_len = sizeof (req_lib_cfg_get_node_addrs);
  601. pthread_mutex_lock (&cfg_instance->response_mutex);
  602. error = coroipcc_msg_send_reply_receive_in_buf (cfg_instance->ipc_ctx,
  603. &iov,
  604. 1,
  605. &return_address);
  606. res_lib_cfg_get_node_addrs = return_address;
  607. pthread_mutex_unlock (&cfg_instance->response_mutex);
  608. if (error != CS_OK) {
  609. goto error_exit;
  610. }
  611. if (res_lib_cfg_get_node_addrs->family == AF_INET)
  612. addrlen = sizeof(struct sockaddr_in);
  613. if (res_lib_cfg_get_node_addrs->family == AF_INET6)
  614. addrlen = sizeof(struct sockaddr_in6);
  615. for (i=0; i<max_addrs && i<res_lib_cfg_get_node_addrs->num_addrs; i++) {
  616. struct sockaddr_in *in;
  617. struct sockaddr_in6 *in6;
  618. addrs[i].address_length = addrlen;
  619. if (res_lib_cfg_get_node_addrs->family == AF_INET) {
  620. in = (struct sockaddr_in *)addrs[i].address;
  621. in->sin_family = AF_INET;
  622. memcpy(&in->sin_addr, &res_lib_cfg_get_node_addrs->addrs[i][0], sizeof(struct in_addr));
  623. }
  624. if (res_lib_cfg_get_node_addrs->family == AF_INET6) {
  625. in6 = (struct sockaddr_in6 *)addrs[i].address;
  626. in6->sin6_family = AF_INET6;
  627. memcpy(&in6->sin6_addr, &res_lib_cfg_get_node_addrs->addrs[i][0], sizeof(struct in6_addr));
  628. }
  629. }
  630. *num_addrs = res_lib_cfg_get_node_addrs->num_addrs;
  631. errno = error = res_lib_cfg_get_node_addrs->header.error;
  632. error_exit:
  633. return (error);
  634. }
  635. cs_error_t corosync_cfg_local_get (
  636. corosync_cfg_handle_t handle,
  637. unsigned int *local_nodeid)
  638. {
  639. cs_error_t error;
  640. struct cfg_instance *cfg_inst;
  641. struct iovec iov;
  642. struct req_lib_cfg_local_get req_lib_cfg_local_get;
  643. struct res_lib_cfg_local_get res_lib_cfg_local_get;
  644. error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, handle, (void *)&cfg_inst));
  645. if (error != CS_OK) {
  646. return (error);
  647. }
  648. req_lib_cfg_local_get.header.size = sizeof (coroipc_request_header_t);
  649. req_lib_cfg_local_get.header.id = MESSAGE_REQ_CFG_LOCAL_GET;
  650. iov.iov_base = &req_lib_cfg_local_get;
  651. iov.iov_len = sizeof (struct req_lib_cfg_local_get);
  652. pthread_mutex_lock (&cfg_inst->response_mutex);
  653. error = coroipcc_msg_send_reply_receive (
  654. cfg_inst->ipc_ctx,
  655. &iov,
  656. 1,
  657. &res_lib_cfg_local_get,
  658. sizeof (struct res_lib_cfg_local_get));
  659. pthread_mutex_unlock (&cfg_inst->response_mutex);
  660. if (error != CS_OK) {
  661. goto error_exit;
  662. }
  663. error = res_lib_cfg_local_get.header.error;
  664. *local_nodeid = res_lib_cfg_local_get.local_nodeid;
  665. error_exit:
  666. (void)hdb_handle_put (&cfg_hdb, handle);
  667. return (error);
  668. }