2 * Copyright (c) 2006-2007 Red Hat Inc
6 * Author: Patrick Caulfield <pcaulfie@redhat.com>
8 * This software licensed under BSD license, the text of which follows:
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
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.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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.
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <sys/select.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
52 static int show_ip
= 0;
54 void print_cpgname (struct cpg_name
*name
)
58 for (i
= 0; i
< name
->length
; i
++) {
59 printf ("%c", name
->value
[i
]);
63 void DeliverCallback (
65 struct cpg_name
*groupName
,
73 saddr
.s_addr
= nodeid
;
74 printf("DeliverCallback: message (len=%d)from node/pid %s/%d: '%s'\n",
75 msg_len
, inet_ntoa(saddr
), pid
, (char *)msg
);
78 printf("DeliverCallback: message (len=%d)from node/pid %d/%d: '%s'\n", msg_len
, nodeid
, pid
, (char *)msg
);
82 void ConfchgCallback (
84 struct cpg_name
*groupName
,
85 struct cpg_address
*member_list
, int member_list_entries
,
86 struct cpg_address
*left_list
, int left_list_entries
,
87 struct cpg_address
*joined_list
, int joined_list_entries
)
92 printf("\nConfchgCallback: group '");
93 print_cpgname(groupName
);
95 for (i
=0; i
<joined_list_entries
; i
++) {
97 saddr
.s_addr
= joined_list
[i
].nodeid
;
98 printf("joined node/pid: %s/%d reason: %d\n",
99 inet_ntoa (saddr
), joined_list
[i
].pid
,
100 joined_list
[i
].reason
);
103 printf("joined node/pid: %d/%d reason: %d\n",
104 joined_list
[i
].nodeid
, joined_list
[i
].pid
,
105 joined_list
[i
].reason
);
109 for (i
=0; i
<left_list_entries
; i
++) {
111 saddr
.s_addr
= left_list
[i
].nodeid
;
112 printf("left node/pid: %s/%d reason: %d\n",
113 inet_ntoa (saddr
), left_list
[i
].pid
,
114 left_list
[i
].reason
);
117 printf("left node/pid: %d/%d reason: %d\n",
118 left_list
[i
].nodeid
, left_list
[i
].pid
,
119 left_list
[i
].reason
);
123 printf("nodes in group now %d\n", member_list_entries
);
124 for (i
=0; i
<member_list_entries
; i
++) {
126 saddr
.s_addr
= member_list
[i
].nodeid
;
127 printf("node/pid: %s/%d\n",
128 inet_ntoa (saddr
), member_list
[i
].pid
);
131 printf("node/pid: %d/%d\n",
132 member_list
[i
].nodeid
, member_list
[i
].pid
);
137 NOTE: in reality we should also check the nodeid */
138 if (left_list_entries
&& left_list
[0].pid
== getpid()) {
139 printf("We have left the building\n");
144 cpg_callbacks_t callbacks
= {
145 .cpg_deliver_fn
= DeliverCallback
,
146 .cpg_confchg_fn
= ConfchgCallback
,
149 void sigintr_handler (int signum
) {
152 static struct cpg_name group_name
;
154 int main (int argc
, char *argv
[]) {
159 const char *options
= "i";
163 while ( (opt
= getopt(argc
, argv
, options
)) != -1 ) {
172 strcpy(group_name
.value
, argv
[optind
]);
173 group_name
.length
= strlen(argv
[optind
])+1;
176 strcpy(group_name
.value
, "GROUP");
177 group_name
.length
= 6;
180 result
= cpg_initialize (&handle
, &callbacks
);
181 if (result
!= SA_AIS_OK
) {
182 printf ("Could not initialize Cluster Process Group API instance error %d\n", result
);
185 result
= cpg_local_get (handle
, &nodeid
);
186 if (result
!= SA_AIS_OK
) {
187 printf ("Could not get local node id\n");
191 printf ("Local node id is %x\n", nodeid
);
192 result
= cpg_join(handle
, &group_name
);
193 if (result
!= SA_AIS_OK
) {
194 printf ("Could not join process group, error %d\n", result
);
199 cpg_fd_get(handle
, &select_fd
);
200 printf ("Type EXIT to finish\n");
202 FD_SET (select_fd
, &read_fds
);
203 FD_SET (STDIN_FILENO
, &read_fds
);
204 result
= select (select_fd
+ 1, &read_fds
, 0, 0, 0);
208 if (FD_ISSET (STDIN_FILENO
, &read_fds
)) {
212 fgets(inbuf
, sizeof(inbuf
), stdin
);
213 if (strncmp(inbuf
, "EXIT", 4) == 0) {
214 cpg_leave(handle
, &group_name
);
217 iov
.iov_base
= inbuf
;
218 iov
.iov_len
= strlen(inbuf
)+1;
219 cpg_mcast_joined(handle
, CPG_TYPE_AGREED
, &iov
, 1);
222 if (FD_ISSET (select_fd
, &read_fds
)) {
223 if (cpg_dispatch (handle
, CPG_DISPATCH_ALL
) != SA_AIS_OK
)
226 } while (result
&& !quit
);
229 result
= cpg_finalize (handle
);
230 printf ("Finalize result is %d (should be 1)\n", result
);