4 Copyright (C) Andrew Tridgell 2006
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "lib/events/events.h"
23 #include "system/filesys.h"
26 enum my_functions
{FUNC_SORT
=1, FUNC_FETCH
=2};
28 static int int_compare(int *i1
, int *i2
)
34 add an integer into a record in sorted order
36 static int sort_func(struct ctdb_call_info
*call
)
38 if (call
->call_data
== NULL
||
39 call
->call_data
->dsize
!= sizeof(int)) {
40 return CTDB_ERR_INVALID
;
42 call
->new_data
= talloc(call
, TDB_DATA
);
43 if (call
->new_data
== NULL
) {
44 return CTDB_ERR_NOMEM
;
46 call
->new_data
->dptr
= talloc_size(call
,
47 call
->record_data
.dsize
+
48 call
->call_data
->dsize
);
49 if (call
->new_data
->dptr
== NULL
) {
50 return CTDB_ERR_NOMEM
;
52 call
->new_data
->dsize
= call
->record_data
.dsize
+ call
->call_data
->dsize
;
53 memcpy(call
->new_data
->dptr
,
54 call
->record_data
.dptr
, call
->record_data
.dsize
);
55 memcpy(call
->new_data
->dptr
+call
->record_data
.dsize
,
56 call
->call_data
->dptr
, call
->call_data
->dsize
);
58 qsort(call
->new_data
->dptr
, call
->new_data
->dsize
/ sizeof(int),
59 sizeof(int), (comparison_fn_t
)int_compare
);
65 ctdb call function to fetch a record
67 static int fetch_func(struct ctdb_call_info
*call
)
69 call
->reply_data
= &call
->record_data
;
76 int main(int argc
, const char *argv
[])
78 struct ctdb_context
*ctdb
;
79 struct ctdb_db_context
*ctdb_db
;
80 const char *nlist
= NULL
;
81 const char *transport
= "tcp";
82 const char *myaddress
= NULL
;
85 struct poptOption popt_options
[] = {
87 { "nlist", 0, POPT_ARG_STRING
, &nlist
, 0, "node list file", "filename" },
88 { "listen", 0, POPT_ARG_STRING
, &myaddress
, 0, "address to listen on", "address" },
89 { "transport", 0, POPT_ARG_STRING
, &transport
, 0, "protocol transport", NULL
},
90 { "self-connect", 0, POPT_ARG_NONE
, &self_connect
, 0, "enable self connect", "boolean" },
94 const char **extra_argv
;
98 struct event_context
*ev
;
99 struct ctdb_call call
;
101 pc
= poptGetContext(argv
[0], argc
, argv
, popt_options
, POPT_CONTEXT_KEEP_FIRST
);
103 while ((opt
= poptGetNextOpt(pc
)) != -1) {
106 fprintf(stderr
, "Invalid option %s: %s\n",
107 poptBadOption(pc
, 0), poptStrerror(opt
));
112 /* setup the remaining options for the main program to use */
113 extra_argv
= poptGetArgs(pc
);
116 while (extra_argv
[extra_argc
]) extra_argc
++;
119 if (nlist
== NULL
|| myaddress
== NULL
) {
120 printf("You must provide a node list with --nlist and an address with --listen\n");
124 ev
= event_context_init(NULL
);
126 /* initialise ctdb */
127 ctdb
= ctdb_init(ev
);
129 printf("Failed to init ctdb\n");
134 ctdb_set_flags(ctdb
, CTDB_FLAG_SELF_CONNECT
);
137 ret
= ctdb_set_transport(ctdb
, transport
);
139 printf("ctdb_set_transport failed - %s\n", ctdb_errstr(ctdb
));
143 /* tell ctdb what address to listen on */
144 ret
= ctdb_set_address(ctdb
, myaddress
);
146 printf("ctdb_set_address failed - %s\n", ctdb_errstr(ctdb
));
150 /* tell ctdb what nodes are available */
151 ret
= ctdb_set_nlist(ctdb
, nlist
);
153 printf("ctdb_set_nlist failed - %s\n", ctdb_errstr(ctdb
));
157 /* attach to a specific database */
158 ctdb_db
= ctdb_attach(ctdb
, "test.tdb", TDB_DEFAULT
, O_RDWR
|O_CREAT
|O_TRUNC
, 0666);
160 printf("ctdb_attach failed - %s\n", ctdb_errstr(ctdb
));
164 /* setup a ctdb call function */
165 ret
= ctdb_set_call(ctdb_db
, sort_func
, FUNC_SORT
);
166 ret
= ctdb_set_call(ctdb_db
, fetch_func
, FUNC_FETCH
);
168 /* start the protocol running */
169 ret
= ctdb_start(ctdb
);
171 /* wait until all nodes are connected (should not be needed
172 outide of test code) */
173 ctdb_connect_wait(ctdb
);
176 call
.key
.dptr
= discard_const("test");
177 call
.key
.dsize
= strlen("test")+1;
179 /* add some random data */
181 int v
= random() % 1000;
183 call
.call_id
= FUNC_SORT
;
184 call
.call_data
.dptr
= (uint8_t *)&v
;
185 call
.call_data
.dsize
= sizeof(v
);
187 ret
= ctdb_call(ctdb_db
, &call
);
189 printf("ctdb_call FUNC_SORT failed - %s\n", ctdb_errstr(ctdb
));
194 /* fetch the record */
195 call
.call_id
= FUNC_FETCH
;
196 call
.call_data
.dptr
= NULL
;
197 call
.call_data
.dsize
= 0;
199 ret
= ctdb_call(ctdb_db
, &call
);
201 printf("ctdb_call FUNC_FETCH failed - %s\n", ctdb_errstr(ctdb
));
205 for (i
=0;i
<call
.reply_data
.dsize
/sizeof(int);i
++) {
206 printf("%3d\n", ((int *)call
.reply_data
.dptr
)[i
]);
208 talloc_free(call
.reply_data
.dptr
);
210 /* go into a wait loop to allow other nodes to complete */
211 ctdb_wait_loop(ctdb
);