cfg.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  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 <stdio.h>
  36. #include <string.h>
  37. #include <stdlib.h>
  38. #include <unistd.h>
  39. #include <errno.h>
  40. #include <signal.h>
  41. #include <pthread.h>
  42. #include <limits.h>
  43. #include <sys/types.h>
  44. #include <sys/socket.h>
  45. #include <sys/select.h>
  46. #include <sys/un.h>
  47. #include <corosync/corotypes.h>
  48. #include <corosync/cfg.h>
  49. #include <corosync/totem/totemip.h>
  50. #include <corosync/mar_gen.h>
  51. #include <corosync/ipc_gen.h>
  52. #include <corosync/ipc_cfg.h>
  53. #include <corosync/coroipc.h>
  54. struct cfg_res_overlay {
  55. mar_res_header_t header;
  56. char data[4096];
  57. };
  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. static struct saHandleDatabase cfg_hdb = {
  75. .handleCount = 0,
  76. .handles = 0,
  77. .mutex = PTHREAD_MUTEX_INITIALIZER,
  78. .handleInstanceDestructor = cfg_handle_instance_destructor
  79. };
  80. /*
  81. * Implementation
  82. */
  83. void cfg_handle_instance_destructor (void *instance)
  84. {
  85. struct cfg_instance *cfg_instance = instance;
  86. pthread_mutex_destroy (&cfg_instance->response_mutex);
  87. pthread_mutex_destroy (&cfg_instance->dispatch_mutex);
  88. }
  89. cs_error_t
  90. corosync_cfg_initialize (
  91. corosync_cfg_handle_t *cfg_handle,
  92. const corosync_cfg_callbacks_t *cfg_callbacks)
  93. {
  94. struct cfg_instance *cfg_instance;
  95. cs_error_t error = CS_OK;
  96. error = saHandleCreate (&cfg_hdb, sizeof (struct cfg_instance), cfg_handle);
  97. if (error != CS_OK) {
  98. goto error_no_destroy;
  99. }
  100. error = saHandleInstanceGet (&cfg_hdb, *cfg_handle, (void *)&cfg_instance);
  101. if (error != CS_OK) {
  102. goto error_destroy;
  103. }
  104. error = cslib_service_connect (CFG_SERVICE, &cfg_instance->ipc_ctx);
  105. if (error != CS_OK) {
  106. goto error_put_destroy;
  107. }
  108. if (cfg_callbacks) {
  109. memcpy (&cfg_instance->callbacks, cfg_callbacks, sizeof (corosync_cfg_callbacks_t));
  110. }
  111. pthread_mutex_init (&cfg_instance->response_mutex, NULL);
  112. pthread_mutex_init (&cfg_instance->dispatch_mutex, NULL);
  113. (void)saHandleInstancePut (&cfg_hdb, *cfg_handle);
  114. return (CS_OK);
  115. error_put_destroy:
  116. (void)saHandleInstancePut (&cfg_hdb, *cfg_handle);
  117. error_destroy:
  118. (void)saHandleDestroy (&cfg_hdb, *cfg_handle);
  119. error_no_destroy:
  120. return (error);
  121. }
  122. cs_error_t
  123. corosync_cfg_fd_get (
  124. corosync_cfg_handle_t cfg_handle,
  125. int32_t *selection_fd)
  126. {
  127. struct cfg_instance *cfg_instance;
  128. cs_error_t error;
  129. error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
  130. if (error != CS_OK) {
  131. return (error);
  132. }
  133. *selection_fd = cslib_fd_get (cfg_instance->ipc_ctx);
  134. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  135. return (CS_OK);
  136. }
  137. cs_error_t
  138. corosync_cfg_dispatch (
  139. corosync_cfg_handle_t cfg_handle,
  140. cs_dispatch_flags_t dispatch_flags)
  141. {
  142. int timeout = -1;
  143. cs_error_t error;
  144. int cont = 1; /* always continue do loop except when set to 0 */
  145. int dispatch_avail;
  146. struct cfg_instance *cfg_instance;
  147. struct res_lib_cfg_testshutdown *res_lib_cfg_testshutdown;
  148. #ifdef COMPILE_OUT
  149. struct res_lib_corosync_healthcheckcallback *res_lib_corosync_healthcheckcallback;
  150. struct res_lib_corosync_readinessstatesetcallback *res_lib_corosync_readinessstatesetcallback;
  151. struct res_lib_corosync_csisetcallback *res_lib_corosync_csisetcallback;
  152. struct res_lib_corosync_csiremovecallback *res_lib_corosync_csiremovecallback;
  153. struct res_lib_cfg_statetrackcallback *res_lib_cfg_statetrackcallback;
  154. #endif
  155. corosync_cfg_callbacks_t callbacks;
  156. struct cfg_res_overlay dispatch_data;
  157. error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
  158. (void *)&cfg_instance);
  159. if (error != CS_OK) {
  160. return (error);
  161. }
  162. /*
  163. * Timeout instantly for CS_DISPATCH_ALL
  164. */
  165. if (dispatch_flags == CS_DISPATCH_ALL) {
  166. timeout = 0;
  167. }
  168. do {
  169. dispatch_avail = cslib_dispatch_recv (cfg_instance->ipc_ctx,
  170. (void *)&dispatch_data, timeout);
  171. /*
  172. * Handle has been finalized in another thread
  173. */
  174. if (cfg_instance->finalize == 1) {
  175. error = CS_OK;
  176. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  177. goto error_unlock;
  178. }
  179. if (dispatch_avail == 0 && dispatch_flags == CS_DISPATCH_ALL) {
  180. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  181. break; /* exit do while cont is 1 loop */
  182. } else
  183. if (dispatch_avail == 0) {
  184. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  185. continue; /* next poll */
  186. }
  187. /*
  188. * Make copy of callbacks, message data, unlock instance, and call callback
  189. * A risk of this dispatch method is that the callback routines may
  190. * operate at the same time that cfgFinalize has been called in another thread.
  191. */
  192. memcpy (&callbacks, &cfg_instance->callbacks, sizeof (corosync_cfg_callbacks_t));
  193. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  194. /*
  195. * Dispatch incoming response
  196. */
  197. switch (dispatch_data.header.id) {
  198. case MESSAGE_RES_CFG_TESTSHUTDOWN:
  199. if (callbacks.corosync_cfg_shutdown_callback) {
  200. res_lib_cfg_testshutdown = (struct res_lib_cfg_testshutdown *)&dispatch_data;
  201. callbacks.corosync_cfg_shutdown_callback(cfg_handle, res_lib_cfg_testshutdown->flags);
  202. }
  203. break;
  204. default:
  205. error = CS_ERR_LIBRARY;
  206. goto error_nounlock;
  207. break;
  208. }
  209. /*
  210. * Determine if more messages should be processed
  211. */
  212. switch (dispatch_flags) {
  213. case CS_DISPATCH_ONE:
  214. cont = 0;
  215. break;
  216. case CS_DISPATCH_ALL:
  217. break;
  218. case CS_DISPATCH_BLOCKING:
  219. break;
  220. }
  221. } while (cont);
  222. error_unlock:
  223. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  224. error_nounlock:
  225. return (error);
  226. }
  227. cs_error_t
  228. corosync_cfg_finalize (
  229. corosync_cfg_handle_t cfg_handle)
  230. {
  231. struct cfg_instance *cfg_instance;
  232. cs_error_t error;
  233. error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
  234. if (error != CS_OK) {
  235. return (error);
  236. }
  237. pthread_mutex_lock (&cfg_instance->dispatch_mutex);
  238. pthread_mutex_lock (&cfg_instance->response_mutex);
  239. /*
  240. * Another thread has already started finalizing
  241. */
  242. if (cfg_instance->finalize) {
  243. pthread_mutex_unlock (&cfg_instance->response_mutex);
  244. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  245. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  246. return (CS_ERR_BAD_HANDLE);
  247. }
  248. cfg_instance->finalize = 1;
  249. cslib_service_disconnect (cfg_instance->ipc_ctx);
  250. pthread_mutex_unlock (&cfg_instance->response_mutex);
  251. pthread_mutex_unlock (&cfg_instance->dispatch_mutex);
  252. pthread_mutex_destroy (&cfg_instance->response_mutex);
  253. pthread_mutex_destroy (&cfg_instance->dispatch_mutex);
  254. (void)saHandleDestroy (&cfg_hdb, cfg_handle);
  255. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  256. return (error);
  257. }
  258. cs_error_t
  259. corosync_cfg_ring_status_get (
  260. corosync_cfg_handle_t cfg_handle,
  261. char ***interface_names,
  262. char ***status,
  263. unsigned int *interface_count)
  264. {
  265. struct cfg_instance *cfg_instance;
  266. struct req_lib_cfg_ringstatusget req_lib_cfg_ringstatusget;
  267. struct res_lib_cfg_ringstatusget res_lib_cfg_ringstatusget;
  268. unsigned int i;
  269. cs_error_t error;
  270. struct iovec iov;
  271. error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
  272. if (error != CS_OK) {
  273. return (error);
  274. }
  275. req_lib_cfg_ringstatusget.header.size = sizeof (struct req_lib_cfg_ringstatusget);
  276. req_lib_cfg_ringstatusget.header.id = MESSAGE_REQ_CFG_RINGSTATUSGET;
  277. iov.iov_base = &req_lib_cfg_ringstatusget,
  278. iov.iov_len = sizeof (struct req_lib_cfg_ringstatusget),
  279. pthread_mutex_lock (&cfg_instance->response_mutex);
  280. error = cslib_msg_send_reply_receive(cfg_instance->ipc_ctx,
  281. &iov,
  282. 1,
  283. &res_lib_cfg_ringstatusget,
  284. sizeof (struct res_lib_cfg_ringstatusget));
  285. pthread_mutex_unlock (&cfg_instance->response_mutex);
  286. *interface_count = res_lib_cfg_ringstatusget.interface_count;
  287. *interface_names = malloc (sizeof (char *) * *interface_count);
  288. if (*interface_names == NULL) {
  289. return (CS_ERR_NO_MEMORY);
  290. }
  291. memset (*interface_names, 0, sizeof (char *) * *interface_count);
  292. *status = malloc (sizeof (char *) * *interface_count);
  293. if (*status == NULL) {
  294. error = CS_ERR_NO_MEMORY;
  295. goto error_free_interface_names;
  296. }
  297. memset (*status, 0, sizeof (char *) * *interface_count);
  298. for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) {
  299. (*(interface_names))[i] = strdup (res_lib_cfg_ringstatusget.interface_name[i]);
  300. if ((*(interface_names))[i] == NULL) {
  301. error = CS_ERR_NO_MEMORY;
  302. goto error_free_contents;
  303. }
  304. (*(status))[i] = strdup (res_lib_cfg_ringstatusget.interface_status[i]);
  305. if ((*(status))[i] == NULL) {
  306. error = CS_ERR_NO_MEMORY;
  307. goto error_free_contents;
  308. }
  309. }
  310. goto no_error;
  311. error_free_contents:
  312. for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) {
  313. if ((*(interface_names))[i]) {
  314. free ((*(interface_names))[i]);
  315. }
  316. if ((*(status))[i]) {
  317. free ((*(status))[i]);
  318. }
  319. }
  320. free (*status);
  321. error_free_interface_names:
  322. free (*interface_names);
  323. no_error:
  324. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  325. return (error);
  326. }
  327. cs_error_t
  328. corosync_cfg_ring_reenable (
  329. corosync_cfg_handle_t cfg_handle)
  330. {
  331. struct cfg_instance *cfg_instance;
  332. struct req_lib_cfg_ringreenable req_lib_cfg_ringreenable;
  333. struct res_lib_cfg_ringreenable res_lib_cfg_ringreenable;
  334. cs_error_t error;
  335. struct iovec iov;
  336. error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
  337. if (error != CS_OK) {
  338. return (error);
  339. }
  340. req_lib_cfg_ringreenable.header.size = sizeof (struct req_lib_cfg_ringreenable);
  341. req_lib_cfg_ringreenable.header.id = MESSAGE_REQ_CFG_RINGREENABLE;
  342. iov.iov_base = &req_lib_cfg_ringreenable,
  343. iov.iov_len = sizeof (struct req_lib_cfg_ringreenable);
  344. pthread_mutex_lock (&cfg_instance->response_mutex);
  345. error = cslib_msg_send_reply_receive (cfg_instance->ipc_ctx,
  346. &iov,
  347. 1,
  348. &res_lib_cfg_ringreenable,
  349. sizeof (struct res_lib_cfg_ringreenable));
  350. pthread_mutex_unlock (&cfg_instance->response_mutex);
  351. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  352. return (error);
  353. }
  354. cs_error_t
  355. corosync_cfg_service_load (
  356. corosync_cfg_handle_t cfg_handle,
  357. char *service_name,
  358. unsigned int service_ver)
  359. {
  360. struct cfg_instance *cfg_instance;
  361. struct req_lib_cfg_serviceload req_lib_cfg_serviceload;
  362. struct res_lib_cfg_serviceload res_lib_cfg_serviceload;
  363. cs_error_t error;
  364. struct iovec iov;
  365. error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
  366. if (error != CS_OK) {
  367. return (error);
  368. }
  369. req_lib_cfg_serviceload.header.size = sizeof (struct req_lib_cfg_serviceload);
  370. req_lib_cfg_serviceload.header.id = MESSAGE_REQ_CFG_SERVICELOAD;
  371. memset (&req_lib_cfg_serviceload.service_name, 0,
  372. sizeof (req_lib_cfg_serviceload.service_name));
  373. strncpy (req_lib_cfg_serviceload.service_name, service_name,
  374. sizeof (req_lib_cfg_serviceload.service_name) - 1);
  375. req_lib_cfg_serviceload.service_ver = service_ver;
  376. iov.iov_base = &req_lib_cfg_serviceload;
  377. iov.iov_len = sizeof (req_lib_cfg_serviceload);
  378. pthread_mutex_lock (&cfg_instance->response_mutex);
  379. error = cslib_msg_send_reply_receive (cfg_instance->ipc_ctx,
  380. &iov,
  381. 1,
  382. &res_lib_cfg_serviceload,
  383. sizeof (struct res_lib_cfg_serviceload));
  384. pthread_mutex_unlock (&cfg_instance->response_mutex);
  385. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  386. return (error);
  387. }
  388. cs_error_t
  389. corosync_cfg_service_unload (
  390. corosync_cfg_handle_t cfg_handle,
  391. char *service_name,
  392. unsigned int service_ver)
  393. {
  394. struct cfg_instance *cfg_instance;
  395. struct req_lib_cfg_serviceunload req_lib_cfg_serviceunload;
  396. struct res_lib_cfg_serviceunload res_lib_cfg_serviceunload;
  397. cs_error_t error;
  398. struct iovec iov;
  399. error = saHandleInstanceGet (&cfg_hdb, cfg_handle, (void *)&cfg_instance);
  400. if (error != CS_OK) {
  401. return (error);
  402. }
  403. req_lib_cfg_serviceunload.header.size = sizeof (struct req_lib_cfg_serviceunload);
  404. req_lib_cfg_serviceunload.header.id = MESSAGE_REQ_CFG_SERVICEUNLOAD;
  405. memset (&req_lib_cfg_serviceunload.service_name, 0,
  406. sizeof (req_lib_cfg_serviceunload.service_name));
  407. strncpy (req_lib_cfg_serviceunload.service_name, service_name,
  408. sizeof (req_lib_cfg_serviceunload.service_name) - 1);
  409. req_lib_cfg_serviceunload.service_ver = service_ver;
  410. iov.iov_base = &req_lib_cfg_serviceunload;
  411. iov.iov_len = sizeof (req_lib_cfg_serviceunload);
  412. pthread_mutex_lock (&cfg_instance->response_mutex);
  413. error = cslib_msg_send_reply_receive (cfg_instance->ipc_ctx,
  414. &iov,
  415. 1,
  416. &res_lib_cfg_serviceunload,
  417. sizeof (struct res_lib_cfg_serviceunload));
  418. pthread_mutex_unlock (&cfg_instance->response_mutex);
  419. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  420. return (error);
  421. }
  422. cs_error_t
  423. corosync_cfg_state_track (
  424. corosync_cfg_handle_t cfg_handle,
  425. uint8_t track_flags,
  426. const corosync_cfg_state_notification_t *notification_buffer)
  427. {
  428. struct cfg_instance *cfg_instance;
  429. struct req_lib_cfg_statetrack req_lib_cfg_statetrack;
  430. struct res_lib_cfg_statetrack res_lib_cfg_statetrack;
  431. cs_error_t error;
  432. struct iovec iov;
  433. req_lib_cfg_statetrack.header.size = sizeof (struct req_lib_cfg_statetrack);
  434. req_lib_cfg_statetrack.header.id = MESSAGE_REQ_CFG_STATETRACKSTART;
  435. req_lib_cfg_statetrack.track_flags = track_flags;
  436. req_lib_cfg_statetrack.notification_buffer_address = (corosync_cfg_state_notification_t *)notification_buffer;
  437. error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
  438. (void *)&cfg_instance);
  439. if (error != CS_OK) {
  440. return (error);
  441. }
  442. iov.iov_base = &req_lib_cfg_statetrack,
  443. iov.iov_len = sizeof (struct req_lib_cfg_statetrack),
  444. pthread_mutex_lock (&cfg_instance->response_mutex);
  445. error = cslib_msg_send_reply_receive (cfg_instance->ipc_ctx,
  446. &iov,
  447. 1,
  448. &res_lib_cfg_statetrack,
  449. sizeof (struct res_lib_cfg_statetrack));
  450. pthread_mutex_unlock (&cfg_instance->response_mutex);
  451. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  452. return (error == CS_OK ? res_lib_cfg_statetrack.header.error : error);
  453. }
  454. cs_error_t
  455. corosync_cfg_state_track_stop (
  456. corosync_cfg_handle_t cfg_handle)
  457. {
  458. struct cfg_instance *cfg_instance;
  459. struct req_lib_cfg_statetrackstop req_lib_cfg_statetrackstop;
  460. struct res_lib_cfg_statetrackstop res_lib_cfg_statetrackstop;
  461. cs_error_t error;
  462. struct iovec iov;
  463. error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
  464. (void *)&cfg_instance);
  465. if (error != CS_OK) {
  466. return (error);
  467. }
  468. req_lib_cfg_statetrackstop.header.size = sizeof (struct req_lib_cfg_statetrackstop);
  469. req_lib_cfg_statetrackstop.header.id = MESSAGE_REQ_CFG_STATETRACKSTOP;
  470. iov.iov_base = &req_lib_cfg_statetrackstop,
  471. iov.iov_len = sizeof (struct req_lib_cfg_statetrackstop),
  472. pthread_mutex_lock (&cfg_instance->response_mutex);
  473. error = cslib_msg_send_reply_receive (cfg_instance->ipc_ctx,
  474. &iov,
  475. 1,
  476. &res_lib_cfg_statetrackstop,
  477. sizeof (struct res_lib_cfg_statetrackstop));
  478. pthread_mutex_unlock (&cfg_instance->response_mutex);
  479. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  480. return (error == CS_OK ? res_lib_cfg_statetrackstop.header.error : error);
  481. }
  482. cs_error_t
  483. corosync_cfg_admin_state_get (
  484. corosync_cfg_handle_t cfg_handle,
  485. corosync_cfg_administrative_target_t administrative_target,
  486. corosync_cfg_administrative_state_t *administrative_state)
  487. {
  488. struct cfg_instance *cfg_instance;
  489. struct req_lib_cfg_administrativestateget req_lib_cfg_administrativestateget;
  490. struct res_lib_cfg_administrativestateget res_lib_cfg_administrativestateget;
  491. cs_error_t error;
  492. struct iovec iov;
  493. error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
  494. (void *)&cfg_instance);
  495. if (error != CS_OK) {
  496. return (error);
  497. }
  498. req_lib_cfg_administrativestateget.header.id = MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET;
  499. req_lib_cfg_administrativestateget.header.size = sizeof (struct req_lib_cfg_administrativestateget);
  500. req_lib_cfg_administrativestateget.administrative_target = administrative_target;
  501. pthread_mutex_lock (&cfg_instance->response_mutex);
  502. iov.iov_base = &req_lib_cfg_administrativestateget,
  503. iov.iov_len = sizeof (struct req_lib_cfg_administrativestateget),
  504. pthread_mutex_lock (&cfg_instance->response_mutex);
  505. error = cslib_msg_send_reply_receive (cfg_instance->ipc_ctx,
  506. &iov,
  507. 1,
  508. &res_lib_cfg_administrativestateget,
  509. sizeof (struct res_lib_cfg_administrativestateget));
  510. error = res_lib_cfg_administrativestateget.header.error;
  511. pthread_mutex_unlock (&cfg_instance->response_mutex);
  512. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  513. return (error == CS_OK ? res_lib_cfg_administrativestateget.header.error : error);
  514. }
  515. cs_error_t
  516. corosync_cfg_admin_state_set (
  517. corosync_cfg_handle_t cfg_handle,
  518. corosync_cfg_administrative_target_t administrative_target,
  519. corosync_cfg_administrative_state_t administrative_state)
  520. {
  521. struct cfg_instance *cfg_instance;
  522. struct req_lib_cfg_administrativestateset req_lib_cfg_administrativestateset;
  523. struct res_lib_cfg_administrativestateset res_lib_cfg_administrativestateset;
  524. cs_error_t error;
  525. struct iovec iov;
  526. error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
  527. (void *)&cfg_instance);
  528. if (error != CS_OK) {
  529. return (error);
  530. }
  531. req_lib_cfg_administrativestateset.header.id = MESSAGE_REQ_CFG_ADMINISTRATIVESTATEGET;
  532. req_lib_cfg_administrativestateset.header.size = sizeof (struct req_lib_cfg_administrativestateset);
  533. req_lib_cfg_administrativestateset.administrative_target = administrative_target;
  534. req_lib_cfg_administrativestateset.administrative_state = administrative_state;
  535. pthread_mutex_lock (&cfg_instance->response_mutex);
  536. iov.iov_base = &req_lib_cfg_administrativestateset,
  537. iov.iov_len = sizeof (struct req_lib_cfg_administrativestateset),
  538. pthread_mutex_lock (&cfg_instance->response_mutex);
  539. error = cslib_msg_send_reply_receive (cfg_instance->ipc_ctx,
  540. &iov,
  541. 1,
  542. &res_lib_cfg_administrativestateset,
  543. sizeof (struct res_lib_cfg_administrativestateset));
  544. error = res_lib_cfg_administrativestateset.header.error;
  545. pthread_mutex_unlock (&cfg_instance->response_mutex);
  546. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  547. return (error == CS_OK ? res_lib_cfg_administrativestateset.header.error : error);
  548. }
  549. cs_error_t
  550. corosync_cfg_kill_node (
  551. corosync_cfg_handle_t cfg_handle,
  552. unsigned int nodeid,
  553. char *reason)
  554. {
  555. struct cfg_instance *cfg_instance;
  556. struct req_lib_cfg_killnode req_lib_cfg_killnode;
  557. struct res_lib_cfg_killnode res_lib_cfg_killnode;
  558. cs_error_t error;
  559. struct iovec iov;
  560. if (strlen(reason) >= CS_MAX_NAME_LENGTH)
  561. return CS_ERR_NAME_TOO_LONG;
  562. error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
  563. (void *)&cfg_instance);
  564. if (error != CS_OK) {
  565. return (error);
  566. }
  567. req_lib_cfg_killnode.header.id = MESSAGE_REQ_CFG_KILLNODE;
  568. req_lib_cfg_killnode.header.size = sizeof (struct req_lib_cfg_killnode);
  569. req_lib_cfg_killnode.nodeid = nodeid;
  570. strcpy((char *)req_lib_cfg_killnode.reason.value, reason);
  571. req_lib_cfg_killnode.reason.length = strlen(reason)+1;
  572. iov.iov_base = &req_lib_cfg_killnode;
  573. iov.iov_len = sizeof (struct req_lib_cfg_killnode);
  574. pthread_mutex_lock (&cfg_instance->response_mutex);
  575. error = cslib_msg_send_reply_receive (cfg_instance->ipc_ctx,
  576. &iov,
  577. 1,
  578. &res_lib_cfg_killnode,
  579. sizeof (struct res_lib_cfg_killnode));
  580. error = res_lib_cfg_killnode.header.error;
  581. pthread_mutex_unlock (&cfg_instance->response_mutex);
  582. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  583. return (error == CS_OK ? res_lib_cfg_killnode.header.error : error);
  584. }
  585. cs_error_t
  586. corosync_cfg_try_shutdown (
  587. corosync_cfg_handle_t cfg_handle,
  588. corosync_cfg_shutdown_flags_t flags)
  589. {
  590. struct cfg_instance *cfg_instance;
  591. struct req_lib_cfg_tryshutdown req_lib_cfg_tryshutdown;
  592. struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown;
  593. cs_error_t error;
  594. struct iovec iov;
  595. error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
  596. (void *)&cfg_instance);
  597. if (error != CS_OK) {
  598. return (error);
  599. }
  600. req_lib_cfg_tryshutdown.header.id = MESSAGE_REQ_CFG_TRYSHUTDOWN;
  601. req_lib_cfg_tryshutdown.header.size = sizeof (struct req_lib_cfg_tryshutdown);
  602. req_lib_cfg_tryshutdown.flags = flags;
  603. iov.iov_base = &req_lib_cfg_tryshutdown;
  604. iov.iov_len = sizeof (req_lib_cfg_tryshutdown);
  605. pthread_mutex_lock (&cfg_instance->response_mutex);
  606. error = cslib_msg_send_reply_receive (cfg_instance->ipc_ctx,
  607. &iov,
  608. 1,
  609. &res_lib_cfg_tryshutdown,
  610. sizeof (struct res_lib_cfg_tryshutdown));
  611. pthread_mutex_unlock (&cfg_instance->response_mutex);
  612. (void)saHandleInstancePut (&cfg_hdb, cfg_handle);
  613. return (error == CS_OK ? res_lib_cfg_tryshutdown.header.error : error);
  614. }
  615. cs_error_t
  616. corosync_cfg_replyto_shutdown (
  617. corosync_cfg_handle_t cfg_handle,
  618. corosync_cfg_shutdown_reply_flags_t response)
  619. {
  620. struct cfg_instance *cfg_instance;
  621. struct req_lib_cfg_replytoshutdown req_lib_cfg_replytoshutdown;
  622. struct res_lib_cfg_replytoshutdown res_lib_cfg_replytoshutdown;
  623. struct iovec iov;
  624. cs_error_t error;
  625. error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
  626. (void *)&cfg_instance);
  627. if (error != CS_OK) {
  628. return (error);
  629. }
  630. req_lib_cfg_replytoshutdown.header.id = MESSAGE_REQ_CFG_REPLYTOSHUTDOWN;
  631. req_lib_cfg_replytoshutdown.header.size = sizeof (struct req_lib_cfg_replytoshutdown);
  632. req_lib_cfg_replytoshutdown.response = response;
  633. iov.iov_base = &req_lib_cfg_replytoshutdown;
  634. iov.iov_len = sizeof (struct req_lib_cfg_replytoshutdown);
  635. pthread_mutex_lock (&cfg_instance->response_mutex);
  636. error = cslib_msg_send_reply_receive (cfg_instance->ipc_ctx,
  637. &iov,
  638. 1,
  639. &res_lib_cfg_replytoshutdown,
  640. sizeof (struct res_lib_cfg_replytoshutdown));
  641. pthread_mutex_unlock (&cfg_instance->response_mutex);
  642. return (error);
  643. }
  644. cs_error_t corosync_cfg_get_node_addrs (
  645. corosync_cfg_handle_t cfg_handle,
  646. int nodeid,
  647. int max_addrs,
  648. int *num_addrs,
  649. corosync_cfg_node_address_t *addrs)
  650. {
  651. cs_error_t error;
  652. struct req_lib_cfg_get_node_addrs req_lib_cfg_get_node_addrs;
  653. struct res_lib_cfg_get_node_addrs *res_lib_cfg_get_node_addrs;
  654. struct cfg_instance *cfg_instance;
  655. int addrlen;
  656. int i;
  657. struct iovec iov;
  658. void *return_address;
  659. error = saHandleInstanceGet (&cfg_hdb, cfg_handle,
  660. (void *)&cfg_instance);
  661. if (error != CS_OK) {
  662. return (error);
  663. }
  664. req_lib_cfg_get_node_addrs.header.size = sizeof (req_lib_cfg_get_node_addrs);
  665. req_lib_cfg_get_node_addrs.header.id = MESSAGE_REQ_CFG_GET_NODE_ADDRS;
  666. req_lib_cfg_get_node_addrs.nodeid = nodeid;
  667. iov.iov_base = (char *)&req_lib_cfg_get_node_addrs;
  668. iov.iov_len = sizeof (req_lib_cfg_get_node_addrs);
  669. pthread_mutex_lock (&cfg_instance->response_mutex);
  670. error = cslib_msg_send_reply_receive_in_buf (cfg_instance->ipc_ctx,
  671. &iov,
  672. 1,
  673. &return_address);
  674. res_lib_cfg_get_node_addrs = return_address;
  675. pthread_mutex_unlock (&cfg_instance->response_mutex);
  676. if (error != CS_OK) {
  677. goto error_exit;
  678. }
  679. if (res_lib_cfg_get_node_addrs->family == AF_INET)
  680. addrlen = sizeof(struct sockaddr_in);
  681. if (res_lib_cfg_get_node_addrs->family == AF_INET6)
  682. addrlen = sizeof(struct sockaddr_in6);
  683. for (i=0; i<max_addrs && i<res_lib_cfg_get_node_addrs->num_addrs; i++) {
  684. addrs[i].address_length = addrlen;
  685. struct sockaddr_in *in;
  686. struct sockaddr_in6 *in6;
  687. if (res_lib_cfg_get_node_addrs->family == AF_INET) {
  688. in = (struct sockaddr_in *)addrs[i].address;
  689. in->sin_family = AF_INET;
  690. memcpy(&in->sin_addr, &res_lib_cfg_get_node_addrs->addrs[i][0], sizeof(struct in_addr));
  691. }
  692. if (res_lib_cfg_get_node_addrs->family == AF_INET6) {
  693. in6 = (struct sockaddr_in6 *)addrs[i].address;
  694. in6->sin6_family = AF_INET6;
  695. memcpy(&in6->sin6_addr, &res_lib_cfg_get_node_addrs->addrs[i][0], sizeof(struct in6_addr));
  696. }
  697. }
  698. *num_addrs = res_lib_cfg_get_node_addrs->num_addrs;
  699. errno = error = res_lib_cfg_get_node_addrs->header.error;
  700. error_exit:
  701. return (error);
  702. }
  703. cs_error_t corosync_cfg_local_get (
  704. corosync_cfg_handle_t handle,
  705. unsigned int *local_nodeid)
  706. {
  707. cs_error_t error;
  708. struct cfg_instance *cfg_inst;
  709. struct iovec iov;
  710. struct req_lib_cfg_local_get req_lib_cfg_local_get;
  711. struct res_lib_cfg_local_get res_lib_cfg_local_get;
  712. error = saHandleInstanceGet (&cfg_hdb, handle, (void *)&cfg_inst);
  713. if (error != CS_OK) {
  714. return (error);
  715. }
  716. req_lib_cfg_local_get.header.size = sizeof (mar_req_header_t);
  717. req_lib_cfg_local_get.header.id = MESSAGE_REQ_CFG_LOCAL_GET;
  718. iov.iov_base = &req_lib_cfg_local_get;
  719. iov.iov_len = sizeof (struct req_lib_cfg_local_get);
  720. pthread_mutex_lock (&cfg_inst->response_mutex);
  721. error = cslib_msg_send_reply_receive (
  722. cfg_inst->ipc_ctx,
  723. &iov,
  724. 1,
  725. &res_lib_cfg_local_get,
  726. sizeof (struct res_lib_cfg_local_get));
  727. pthread_mutex_unlock (&cfg_inst->response_mutex);
  728. if (error != CS_OK) {
  729. goto error_exit;
  730. }
  731. error = res_lib_cfg_local_get.header.error;
  732. *local_nodeid = res_lib_cfg_local_get.local_nodeid;
  733. error_exit:
  734. (void)saHandleInstancePut (&cfg_hdb, handle);
  735. return (error);
  736. }