]>
Commit | Line | Data |
---|---|---|
a8256ad5 | 1 | /* |
fcba1652 | 2 | * Copyright (c) 2009-2014 Red Hat, Inc. |
a8256ad5 CC |
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 | */ | |
031c02f5 FDN |
34 | |
35 | #include <config.h> | |
36 | ||
a8256ad5 | 37 | #include <sys/types.h> |
b8902464 | 38 | #include <inttypes.h> |
a8256ad5 CC |
39 | #include <stdio.h> |
40 | #include <stdint.h> | |
fcba1652 | 41 | #include <string.h> |
a8256ad5 CC |
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 | ||
b8902464 | 49 | static votequorum_ring_id_t last_received_ring_id; |
f8413350 JF |
50 | static votequorum_ring_id_t ring_id_to_send; |
51 | static int no_sent_old_ringid = 0; | |
b8902464 | 52 | |
fcba1652 | 53 | static int print_info(int ok_to_fail) |
a8256ad5 | 54 | { |
cc7bfeb4 | 55 | struct votequorum_info info; |
a8256ad5 CC |
56 | int err; |
57 | ||
fcba1652 | 58 | if ( (err=votequorum_getinfo(handle, VOTEQUORUM_QDEVICE_NODEID, &info)) != CS_OK) { |
cc7bfeb4 | 59 | fprintf(stderr, "votequorum_getinfo error %d: %s\n", err, ok_to_fail?"OK":"FAILED"); |
fcba1652 CC |
60 | return -1; |
61 | } | |
a8256ad5 | 62 | else { |
cc7bfeb4 FDN |
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) { | |
fcba1652 | 66 | printf("alive "); |
cc7bfeb4 FDN |
67 | } |
68 | if (info.flags & VOTEQUORUM_INFO_QDEVICE_CAST_VOTE) { | |
fcba1652 | 69 | printf("cast-vote "); |
cc7bfeb4 | 70 | } |
2f369e70 | 71 | if (info.flags & VOTEQUORUM_INFO_QDEVICE_MASTER_WINS) { |
fcba1652 | 72 | printf("master-wins"); |
2f369e70 | 73 | } |
fcba1652 | 74 | printf("\n\n"); |
a8256ad5 | 75 | } |
fcba1652 CC |
76 | return 0; |
77 | } | |
78 | ||
cf0028c8 | 79 | static void votequorum_nodelist_notification_fn( |
b8902464 JF |
80 | votequorum_handle_t vq_handle, |
81 | uint64_t context, | |
b8902464 JF |
82 | votequorum_ring_id_t ring_id, |
83 | uint32_t node_list_entries, | |
3a5d51fc | 84 | uint32_t node_list[]) |
b8902464 JF |
85 | { |
86 | ||
cf0028c8 | 87 | printf("votequorum nodelist notification called \n"); |
5731af27 | 88 | printf(" current ringid = (" CS_PRI_RING_ID ")\n", ring_id.nodeid, ring_id.seq); |
b8902464 JF |
89 | printf("\n"); |
90 | ||
91 | memcpy(&last_received_ring_id, &ring_id, sizeof(ring_id)); | |
f8413350 | 92 | no_sent_old_ringid = 0; |
b8902464 JF |
93 | } |
94 | ||
fcba1652 CC |
95 | static void usage(const char *command) |
96 | { | |
f8413350 JF |
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"); | |
fcba1652 CC |
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"); | |
fc9817fe | 102 | printf(" -c Don't cast vote (default is to cast vote)\n"); |
fcba1652 CC |
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"); | |
a8256ad5 CC |
106 | } |
107 | ||
108 | int main(int argc, char *argv[]) | |
109 | { | |
cb5fd775 | 110 | int ret = 0; |
fcba1652 CC |
111 | int cast_vote = 1, master_wins = 0; |
112 | int pollcount=0, polltime=1, quiet=0, once=0; | |
f8413350 | 113 | int send_old_ringid = 0; |
a8256ad5 | 114 | int err; |
fcba1652 | 115 | int opt; |
b8902464 | 116 | votequorum_callbacks_t callbacks; |
fcba1652 | 117 | const char *devicename = "QDEVICE"; |
f8413350 | 118 | const char *options = "F:n:p:t:cmq1h"; |
b8902464 JF |
119 | |
120 | memset(&callbacks, 0, sizeof(callbacks)); | |
cf0028c8 | 121 | callbacks.votequorum_nodelist_notify_fn = votequorum_nodelist_notification_fn; |
b8902464 | 122 | |
fcba1652 CC |
123 | while ((opt = getopt(argc, argv, options)) != -1) { |
124 | switch (opt) { | |
125 | case 'm': | |
126 | master_wins = 1; | |
127 | break; | |
128 | case 'c': | |
fc9817fe | 129 | cast_vote = 0; |
fcba1652 CC |
130 | break; |
131 | case '1': | |
132 | once = 1; | |
133 | break; | |
134 | case 'q': | |
135 | quiet = 1; | |
136 | break; | |
f8413350 JF |
137 | case 'F': |
138 | send_old_ringid = atoi(optarg)+1; | |
139 | break; | |
fcba1652 CC |
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 | } | |
a8256ad5 | 154 | |
b8902464 | 155 | if ( (err=votequorum_initialize(&handle, &callbacks)) != CS_OK) { |
a8256ad5 CC |
156 | fprintf(stderr, "votequorum_initialize FAILED: %d\n", err); |
157 | return -1; | |
158 | } | |
159 | ||
fcba1652 CC |
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); | |
a8256ad5 | 164 | } |
fcba1652 CC |
165 | |
166 | if (!quiet) { | |
167 | print_info(1); | |
2dae49e5 | 168 | } |
fcba1652 CC |
169 | if (once) { |
170 | exit(0); | |
2f369e70 | 171 | } |
a8256ad5 CC |
172 | |
173 | if (argc >= 2) { | |
b8902464 JF |
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 | ||
fcba1652 | 180 | if ( (err=votequorum_qdevice_register(handle, devicename)) != CS_OK) { |
ccd36af0 | 181 | fprintf(stderr, "qdevice_register FAILED: %d\n", err); |
cb5fd775 FDN |
182 | ret = -1; |
183 | goto out; | |
184 | } | |
a8256ad5 | 185 | |
fcba1652 | 186 | if ( (err=votequorum_qdevice_master_wins(handle, devicename, master_wins)) != CS_OK) { |
2f369e70 FDN |
187 | fprintf(stderr, "qdevice_master_wins FAILED: %d\n", err); |
188 | ret = -1; | |
189 | goto out; | |
190 | } | |
191 | ||
b8902464 | 192 | |
fcba1652 | 193 | while (--pollcount) { |
b8902464 JF |
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 | ||
fcba1652 | 200 | if (!quiet) print_info(0); |
f8413350 JF |
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 && | |
b8902464 | 212 | err != CS_ERR_MESSAGE_ERROR) { |
ccd36af0 | 213 | fprintf(stderr, "qdevice poll FAILED: %d\n", err); |
cb5fd775 FDN |
214 | ret = -1; |
215 | goto out; | |
216 | } | |
b8902464 JF |
217 | if (err == CS_ERR_MESSAGE_ERROR) { |
218 | fprintf(stderr, "qdevice poll passed OLD ring_id\n"); | |
219 | } | |
220 | ||
fcba1652 | 221 | if (!quiet) print_info(0); |
a8256ad5 CC |
222 | sleep(polltime); |
223 | } | |
fcba1652 | 224 | if ((err= votequorum_qdevice_unregister(handle, devicename)) != CS_OK) { |
ccd36af0 | 225 | fprintf(stderr, "qdevice unregister FAILED: %d\n", err); |
cb5fd775 FDN |
226 | ret = -1; |
227 | goto out; | |
228 | } | |
a8256ad5 | 229 | } |
fcba1652 CC |
230 | |
231 | if (!quiet) print_info(1); | |
a8256ad5 | 232 | |
cb5fd775 | 233 | out: |
2cd6ad99 | 234 | votequorum_finalize(handle); |
cb5fd775 | 235 | return ret; |
a8256ad5 | 236 | } |