corosync  3.1.2
lib/votequorum.c
Go to the documentation of this file.
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 /*
36  * Provides a quorum API using the corosync executive
37  */
38 
39 #include <config.h>
40 
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <sys/types.h>
45 #include <sys/socket.h>
46 #include <sys/uio.h>
47 #include <errno.h>
48 
49 #include <qb/qbdefs.h>
50 #include <qb/qbipcc.h>
51 
52 #include <corosync/corotypes.h>
53 #include <corosync/corodefs.h>
54 #include <corosync/hdb.h>
55 
56 #include <corosync/votequorum.h>
58 
59 #include "util.h"
60 
62  qb_ipcc_connection_t *c;
63  int finalize;
64  void *context;
66 };
67 
68 static void votequorum_inst_free (void *inst);
69 
70 DECLARE_HDB_DATABASE(votequorum_handle_t_db, votequorum_inst_free);
71 
73  votequorum_handle_t *handle,
75 {
76  cs_error_t error;
78 
79  error = hdb_error_to_cs(hdb_handle_create (&votequorum_handle_t_db, sizeof (struct votequorum_inst), handle));
80  if (error != CS_OK) {
81  goto error_no_destroy;
82  }
83 
84  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, *handle, (void *)&votequorum_inst));
85  if (error != CS_OK) {
86  goto error_destroy;
87  }
88 
89  votequorum_inst->finalize = 0;
90  votequorum_inst->c = qb_ipcc_connect ("votequorum", IPC_REQUEST_SIZE);
91  if (votequorum_inst->c == NULL) {
92  error = qb_to_cs_error(-errno);
93  goto error_put_destroy;
94  }
95 
96  if (callbacks)
97  memcpy(&votequorum_inst->callbacks, callbacks, sizeof (*callbacks));
98  else
99  memset(&votequorum_inst->callbacks, 0, sizeof (*callbacks));
100 
101  hdb_handle_put (&votequorum_handle_t_db, *handle);
102 
103  return (CS_OK);
104 
105 error_put_destroy:
106  hdb_handle_put (&votequorum_handle_t_db, *handle);
107 error_destroy:
108  hdb_handle_destroy (&votequorum_handle_t_db, *handle);
109 error_no_destroy:
110  return (error);
111 }
112 
113 static void votequorum_inst_free (void *inst)
114 {
115  struct votequorum_inst *vq_inst = (struct votequorum_inst *)inst;
116  qb_ipcc_disconnect(vq_inst->c);
117 }
118 
120  votequorum_handle_t handle)
121 {
123  cs_error_t error;
124 
125  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
126  if (error != CS_OK) {
127  return (error);
128  }
129 
130  /*
131  * Another thread has already started finalizing
132  */
133  if (votequorum_inst->finalize) {
134  hdb_handle_put (&votequorum_handle_t_db, handle);
135  return (CS_ERR_BAD_HANDLE);
136  }
137 
138  votequorum_inst->finalize = 1;
139 
140  hdb_handle_destroy (&votequorum_handle_t_db, handle);
141 
142  hdb_handle_put (&votequorum_handle_t_db, handle);
143 
144  return (CS_OK);
145 }
146 
147 
149  votequorum_handle_t handle,
150  unsigned int nodeid,
151  struct votequorum_info *info)
152 {
153  cs_error_t error;
155  struct iovec iov;
156  struct req_lib_votequorum_getinfo req_lib_votequorum_getinfo;
157  struct res_lib_votequorum_getinfo res_lib_votequorum_getinfo;
158 
159  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
160  if (error != CS_OK) {
161  return (error);
162  }
163 
164  req_lib_votequorum_getinfo.header.size = sizeof (struct req_lib_votequorum_getinfo);
165  req_lib_votequorum_getinfo.header.id = MESSAGE_REQ_VOTEQUORUM_GETINFO;
166  req_lib_votequorum_getinfo.nodeid = nodeid;
167 
168  iov.iov_base = (char *)&req_lib_votequorum_getinfo;
169  iov.iov_len = sizeof (struct req_lib_votequorum_getinfo);
170 
171  error = qb_to_cs_error(qb_ipcc_sendv_recv (
172  votequorum_inst->c,
173  &iov,
174  1,
175  &res_lib_votequorum_getinfo,
176  sizeof (struct res_lib_votequorum_getinfo), CS_IPC_TIMEOUT_MS));
177 
178  if (error != CS_OK) {
179  goto error_exit;
180  }
181 
182  error = res_lib_votequorum_getinfo.header.error;
183 
184  info->node_id = res_lib_votequorum_getinfo.nodeid;
185  info->node_state = res_lib_votequorum_getinfo.state;
186  info->node_votes = res_lib_votequorum_getinfo.votes;
187  info->node_expected_votes = res_lib_votequorum_getinfo.expected_votes;
188  info->highest_expected = res_lib_votequorum_getinfo.highest_expected;
189  info->total_votes = res_lib_votequorum_getinfo.total_votes;
190  info->quorum = res_lib_votequorum_getinfo.quorum;
191  info->flags = res_lib_votequorum_getinfo.flags;
192  info->qdevice_votes = res_lib_votequorum_getinfo.qdevice_votes;
194  strcpy(info->qdevice_name, res_lib_votequorum_getinfo.qdevice_name);
195 
196 error_exit:
197  hdb_handle_put (&votequorum_handle_t_db, handle);
198 
199  return (error);
200 }
201 
203  votequorum_handle_t handle,
204  unsigned int expected_votes)
205 {
206  cs_error_t error;
208  struct iovec iov;
209  struct req_lib_votequorum_setexpected req_lib_votequorum_setexpected;
210  struct res_lib_votequorum_status res_lib_votequorum_status;
211 
212  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
213  if (error != CS_OK) {
214  return (error);
215  }
216 
217 
218  req_lib_votequorum_setexpected.header.size = sizeof (struct req_lib_votequorum_setexpected);
219  req_lib_votequorum_setexpected.header.id = MESSAGE_REQ_VOTEQUORUM_SETEXPECTED;
220  req_lib_votequorum_setexpected.expected_votes = expected_votes;
221 
222  iov.iov_base = (char *)&req_lib_votequorum_setexpected;
223  iov.iov_len = sizeof (struct req_lib_votequorum_setexpected);
224 
225  error = qb_to_cs_error(qb_ipcc_sendv_recv (
226  votequorum_inst->c,
227  &iov,
228  1,
229  &res_lib_votequorum_status,
230  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
231 
232  if (error != CS_OK) {
233  goto error_exit;
234  }
235 
236  error = res_lib_votequorum_status.header.error;
237 
238 error_exit:
239  hdb_handle_put (&votequorum_handle_t_db, handle);
240 
241  return (error);
242 }
243 
245  votequorum_handle_t handle,
246  unsigned int nodeid,
247  unsigned int votes)
248 {
249  cs_error_t error;
251  struct iovec iov;
252  struct req_lib_votequorum_setvotes req_lib_votequorum_setvotes;
253  struct res_lib_votequorum_status res_lib_votequorum_status;
254 
255  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
256  if (error != CS_OK) {
257  return (error);
258  }
259 
260  req_lib_votequorum_setvotes.header.size = sizeof (struct req_lib_votequorum_setvotes);
261  req_lib_votequorum_setvotes.header.id = MESSAGE_REQ_VOTEQUORUM_SETVOTES;
262  req_lib_votequorum_setvotes.nodeid = nodeid;
263  req_lib_votequorum_setvotes.votes = votes;
264 
265  iov.iov_base = (char *)&req_lib_votequorum_setvotes;
266  iov.iov_len = sizeof (struct req_lib_votequorum_setvotes);
267 
268  error = qb_to_cs_error(qb_ipcc_sendv_recv (
269  votequorum_inst->c,
270  &iov,
271  1,
272  &res_lib_votequorum_status,
273  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
274 
275  if (error != CS_OK) {
276  goto error_exit;
277  }
278 
279  error = res_lib_votequorum_status.header.error;
280 
281 error_exit:
282  hdb_handle_put (&votequorum_handle_t_db, handle);
283 
284  return (error);
285 }
286 
288  votequorum_handle_t handle,
289  uint64_t context,
290  unsigned int flags)
291 {
292  cs_error_t error;
294  struct iovec iov;
295  struct req_lib_votequorum_trackstart req_lib_votequorum_trackstart;
296  struct res_lib_votequorum_status res_lib_votequorum_status;
297 
298  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
299  if (error != CS_OK) {
300  return (error);
301  }
302 
303  req_lib_votequorum_trackstart.header.size = sizeof (struct req_lib_votequorum_trackstart);
304  req_lib_votequorum_trackstart.header.id = MESSAGE_REQ_VOTEQUORUM_TRACKSTART;
305  req_lib_votequorum_trackstart.track_flags = flags;
306  req_lib_votequorum_trackstart.context = context;
307 
308  iov.iov_base = (char *)&req_lib_votequorum_trackstart;
309  iov.iov_len = sizeof (struct req_lib_votequorum_trackstart);
310 
311  error = qb_to_cs_error(qb_ipcc_sendv_recv (
312  votequorum_inst->c,
313  &iov,
314  1,
315  &res_lib_votequorum_status,
316  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
317 
318  if (error != CS_OK) {
319  goto error_exit;
320  }
321 
322  error = res_lib_votequorum_status.header.error;
323 
324 error_exit:
325  hdb_handle_put (&votequorum_handle_t_db, handle);
326 
327  return (error);
328 }
329 
331  votequorum_handle_t handle)
332 {
333  cs_error_t error;
335  struct iovec iov;
336  struct req_lib_votequorum_general req_lib_votequorum_general;
337  struct res_lib_votequorum_status res_lib_votequorum_status;
338 
339  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
340  if (error != CS_OK) {
341  return (error);
342  }
343 
344  req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general);
345  req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_TRACKSTOP;
346 
347  iov.iov_base = (char *)&req_lib_votequorum_general;
348  iov.iov_len = sizeof (struct req_lib_votequorum_general);
349 
350  error = qb_to_cs_error(qb_ipcc_sendv_recv (
351  votequorum_inst->c,
352  &iov,
353  1,
354  &res_lib_votequorum_status,
355  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
356 
357  if (error != CS_OK) {
358  goto error_exit;
359  }
360 
361  error = res_lib_votequorum_status.header.error;
362 
363 error_exit:
364  hdb_handle_put (&votequorum_handle_t_db, handle);
365 
366  return (error);
367 }
368 
369 
371  votequorum_handle_t handle,
372  void **context)
373 {
374  cs_error_t error;
376 
377  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
378  if (error != CS_OK) {
379  return (error);
380  }
381 
382  *context = votequorum_inst->context;
383 
384  hdb_handle_put (&votequorum_handle_t_db, handle);
385 
386  return (CS_OK);
387 }
388 
390  votequorum_handle_t handle,
391  void *context)
392 {
393  cs_error_t error;
395 
396  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
397  if (error != CS_OK) {
398  return (error);
399  }
400 
401  votequorum_inst->context = context;
402 
403  hdb_handle_put (&votequorum_handle_t_db, handle);
404 
405  return (CS_OK);
406 }
407 
408 
410  votequorum_handle_t handle,
411  int *fd)
412 {
413  cs_error_t error;
415 
416  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
417  if (error != CS_OK) {
418  return (error);
419  }
420 
421  error = qb_to_cs_error(qb_ipcc_fd_get (votequorum_inst->c, fd));
422 
423  (void)hdb_handle_put (&votequorum_handle_t_db, handle);
424 
425  return (error);
426 }
427 
429  votequorum_handle_t handle,
430  cs_dispatch_flags_t dispatch_types)
431 {
432  int timeout = -1;
433  cs_error_t error;
434  int cont = 1; /* always continue do loop except when set to 0 */
437  struct qb_ipc_response_header *dispatch_data;
441  char dispatch_buf[IPC_DISPATCH_SIZE];
443 
444  if (dispatch_types != CS_DISPATCH_ONE &&
445  dispatch_types != CS_DISPATCH_ALL &&
446  dispatch_types != CS_DISPATCH_BLOCKING &&
447  dispatch_types != CS_DISPATCH_ONE_NONBLOCKING) {
448 
449  return (CS_ERR_INVALID_PARAM);
450  }
451 
452  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle,
453  (void *)&votequorum_inst));
454  if (error != CS_OK) {
455  return (error);
456  }
457 
458  /*
459  * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
460  * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
461  */
462  if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
463  timeout = 0;
464  }
465 
466  dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
467  do {
468  error = qb_to_cs_error (qb_ipcc_event_recv (
469  votequorum_inst->c,
470  dispatch_buf,
472  timeout));
473  if (error == CS_ERR_BAD_HANDLE) {
474  error = CS_OK;
475  goto error_put;
476  }
477  if (error == CS_ERR_TRY_AGAIN) {
478  if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
479  /*
480  * Don't mask error
481  */
482  goto error_put;
483  }
484  error = CS_OK;
485  if (dispatch_types == CS_DISPATCH_ALL) {
486  break; /* exit do while cont is 1 loop */
487  } else {
488  continue; /* next poll */
489  }
490  }
491  if (error != CS_OK) {
492  goto error_put;
493  }
494 
495  /*
496  * Make copy of callbacks, message data, unlock instance, and call callback
497  * A risk of this dispatch method is that the callback routines may
498  * operate at the same time that votequorum_finalize has been called in another thread.
499  */
500  memcpy (&callbacks, &votequorum_inst->callbacks, sizeof (votequorum_callbacks_t));
501 
502  /*
503  * Dispatch incoming message
504  */
505  switch (dispatch_data->id) {
506 
508  if (callbacks.votequorum_quorum_notify_fn == NULL) {
509  break;
510  }
511  res_lib_votequorum_quorum_notification = (struct res_lib_votequorum_quorum_notification *)dispatch_data;
512 
513  callbacks.votequorum_quorum_notify_fn ( handle,
514  res_lib_votequorum_quorum_notification->context,
515  res_lib_votequorum_quorum_notification->quorate,
516  res_lib_votequorum_quorum_notification->node_list_entries,
517  (votequorum_node_t *)res_lib_votequorum_quorum_notification->node_list );
518  break;
519 
521  if (callbacks.votequorum_nodelist_notify_fn == NULL) {
522  break;
523  }
524  res_lib_votequorum_nodelist_notification = (struct res_lib_votequorum_nodelist_notification *)dispatch_data;
525  marshall_from_mar_votequorum_ring_id (&ring_id, &res_lib_votequorum_nodelist_notification->ring_id);
526 
527  callbacks.votequorum_nodelist_notify_fn ( handle,
528  res_lib_votequorum_nodelist_notification->context,
529  ring_id,
530  res_lib_votequorum_nodelist_notification->node_list_entries,
531  res_lib_votequorum_nodelist_notification->node_list );
532  break;
533 
535  if (callbacks.votequorum_expectedvotes_notify_fn == NULL) {
536  break;
537  }
538  res_lib_votequorum_expectedvotes_notification = (struct res_lib_votequorum_expectedvotes_notification *)dispatch_data;
539 
540  callbacks.votequorum_expectedvotes_notify_fn ( handle,
541  res_lib_votequorum_expectedvotes_notification->context,
542  res_lib_votequorum_expectedvotes_notification->expected_votes);
543  break;
544 
545  default:
546  error = CS_ERR_LIBRARY;
547  goto error_put;
548  break;
549  }
550  if (votequorum_inst->finalize) {
551  /*
552  * If the finalize has been called then get out of the dispatch.
553  */
554  error = CS_ERR_BAD_HANDLE;
555  goto error_put;
556  }
557 
558  /*
559  * Determine if more messages should be processed
560  */
561  if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
562  cont = 0;
563  }
564  } while (cont);
565 
566 
567 error_put:
568  hdb_handle_put (&votequorum_handle_t_db, handle);
569  return (error);
570 }
571 
573  votequorum_handle_t handle,
574  const char *name)
575 {
576  cs_error_t error;
578  struct iovec iov;
579  struct req_lib_votequorum_qdevice_register req_lib_votequorum_qdevice_register;
580  struct res_lib_votequorum_status res_lib_votequorum_status;
581 
582  if ((strlen(name) == 0) ||
583  (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
584  return CS_ERR_INVALID_PARAM;
585  }
586 
587  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
588  if (error != CS_OK) {
589  return (error);
590  }
591 
592 
593  req_lib_votequorum_qdevice_register.header.size = sizeof (struct req_lib_votequorum_qdevice_register);
594  req_lib_votequorum_qdevice_register.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_REGISTER;
595  strcpy(req_lib_votequorum_qdevice_register.name, name);
596 
597  iov.iov_base = (char *)&req_lib_votequorum_qdevice_register;
598  iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_register);
599 
600  error = qb_to_cs_error(qb_ipcc_sendv_recv (
601  votequorum_inst->c,
602  &iov,
603  1,
604  &res_lib_votequorum_status,
605  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
606 
607  if (error != CS_OK) {
608  goto error_exit;
609  }
610 
611  error = res_lib_votequorum_status.header.error;
612 
613 error_exit:
614  hdb_handle_put (&votequorum_handle_t_db, handle);
615 
616  return (error);
617 }
618 
620  votequorum_handle_t handle,
621  const char *name,
622  unsigned int cast_vote,
624 {
625  cs_error_t error;
627  struct iovec iov;
628  struct req_lib_votequorum_qdevice_poll req_lib_votequorum_qdevice_poll;
629  struct res_lib_votequorum_status res_lib_votequorum_status;
630 
631  if ((strlen(name) == 0) ||
632  (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
633  return CS_ERR_INVALID_PARAM;
634  }
635 
636  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
637  if (error != CS_OK) {
638  return (error);
639  }
640 
641  req_lib_votequorum_qdevice_poll.header.size = sizeof (struct req_lib_votequorum_qdevice_poll);
642  req_lib_votequorum_qdevice_poll.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_POLL;
643  strcpy(req_lib_votequorum_qdevice_poll.name, name);
644  req_lib_votequorum_qdevice_poll.cast_vote = cast_vote;
645  marshall_to_mar_votequorum_ring_id(&req_lib_votequorum_qdevice_poll.ring_id, &ring_id);
646 
647  iov.iov_base = (char *)&req_lib_votequorum_qdevice_poll;
648  iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_poll);
649 
650  error = qb_to_cs_error(qb_ipcc_sendv_recv (
651  votequorum_inst->c,
652  &iov,
653  1,
654  &res_lib_votequorum_status,
655  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
656 
657  if (error != CS_OK) {
658  goto error_exit;
659  }
660 
661  error = res_lib_votequorum_status.header.error;
662 
663 error_exit:
664  hdb_handle_put (&votequorum_handle_t_db, handle);
665 
666  return (error);
667 }
668 
670  votequorum_handle_t handle,
671  const char *name,
672  unsigned int allow)
673 {
674  cs_error_t error;
676  struct iovec iov;
677  struct req_lib_votequorum_qdevice_master_wins req_lib_votequorum_qdevice_master_wins;
678  struct res_lib_votequorum_status res_lib_votequorum_status;
679 
680  if ((strlen(name) == 0) ||
681  (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
682  return CS_ERR_INVALID_PARAM;
683  }
684 
685  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
686  if (error != CS_OK) {
687  return (error);
688  }
689 
690  req_lib_votequorum_qdevice_master_wins.header.size = sizeof (struct req_lib_votequorum_qdevice_master_wins);
691  req_lib_votequorum_qdevice_master_wins.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_MASTER_WINS;
692  strcpy(req_lib_votequorum_qdevice_master_wins.name, name);
693  req_lib_votequorum_qdevice_master_wins.allow = allow;
694 
695  iov.iov_base = (char *)&req_lib_votequorum_qdevice_master_wins;
696  iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_master_wins);
697 
698  error = qb_to_cs_error(qb_ipcc_sendv_recv (
699  votequorum_inst->c,
700  &iov,
701  1,
702  &res_lib_votequorum_status,
703  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
704 
705  if (error != CS_OK) {
706  goto error_exit;
707  }
708 
709  error = res_lib_votequorum_status.header.error;
710 
711 error_exit:
712  hdb_handle_put (&votequorum_handle_t_db, handle);
713 
714  return (error);
715 }
716 
718  votequorum_handle_t handle,
719  const char *oldname,
720  const char *newname)
721 {
722  cs_error_t error;
724  struct iovec iov;
725  struct req_lib_votequorum_qdevice_update req_lib_votequorum_qdevice_update;
726  struct res_lib_votequorum_status res_lib_votequorum_status;
727 
728  if ((strlen(oldname) == 0) ||
729  (strlen(oldname) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN) ||
730  (strlen(newname) == 0) ||
731  (strlen(newname) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
732  return CS_ERR_INVALID_PARAM;
733  }
734 
735  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
736  if (error != CS_OK) {
737  return (error);
738  }
739 
740  req_lib_votequorum_qdevice_update.header.size = sizeof (struct req_lib_votequorum_qdevice_update);
741  req_lib_votequorum_qdevice_update.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_UPDATE;
742  strcpy(req_lib_votequorum_qdevice_update.oldname, oldname);
743  strcpy(req_lib_votequorum_qdevice_update.newname, newname);
744 
745  iov.iov_base = (char *)&req_lib_votequorum_qdevice_update;
746  iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_update);
747 
748  error = qb_to_cs_error(qb_ipcc_sendv_recv (
749  votequorum_inst->c,
750  &iov,
751  1,
752  &res_lib_votequorum_status,
753  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
754 
755  if (error != CS_OK) {
756  goto error_exit;
757  }
758 
759  error = res_lib_votequorum_status.header.error;
760 
761 error_exit:
762  hdb_handle_put (&votequorum_handle_t_db, handle);
763 
764  return (error);
765 }
766 
768  votequorum_handle_t handle,
769  const char *name)
770 {
771  cs_error_t error;
773  struct iovec iov;
774  struct req_lib_votequorum_qdevice_unregister req_lib_votequorum_qdevice_unregister;
775  struct res_lib_votequorum_status res_lib_votequorum_status;
776 
777  if ((strlen(name) == 0) ||
778  (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
779  return CS_ERR_INVALID_PARAM;
780  }
781 
782  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
783  if (error != CS_OK) {
784  return (error);
785  }
786 
787  req_lib_votequorum_qdevice_unregister.header.size = sizeof (struct req_lib_votequorum_qdevice_unregister);
788  req_lib_votequorum_qdevice_unregister.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_UNREGISTER;
789  strcpy(req_lib_votequorum_qdevice_unregister.name, name);
790 
791  iov.iov_base = (char *)&req_lib_votequorum_qdevice_unregister;
792  iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_unregister);
793 
794  error = qb_to_cs_error(qb_ipcc_sendv_recv (
795  votequorum_inst->c,
796  &iov,
797  1,
798  &res_lib_votequorum_status,
799  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
800 
801  if (error != CS_OK) {
802  goto error_exit;
803  }
804 
805  error = res_lib_votequorum_status.header.error;
806 
807 error_exit:
808  hdb_handle_put (&votequorum_handle_t_db, handle);
809 
810  return (error);
811 }
char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
char newname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
cs_error_t votequorum_trackstart(votequorum_handle_t handle, uint64_t context, unsigned int flags)
Track node and quorum changes.
uint32_t votes
The votequorum_callbacks_t struct.
char oldname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
cs_error_t votequorum_setvotes(votequorum_handle_t handle, unsigned int nodeid, unsigned int votes)
set votes for a node
cs_error_t votequorum_initialize(votequorum_handle_t *handle, votequorum_callbacks_t *callbacks)
Create a new quorum connection.
cs_error_t hdb_error_to_cs(int res)
cs_error_t votequorum_context_set(votequorum_handle_t handle, void *context)
votequorum_context_set
uint64_t votequorum_handle_t
votequorum_handle_t
The req_lib_votequorum_qdevice_master_wins struct.
DECLARE_HDB_DATABASE(votequorum_handle_t_db, votequorum_inst_free)
votequorum_callbacks_t callbacks
char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
char qdevice_name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
cs_error_t votequorum_dispatch(votequorum_handle_t handle, cs_dispatch_flags_t dispatch_types)
Dispatch messages and configuration changes.
The req_lib_votequorum_qdevice_unregister struct.
The res_lib_votequorum_quorum_notification struct.
The res_lib_votequorum_status struct.
char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
The votequorum_node_t struct.
The req_lib_votequorum_general struct.
cs_error_t votequorum_qdevice_update(votequorum_handle_t handle, const char *oldname, const char *newname)
Update registered name of a quorum device.
cs_error_t votequorum_finalize(votequorum_handle_t handle)
Close the quorum handle.
uint32_t expected_votes
#define IPC_DISPATCH_SIZE
Definition: lib/util.h:51
cs_error_t votequorum_setexpected(votequorum_handle_t handle, unsigned int expected_votes)
set expected_votes
cs_error_t votequorum_fd_get(votequorum_handle_t handle, int *fd)
Get a file descriptor on which to poll.
uint32_t flags
The req_lib_votequorum_getinfo struct.
char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
votequorum_nodelist_notification_fn_t votequorum_nodelist_notify_fn
cs_error_t votequorum_qdevice_register(votequorum_handle_t handle, const char *name)
Register a quorum device.
The req_lib_votequorum_qdevice_update struct.
#define IPC_REQUEST_SIZE
Definition: lib/util.h:49
cs_error_t
The cs_error_t enum.
Definition: corotypes.h:97
cs_error_t votequorum_context_get(votequorum_handle_t handle, void **context)
Save and retrieve private data/context.
The req_lib_votequorum_setvotes struct.
cs_dispatch_flags_t
The cs_dispatch_flags_t enum.
Definition: corotypes.h:83
votequorum_expectedvotes_notification_fn_t votequorum_expectedvotes_notify_fn
The req_lib_votequorum_setexpected struct.
The res_lib_votequorum_expectedvotes_notification struct.
cs_error_t votequorum_qdevice_poll(votequorum_handle_t handle, const char *name, unsigned int cast_vote, votequorum_ring_id_t ring_id)
Poll a quorum device.
The req_lib_votequorum_qdevice_register struct.
char qdevice_name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
char newname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
cs_error_t votequorum_qdevice_master_wins(votequorum_handle_t handle, const char *name, unsigned int allow)
Allow qdevice to tell votequorum if master_wins can be enabled or not.
cs_error_t votequorum_trackstop(votequorum_handle_t handle)
votequorum_trackstop
qb_ipcc_connection_t * c
The votequorum_info struct.
The req_lib_votequorum_trackstart struct.
#define VOTEQUORUM_QDEVICE_MAX_NAME_LEN
The req_lib_votequorum_qdevice_poll struct.
votequorum_quorum_notification_fn_t votequorum_quorum_notify_fn
char oldname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
The votequorum_ring_id_t struct.
The res_lib_votequorum_getinfo struct.
cs_error_t votequorum_qdevice_unregister(votequorum_handle_t handle, const char *name)
Unregister a quorum device.
unsigned int nodeid
Definition: coroapi.h:75
#define CS_IPC_TIMEOUT_MS
Definition: corotypes.h:130
cs_error_t votequorum_getinfo(votequorum_handle_t handle, unsigned int nodeid, struct votequorum_info *info)
Get quorum information.
struct memb_ring_id ring_id
Definition: totemsrp.c:264
cs_error_t qb_to_cs_error(int result)
qb_to_cs_error