s4:dsdb: allocate DSDB_CONTROL_DBCHECK_FIX_DUPLICATE_LINKS oid
[Samba.git] / ctdb / tests / src / fetch_readonly_loop.c
blob9d5d22e7534c4867561baec745ab1f719e6f1a4f
1 /*
2 simple ctdb benchmark
4 Copyright (C) Amitay Isaacs 2015
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program 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
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "replace.h"
21 #include "system/network.h"
23 #include "lib/util/tevent_unix.h"
25 #include "client/client.h"
26 #include "tests/src/test_options.h"
27 #include "tests/src/cluster_wait.h"
29 #define TESTDB "fetch_readonly_loop.tdb"
30 #define TESTKEY "testkey"
32 struct fetch_loop_state {
33 struct tevent_context *ev;
34 struct ctdb_client_context *client;
35 struct ctdb_db_context *ctdb_db;
36 int num_nodes;
37 int timelimit;
38 TDB_DATA key;
39 int locks_count;
42 static void fetch_loop_start(struct tevent_req *subreq);
43 static void fetch_loop_next(struct tevent_req *subreq);
44 static void fetch_loop_each_second(struct tevent_req *subreq);
45 static void fetch_loop_finish(struct tevent_req *subreq);
47 static struct tevent_req *fetch_loop_send(TALLOC_CTX *mem_ctx,
48 struct tevent_context *ev,
49 struct ctdb_client_context *client,
50 struct ctdb_db_context *ctdb_db,
51 int num_nodes, int timelimit)
53 struct tevent_req *req, *subreq;
54 struct fetch_loop_state *state;
56 req = tevent_req_create(mem_ctx, &state, struct fetch_loop_state);
57 if (req == NULL) {
58 return NULL;
61 state->ev = ev;
62 state->client = client;
63 state->ctdb_db = ctdb_db;
64 state->num_nodes = num_nodes;
65 state->timelimit = timelimit;
66 state->key.dptr = discard_const(TESTKEY);
67 state->key.dsize = strlen(TESTKEY);
69 subreq = cluster_wait_send(state, state->ev, state->client,
70 state->num_nodes);
71 if (tevent_req_nomem(subreq, req)) {
72 return tevent_req_post(req, ev);
74 tevent_req_set_callback(subreq, fetch_loop_start, req);
76 return req;
79 static void fetch_loop_start(struct tevent_req *subreq)
81 struct tevent_req *req = tevent_req_callback_data(
82 subreq, struct tevent_req);
83 struct fetch_loop_state *state = tevent_req_data(
84 req, struct fetch_loop_state);
85 bool status;
86 int ret;
88 status = cluster_wait_recv(subreq, &ret);
89 TALLOC_FREE(subreq);
90 if (! status) {
91 tevent_req_error(req, ret);
92 return;
95 subreq = ctdb_fetch_lock_send(state, state->ev, state->client,
96 state->ctdb_db, state->key, true);
97 if (tevent_req_nomem(subreq, req)) {
98 return;
100 tevent_req_set_callback(subreq, fetch_loop_next, req);
102 if (ctdb_client_pnn(state->client) == 0) {
103 subreq = tevent_wakeup_send(state, state->ev,
104 tevent_timeval_current_ofs(1, 0));
105 if (tevent_req_nomem(subreq, req)) {
106 return;
108 tevent_req_set_callback(subreq, fetch_loop_each_second, req);
111 subreq = tevent_wakeup_send(state, state->ev,
112 tevent_timeval_current_ofs(
113 state->timelimit, 0));
114 if (tevent_req_nomem(subreq, req)) {
115 return;
117 tevent_req_set_callback(subreq, fetch_loop_finish, req);
120 static void fetch_loop_next(struct tevent_req *subreq)
122 struct tevent_req *req = tevent_req_callback_data(
123 subreq, struct tevent_req);
124 struct fetch_loop_state *state = tevent_req_data(
125 req, struct fetch_loop_state);
126 struct ctdb_record_handle *h;
127 int ret;
129 h = ctdb_fetch_lock_recv(subreq, NULL, state, NULL, &ret);
130 TALLOC_FREE(subreq);
131 if (h == NULL) {
132 tevent_req_error(req, ret);
133 return;
136 state->locks_count += 1;
137 talloc_free(h);
139 subreq = ctdb_fetch_lock_send(state, state->ev, state->client,
140 state->ctdb_db, state->key, true);
141 if (tevent_req_nomem(subreq, req)) {
142 return;
144 tevent_req_set_callback(subreq, fetch_loop_next, req);
147 static void fetch_loop_each_second(struct tevent_req *subreq)
149 struct tevent_req *req = tevent_req_callback_data(
150 subreq, struct tevent_req);
151 struct fetch_loop_state *state = tevent_req_data(
152 req, struct fetch_loop_state);
153 bool status;
155 status = tevent_wakeup_recv(subreq);
156 TALLOC_FREE(subreq);
157 if (! status) {
158 tevent_req_error(req, EIO);
159 return;
162 printf("Locks:%d\r", state->locks_count);
163 fflush(stdout);
165 subreq = tevent_wakeup_send(state, state->ev,
166 tevent_timeval_current_ofs(1, 0));
167 if (tevent_req_nomem(subreq, req)) {
168 return;
170 tevent_req_set_callback(subreq, fetch_loop_each_second, req);
173 static void fetch_loop_finish(struct tevent_req *subreq)
175 struct tevent_req *req = tevent_req_callback_data(
176 subreq, struct tevent_req);
177 struct fetch_loop_state *state = tevent_req_data(
178 req, struct fetch_loop_state);
179 bool status;
181 status = tevent_wakeup_recv(subreq);
182 TALLOC_FREE(subreq);
183 if (! status) {
184 tevent_req_error(req, EIO);
185 return;
188 printf("Locks:%d\n", state->locks_count);
190 tevent_req_done(req);
193 static bool fetch_loop_recv(struct tevent_req *req, int *perr)
195 int err;
197 if (tevent_req_is_unix_error(req, &err)) {
198 if (perr != NULL) {
199 *perr = err;
201 return false;
203 return true;
206 int main(int argc, const char *argv[])
208 const struct test_options *opts;
209 TALLOC_CTX *mem_ctx;
210 struct tevent_context *ev;
211 struct ctdb_client_context *client;
212 struct ctdb_db_context *ctdb_db;
213 struct tevent_req *req;
214 int ret;
215 bool status;
217 status = process_options_basic(argc, argv, &opts);
218 if (! status) {
219 exit(1);
222 mem_ctx = talloc_new(NULL);
223 if (mem_ctx == NULL) {
224 fprintf(stderr, "Memory allocation error\n");
225 exit(1);
228 ev = tevent_context_init(mem_ctx);
229 if (ev == NULL) {
230 fprintf(stderr, "Memory allocation error\n");
231 exit(1);
234 ret = ctdb_client_init(mem_ctx, ev, opts->socket, &client);
235 if (ret != 0) {
236 fprintf(stderr, "Failed to initialize client, ret=%d\n", ret);
237 exit(1);
240 if (! ctdb_recovery_wait(ev, client)) {
241 fprintf(stderr, "Memory allocation error\n");
242 exit(1);
245 ret = ctdb_attach(ev, client, tevent_timeval_zero(), TESTDB, 0,
246 &ctdb_db);
247 if (ret != 0) {
248 fprintf(stderr, "Failed to attach to DB %s\n", TESTDB);
249 exit(1);
252 req = fetch_loop_send(mem_ctx, ev, client, ctdb_db,
253 opts->num_nodes, opts->timelimit);
254 if (req == NULL) {
255 fprintf(stderr, "Memory allocation error\n");
256 exit(1);
259 tevent_req_poll(req, ev);
261 status = fetch_loop_recv(req, &ret);
262 if (! status) {
263 fprintf(stderr, "fetch readonly loop test failed\n");
264 exit(1);
267 talloc_free(mem_ctx);
268 return 0;