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/>.
21 #include "system/network.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,
42 uint8_t **buf, size_t *buflen,
45 struct ctdb_event_request *request =
46 (struct ctdb_event_request *)request_data;
49 sock_packet_header_set_reqid(&request->header, reqid);
51 *buflen = ctdb_event_request_len(request);
52 *buf = talloc_size(mem_ctx, *buflen);
57 ret = ctdb_event_request_push(request, *buf, buflen);
65 static int ctdb_event_msg_reply_pull(uint8_t *buf, size_t buflen,
66 TALLOC_CTX *mem_ctx, void **reply_data,
69 struct ctdb_event_reply *reply;
72 reply = talloc_zero(mem_ctx, struct ctdb_event_reply);
77 ret = ctdb_event_reply_pull(buf, buflen, reply, reply);
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;
94 ret = sock_packet_header_pull(buf, buflen, &header, &np);
99 *reqid = header.reqid;
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;
116 eclient = talloc_zero(mem_ctx, struct ctdb_event_context);
117 if (eclient == NULL) {
118 DEBUG(DEBUG_ERR, (__location__ " memory allocation error\n"));
122 ret = sock_client_setup(eclient, ev, sockpath,
123 &event_proto_funcs, eclient,
126 talloc_free(eclient);
134 void ctdb_event_set_disconnect_callback(struct ctdb_event_context *eclient,
135 ctdb_client_callback_func_t callback,
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);
158 bool ctdb_event_msg_recv(struct tevent_req *req, int *perr,
160 struct ctdb_event_reply **reply)
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);
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;
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;
204 status = ctdb_event_msg_recv(req, &ret, req, &reply);
212 if (reply->rdata.command != CTDB_EVENT_COMMAND_RUN) {
220 if (result != NULL) {
221 *result = reply->rdata.result;
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;
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,
253 struct ctdb_script_list **script_list)
255 struct ctdb_event_reply *reply;
259 status = ctdb_event_msg_recv(req, &ret, req, &reply);
267 if (reply->rdata.command != CTDB_EVENT_COMMAND_STATUS) {
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);
294 struct tevent_req *ctdb_event_script_list_send(
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;
314 status = ctdb_event_msg_recv(req, &ret, req, &reply);
322 if (reply->rdata.command != CTDB_EVENT_COMMAND_SCRIPT_LIST) {
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);
346 struct tevent_req *ctdb_event_script_enable_send(
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,
366 struct ctdb_event_reply *reply;
370 status = ctdb_event_msg_recv(req, &ret, req, &reply);
378 if (reply->rdata.command != CTDB_EVENT_COMMAND_SCRIPT_ENABLE) {
386 if (result != NULL) {
387 *result = reply->rdata.result;
398 struct tevent_req *ctdb_event_script_disable_send(
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,
418 struct ctdb_event_reply *reply;
422 status = ctdb_event_msg_recv(req, &ret, req, &reply);
430 if (reply->rdata.command != CTDB_EVENT_COMMAND_SCRIPT_DISABLE) {
438 if (result != NULL) {
439 *result = reply->rdata.result;