]> git.proxmox.com Git - mirror_corosync.git/blob - test/testvotequorum2.c
test: Fix cpgtest
[mirror_corosync.git] / test / testvotequorum2.c
1 /*
2 * Copyright (c) 2009-2014 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 #include <config.h>
36
37 #include <sys/types.h>
38 #include <inttypes.h>
39 #include <stdio.h>
40 #include <stdint.h>
41 #include <string.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <corosync/corotypes.h>
45 #include <corosync/votequorum.h>
46
47 static votequorum_handle_t handle;
48
49 static votequorum_ring_id_t last_received_ring_id;
50 static votequorum_ring_id_t ring_id_to_send;
51 static int no_sent_old_ringid = 0;
52
53 static int print_info(int ok_to_fail)
54 {
55 struct votequorum_info info;
56 int err;
57
58 if ( (err=votequorum_getinfo(handle, VOTEQUORUM_QDEVICE_NODEID, &info)) != CS_OK) {
59 fprintf(stderr, "votequorum_getinfo error %d: %s\n", err, ok_to_fail?"OK":"FAILED");
60 return -1;
61 }
62 else {
63 printf("name %s\n", info.qdevice_name);
64 printf("qdevice votes %d\n", info.qdevice_votes);
65 if (info.flags & VOTEQUORUM_INFO_QDEVICE_ALIVE) {
66 printf("alive ");
67 }
68 if (info.flags & VOTEQUORUM_INFO_QDEVICE_CAST_VOTE) {
69 printf("cast-vote ");
70 }
71 if (info.flags & VOTEQUORUM_INFO_QDEVICE_MASTER_WINS) {
72 printf("master-wins");
73 }
74 printf("\n\n");
75 }
76 return 0;
77 }
78
79 static void votequorum_nodelist_notification_fn(
80 votequorum_handle_t vq_handle,
81 uint64_t context,
82 votequorum_ring_id_t ring_id,
83 uint32_t node_list_entries,
84 uint32_t node_list[])
85 {
86
87 printf("votequorum nodelist notification called \n");
88 printf(" current ringid = (" CS_PRI_RING_ID ")\n", ring_id.nodeid, ring_id.seq);
89 printf("\n");
90
91 memcpy(&last_received_ring_id, &ring_id, sizeof(ring_id));
92 no_sent_old_ringid = 0;
93 }
94
95 static void usage(const char *command)
96 {
97 printf("%s [-F <num>] [-p <num>] [-t <time>] [-n <name>] [-c] [-m]\n", command);
98 printf(" -F <num> Number of times to send old ringid before actual ringid is sent (for testing, default = 0)\n");
99 printf(" -p <num> Number of times to poll qdevice (default 0=infinte)\n");
100 printf(" -t <secs> Time (in seconds) to wait between polls (default=1)\n");
101 printf(" -n <name> Name of quorum device (default QDEVICE)\n");
102 printf(" -c Don't cast vote (default is to cast vote)\n");
103 printf(" -q Don't print device status every poll time (default=will print)\n");
104 printf(" -m Master wins (default no)\n");
105 printf(" -1 Print status once and exit\n");
106 }
107
108 int main(int argc, char *argv[])
109 {
110 int ret = 0;
111 int cast_vote = 1, master_wins = 0;
112 int pollcount=0, polltime=1, quiet=0, once=0;
113 int send_old_ringid = 0;
114 int err;
115 int opt;
116 votequorum_callbacks_t callbacks;
117 const char *devicename = "QDEVICE";
118 const char *options = "F:n:p:t:cmq1h";
119
120 memset(&callbacks, 0, sizeof(callbacks));
121 callbacks.votequorum_nodelist_notify_fn = votequorum_nodelist_notification_fn;
122
123 while ((opt = getopt(argc, argv, options)) != -1) {
124 switch (opt) {
125 case 'm':
126 master_wins = 1;
127 break;
128 case 'c':
129 cast_vote = 0;
130 break;
131 case '1':
132 once = 1;
133 break;
134 case 'q':
135 quiet = 1;
136 break;
137 case 'F':
138 send_old_ringid = atoi(optarg)+1;
139 break;
140 case 'p':
141 pollcount = atoi(optarg)+1;
142 break;
143 case 'n':
144 devicename = strdup(optarg);
145 break;
146 case 't':
147 polltime = atoi(optarg);
148 break;
149 case 'h':
150 usage(argv[0]);
151 exit(0);
152 }
153 }
154
155 if ( (err=votequorum_initialize(&handle, &callbacks)) != CS_OK) {
156 fprintf(stderr, "votequorum_initialize FAILED: %d\n", err);
157 return -1;
158 }
159
160 if (quiet && once) {
161 fprintf(stderr, "setting both -q (quet) and -1 (once) makes no sense\n");
162 usage(argv[0]);
163 exit(1);
164 }
165
166 if (!quiet) {
167 print_info(1);
168 }
169 if (once) {
170 exit(0);
171 }
172
173 if (argc >= 2) {
174 if ( (err = votequorum_trackstart(handle, handle, CS_TRACK_CHANGES)) != CS_OK) {
175 fprintf(stderr, "votequorum_trackstart FAILED: %d\n", err);
176 ret = -1;
177 goto out;
178 }
179
180 if ( (err=votequorum_qdevice_register(handle, devicename)) != CS_OK) {
181 fprintf(stderr, "qdevice_register FAILED: %d\n", err);
182 ret = -1;
183 goto out;
184 }
185
186 if ( (err=votequorum_qdevice_master_wins(handle, devicename, master_wins)) != CS_OK) {
187 fprintf(stderr, "qdevice_master_wins FAILED: %d\n", err);
188 ret = -1;
189 goto out;
190 }
191
192
193 while (--pollcount) {
194 if (votequorum_dispatch(handle, CS_DISPATCH_ALL) != CS_OK) {
195 fprintf(stderr, "votequorum_dispatch error\n");
196 ret = -1;
197 goto out;
198 }
199
200 if (!quiet) print_info(0);
201
202 if (no_sent_old_ringid + 1 >= send_old_ringid) {
203 /*
204 * Finally send correct ringid
205 */
206 memcpy(&ring_id_to_send, &last_received_ring_id, sizeof(ring_id_to_send));
207 } else {
208 no_sent_old_ringid++;
209 }
210
211 if ((err=votequorum_qdevice_poll(handle, devicename, cast_vote, ring_id_to_send)) != CS_OK &&
212 err != CS_ERR_MESSAGE_ERROR) {
213 fprintf(stderr, "qdevice poll FAILED: %d\n", err);
214 ret = -1;
215 goto out;
216 }
217 if (err == CS_ERR_MESSAGE_ERROR) {
218 fprintf(stderr, "qdevice poll passed OLD ring_id\n");
219 }
220
221 if (!quiet) print_info(0);
222 sleep(polltime);
223 }
224 if ((err= votequorum_qdevice_unregister(handle, devicename)) != CS_OK) {
225 fprintf(stderr, "qdevice unregister FAILED: %d\n", err);
226 ret = -1;
227 goto out;
228 }
229 }
230
231 if (!quiet) print_info(1);
232
233 out:
234 votequorum_finalize(handle);
235 return ret;
236 }