ctdb-doc: Sort the tunable variables in alphabetical order
[Samba.git] / ctdb / client / client_message.c
blobc316f42ff3385f4f8260bb45d9d2eceef8d4d4f2
1 /*
2 CTDB client code
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"
22 #include "system/filesys.h"
24 #include <talloc.h>
25 #include <tevent.h>
26 #include <tdb.h>
28 #include "lib/util/tevent_unix.h"
30 #include "common/reqid.h"
31 #include "common/srvid.h"
32 #include "common/comm.h"
34 #include "protocol/protocol.h"
35 #include "protocol/protocol_api.h"
37 #include "client/client_private.h"
38 #include "client/client.h"
42 * Handle REQ_MESSAGE
45 struct ctdb_client_message_state {
46 struct ctdb_client_context *client;
47 uint32_t reqid;
50 static int ctdb_client_message_state_destructor(
51 struct ctdb_client_message_state *state);
52 static void ctdb_client_message_done(struct tevent_req *subreq);
54 struct tevent_req *ctdb_client_message_send(TALLOC_CTX *mem_ctx,
55 struct tevent_context *ev,
56 struct ctdb_client_context *client,
57 uint32_t destnode,
58 struct ctdb_req_message *message)
60 struct tevent_req *req, *subreq;
61 struct ctdb_client_message_state *state;
62 struct ctdb_req_header h;
63 uint32_t reqid;
64 uint8_t *buf;
65 size_t buflen;
66 int ret;
68 req = tevent_req_create(mem_ctx, &state,
69 struct ctdb_client_message_state);
70 if (req == NULL) {
71 return NULL;
74 reqid = reqid_new(client->idr, state);
75 if (reqid == REQID_INVALID) {
76 talloc_free(req);
77 return NULL;
80 state->client = client;
81 state->reqid = reqid;
83 talloc_set_destructor(state, ctdb_client_message_state_destructor);
85 ctdb_req_header_fill(&h, 0, CTDB_REQ_MESSAGE, destnode,
86 client->pnn, reqid);
88 ret = ctdb_req_message_push(&h, message, state, &buf, &buflen);
89 if (ret != 0) {
90 tevent_req_error(req, ret);
91 return tevent_req_post(req, ev);
94 subreq = comm_write_send(state, ev, client->comm, buf, buflen);
95 if (tevent_req_nomem(subreq, req)) {
96 return tevent_req_post(req, ev);
98 tevent_req_set_callback(subreq, ctdb_client_message_done, req);
100 return req;
103 static int ctdb_client_message_state_destructor(
104 struct ctdb_client_message_state *state)
106 reqid_remove(state->client->idr, state->reqid);
107 return 0;
110 static void ctdb_client_message_done(struct tevent_req *subreq)
112 struct tevent_req *req = tevent_req_callback_data(
113 subreq, struct tevent_req);
114 int ret;
115 bool status;
117 status = comm_write_recv(subreq, &ret);
118 TALLOC_FREE(subreq);
119 if (! status) {
120 tevent_req_error(req, ret);
121 return;
124 tevent_req_done(req);
127 bool ctdb_client_message_recv(struct tevent_req *req, int *perr)
129 int err;
131 if (tevent_req_is_unix_error(req, &err)) {
132 if (perr != NULL) {
133 *perr = err;
135 return false;
138 return true;
141 void ctdb_client_req_message(struct ctdb_client_context *client,
142 uint8_t *buf, size_t buflen, uint32_t reqid)
144 struct ctdb_req_header h;
145 struct ctdb_req_message_data message;
146 TALLOC_CTX *tmp_ctx = talloc_new(client);
147 int ret;
149 ret = ctdb_req_message_data_pull(buf, buflen, &h, tmp_ctx, &message);
150 if (ret != 0) {
151 return;
154 srvid_dispatch(client->srv, message.srvid, CTDB_SRVID_ALL,
155 message.data);
156 talloc_free(tmp_ctx);
160 * sync version of message send
163 int ctdb_client_message(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
164 struct ctdb_client_context *client,
165 uint32_t destnode, struct ctdb_req_message *message)
167 TALLOC_CTX *tmp_ctx;
168 struct tevent_req *req;
169 int ret;
170 bool status;
172 tmp_ctx = talloc_new(client);
173 if (tmp_ctx == NULL) {
174 return ENOMEM;
177 req = ctdb_client_message_send(tmp_ctx, ev, client, destnode, message);
178 if (req == NULL) {
179 talloc_free(tmp_ctx);
180 return ENOMEM;
183 tevent_req_poll(req, ev);
185 status = ctdb_client_message_recv(req, &ret);
186 if (! status) {
187 talloc_free(tmp_ctx);
188 return ret;
191 talloc_free(tmp_ctx);
192 return 0;
195 struct ctdb_client_set_message_handler_state {
196 struct ctdb_client_context *client;
197 uint64_t srvid;
198 srvid_handler_fn handler;
199 void *private_data;
202 static void ctdb_client_set_message_handler_done(struct tevent_req *subreq);
204 struct tevent_req *ctdb_client_set_message_handler_send(
205 TALLOC_CTX *mem_ctx,
206 struct tevent_context *ev,
207 struct ctdb_client_context *client,
208 uint64_t srvid,
209 srvid_handler_fn handler,
210 void *private_data)
212 struct tevent_req *req, *subreq;
213 struct ctdb_client_set_message_handler_state *state;
214 struct ctdb_req_control request;
216 req = tevent_req_create(mem_ctx, &state,
217 struct ctdb_client_set_message_handler_state);
218 if (req == NULL) {
219 return NULL;
222 state->client = client;
223 state->srvid = srvid;
224 state->handler = handler;
225 state->private_data = private_data;
227 ctdb_req_control_register_srvid(&request, srvid);
228 subreq = ctdb_client_control_send(state, ev, client, client->pnn,
229 tevent_timeval_zero(), &request);
230 if (tevent_req_nomem(subreq, req)) {
231 return tevent_req_post(req, ev);
233 tevent_req_set_callback(subreq, ctdb_client_set_message_handler_done,
234 req);
236 return req;
239 static void ctdb_client_set_message_handler_done(struct tevent_req *subreq)
241 struct tevent_req *req = tevent_req_callback_data(
242 subreq, struct tevent_req);
243 struct ctdb_client_set_message_handler_state *state = tevent_req_data(
244 req, struct ctdb_client_set_message_handler_state);
245 struct ctdb_reply_control *reply;
246 bool status;
247 int ret;
249 status = ctdb_client_control_recv(subreq, &ret, state, &reply);
250 TALLOC_FREE(subreq);
251 if (! status) {
252 tevent_req_error(req, ret);
253 return;
256 ret = ctdb_reply_control_register_srvid(reply);
257 talloc_free(reply);
258 if (ret != 0) {
259 tevent_req_error(req, ret);
260 return;
263 ret = srvid_register(state->client->srv, state->client, state->srvid,
264 state->handler, state->private_data);
265 if (ret != 0) {
266 tevent_req_error(req, ret);
267 return;
270 tevent_req_done(req);
273 bool ctdb_client_set_message_handler_recv(struct tevent_req *req, int *perr)
275 int err;
277 if (tevent_req_is_unix_error(req, &err)) {
278 if (perr != NULL) {
279 *perr = err;
281 return false;
283 return true;
286 struct ctdb_client_remove_message_handler_state {
287 struct ctdb_client_context *client;
288 uint64_t srvid;
289 void *private_data;
292 static void ctdb_client_remove_message_handler_done(struct tevent_req *subreq);
294 struct tevent_req *ctdb_client_remove_message_handler_send(
295 TALLOC_CTX *mem_ctx,
296 struct tevent_context *ev,
297 struct ctdb_client_context *client,
298 uint64_t srvid,
299 void *private_data)
301 struct tevent_req *req, *subreq;
302 struct ctdb_client_remove_message_handler_state *state;
303 struct ctdb_req_control request;
305 req = tevent_req_create(mem_ctx, &state,
306 struct ctdb_client_remove_message_handler_state);
307 if (req == NULL) {
308 return NULL;
311 state->client = client;
312 state->srvid = srvid;
313 state->private_data = private_data;
315 ctdb_req_control_deregister_srvid(&request, srvid);
316 subreq = ctdb_client_control_send(state, ev, client, client->pnn,
317 tevent_timeval_zero(), &request);
318 if (tevent_req_nomem(subreq, req)) {
319 return tevent_req_post(req, ev);
321 tevent_req_set_callback(subreq,
322 ctdb_client_remove_message_handler_done, req);
324 return req;
327 static void ctdb_client_remove_message_handler_done(struct tevent_req *subreq)
329 struct tevent_req *req = tevent_req_callback_data(
330 subreq, struct tevent_req);
331 struct ctdb_client_remove_message_handler_state *state = tevent_req_data(
332 req, struct ctdb_client_remove_message_handler_state);
333 struct ctdb_reply_control *reply;
334 bool status;
335 int ret;
337 status = ctdb_client_control_recv(subreq, &ret, state, &reply);
338 TALLOC_FREE(subreq);
339 if (! status) {
340 tevent_req_error(req, ret);
341 return;
344 ret = ctdb_reply_control_deregister_srvid(reply);
345 talloc_free(reply);
346 if (ret != 0) {
347 tevent_req_error(req, ret);
348 return;
351 ret = srvid_deregister(state->client->srv, state->srvid,
352 state->private_data);
353 if (ret != 0) {
354 tevent_req_error(req, ret);
355 return;
358 tevent_req_done(req);
361 bool ctdb_client_remove_message_handler_recv(struct tevent_req *req, int *perr)
363 int err;
365 if (tevent_req_is_unix_error(req, &err)) {
366 if (perr != NULL) {
367 *perr = err;
369 return false;
371 return true;
374 int ctdb_client_set_message_handler(TALLOC_CTX *mem_ctx,
375 struct tevent_context *ev,
376 struct ctdb_client_context *client,
377 uint64_t srvid, srvid_handler_fn handler,
378 void *private_data)
380 int ret;
382 ret = ctdb_ctrl_register_srvid(mem_ctx, ev, client, client->pnn,
383 tevent_timeval_zero(), srvid);
384 if (ret != 0) {
385 return ret;
388 return srvid_register(client->srv, client, srvid,
389 handler, private_data);
392 int ctdb_client_remove_message_handler(TALLOC_CTX *mem_ctx,
393 struct tevent_context *ev,
394 struct ctdb_client_context *client,
395 uint64_t srvid, void *private_data)
397 int ret;
399 ret = ctdb_ctrl_deregister_srvid(mem_ctx, ev, client, client->pnn,
400 tevent_timeval_zero(), srvid);
401 if (ret != 0) {
402 return ret;
405 return srvid_deregister(client->srv, srvid, private_data);