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