packaging: Update READMEs to reflect current status.
[Samba.git] / ctdb / client / client_event.c
blob7111fe7a952fc1c40d49737632c02b3cc4307b94
1 /*
2 Eventd client api
4 Copyright (C) Amitay Isaacs 2016
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 <talloc.h>
24 #include <tevent.h>
26 #include "lib/util/debug.h"
27 #include "lib/util/tevent_unix.h"
29 #include "common/logging.h"
30 #include "common/sock_client.h"
32 #include "protocol/protocol_api.h"
34 #include "client/client_event.h"
36 struct ctdb_event_context {
37 struct sock_client_context *sockc;
40 static int ctdb_event_msg_request_push(void *request_data, uint32_t reqid,
41 TALLOC_CTX *mem_ctx,
42 uint8_t **buf, size_t *buflen,
43 void *private_data)
45 struct ctdb_event_request *request =
46 (struct ctdb_event_request *)request_data;
47 int ret;
49 sock_packet_header_set_reqid(&request->header, reqid);
51 *buflen = ctdb_event_request_len(request);
52 *buf = talloc_size(mem_ctx, *buflen);
53 if (*buf == NULL) {
54 return ENOMEM;
57 ret = ctdb_event_request_push(request, *buf, buflen);
58 if (ret != 0) {
59 return ret;
62 return 0;
65 static int ctdb_event_msg_reply_pull(uint8_t *buf, size_t buflen,
66 TALLOC_CTX *mem_ctx, void **reply_data,
67 void *private_data)
69 struct ctdb_event_reply *reply;
70 int ret;
72 reply = talloc_zero(mem_ctx, struct ctdb_event_reply);
73 if (reply == NULL) {
74 return ENOMEM;
77 ret = ctdb_event_reply_pull(buf, buflen, reply, reply);
78 if (ret != 0) {
79 talloc_free(reply);
80 return ret;
83 *reply_data = reply;
84 return 0;
87 static int ctdb_event_msg_reply_reqid(uint8_t *buf, size_t buflen,
88 uint32_t *reqid, void *private_data)
90 struct sock_packet_header header;
91 size_t np;
92 int ret;
94 ret = sock_packet_header_pull(buf, buflen, &header, &np);
95 if (ret != 0) {
96 return ret;
99 *reqid = header.reqid;
100 return 0;
103 struct sock_client_proto_funcs event_proto_funcs = {
104 .request_push = ctdb_event_msg_request_push,
105 .reply_pull = ctdb_event_msg_reply_pull,
106 .reply_reqid = ctdb_event_msg_reply_reqid,
110 int ctdb_event_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
111 const char *sockpath, struct ctdb_event_context **out)
113 struct ctdb_event_context *eclient;
114 int ret;
116 eclient = talloc_zero(mem_ctx, struct ctdb_event_context);
117 if (eclient == NULL) {
118 DEBUG(DEBUG_ERR, (__location__ " memory allocation error\n"));
119 return ENOMEM;
122 ret = sock_client_setup(eclient, ev, sockpath,
123 &event_proto_funcs, eclient,
124 &eclient->sockc);
125 if (ret != 0) {
126 talloc_free(eclient);
127 return ret;
130 *out = eclient;
131 return 0;
134 void ctdb_event_set_disconnect_callback(struct ctdb_event_context *eclient,
135 ctdb_client_callback_func_t callback,
136 void *private_data)
138 sock_client_set_disconnect_callback(eclient->sockc,
139 callback, private_data);
143 * Handle eventd_request and eventd_reply
146 struct tevent_req *ctdb_event_msg_send(TALLOC_CTX *mem_ctx,
147 struct tevent_context *ev,
148 struct ctdb_event_context *eclient,
149 struct ctdb_event_request *request)
151 struct tevent_req *req;
153 req = sock_client_msg_send(mem_ctx, ev, eclient->sockc,
154 tevent_timeval_zero(), request);
155 return req;
158 bool ctdb_event_msg_recv(struct tevent_req *req, int *perr,
159 TALLOC_CTX *mem_ctx,
160 struct ctdb_event_reply **reply)
162 void *reply_data;
163 bool status;
165 status = sock_client_msg_recv(req, perr, mem_ctx, &reply_data);
167 if (status && reply != NULL) {
168 *reply = talloc_get_type_abort(
169 reply_data, struct ctdb_event_reply);
172 return status;
176 * Run an event
179 struct tevent_req *ctdb_event_run_send(TALLOC_CTX *mem_ctx,
180 struct tevent_context *ev,
181 struct ctdb_event_context *eclient,
182 enum ctdb_event event,
183 uint32_t timeout, const char *arg_str)
185 struct ctdb_event_request request;
186 struct ctdb_event_request_run rdata;
188 rdata.event = event;
189 rdata.timeout = timeout;
190 rdata.arg_str = arg_str;
192 request.rdata.command = CTDB_EVENT_COMMAND_RUN;
193 request.rdata.data.run = &rdata;
195 return ctdb_event_msg_send(mem_ctx, ev, eclient, &request);
198 bool ctdb_event_run_recv(struct tevent_req *req, int *perr, int *result)
200 struct ctdb_event_reply *reply;
201 int ret;
202 bool status;
204 status = ctdb_event_msg_recv(req, &ret, req, &reply);
205 if (! status) {
206 if (perr != NULL) {
207 *perr = ret;
209 return false;
212 if (reply->rdata.command != CTDB_EVENT_COMMAND_RUN) {
213 if (perr != NULL) {
214 *perr = EPROTO;
216 talloc_free(reply);
217 return false;
220 if (result != NULL) {
221 *result = reply->rdata.result;
224 talloc_free(reply);
225 return true;
229 * Get event status
232 struct tevent_req *ctdb_event_status_send(TALLOC_CTX *mem_ctx,
233 struct tevent_context *ev,
234 struct ctdb_event_context *eclient,
235 enum ctdb_event event,
236 enum ctdb_event_status_state state)
238 struct ctdb_event_request request;
239 struct ctdb_event_request_status rdata;
241 rdata.event = event;
242 rdata.state = state;
244 request.rdata.command = CTDB_EVENT_COMMAND_STATUS;
245 request.rdata.data.status = &rdata;
247 return ctdb_event_msg_send(mem_ctx, ev, eclient, &request);
250 bool ctdb_event_status_recv(struct tevent_req *req, int *perr,
251 int32_t *result, int *event_status,
252 TALLOC_CTX *mem_ctx,
253 struct ctdb_script_list **script_list)
255 struct ctdb_event_reply *reply;
256 int ret;
257 bool status;
259 status = ctdb_event_msg_recv(req, &ret, req, &reply);
260 if (! status) {
261 if (perr != NULL) {
262 *perr = ret;
264 return false;
267 if (reply->rdata.command != CTDB_EVENT_COMMAND_STATUS) {
268 if (perr != NULL) {
269 *perr = EPROTO;
271 talloc_free(reply);
272 return false;
275 if (result != NULL) {
276 *result = reply->rdata.result;
278 if (event_status != NULL) {
279 *event_status = reply->rdata.data.status->status;
281 if (script_list != NULL) {
282 *script_list = talloc_steal(mem_ctx,
283 reply->rdata.data.status->script_list);
286 talloc_free(reply);
287 return true;
291 * Get script list
294 struct tevent_req *ctdb_event_script_list_send(
295 TALLOC_CTX *mem_ctx,
296 struct tevent_context *ev,
297 struct ctdb_event_context *eclient)
299 struct ctdb_event_request request;
301 request.rdata.command = CTDB_EVENT_COMMAND_SCRIPT_LIST;
303 return ctdb_event_msg_send(mem_ctx, ev, eclient, &request);
306 bool ctdb_event_script_list_recv(struct tevent_req *req, int *perr,
307 int32_t *result, TALLOC_CTX *mem_ctx,
308 struct ctdb_script_list **script_list)
310 struct ctdb_event_reply *reply;
311 int ret;
312 bool status;
314 status = ctdb_event_msg_recv(req, &ret, req, &reply);
315 if (! status) {
316 if (perr != NULL) {
317 *perr = ret;
319 return false;
322 if (reply->rdata.command != CTDB_EVENT_COMMAND_SCRIPT_LIST) {
323 if (perr != NULL) {
324 *perr = EPROTO;
326 talloc_free(reply);
327 return false;
330 if (result != NULL) {
331 *result = reply->rdata.result;
333 if (script_list != NULL) {
334 *script_list = talloc_steal(mem_ctx,
335 reply->rdata.data.script_list->script_list);
338 talloc_free(reply);
339 return true;
343 * Enable a script
346 struct tevent_req *ctdb_event_script_enable_send(
347 TALLOC_CTX *mem_ctx,
348 struct tevent_context *ev,
349 struct ctdb_event_context *eclient,
350 const char *script_name)
352 struct ctdb_event_request request;
353 struct ctdb_event_request_script_enable rdata;
355 rdata.script_name = script_name;
357 request.rdata.command = CTDB_EVENT_COMMAND_SCRIPT_ENABLE;
358 request.rdata.data.script_enable = &rdata;
360 return ctdb_event_msg_send(mem_ctx, ev, eclient, &request);
363 bool ctdb_event_script_enable_recv(struct tevent_req *req, int *perr,
364 int *result)
366 struct ctdb_event_reply *reply;
367 int ret;
368 bool status;
370 status = ctdb_event_msg_recv(req, &ret, req, &reply);
371 if (! status) {
372 if (perr != NULL) {
373 *perr = ret;
375 return false;
378 if (reply->rdata.command != CTDB_EVENT_COMMAND_SCRIPT_ENABLE) {
379 if (perr != NULL) {
380 *perr = EPROTO;
382 talloc_free(reply);
383 return false;
386 if (result != NULL) {
387 *result = reply->rdata.result;
390 talloc_free(reply);
391 return true;
395 * Disable a script
398 struct tevent_req *ctdb_event_script_disable_send(
399 TALLOC_CTX *mem_ctx,
400 struct tevent_context *ev,
401 struct ctdb_event_context *eclient,
402 const char *script_name)
404 struct ctdb_event_request request;
405 struct ctdb_event_request_script_disable rdata;
407 rdata.script_name = script_name;
409 request.rdata.command = CTDB_EVENT_COMMAND_SCRIPT_DISABLE;
410 request.rdata.data.script_disable = &rdata;
412 return ctdb_event_msg_send(mem_ctx, ev, eclient, &request);
415 bool ctdb_event_script_disable_recv(struct tevent_req *req, int *perr,
416 int *result)
418 struct ctdb_event_reply *reply;
419 int ret;
420 bool status;
422 status = ctdb_event_msg_recv(req, &ret, req, &reply);
423 if (! status) {
424 if (perr != NULL) {
425 *perr = ret;
427 return false;
430 if (reply->rdata.command != CTDB_EVENT_COMMAND_SCRIPT_DISABLE) {
431 if (perr != NULL) {
432 *perr = EPROTO;
434 talloc_free(reply);
435 return false;
438 if (result != NULL) {
439 *result = reply->rdata.result;
442 talloc_free(reply);
443 return true;