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
;