aio_fork: Fix CID 1273291 Uninitialized scalar variable
[Samba.git] / source3 / torture / test_ctdbconn.c
blob1f80cff5fdfaec2f74797d5b18a6f5a5924fa633
1 /*
2 Unix SMB/CIFS implementation.
3 Test new ctdb API
4 Copyright (C) Volker Lendecke 2012
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 "includes.h"
21 #include "torture/proto.h"
23 #include "ctdb_conn.h"
24 #include "ctdbd_conn.h"
25 #include "lib/util/tevent_unix.h"
26 #include "tdb.h"
28 #include "ctdb_protocol.h"
30 #include "messages.h"
32 struct ctdb_conn_test_state {
33 struct tevent_context *ev;
34 struct ctdb_conn *conn;
35 struct ctdb_msg_channel *channel;
36 int msgno;
39 static void ctdb_conn_test_got_conn(struct tevent_req *subreq);
40 static void ctdb_conn_test_got_pnn(struct tevent_req *subreq);
41 static void ctdb_conn_test_got_channel(struct tevent_req *subreq);
42 static void ctdb_conn_test_got_msg(struct tevent_req *subreq);
43 static void ctdb_conn_test_msg_sent(struct tevent_req *subreq);
45 static struct tevent_req *ctdb_conn_test_send(TALLOC_CTX *mem_ctx,
46 struct tevent_context *ev)
48 struct tevent_req *req, *subreq;
49 struct ctdb_conn_test_state *state;
51 req = tevent_req_create(mem_ctx, &state, struct ctdb_conn_test_state);
52 if (req == NULL) {
53 return NULL;
55 state->ev = ev;
57 subreq = ctdb_conn_init_send(mem_ctx, ev, lp_ctdbd_socket());
58 if (tevent_req_nomem(subreq, req)) {
59 return tevent_req_post(req, ev);
61 tevent_req_set_callback(subreq, ctdb_conn_test_got_conn, req);
62 return req;
65 static void ctdb_conn_test_got_conn(struct tevent_req *subreq)
67 struct tevent_req *req = tevent_req_callback_data(
68 subreq, struct tevent_req);
69 struct ctdb_conn_test_state *state = tevent_req_data(
70 req, struct ctdb_conn_test_state);
71 uint64_t ret;
73 ret = ctdb_conn_init_recv(subreq, state, &state->conn);
74 TALLOC_FREE(subreq);
75 if (tevent_req_error(req, ret)) {
76 return;
78 subreq = ctdb_conn_control_send(state, state->ev, state->conn,
79 CTDB_CURRENT_NODE,
80 CTDB_CONTROL_GET_PNN, 0, 0, NULL, 0);
81 if (tevent_req_nomem(subreq, req)) {
82 return;
84 tevent_req_set_callback(subreq, ctdb_conn_test_got_pnn, req);
87 static void ctdb_conn_test_got_pnn(struct tevent_req *subreq)
89 struct tevent_req *req = tevent_req_callback_data(
90 subreq, struct tevent_req);
91 struct ctdb_conn_test_state *state = tevent_req_data(
92 req, struct ctdb_conn_test_state);
93 int ret;
94 struct ctdb_reply_control *reply;
96 ret = ctdb_conn_control_recv(subreq, talloc_tos(), &reply);
97 TALLOC_FREE(subreq);
98 if (tevent_req_error(req, ret)) {
99 return;
101 printf("vnn=%d\n", (int)reply->status);
103 subreq = ctdb_msg_channel_init_send(
104 state, state->ev, lp_ctdbd_socket(), 999999);
105 if (tevent_req_nomem(subreq, req)) {
106 return;
108 tevent_req_set_callback(subreq, ctdb_conn_test_got_channel, req);
111 static void ctdb_conn_test_got_channel(struct tevent_req *subreq)
113 struct tevent_req *req = tevent_req_callback_data(
114 subreq, struct tevent_req);
115 struct ctdb_conn_test_state *state = tevent_req_data(
116 req, struct ctdb_conn_test_state);
117 int ret;
119 ret = ctdb_msg_channel_init_recv(subreq, state, &state->channel);
120 TALLOC_FREE(subreq);
121 if (tevent_req_error(req, ret)) {
122 return;
125 subreq = ctdb_msg_read_send(state, state->ev, state->channel);
126 if (tevent_req_nomem(subreq, req)) {
127 return;
129 tevent_req_set_callback(subreq, ctdb_conn_test_got_msg, req);
131 state->msgno += 1;
133 subreq = ctdb_conn_msg_write_send(
134 state, state->ev, state->conn, CTDB_CURRENT_NODE, 999999,
135 (uint8_t *)&state->msgno, sizeof(state->msgno));
136 if (tevent_req_nomem(subreq, req)) {
137 return;
139 tevent_req_set_callback(subreq, ctdb_conn_test_msg_sent, req);
142 static void ctdb_conn_test_got_msg(struct tevent_req *subreq)
144 struct tevent_req *req = tevent_req_callback_data(
145 subreq, struct tevent_req);
146 struct ctdb_conn_test_state *state = tevent_req_data(
147 req, struct ctdb_conn_test_state);
148 uint8_t *buf;
149 size_t buf_len;
150 int ret;
152 ret = ctdb_msg_read_recv(subreq, talloc_tos(), &buf, &buf_len);
153 TALLOC_FREE(subreq);
154 if (tevent_req_error(req, ret)) {
155 return;
157 if (buf_len != sizeof(int)) {
158 printf("got invalid msg\n");
159 tevent_req_error(req, EINVAL);
160 return;
162 memcpy(&ret, buf, buf_len);
163 printf("got msg %d\n", ret);
164 if (ret == 5) {
165 tevent_req_done(req);
166 return;
169 subreq = ctdb_msg_read_send(state, state->ev, state->channel);
170 if (tevent_req_nomem(subreq, req)) {
171 return;
173 tevent_req_set_callback(subreq, ctdb_conn_test_got_msg, req);
176 static void ctdb_conn_test_msg_sent(struct tevent_req *subreq)
178 struct tevent_req *req = tevent_req_callback_data(
179 subreq, struct tevent_req);
180 struct ctdb_conn_test_state *state = tevent_req_data(
181 req, struct ctdb_conn_test_state);
182 int ret;
184 ret = ctdb_conn_msg_write_recv(subreq);
185 TALLOC_FREE(subreq);
186 if (tevent_req_error(req, ret)) {
187 return;
189 state->msgno += 1;
191 if (state->msgno >= 10) {
192 return;
195 subreq = ctdb_conn_msg_write_send(
196 state, state->ev, state->conn, CTDB_CURRENT_NODE, 999999,
197 (uint8_t *)&state->msgno, sizeof(state->msgno));
198 if (tevent_req_nomem(subreq, req)) {
199 return;
201 tevent_req_set_callback(subreq, ctdb_conn_test_msg_sent, req);
204 static int ctdb_conn_test_recv(struct tevent_req *req)
206 int err;
207 if (tevent_req_is_unix_error(req, &err)) {
208 return err;
210 return 0;
213 bool run_ctdb_conn(int dummy)
215 struct tevent_context *ev;
216 struct tevent_req *req;
217 int ret;
219 ev = samba_tevent_context_init(talloc_tos());
220 if (ev == NULL) {
221 fprintf(stderr, "tevent_context_init failed\n");
222 return false;
224 req = ctdb_conn_test_send(ev, ev);
225 if (req == NULL) {
226 fprintf(stderr, "ctdb_conn_test_send failed\n");
227 return false;
229 if (!tevent_req_poll(req, ev)) {
230 fprintf(stderr, "tevent_req_poll failed\n");
231 return false;
233 ret = ctdb_conn_test_recv(req);
234 TALLOC_FREE(req);
235 printf("ctdb_conn_test returned %s\n",
236 ret ? strerror(ret) : "success");
237 TALLOC_FREE(ev);
238 return (ret == 0);