2 CTDB event daemon - command handling
4 Copyright (C) Amitay Isaacs 2018
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/>.
25 #include "lib/util/debug.h"
26 #include "lib/util/tevent_unix.h"
28 #include "common/logging.h"
30 #include "event/event_private.h"
32 struct event_cmd_state
{
33 struct event_context
*eventd
;
34 struct ctdb_event_request
*request
;
35 struct ctdb_event_reply
*reply
;
42 static void event_cmd_run_done(struct tevent_req
*subreq
);
44 static struct tevent_req
*event_cmd_run_send(
46 struct tevent_context
*ev
,
47 struct event_context
*eventd
,
48 struct ctdb_event_request
*request
,
49 struct ctdb_event_reply
*reply
)
51 struct tevent_req
*req
, *subreq
;
52 struct event_cmd_state
*state
;
53 struct run_event_context
*run_ctx
;
54 struct ctdb_event_request_run
*rdata
;
56 bool continue_on_failure
= false;
58 req
= tevent_req_create(mem_ctx
, &state
, struct event_cmd_state
);
63 state
->eventd
= eventd
;
64 state
->request
= request
;
67 rdata
= request
->data
.run
;
69 ret
= eventd_run_ctx(eventd
, rdata
->component
, &run_ctx
);
71 state
->reply
->result
= ret
;
73 return tevent_req_post(req
, ev
);
76 if (rdata
->flags
& CTDB_EVENT_RUN_ALL
) {
77 continue_on_failure
= true;
80 subreq
= run_event_send(state
,
85 tevent_timeval_current_ofs(rdata
->timeout
,0),
87 if (tevent_req_nomem(subreq
, req
)) {
88 return tevent_req_post(req
, ev
);
90 tevent_req_set_callback(subreq
, event_cmd_run_done
, req
);
95 static void event_cmd_run_done(struct tevent_req
*subreq
)
97 struct tevent_req
*req
= tevent_req_callback_data(
98 subreq
, struct tevent_req
);
99 struct event_cmd_state
*state
= tevent_req_data(
100 req
, struct event_cmd_state
);
101 struct run_event_script_list
*script_list
= NULL
;
102 struct ctdb_event_request_run
*rdata
;
106 ok
= run_event_recv(subreq
, &ret
, state
, &script_list
);
109 state
->reply
->result
= ret
;
113 if (script_list
== NULL
) {
114 state
->reply
->result
= EIO
;
118 if (script_list
->summary
== -ECANCELED
) {
119 state
->reply
->result
= ECANCELED
;
123 rdata
= state
->request
->data
.run
;
124 ret
= eventd_set_event_result(state
->eventd
,
129 state
->reply
->result
= ret
;
133 if (script_list
->summary
== -ETIMEDOUT
) {
134 state
->reply
->result
= ETIMEDOUT
;
135 } else if (script_list
->summary
!= 0) {
136 state
->reply
->result
= ENOEXEC
;
140 tevent_req_done(req
);
144 * CTDB_EVENT_CMD_STATUS
147 static struct tevent_req
*event_cmd_status_send(
149 struct tevent_context
*ev
,
150 struct event_context
*eventd
,
151 struct ctdb_event_request
*request
,
152 struct ctdb_event_reply
*reply
)
154 struct tevent_req
*req
;
155 struct event_cmd_state
*state
;
156 struct ctdb_event_request_run
*rdata
;
157 struct run_event_script_list
*script_list
;
160 req
= tevent_req_create(mem_ctx
, &state
, struct event_cmd_state
);
165 reply
->data
.status
= talloc_zero(reply
,
166 struct ctdb_event_reply_status
);
167 if (tevent_req_nomem(reply
->data
.status
, req
)) {
168 reply
->result
= ENOMEM
;
172 rdata
= request
->data
.run
;
174 ret
= eventd_get_event_result(eventd
,
183 reply
->data
.status
->script_list
= eventd_script_list(reply
,
185 if (reply
->data
.status
->script_list
== NULL
) {
186 reply
->result
= ENOMEM
;
189 reply
->data
.status
->summary
= script_list
->summary
;
194 tevent_req_done(req
);
195 return tevent_req_post(req
, ev
);
199 * CTDB_EVENT_CMD_SCRIPT
202 static struct tevent_req
*event_cmd_script_send(
204 struct tevent_context
*ev
,
205 struct event_context
*eventd
,
206 struct ctdb_event_request
*request
,
207 struct ctdb_event_reply
*reply
)
209 struct tevent_req
*req
;
210 struct event_cmd_state
*state
;
211 struct run_event_context
*run_ctx
;
212 struct ctdb_event_request_script
*rdata
;
215 req
= tevent_req_create(mem_ctx
, &state
, struct event_cmd_state
);
220 rdata
= request
->data
.script
;
222 ret
= eventd_run_ctx(eventd
, rdata
->component
, &run_ctx
);
228 if (rdata
->action
== CTDB_EVENT_SCRIPT_DISABLE
) {
229 ret
= run_event_script_disable(run_ctx
, rdata
->script
);
230 } else if (rdata
->action
== CTDB_EVENT_SCRIPT_ENABLE
) {
231 ret
= run_event_script_enable(run_ctx
, rdata
->script
);
233 D_ERR("Invalid action specified\n");
234 reply
->result
= EPROTO
;
246 tevent_req_done(req
);
247 return tevent_req_post(req
, ev
);
250 static bool event_cmd_recv(struct tevent_req
*req
, int *perr
)
252 if (tevent_req_is_unix_error(req
, perr
)) {
260 struct event_cmd_dispatch_state
{
261 struct ctdb_event_reply
*reply
;
264 static void event_cmd_dispatch_done(struct tevent_req
*subreq
);
266 struct tevent_req
*event_cmd_dispatch_send(TALLOC_CTX
*mem_ctx
,
267 struct tevent_context
*ev
,
268 struct event_context
*eventd
,
269 struct ctdb_event_request
*request
)
271 struct tevent_req
*req
, *subreq
;
272 struct event_cmd_dispatch_state
*state
;
274 req
= tevent_req_create(mem_ctx
,
276 struct event_cmd_dispatch_state
);
281 state
->reply
= talloc_zero(state
, struct ctdb_event_reply
);
282 if (tevent_req_nomem(state
->reply
, req
)) {
283 return tevent_req_post(req
, ev
);
286 state
->reply
->cmd
= request
->cmd
;
288 switch (request
->cmd
) {
289 case CTDB_EVENT_CMD_RUN
:
290 subreq
= event_cmd_run_send(state
,
297 case CTDB_EVENT_CMD_STATUS
:
298 subreq
= event_cmd_status_send(state
,
305 case CTDB_EVENT_CMD_SCRIPT
:
306 subreq
= event_cmd_script_send(state
,
314 state
->reply
->result
= EPROTO
;
315 tevent_req_done(req
);
316 return tevent_req_post(req
, ev
);
319 if (tevent_req_nomem(subreq
, req
)) {
320 return tevent_req_post(req
, ev
);
322 tevent_req_set_callback(subreq
, event_cmd_dispatch_done
, req
);
327 static void event_cmd_dispatch_done(struct tevent_req
*subreq
)
329 struct tevent_req
*req
= tevent_req_callback_data(
330 subreq
, struct tevent_req
);
334 ok
= event_cmd_recv(subreq
, &ret
);
337 tevent_req_error(req
, ret
);
341 tevent_req_done(req
);
344 bool event_cmd_dispatch_recv(struct tevent_req
*req
,
347 struct ctdb_event_reply
**reply
)
349 struct event_cmd_dispatch_state
*state
= tevent_req_data(
350 req
, struct event_cmd_dispatch_state
);
352 if (tevent_req_is_unix_error(req
, perr
)) {
356 *reply
= talloc_steal(mem_ctx
, state
->reply
);