votequorum.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. /*
  2. * Copyright (c) 2009-2012 Red Hat, Inc.
  3. *
  4. * All rights reserved.
  5. *
  6. * Author: Christine Caulfield (ccaulfie@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 MontaVista Software, 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 CONTIBUTORS "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. /*
  35. * Provides a quorum API using the corosync executive
  36. */
  37. #include <config.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <unistd.h>
  41. #include <sys/types.h>
  42. #include <sys/socket.h>
  43. #include <errno.h>
  44. #include <qb/qbdefs.h>
  45. #include <qb/qbipcc.h>
  46. #include <corosync/corotypes.h>
  47. #include <corosync/corodefs.h>
  48. #include <corosync/hdb.h>
  49. #include <corosync/votequorum.h>
  50. #include <corosync/ipc_votequorum.h>
  51. #include "util.h"
  52. struct votequorum_inst {
  53. qb_ipcc_connection_t *c;
  54. int finalize;
  55. void *context;
  56. votequorum_callbacks_t callbacks;
  57. };
  58. static void votequorum_inst_free (void *inst);
  59. DECLARE_HDB_DATABASE(votequorum_handle_t_db, votequorum_inst_free);
  60. cs_error_t votequorum_initialize (
  61. votequorum_handle_t *handle,
  62. votequorum_callbacks_t *callbacks)
  63. {
  64. cs_error_t error;
  65. struct votequorum_inst *votequorum_inst;
  66. error = hdb_error_to_cs(hdb_handle_create (&votequorum_handle_t_db, sizeof (struct votequorum_inst), handle));
  67. if (error != CS_OK) {
  68. goto error_no_destroy;
  69. }
  70. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, *handle, (void *)&votequorum_inst));
  71. if (error != CS_OK) {
  72. goto error_destroy;
  73. }
  74. votequorum_inst->finalize = 0;
  75. votequorum_inst->c = qb_ipcc_connect ("votequorum", IPC_REQUEST_SIZE);
  76. if (votequorum_inst->c == NULL) {
  77. error = qb_to_cs_error(-errno);
  78. goto error_put_destroy;
  79. }
  80. if (callbacks)
  81. memcpy(&votequorum_inst->callbacks, callbacks, sizeof (*callbacks));
  82. else
  83. memset(&votequorum_inst->callbacks, 0, sizeof (*callbacks));
  84. hdb_handle_put (&votequorum_handle_t_db, *handle);
  85. return (CS_OK);
  86. error_put_destroy:
  87. hdb_handle_put (&votequorum_handle_t_db, *handle);
  88. error_destroy:
  89. hdb_handle_destroy (&votequorum_handle_t_db, *handle);
  90. error_no_destroy:
  91. return (error);
  92. }
  93. static void votequorum_inst_free (void *inst)
  94. {
  95. struct votequorum_inst *vq_inst = (struct votequorum_inst *)inst;
  96. qb_ipcc_disconnect(vq_inst->c);
  97. }
  98. cs_error_t votequorum_finalize (
  99. votequorum_handle_t handle)
  100. {
  101. struct votequorum_inst *votequorum_inst;
  102. cs_error_t error;
  103. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  104. if (error != CS_OK) {
  105. return (error);
  106. }
  107. /*
  108. * Another thread has already started finalizing
  109. */
  110. if (votequorum_inst->finalize) {
  111. hdb_handle_put (&votequorum_handle_t_db, handle);
  112. return (CS_ERR_BAD_HANDLE);
  113. }
  114. votequorum_inst->finalize = 1;
  115. hdb_handle_destroy (&votequorum_handle_t_db, handle);
  116. hdb_handle_put (&votequorum_handle_t_db, handle);
  117. return (CS_OK);
  118. }
  119. cs_error_t votequorum_getinfo (
  120. votequorum_handle_t handle,
  121. unsigned int nodeid,
  122. struct votequorum_info *info)
  123. {
  124. cs_error_t error;
  125. struct votequorum_inst *votequorum_inst;
  126. struct iovec iov;
  127. struct req_lib_votequorum_getinfo req_lib_votequorum_getinfo;
  128. struct res_lib_votequorum_getinfo res_lib_votequorum_getinfo;
  129. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  130. if (error != CS_OK) {
  131. return (error);
  132. }
  133. req_lib_votequorum_getinfo.header.size = sizeof (struct req_lib_votequorum_getinfo);
  134. req_lib_votequorum_getinfo.header.id = MESSAGE_REQ_VOTEQUORUM_GETINFO;
  135. req_lib_votequorum_getinfo.nodeid = nodeid;
  136. iov.iov_base = (char *)&req_lib_votequorum_getinfo;
  137. iov.iov_len = sizeof (struct req_lib_votequorum_getinfo);
  138. error = qb_to_cs_error(qb_ipcc_sendv_recv (
  139. votequorum_inst->c,
  140. &iov,
  141. 1,
  142. &res_lib_votequorum_getinfo,
  143. sizeof (struct res_lib_votequorum_getinfo), CS_IPC_TIMEOUT_MS));
  144. if (error != CS_OK) {
  145. goto error_exit;
  146. }
  147. error = res_lib_votequorum_getinfo.header.error;
  148. info->node_id = res_lib_votequorum_getinfo.nodeid;
  149. info->node_state = res_lib_votequorum_getinfo.state;
  150. info->node_votes = res_lib_votequorum_getinfo.votes;
  151. info->node_expected_votes = res_lib_votequorum_getinfo.expected_votes;
  152. info->highest_expected = res_lib_votequorum_getinfo.highest_expected;
  153. info->total_votes = res_lib_votequorum_getinfo.total_votes;
  154. info->quorum = res_lib_votequorum_getinfo.quorum;
  155. info->flags = res_lib_votequorum_getinfo.flags;
  156. info->qdevice_votes = res_lib_votequorum_getinfo.qdevice_votes;
  157. memset(info->qdevice_name, 0, VOTEQUORUM_QDEVICE_MAX_NAME_LEN);
  158. strcpy(info->qdevice_name, res_lib_votequorum_getinfo.qdevice_name);
  159. error_exit:
  160. hdb_handle_put (&votequorum_handle_t_db, handle);
  161. return (error);
  162. }
  163. cs_error_t votequorum_setexpected (
  164. votequorum_handle_t handle,
  165. unsigned int expected_votes)
  166. {
  167. cs_error_t error;
  168. struct votequorum_inst *votequorum_inst;
  169. struct iovec iov;
  170. struct req_lib_votequorum_setexpected req_lib_votequorum_setexpected;
  171. struct res_lib_votequorum_status res_lib_votequorum_status;
  172. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  173. if (error != CS_OK) {
  174. return (error);
  175. }
  176. req_lib_votequorum_setexpected.header.size = sizeof (struct req_lib_votequorum_setexpected);
  177. req_lib_votequorum_setexpected.header.id = MESSAGE_REQ_VOTEQUORUM_SETEXPECTED;
  178. req_lib_votequorum_setexpected.expected_votes = expected_votes;
  179. iov.iov_base = (char *)&req_lib_votequorum_setexpected;
  180. iov.iov_len = sizeof (struct req_lib_votequorum_setexpected);
  181. error = qb_to_cs_error(qb_ipcc_sendv_recv (
  182. votequorum_inst->c,
  183. &iov,
  184. 1,
  185. &res_lib_votequorum_status,
  186. sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
  187. if (error != CS_OK) {
  188. goto error_exit;
  189. }
  190. error = res_lib_votequorum_status.header.error;
  191. error_exit:
  192. hdb_handle_put (&votequorum_handle_t_db, handle);
  193. return (error);
  194. }
  195. cs_error_t votequorum_setvotes (
  196. votequorum_handle_t handle,
  197. unsigned int nodeid,
  198. unsigned int votes)
  199. {
  200. cs_error_t error;
  201. struct votequorum_inst *votequorum_inst;
  202. struct iovec iov;
  203. struct req_lib_votequorum_setvotes req_lib_votequorum_setvotes;
  204. struct res_lib_votequorum_status res_lib_votequorum_status;
  205. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  206. if (error != CS_OK) {
  207. return (error);
  208. }
  209. req_lib_votequorum_setvotes.header.size = sizeof (struct req_lib_votequorum_setvotes);
  210. req_lib_votequorum_setvotes.header.id = MESSAGE_REQ_VOTEQUORUM_SETVOTES;
  211. req_lib_votequorum_setvotes.nodeid = nodeid;
  212. req_lib_votequorum_setvotes.votes = votes;
  213. iov.iov_base = (char *)&req_lib_votequorum_setvotes;
  214. iov.iov_len = sizeof (struct req_lib_votequorum_setvotes);
  215. error = qb_to_cs_error(qb_ipcc_sendv_recv (
  216. votequorum_inst->c,
  217. &iov,
  218. 1,
  219. &res_lib_votequorum_status,
  220. sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
  221. if (error != CS_OK) {
  222. goto error_exit;
  223. }
  224. error = res_lib_votequorum_status.header.error;
  225. error_exit:
  226. hdb_handle_put (&votequorum_handle_t_db, handle);
  227. return (error);
  228. }
  229. cs_error_t votequorum_trackstart (
  230. votequorum_handle_t handle,
  231. uint64_t context,
  232. unsigned int flags)
  233. {
  234. cs_error_t error;
  235. struct votequorum_inst *votequorum_inst;
  236. struct iovec iov;
  237. struct req_lib_votequorum_trackstart req_lib_votequorum_trackstart;
  238. struct res_lib_votequorum_status res_lib_votequorum_status;
  239. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  240. if (error != CS_OK) {
  241. return (error);
  242. }
  243. req_lib_votequorum_trackstart.header.size = sizeof (struct req_lib_votequorum_trackstart);
  244. req_lib_votequorum_trackstart.header.id = MESSAGE_REQ_VOTEQUORUM_TRACKSTART;
  245. req_lib_votequorum_trackstart.track_flags = flags;
  246. req_lib_votequorum_trackstart.context = context;
  247. iov.iov_base = (char *)&req_lib_votequorum_trackstart;
  248. iov.iov_len = sizeof (struct req_lib_votequorum_trackstart);
  249. error = qb_to_cs_error(qb_ipcc_sendv_recv (
  250. votequorum_inst->c,
  251. &iov,
  252. 1,
  253. &res_lib_votequorum_status,
  254. sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
  255. if (error != CS_OK) {
  256. goto error_exit;
  257. }
  258. error = res_lib_votequorum_status.header.error;
  259. error_exit:
  260. hdb_handle_put (&votequorum_handle_t_db, handle);
  261. return (error);
  262. }
  263. cs_error_t votequorum_trackstop (
  264. votequorum_handle_t handle)
  265. {
  266. cs_error_t error;
  267. struct votequorum_inst *votequorum_inst;
  268. struct iovec iov;
  269. struct req_lib_votequorum_general req_lib_votequorum_general;
  270. struct res_lib_votequorum_status res_lib_votequorum_status;
  271. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  272. if (error != CS_OK) {
  273. return (error);
  274. }
  275. req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general);
  276. req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_TRACKSTOP;
  277. iov.iov_base = (char *)&req_lib_votequorum_general;
  278. iov.iov_len = sizeof (struct req_lib_votequorum_general);
  279. error = qb_to_cs_error(qb_ipcc_sendv_recv (
  280. votequorum_inst->c,
  281. &iov,
  282. 1,
  283. &res_lib_votequorum_status,
  284. sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
  285. if (error != CS_OK) {
  286. goto error_exit;
  287. }
  288. error = res_lib_votequorum_status.header.error;
  289. error_exit:
  290. hdb_handle_put (&votequorum_handle_t_db, handle);
  291. return (error);
  292. }
  293. cs_error_t votequorum_context_get (
  294. votequorum_handle_t handle,
  295. void **context)
  296. {
  297. cs_error_t error;
  298. struct votequorum_inst *votequorum_inst;
  299. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  300. if (error != CS_OK) {
  301. return (error);
  302. }
  303. *context = votequorum_inst->context;
  304. hdb_handle_put (&votequorum_handle_t_db, handle);
  305. return (CS_OK);
  306. }
  307. cs_error_t votequorum_context_set (
  308. votequorum_handle_t handle,
  309. void *context)
  310. {
  311. cs_error_t error;
  312. struct votequorum_inst *votequorum_inst;
  313. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  314. if (error != CS_OK) {
  315. return (error);
  316. }
  317. votequorum_inst->context = context;
  318. hdb_handle_put (&votequorum_handle_t_db, handle);
  319. return (CS_OK);
  320. }
  321. cs_error_t votequorum_fd_get (
  322. votequorum_handle_t handle,
  323. int *fd)
  324. {
  325. cs_error_t error;
  326. struct votequorum_inst *votequorum_inst;
  327. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  328. if (error != CS_OK) {
  329. return (error);
  330. }
  331. error = qb_to_cs_error(qb_ipcc_fd_get (votequorum_inst->c, fd));
  332. (void)hdb_handle_put (&votequorum_handle_t_db, handle);
  333. return (error);
  334. }
  335. cs_error_t votequorum_dispatch (
  336. votequorum_handle_t handle,
  337. cs_dispatch_flags_t dispatch_types)
  338. {
  339. int timeout = -1;
  340. cs_error_t error;
  341. int cont = 1; /* always continue do loop except when set to 0 */
  342. struct votequorum_inst *votequorum_inst;
  343. votequorum_callbacks_t callbacks;
  344. struct qb_ipc_response_header *dispatch_data;
  345. struct res_lib_votequorum_notification *res_lib_votequorum_notification;
  346. struct res_lib_votequorum_expectedvotes_notification *res_lib_votequorum_expectedvotes_notification;
  347. char dispatch_buf[IPC_DISPATCH_SIZE];
  348. if (dispatch_types != CS_DISPATCH_ONE &&
  349. dispatch_types != CS_DISPATCH_ALL &&
  350. dispatch_types != CS_DISPATCH_BLOCKING &&
  351. dispatch_types != CS_DISPATCH_ONE_NONBLOCKING) {
  352. return (CS_ERR_INVALID_PARAM);
  353. }
  354. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle,
  355. (void *)&votequorum_inst));
  356. if (error != CS_OK) {
  357. return (error);
  358. }
  359. /*
  360. * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
  361. * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
  362. */
  363. if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
  364. timeout = 0;
  365. }
  366. dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
  367. do {
  368. error = qb_to_cs_error (qb_ipcc_event_recv (
  369. votequorum_inst->c,
  370. dispatch_buf,
  371. IPC_DISPATCH_SIZE,
  372. timeout));
  373. if (error == CS_ERR_BAD_HANDLE) {
  374. error = CS_OK;
  375. goto error_put;
  376. }
  377. if (error == CS_ERR_TRY_AGAIN) {
  378. if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
  379. /*
  380. * Don't mask error
  381. */
  382. goto error_put;
  383. }
  384. error = CS_OK;
  385. if (dispatch_types == CS_DISPATCH_ALL) {
  386. break; /* exit do while cont is 1 loop */
  387. } else {
  388. continue; /* next poll */
  389. }
  390. }
  391. if (error != CS_OK) {
  392. goto error_put;
  393. }
  394. /*
  395. * Make copy of callbacks, message data, unlock instance, and call callback
  396. * A risk of this dispatch method is that the callback routines may
  397. * operate at the same time that votequorum_finalize has been called in another thread.
  398. */
  399. memcpy (&callbacks, &votequorum_inst->callbacks, sizeof (votequorum_callbacks_t));
  400. /*
  401. * Dispatch incoming message
  402. */
  403. switch (dispatch_data->id) {
  404. case MESSAGE_RES_VOTEQUORUM_NOTIFICATION:
  405. if (callbacks.votequorum_notify_fn == NULL) {
  406. break;
  407. }
  408. res_lib_votequorum_notification = (struct res_lib_votequorum_notification *)dispatch_data;
  409. callbacks.votequorum_notify_fn ( handle,
  410. res_lib_votequorum_notification->context,
  411. res_lib_votequorum_notification->quorate,
  412. res_lib_votequorum_notification->node_list_entries,
  413. (votequorum_node_t *)res_lib_votequorum_notification->node_list );
  414. ;
  415. break;
  416. case MESSAGE_RES_VOTEQUORUM_EXPECTEDVOTES_NOTIFICATION:
  417. if (callbacks.votequorum_expectedvotes_notify_fn == NULL) {
  418. break;
  419. }
  420. res_lib_votequorum_expectedvotes_notification = (struct res_lib_votequorum_expectedvotes_notification *)dispatch_data;
  421. callbacks.votequorum_expectedvotes_notify_fn ( handle,
  422. res_lib_votequorum_expectedvotes_notification->context,
  423. res_lib_votequorum_expectedvotes_notification->expected_votes);
  424. break;
  425. default:
  426. error = CS_ERR_LIBRARY;
  427. goto error_put;
  428. break;
  429. }
  430. if (votequorum_inst->finalize) {
  431. /*
  432. * If the finalize has been called then get out of the dispatch.
  433. */
  434. error = CS_ERR_BAD_HANDLE;
  435. goto error_put;
  436. }
  437. /*
  438. * Determine if more messages should be processed
  439. */
  440. if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
  441. cont = 0;
  442. }
  443. } while (cont);
  444. error_put:
  445. hdb_handle_put (&votequorum_handle_t_db, handle);
  446. return (error);
  447. }
  448. cs_error_t votequorum_qdevice_register (
  449. votequorum_handle_t handle,
  450. const char *name)
  451. {
  452. cs_error_t error;
  453. struct votequorum_inst *votequorum_inst;
  454. struct iovec iov;
  455. struct req_lib_votequorum_qdevice_register req_lib_votequorum_qdevice_register;
  456. struct res_lib_votequorum_status res_lib_votequorum_status;
  457. if ((strlen(name) == 0) ||
  458. (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
  459. return CS_ERR_INVALID_PARAM;
  460. }
  461. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  462. if (error != CS_OK) {
  463. return (error);
  464. }
  465. req_lib_votequorum_qdevice_register.header.size = sizeof (struct req_lib_votequorum_qdevice_register);
  466. req_lib_votequorum_qdevice_register.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_REGISTER;
  467. strcpy(req_lib_votequorum_qdevice_register.name, name);
  468. iov.iov_base = (char *)&req_lib_votequorum_qdevice_register;
  469. iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_register);
  470. error = qb_to_cs_error(qb_ipcc_sendv_recv (
  471. votequorum_inst->c,
  472. &iov,
  473. 1,
  474. &res_lib_votequorum_status,
  475. sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
  476. if (error != CS_OK) {
  477. goto error_exit;
  478. }
  479. error = res_lib_votequorum_status.header.error;
  480. error_exit:
  481. hdb_handle_put (&votequorum_handle_t_db, handle);
  482. return (error);
  483. }
  484. cs_error_t votequorum_qdevice_poll (
  485. votequorum_handle_t handle,
  486. const char *name,
  487. unsigned int cast_vote)
  488. {
  489. cs_error_t error;
  490. struct votequorum_inst *votequorum_inst;
  491. struct iovec iov;
  492. struct req_lib_votequorum_qdevice_poll req_lib_votequorum_qdevice_poll;
  493. struct res_lib_votequorum_status res_lib_votequorum_status;
  494. if ((strlen(name) == 0) ||
  495. (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
  496. return CS_ERR_INVALID_PARAM;
  497. }
  498. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  499. if (error != CS_OK) {
  500. return (error);
  501. }
  502. req_lib_votequorum_qdevice_poll.header.size = sizeof (struct req_lib_votequorum_qdevice_poll);
  503. req_lib_votequorum_qdevice_poll.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_POLL;
  504. strcpy(req_lib_votequorum_qdevice_poll.name, name);
  505. req_lib_votequorum_qdevice_poll.cast_vote = cast_vote;
  506. iov.iov_base = (char *)&req_lib_votequorum_qdevice_poll;
  507. iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_poll);
  508. error = qb_to_cs_error(qb_ipcc_sendv_recv (
  509. votequorum_inst->c,
  510. &iov,
  511. 1,
  512. &res_lib_votequorum_status,
  513. sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
  514. if (error != CS_OK) {
  515. goto error_exit;
  516. }
  517. error = res_lib_votequorum_status.header.error;
  518. error_exit:
  519. hdb_handle_put (&votequorum_handle_t_db, handle);
  520. return (error);
  521. }
  522. cs_error_t votequorum_qdevice_master_wins (
  523. votequorum_handle_t handle,
  524. const char *name,
  525. unsigned int allow)
  526. {
  527. cs_error_t error;
  528. struct votequorum_inst *votequorum_inst;
  529. struct iovec iov;
  530. struct req_lib_votequorum_qdevice_master_wins req_lib_votequorum_qdevice_master_wins;
  531. struct res_lib_votequorum_status res_lib_votequorum_status;
  532. if ((strlen(name) == 0) ||
  533. (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
  534. return CS_ERR_INVALID_PARAM;
  535. }
  536. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  537. if (error != CS_OK) {
  538. return (error);
  539. }
  540. req_lib_votequorum_qdevice_master_wins.header.size = sizeof (struct req_lib_votequorum_qdevice_master_wins);
  541. req_lib_votequorum_qdevice_master_wins.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_MASTER_WINS;
  542. strcpy(req_lib_votequorum_qdevice_master_wins.name, name);
  543. req_lib_votequorum_qdevice_master_wins.allow = allow;
  544. iov.iov_base = (char *)&req_lib_votequorum_qdevice_master_wins;
  545. iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_master_wins);
  546. error = qb_to_cs_error(qb_ipcc_sendv_recv (
  547. votequorum_inst->c,
  548. &iov,
  549. 1,
  550. &res_lib_votequorum_status,
  551. sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
  552. if (error != CS_OK) {
  553. goto error_exit;
  554. }
  555. error = res_lib_votequorum_status.header.error;
  556. error_exit:
  557. hdb_handle_put (&votequorum_handle_t_db, handle);
  558. return (error);
  559. }
  560. cs_error_t votequorum_qdevice_update (
  561. votequorum_handle_t handle,
  562. const char *oldname,
  563. const char *newname)
  564. {
  565. cs_error_t error;
  566. struct votequorum_inst *votequorum_inst;
  567. struct iovec iov;
  568. struct req_lib_votequorum_qdevice_update req_lib_votequorum_qdevice_update;
  569. struct res_lib_votequorum_status res_lib_votequorum_status;
  570. if ((strlen(oldname) == 0) ||
  571. (strlen(oldname) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN) ||
  572. (strlen(newname) == 0) ||
  573. (strlen(newname) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
  574. return CS_ERR_INVALID_PARAM;
  575. }
  576. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  577. if (error != CS_OK) {
  578. return (error);
  579. }
  580. req_lib_votequorum_qdevice_update.header.size = sizeof (struct req_lib_votequorum_qdevice_update);
  581. req_lib_votequorum_qdevice_update.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_UPDATE;
  582. strcpy(req_lib_votequorum_qdevice_update.oldname, oldname);
  583. strcpy(req_lib_votequorum_qdevice_update.newname, newname);
  584. iov.iov_base = (char *)&req_lib_votequorum_qdevice_update;
  585. iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_update);
  586. error = qb_to_cs_error(qb_ipcc_sendv_recv (
  587. votequorum_inst->c,
  588. &iov,
  589. 1,
  590. &res_lib_votequorum_status,
  591. sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
  592. if (error != CS_OK) {
  593. goto error_exit;
  594. }
  595. error = res_lib_votequorum_status.header.error;
  596. error_exit:
  597. hdb_handle_put (&votequorum_handle_t_db, handle);
  598. return (error);
  599. }
  600. cs_error_t votequorum_qdevice_unregister (
  601. votequorum_handle_t handle,
  602. const char *name)
  603. {
  604. cs_error_t error;
  605. struct votequorum_inst *votequorum_inst;
  606. struct iovec iov;
  607. struct req_lib_votequorum_qdevice_unregister req_lib_votequorum_qdevice_unregister;
  608. struct res_lib_votequorum_status res_lib_votequorum_status;
  609. if ((strlen(name) == 0) ||
  610. (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
  611. return CS_ERR_INVALID_PARAM;
  612. }
  613. error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
  614. if (error != CS_OK) {
  615. return (error);
  616. }
  617. req_lib_votequorum_qdevice_unregister.header.size = sizeof (struct req_lib_votequorum_qdevice_unregister);
  618. req_lib_votequorum_qdevice_unregister.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_UNREGISTER;
  619. strcpy(req_lib_votequorum_qdevice_unregister.name, name);
  620. iov.iov_base = (char *)&req_lib_votequorum_qdevice_unregister;
  621. iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_unregister);
  622. error = qb_to_cs_error(qb_ipcc_sendv_recv (
  623. votequorum_inst->c,
  624. &iov,
  625. 1,
  626. &res_lib_votequorum_status,
  627. sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
  628. if (error != CS_OK) {
  629. goto error_exit;
  630. }
  631. error = res_lib_votequorum_status.header.error;
  632. error_exit:
  633. hdb_handle_put (&votequorum_handle_t_db, handle);
  634. return (error);
  635. }