corosync  2.3.5
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,
74  votequorum_callbacks_t *callbacks)
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;
440  char dispatch_buf[IPC_DISPATCH_SIZE];
442 
443  if (dispatch_types != CS_DISPATCH_ONE &&
444  dispatch_types != CS_DISPATCH_ALL &&
445  dispatch_types != CS_DISPATCH_BLOCKING &&
446  dispatch_types != CS_DISPATCH_ONE_NONBLOCKING) {
447 
448  return (CS_ERR_INVALID_PARAM);
449  }
450 
451  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle,
452  (void *)&votequorum_inst));
453  if (error != CS_OK) {
454  return (error);
455  }
456 
457  /*
458  * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and
459  * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING
460  */
461  if (dispatch_types == CS_DISPATCH_ALL || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
462  timeout = 0;
463  }
464 
465  dispatch_data = (struct qb_ipc_response_header *)dispatch_buf;
466  do {
467  error = qb_to_cs_error (qb_ipcc_event_recv (
468  votequorum_inst->c,
469  dispatch_buf,
471  timeout));
472  if (error == CS_ERR_BAD_HANDLE) {
473  error = CS_OK;
474  goto error_put;
475  }
476  if (error == CS_ERR_TRY_AGAIN) {
477  if (dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
478  /*
479  * Don't mask error
480  */
481  goto error_put;
482  }
483  error = CS_OK;
484  if (dispatch_types == CS_DISPATCH_ALL) {
485  break; /* exit do while cont is 1 loop */
486  } else {
487  continue; /* next poll */
488  }
489  }
490  if (error != CS_OK) {
491  goto error_put;
492  }
493 
494  /*
495  * Make copy of callbacks, message data, unlock instance, and call callback
496  * A risk of this dispatch method is that the callback routines may
497  * operate at the same time that votequorum_finalize has been called in another thread.
498  */
499  memcpy (&callbacks, &votequorum_inst->callbacks, sizeof (votequorum_callbacks_t));
500 
501  /*
502  * Dispatch incoming message
503  */
504  switch (dispatch_data->id) {
505 
507  if (callbacks.votequorum_notify_fn == NULL) {
508  break;
509  }
510  res_lib_votequorum_notification = (struct res_lib_votequorum_notification *)dispatch_data;
511  marshall_from_mar_votequorum_ring_id (&ring_id, &res_lib_votequorum_notification->ring_id);
512 
513  callbacks.votequorum_notify_fn ( handle,
514  res_lib_votequorum_notification->context,
515  res_lib_votequorum_notification->quorate,
516  ring_id,
517  res_lib_votequorum_notification->node_list_entries,
518  (votequorum_node_t *)res_lib_votequorum_notification->node_list );
519  ;
520  break;
521 
523  if (callbacks.votequorum_expectedvotes_notify_fn == NULL) {
524  break;
525  }
526  res_lib_votequorum_expectedvotes_notification = (struct res_lib_votequorum_expectedvotes_notification *)dispatch_data;
527 
528  callbacks.votequorum_expectedvotes_notify_fn ( handle,
529  res_lib_votequorum_expectedvotes_notification->context,
530  res_lib_votequorum_expectedvotes_notification->expected_votes);
531  break;
532 
533  default:
534  error = CS_ERR_LIBRARY;
535  goto error_put;
536  break;
537  }
538  if (votequorum_inst->finalize) {
539  /*
540  * If the finalize has been called then get out of the dispatch.
541  */
542  error = CS_ERR_BAD_HANDLE;
543  goto error_put;
544  }
545 
546  /*
547  * Determine if more messages should be processed
548  */
549  if (dispatch_types == CS_DISPATCH_ONE || dispatch_types == CS_DISPATCH_ONE_NONBLOCKING) {
550  cont = 0;
551  }
552  } while (cont);
553 
554 
555 error_put:
556  hdb_handle_put (&votequorum_handle_t_db, handle);
557  return (error);
558 }
559 
561  votequorum_handle_t handle,
562  const char *name)
563 {
564  cs_error_t error;
566  struct iovec iov;
567  struct req_lib_votequorum_qdevice_register req_lib_votequorum_qdevice_register;
568  struct res_lib_votequorum_status res_lib_votequorum_status;
569 
570  if ((strlen(name) == 0) ||
571  (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
572  return CS_ERR_INVALID_PARAM;
573  }
574 
575  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
576  if (error != CS_OK) {
577  return (error);
578  }
579 
580 
581  req_lib_votequorum_qdevice_register.header.size = sizeof (struct req_lib_votequorum_qdevice_register);
582  req_lib_votequorum_qdevice_register.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_REGISTER;
583  strcpy(req_lib_votequorum_qdevice_register.name, name);
584 
585  iov.iov_base = (char *)&req_lib_votequorum_qdevice_register;
586  iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_register);
587 
588  error = qb_to_cs_error(qb_ipcc_sendv_recv (
589  votequorum_inst->c,
590  &iov,
591  1,
592  &res_lib_votequorum_status,
593  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
594 
595  if (error != CS_OK) {
596  goto error_exit;
597  }
598 
599  error = res_lib_votequorum_status.header.error;
600 
601 error_exit:
602  hdb_handle_put (&votequorum_handle_t_db, handle);
603 
604  return (error);
605 }
606 
608  votequorum_handle_t handle,
609  const char *name,
610  unsigned int cast_vote,
612 {
613  cs_error_t error;
615  struct iovec iov;
616  struct req_lib_votequorum_qdevice_poll req_lib_votequorum_qdevice_poll;
617  struct res_lib_votequorum_status res_lib_votequorum_status;
618 
619  if ((strlen(name) == 0) ||
620  (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
621  return CS_ERR_INVALID_PARAM;
622  }
623 
624  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
625  if (error != CS_OK) {
626  return (error);
627  }
628 
629  req_lib_votequorum_qdevice_poll.header.size = sizeof (struct req_lib_votequorum_qdevice_poll);
630  req_lib_votequorum_qdevice_poll.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_POLL;
631  strcpy(req_lib_votequorum_qdevice_poll.name, name);
632  req_lib_votequorum_qdevice_poll.cast_vote = cast_vote;
633  marshall_to_mar_votequorum_ring_id(&req_lib_votequorum_qdevice_poll.ring_id, &ring_id);
634 
635  iov.iov_base = (char *)&req_lib_votequorum_qdevice_poll;
636  iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_poll);
637 
638  error = qb_to_cs_error(qb_ipcc_sendv_recv (
639  votequorum_inst->c,
640  &iov,
641  1,
642  &res_lib_votequorum_status,
643  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
644 
645  if (error != CS_OK) {
646  goto error_exit;
647  }
648 
649  error = res_lib_votequorum_status.header.error;
650 
651 error_exit:
652  hdb_handle_put (&votequorum_handle_t_db, handle);
653 
654  return (error);
655 }
656 
658  votequorum_handle_t handle,
659  const char *name,
660  unsigned int allow)
661 {
662  cs_error_t error;
664  struct iovec iov;
665  struct req_lib_votequorum_qdevice_master_wins req_lib_votequorum_qdevice_master_wins;
666  struct res_lib_votequorum_status res_lib_votequorum_status;
667 
668  if ((strlen(name) == 0) ||
669  (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
670  return CS_ERR_INVALID_PARAM;
671  }
672 
673  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
674  if (error != CS_OK) {
675  return (error);
676  }
677 
678  req_lib_votequorum_qdevice_master_wins.header.size = sizeof (struct req_lib_votequorum_qdevice_master_wins);
679  req_lib_votequorum_qdevice_master_wins.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_MASTER_WINS;
680  strcpy(req_lib_votequorum_qdevice_master_wins.name, name);
681  req_lib_votequorum_qdevice_master_wins.allow = allow;
682 
683  iov.iov_base = (char *)&req_lib_votequorum_qdevice_master_wins;
684  iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_master_wins);
685 
686  error = qb_to_cs_error(qb_ipcc_sendv_recv (
687  votequorum_inst->c,
688  &iov,
689  1,
690  &res_lib_votequorum_status,
691  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
692 
693  if (error != CS_OK) {
694  goto error_exit;
695  }
696 
697  error = res_lib_votequorum_status.header.error;
698 
699 error_exit:
700  hdb_handle_put (&votequorum_handle_t_db, handle);
701 
702  return (error);
703 }
704 
706  votequorum_handle_t handle,
707  const char *oldname,
708  const char *newname)
709 {
710  cs_error_t error;
712  struct iovec iov;
713  struct req_lib_votequorum_qdevice_update req_lib_votequorum_qdevice_update;
714  struct res_lib_votequorum_status res_lib_votequorum_status;
715 
716  if ((strlen(oldname) == 0) ||
717  (strlen(oldname) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN) ||
718  (strlen(newname) == 0) ||
719  (strlen(newname) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
720  return CS_ERR_INVALID_PARAM;
721  }
722 
723  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
724  if (error != CS_OK) {
725  return (error);
726  }
727 
728  req_lib_votequorum_qdevice_update.header.size = sizeof (struct req_lib_votequorum_qdevice_update);
729  req_lib_votequorum_qdevice_update.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_UPDATE;
730  strcpy(req_lib_votequorum_qdevice_update.oldname, oldname);
731  strcpy(req_lib_votequorum_qdevice_update.newname, newname);
732 
733  iov.iov_base = (char *)&req_lib_votequorum_qdevice_update;
734  iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_update);
735 
736  error = qb_to_cs_error(qb_ipcc_sendv_recv (
737  votequorum_inst->c,
738  &iov,
739  1,
740  &res_lib_votequorum_status,
741  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
742 
743  if (error != CS_OK) {
744  goto error_exit;
745  }
746 
747  error = res_lib_votequorum_status.header.error;
748 
749 error_exit:
750  hdb_handle_put (&votequorum_handle_t_db, handle);
751 
752  return (error);
753 }
754 
756  votequorum_handle_t handle,
757  const char *name)
758 {
759  cs_error_t error;
761  struct iovec iov;
762  struct req_lib_votequorum_qdevice_unregister req_lib_votequorum_qdevice_unregister;
763  struct res_lib_votequorum_status res_lib_votequorum_status;
764 
765  if ((strlen(name) == 0) ||
766  (strlen(name) >= VOTEQUORUM_QDEVICE_MAX_NAME_LEN)) {
767  return CS_ERR_INVALID_PARAM;
768  }
769 
770  error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
771  if (error != CS_OK) {
772  return (error);
773  }
774 
775  req_lib_votequorum_qdevice_unregister.header.size = sizeof (struct req_lib_votequorum_qdevice_unregister);
776  req_lib_votequorum_qdevice_unregister.header.id = MESSAGE_REQ_VOTEQUORUM_QDEVICE_UNREGISTER;
777  strcpy(req_lib_votequorum_qdevice_unregister.name, name);
778 
779  iov.iov_base = (char *)&req_lib_votequorum_qdevice_unregister;
780  iov.iov_len = sizeof (struct req_lib_votequorum_qdevice_unregister);
781 
782  error = qb_to_cs_error(qb_ipcc_sendv_recv (
783  votequorum_inst->c,
784  &iov,
785  1,
786  &res_lib_votequorum_status,
787  sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
788 
789  if (error != CS_OK) {
790  goto error_exit;
791  }
792 
793  error = res_lib_votequorum_status.header.error;
794 
795 error_exit:
796  hdb_handle_put (&votequorum_handle_t_db, handle);
797 
798  return (error);
799 }
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
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)
uint64_t votequorum_handle_t
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.
char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
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
char name[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
cs_error_t votequorum_qdevice_register(votequorum_handle_t handle, const char *name)
Register a quorum device.
#define IPC_REQUEST_SIZE
Definition: lib/util.h:49
cs_error_t
Definition: corotypes.h:78
cs_error_t votequorum_context_get(votequorum_handle_t handle, void **context)
Save and retrieve private data/context.
cs_dispatch_flags_t
Definition: corotypes.h:67
votequorum_expectedvotes_notification_fn_t votequorum_expectedvotes_notify_fn
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.
votequorum_notification_fn_t votequorum_notify_fn
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)
qb_ipcc_connection_t * c
#define VOTEQUORUM_QDEVICE_MAX_NAME_LEN
char oldname[VOTEQUORUM_QDEVICE_MAX_NAME_LEN]
cs_error_t votequorum_qdevice_unregister(votequorum_handle_t handle, const char *name)
Unregister a quorum device.
unsigned int nodeid
Definition: coroapi.h:65
#define CS_IPC_TIMEOUT_MS
Definition: corotypes.h:111
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:64
cs_error_t qb_to_cs_error(int result)