2 Event script running daemon
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/filesys.h"
22 #include "system/dir.h"
23 #include "system/wait.h"
24 #include "system/locale.h"
30 #include "lib/util/debug.h"
31 #include "lib/util/tevent_unix.h"
32 #include "lib/util/blocking.h"
33 #include "lib/util/sys_rw.h"
34 #include "lib/util/dlinklist.h"
35 #include "lib/async_req/async_sock.h"
37 #include "protocol/protocol_api.h"
38 #include "protocol/protocol_util.h"
40 #include "common/comm.h"
41 #include "common/logging.h"
42 #include "common/run_event.h"
43 #include "common/sock_daemon.h"
45 struct eventd_client
{
46 struct eventd_client
*prev
, *next
;
48 struct sock_client_context
*client_ctx
;
49 struct pending_event
*pending_list
;
52 struct eventd_context
{
53 struct run_event_context
*run_ctx
;
55 /* result of last execution */
56 struct run_event_script_list
*status_run
[CTDB_EVENT_MAX
];
57 struct run_event_script_list
*status_pass
[CTDB_EVENT_MAX
];
58 struct run_event_script_list
*status_fail
[CTDB_EVENT_MAX
];
60 struct eventd_client
*client_list
;
64 * Global state manipulation functions
67 static int eventd_context_init(TALLOC_CTX
*mem_ctx
,
68 struct tevent_context
*ev
,
69 const char *script_dir
,
70 const char *debug_script
,
71 struct eventd_context
**result
)
73 struct eventd_context
*ectx
;
76 ectx
= talloc_zero(mem_ctx
, struct eventd_context
);
81 ret
= run_event_init(ectx
, ev
, script_dir
, debug_script
,
92 static struct run_event_context
*eventd_run_context(struct eventd_context
*ectx
)
97 static struct run_event_script_list
*script_list_copy(
99 struct run_event_script_list
*s
)
101 struct run_event_script_list
*s2
;
103 s2
= talloc_zero(mem_ctx
, struct run_event_script_list
);
108 s2
->num_scripts
= s
->num_scripts
;
109 s2
->script
= talloc_memdup(s2
, s
->script
,
111 sizeof(struct run_event_script
));
112 if (s2
->script
== NULL
) {
116 s2
->summary
= s
->summary
;
121 static struct ctdb_script_list
*script_list_to_ctdb_script_list(
123 struct run_event_script_list
*s
)
125 struct ctdb_script_list
*sl
;
128 sl
= talloc_zero(mem_ctx
, struct ctdb_script_list
);
133 sl
->script
= talloc_zero_array(sl
, struct ctdb_script
, s
->num_scripts
);
134 if (sl
->script
== NULL
) {
139 sl
->num_scripts
= s
->num_scripts
;
141 for (i
=0; i
<s
->num_scripts
; i
++) {
142 struct run_event_script
*escript
= &s
->script
[i
];
143 struct ctdb_script
*script
= &sl
->script
[i
];
145 strlcpy(script
->name
, escript
->name
, MAX_SCRIPT_NAME
+1);
146 script
->start
= escript
->begin
;
147 script
->finished
= escript
->end
;
148 script
->status
= escript
->summary
;
149 if (escript
->output
!= NULL
) {
150 strlcpy(script
->output
, escript
->output
,
151 MAX_SCRIPT_OUTPUT
+1);
158 static void eventd_set_result(struct eventd_context
*ectx
,
159 enum ctdb_event event
,
160 struct run_event_script_list
*script_list
)
162 struct run_event_script_list
*s
;
164 if (script_list
== NULL
) {
168 /* Do not update status if event was cancelled */
169 if (script_list
->summary
== -ECANCELED
) {
173 TALLOC_FREE(ectx
->status_run
[event
]);
174 ectx
->status_run
[event
] = talloc_steal(ectx
, script_list
);
176 s
= script_list_copy(ectx
, script_list
);
181 if (s
->summary
== 0) {
182 TALLOC_FREE(ectx
->status_pass
[event
]);
183 ectx
->status_pass
[event
] = s
;
185 TALLOC_FREE(ectx
->status_fail
[event
]);
186 ectx
->status_fail
[event
] = s
;
190 static int eventd_get_result(struct eventd_context
*ectx
,
191 enum ctdb_event event
,
192 enum ctdb_event_status_state state
,
194 struct ctdb_script_list
**out
)
196 struct run_event_script_list
*s
= NULL
;
199 case CTDB_EVENT_LAST_RUN
:
200 s
= ectx
->status_run
[event
];
203 case CTDB_EVENT_LAST_PASS
:
204 s
= ectx
->status_pass
[event
];
207 case CTDB_EVENT_LAST_FAIL
:
208 s
= ectx
->status_fail
[event
];
217 *out
= script_list_to_ctdb_script_list(mem_ctx
, s
);
222 * Process RUN command
225 struct command_run_state
{
226 struct eventd_context
*ectx
;
228 enum ctdb_event event
;
229 struct ctdb_event_reply
*reply
;
232 static void command_run_done(struct tevent_req
*subreq
);
234 static struct tevent_req
*command_run_send(TALLOC_CTX
*mem_ctx
,
235 struct tevent_context
*ev
,
236 struct eventd_context
*ectx
,
237 struct eventd_client
*client
,
238 struct ctdb_event_request
*request
)
240 struct tevent_req
*req
, *subreq
;
241 struct command_run_state
*state
;
244 req
= tevent_req_create(mem_ctx
, &state
, struct command_run_state
);
250 state
->event
= request
->rdata
.data
.run
->event
;
252 state
->reply
= talloc_zero(state
, struct ctdb_event_reply
);
253 if (tevent_req_nomem(state
->reply
, req
)) {
254 return tevent_req_post(req
, ev
);
257 state
->reply
->rdata
.command
= request
->rdata
.command
;
259 timeout
= request
->rdata
.data
.run
->timeout
;
260 subreq
= run_event_send(state
, ev
,
261 eventd_run_context(state
->ectx
),
262 ctdb_event_to_string(state
->event
),
263 request
->rdata
.data
.run
->arg_str
,
264 tevent_timeval_current_ofs(timeout
, 0));
265 if (tevent_req_nomem(subreq
, req
)) {
266 return tevent_req_post(req
, ev
);
268 tevent_req_set_callback(subreq
, command_run_done
, req
);
273 static void command_run_done(struct tevent_req
*subreq
)
275 struct tevent_req
*req
= tevent_req_callback_data(
276 subreq
, struct tevent_req
);
277 struct command_run_state
*state
= tevent_req_data(
278 req
, struct command_run_state
);
279 struct run_event_script_list
*script_list
;
283 status
= run_event_recv(subreq
, &ret
, state
, &script_list
);
286 tevent_req_error(req
, ret
);
290 if (script_list
== NULL
) {
291 eventd_set_result(state
->ectx
, state
->event
, NULL
);
292 state
->reply
->rdata
.result
= 0;
294 eventd_set_result(state
->ectx
, state
->event
, script_list
);
295 state
->reply
->rdata
.result
= script_list
->summary
;
298 tevent_req_done(req
);
301 static bool command_run_recv(struct tevent_req
*req
, int *perr
,
303 struct ctdb_event_reply
**reply
)
305 struct command_run_state
*state
= tevent_req_data(
306 req
, struct command_run_state
);
309 if (tevent_req_is_unix_error(req
, &ret
)) {
317 *reply
= talloc_steal(mem_ctx
, state
->reply
);
323 * Process STATUS command
326 struct command_status_state
{
327 struct ctdb_event_reply
*reply
;
330 static struct tevent_req
*command_status_send(
332 struct tevent_context
*ev
,
333 struct eventd_context
*ectx
,
334 struct eventd_client
*client
,
335 struct ctdb_event_request
*request
)
337 struct tevent_req
*req
;
338 struct command_status_state
*state
;
339 enum ctdb_event event
;
340 enum ctdb_event_status_state estate
;
342 req
= tevent_req_create(mem_ctx
, &state
, struct command_status_state
);
347 event
= request
->rdata
.data
.status
->event
;
348 estate
= request
->rdata
.data
.status
->state
;
350 state
->reply
= talloc_zero(state
, struct ctdb_event_reply
);
351 if (tevent_req_nomem(state
->reply
, req
)) {
352 return tevent_req_post(req
, ev
);
355 state
->reply
->rdata
.data
.status
=
356 talloc(state
->reply
, struct ctdb_event_reply_status
);
357 if (tevent_req_nomem(state
->reply
->rdata
.data
.status
, req
)) {
358 return tevent_req_post(req
, ev
);
361 state
->reply
->rdata
.command
= request
->rdata
.command
;
362 state
->reply
->rdata
.result
= 0;
363 state
->reply
->rdata
.data
.status
->status
=
364 eventd_get_result(ectx
, event
, estate
, state
->reply
,
365 &state
->reply
->rdata
.data
.status
->script_list
);
367 tevent_req_done(req
);
368 return tevent_req_post(req
, ev
);
371 static bool command_status_recv(struct tevent_req
*req
, int *perr
,
373 struct ctdb_event_reply
**reply
)
375 struct command_status_state
*state
= tevent_req_data(
376 req
, struct command_status_state
);
379 if (tevent_req_is_unix_error(req
, &ret
)) {
387 *reply
= talloc_steal(mem_ctx
, state
->reply
);
393 * Process SCRIPT_LIST command
396 struct command_script_list_state
{
397 struct ctdb_event_reply
*reply
;
400 static struct tevent_req
*command_script_list_send(
402 struct tevent_context
*ev
,
403 struct eventd_context
*ectx
,
404 struct eventd_client
*client
,
405 struct ctdb_event_request
*request
)
407 struct tevent_req
*req
;
408 struct command_script_list_state
*state
;
409 struct run_event_script_list
*s
;
412 req
= tevent_req_create(mem_ctx
, &state
,
413 struct command_script_list_state
);
418 state
->reply
= talloc_zero(state
, struct ctdb_event_reply
);
419 if (tevent_req_nomem(state
->reply
, req
)) {
420 return tevent_req_post(req
, ev
);
423 state
->reply
->rdata
.data
.script_list
=
424 talloc(state
->reply
, struct ctdb_event_reply_script_list
);
425 if (tevent_req_nomem(state
->reply
->rdata
.data
.script_list
, req
)) {
426 return tevent_req_post(req
, ev
);
429 ret
= run_event_script_list(eventd_run_context(ectx
), state
->reply
,
432 tevent_req_error(req
, ret
);
433 return tevent_req_post(req
, ev
);
436 state
->reply
->rdata
.command
= request
->rdata
.command
;
438 state
->reply
->rdata
.result
= 0;
439 state
->reply
->rdata
.data
.script_list
->script_list
= NULL
;
441 state
->reply
->rdata
.result
= s
->summary
;
442 state
->reply
->rdata
.data
.script_list
->script_list
=
443 script_list_to_ctdb_script_list(state
->reply
, s
);
446 tevent_req_done(req
);
447 return tevent_req_post(req
, ev
);
450 static bool command_script_list_recv(struct tevent_req
*req
, int *perr
,
452 struct ctdb_event_reply
**reply
)
454 struct command_script_list_state
*state
= tevent_req_data(
455 req
, struct command_script_list_state
);
458 if (tevent_req_is_unix_error(req
, &ret
)) {
466 *reply
= talloc_steal(mem_ctx
, state
->reply
);
472 * Process SCRIPT_ENABLE command
475 struct command_script_enable_state
{
476 struct ctdb_event_reply
*reply
;
479 static struct tevent_req
*command_script_enable_send(
481 struct tevent_context
*ev
,
482 struct eventd_context
*ectx
,
483 struct eventd_client
*client
,
484 struct ctdb_event_request
*request
)
486 struct tevent_req
*req
;
487 struct command_script_enable_state
*state
;
488 const char *script_name
;
491 req
= tevent_req_create(mem_ctx
, &state
,
492 struct command_script_enable_state
);
497 script_name
= request
->rdata
.data
.script_enable
->script_name
;
499 state
->reply
= talloc_zero(state
, struct ctdb_event_reply
);
500 if (tevent_req_nomem(state
->reply
, req
)) {
501 return tevent_req_post(req
, ev
);
504 state
->reply
->rdata
.command
= request
->rdata
.command
;
506 ret
= run_event_script_enable(eventd_run_context(ectx
), script_name
);
507 state
->reply
->rdata
.result
= -ret
;
509 tevent_req_done(req
);
510 return tevent_req_post(req
, ev
);
513 static bool command_script_enable_recv(struct tevent_req
*req
, int *perr
,
515 struct ctdb_event_reply
**reply
)
517 struct command_script_enable_state
*state
= tevent_req_data(
518 req
, struct command_script_enable_state
);
521 if (tevent_req_is_unix_error(req
, &ret
)) {
529 *reply
= talloc_steal(mem_ctx
, state
->reply
);
535 * Process SCRIPT_DISABLE command
538 struct command_script_disable_state
{
539 struct ctdb_event_reply
*reply
;
542 static struct tevent_req
*command_script_disable_send(
544 struct tevent_context
*ev
,
545 struct eventd_context
*ectx
,
546 struct eventd_client
*client
,
547 struct ctdb_event_request
*request
)
549 struct tevent_req
*req
;
550 struct command_script_disable_state
*state
;
551 const char *script_name
;
554 req
= tevent_req_create(mem_ctx
, &state
,
555 struct command_script_disable_state
);
560 script_name
= request
->rdata
.data
.script_disable
->script_name
;
562 state
->reply
= talloc_zero(state
, struct ctdb_event_reply
);
563 if (tevent_req_nomem(state
->reply
, req
)) {
564 return tevent_req_post(req
, ev
);
567 state
->reply
->rdata
.command
= request
->rdata
.command
;
569 ret
= run_event_script_disable(eventd_run_context(ectx
), script_name
);
570 state
->reply
->rdata
.result
= -ret
;
572 tevent_req_done(req
);
573 return tevent_req_post(req
, ev
);
576 static bool command_script_disable_recv(struct tevent_req
*req
, int *perr
,
578 struct ctdb_event_reply
**reply
)
580 struct command_script_disable_state
*state
= tevent_req_data(
581 req
, struct command_script_disable_state
);
584 if (tevent_req_is_unix_error(req
, &ret
)) {
592 *reply
= talloc_steal(mem_ctx
, state
->reply
);
601 static struct eventd_client
*client_find(struct eventd_context
*ectx
,
602 struct sock_client_context
*client_ctx
)
604 struct eventd_client
*client
;
606 for (client
= ectx
->client_list
;
608 client
= client
->next
) {
609 if (client
->client_ctx
== client_ctx
) {
617 static bool client_connect(struct sock_client_context
*client_ctx
,
620 struct eventd_context
*ectx
= talloc_get_type_abort(
621 private_data
, struct eventd_context
);
622 struct eventd_client
*client
;
624 client
= talloc_zero(ectx
, struct eventd_client
);
625 if (client
== NULL
) {
629 client
->client_ctx
= client_ctx
;
631 DLIST_ADD(ectx
->client_list
, client
);
635 static void client_disconnect(struct sock_client_context
*client_ctx
,
638 struct eventd_context
*ectx
= talloc_get_type_abort(
639 private_data
, struct eventd_context
);
640 struct eventd_client
*client
;
642 client
= client_find(ectx
, client_ctx
);
643 if (client
== NULL
) {
647 DLIST_REMOVE(ectx
->client_list
, client
);
651 struct client_process_state
{
652 struct tevent_context
*ev
;
654 struct eventd_client
*client
;
655 struct ctdb_event_request request
;
658 static void client_run_done(struct tevent_req
*subreq
);
659 static void client_status_done(struct tevent_req
*subreq
);
660 static void client_script_list_done(struct tevent_req
*subreq
);
661 static void client_script_enable_done(struct tevent_req
*subreq
);
662 static void client_script_disable_done(struct tevent_req
*subreq
);
663 static void client_process_reply(struct tevent_req
*req
,
664 struct ctdb_event_reply
*reply
);
665 static void client_process_reply_done(struct tevent_req
*subreq
);
667 static struct tevent_req
*client_process_send(
669 struct tevent_context
*ev
,
670 struct sock_client_context
*client_ctx
,
671 uint8_t *buf
, size_t buflen
,
674 struct eventd_context
*ectx
= talloc_get_type_abort(
675 private_data
, struct eventd_context
);
676 struct tevent_req
*req
, *subreq
;
677 struct client_process_state
*state
;
680 req
= tevent_req_create(mem_ctx
, &state
, struct client_process_state
);
687 state
->client
= client_find(ectx
, client_ctx
);
688 if (state
->client
== NULL
) {
689 tevent_req_error(req
, EIO
);
690 return tevent_req_post(req
, ev
);
693 ret
= ctdb_event_request_pull(buf
, buflen
, state
, &state
->request
);
695 tevent_req_error(req
, EPROTO
);
696 return tevent_req_post(req
, ev
);
699 switch (state
->request
.rdata
.command
) {
700 case CTDB_EVENT_COMMAND_RUN
:
701 subreq
= command_run_send(state
, ev
, ectx
, state
->client
,
703 if (tevent_req_nomem(subreq
, req
)) {
704 return tevent_req_post(req
, ev
);
706 tevent_req_set_callback(subreq
, client_run_done
, req
);
709 case CTDB_EVENT_COMMAND_STATUS
:
710 subreq
= command_status_send(state
, ev
, ectx
, state
->client
,
712 if (tevent_req_nomem(subreq
, req
)) {
713 return tevent_req_post(req
, ev
);
715 tevent_req_set_callback(subreq
, client_status_done
, req
);
718 case CTDB_EVENT_COMMAND_SCRIPT_LIST
:
719 subreq
= command_script_list_send(state
, ev
, ectx
,
722 if (tevent_req_nomem(subreq
, req
)) {
723 return tevent_req_post(req
, ev
);
725 tevent_req_set_callback(subreq
, client_script_list_done
, req
);
728 case CTDB_EVENT_COMMAND_SCRIPT_ENABLE
:
729 subreq
= command_script_enable_send(state
, ev
, ectx
,
732 if (tevent_req_nomem(subreq
, req
)) {
733 return tevent_req_post(req
, ev
);
735 tevent_req_set_callback(subreq
, client_script_enable_done
,
739 case CTDB_EVENT_COMMAND_SCRIPT_DISABLE
:
740 subreq
= command_script_disable_send(state
, ev
, ectx
,
743 if (tevent_req_nomem(subreq
, req
)) {
744 return tevent_req_post(req
, ev
);
746 tevent_req_set_callback(subreq
, client_script_disable_done
,
754 static void client_run_done(struct tevent_req
*subreq
)
756 struct tevent_req
*req
= tevent_req_callback_data(
757 subreq
, struct tevent_req
);
758 struct client_process_state
*state
= tevent_req_data(
759 req
, struct client_process_state
);
760 struct ctdb_event_reply
*reply
= NULL
;
764 status
= command_run_recv(subreq
, &ret
, state
, &reply
);
767 D_ERR("COMMAND_RUN failed\n");
768 tevent_req_error(req
, ret
);
772 client_process_reply(req
, reply
);
776 static void client_status_done(struct tevent_req
*subreq
)
778 struct tevent_req
*req
= tevent_req_callback_data(
779 subreq
, struct tevent_req
);
780 struct client_process_state
*state
= tevent_req_data(
781 req
, struct client_process_state
);
782 struct ctdb_event_reply
*reply
= NULL
;
786 status
= command_status_recv(subreq
, &ret
, state
, &reply
);
789 D_ERR("COMMAND_STATUS failed\n");
790 tevent_req_error(req
, ret
);
794 client_process_reply(req
, reply
);
798 static void client_script_list_done(struct tevent_req
*subreq
)
800 struct tevent_req
*req
= tevent_req_callback_data(
801 subreq
, struct tevent_req
);
802 struct client_process_state
*state
= tevent_req_data(
803 req
, struct client_process_state
);
804 struct ctdb_event_reply
*reply
= NULL
;
808 status
= command_script_list_recv(subreq
, &ret
, state
, &reply
);
811 D_ERR("COMMAND_SCRIPT_LIST failed\n");
812 tevent_req_error(req
, ret
);
816 client_process_reply(req
, reply
);
820 static void client_script_enable_done(struct tevent_req
*subreq
)
822 struct tevent_req
*req
= tevent_req_callback_data(
823 subreq
, struct tevent_req
);
824 struct client_process_state
*state
= tevent_req_data(
825 req
, struct client_process_state
);
826 struct ctdb_event_reply
*reply
= NULL
;
830 status
= command_script_enable_recv(subreq
, &ret
, state
, &reply
);
833 D_ERR("COMMAND_SCRIPT_ENABLE failed\n");
834 tevent_req_error(req
, ret
);
838 client_process_reply(req
, reply
);
842 static void client_script_disable_done(struct tevent_req
*subreq
)
844 struct tevent_req
*req
= tevent_req_callback_data(
845 subreq
, struct tevent_req
);
846 struct client_process_state
*state
= tevent_req_data(
847 req
, struct client_process_state
);
848 struct ctdb_event_reply
*reply
= NULL
;
852 status
= command_script_disable_recv(subreq
, &ret
, state
, &reply
);
855 D_ERR("COMMAND_SCRIPT_DISABLE failed\n");
856 tevent_req_error(req
, ret
);
860 client_process_reply(req
, reply
);
864 static void client_process_reply(struct tevent_req
*req
,
865 struct ctdb_event_reply
*reply
)
867 struct client_process_state
*state
= tevent_req_data(
868 req
, struct client_process_state
);
869 struct tevent_req
*subreq
;
874 sock_packet_header_set_reqid(&reply
->header
,
875 state
->request
.header
.reqid
);
877 buflen
= ctdb_event_reply_len(reply
);
878 buf
= talloc_zero_size(state
, buflen
);
879 if (tevent_req_nomem(buf
, req
)) {
883 ret
= ctdb_event_reply_push(reply
, buf
, &buflen
);
886 tevent_req_error(req
, ret
);
890 subreq
= sock_socket_write_send(state
, state
->ev
,
891 state
->client
->client_ctx
,
893 if (tevent_req_nomem(subreq
, req
)) {
896 tevent_req_set_callback(subreq
, client_process_reply_done
, req
);
899 static void client_process_reply_done(struct tevent_req
*subreq
)
901 struct tevent_req
*req
= tevent_req_callback_data(
902 subreq
, struct tevent_req
);
906 status
= sock_socket_write_recv(subreq
, &ret
);
909 D_ERR("Sending reply failed\n");
910 tevent_req_error(req
, ret
);
914 tevent_req_done(req
);
917 static bool client_process_recv(struct tevent_req
*req
, int *perr
)
921 if (tevent_req_is_unix_error(req
, &ret
)) {
935 static void eventd_shutdown(void *private_data
)
937 struct eventd_context
*ectx
= talloc_get_type_abort(
938 private_data
, struct eventd_context
);
939 struct eventd_client
*client
;
941 while ((client
= ectx
->client_list
) != NULL
) {
942 DLIST_REMOVE(ectx
->client_list
, client
);
948 const char *debug_script
;
949 const char *script_dir
;
951 const char *debug_level
;
956 .debug_level
= "ERR",
959 struct poptOption cmdline_options
[] = {
961 { "debug_script", 'D', POPT_ARG_STRING
, &options
.debug_script
, 0,
962 "debug script", "FILE" },
963 { "pid", 'P', POPT_ARG_INT
, &options
.pid
, 0,
964 "pid to wait for", "PID" },
965 { "event_script_dir", 'e', POPT_ARG_STRING
, &options
.script_dir
, 0,
966 "event script dir", "DIRECTORY" },
967 { "logging", 'l', POPT_ARG_STRING
, &options
.logging
, 0,
968 "logging specification" },
969 { "debug", 'd', POPT_ARG_STRING
, &options
.debug_level
, 0,
971 { "pidfile", 'p', POPT_ARG_STRING
, &options
.pidfile
, 0,
972 "eventd pid file", "FILE" },
973 { "socket", 's', POPT_ARG_STRING
, &options
.socket
, 0,
974 "eventd socket path", "FILE" },
978 int main(int argc
, const char **argv
)
982 struct tevent_context
*ev
;
983 struct eventd_context
*ectx
;
984 struct sock_daemon_context
*sockd
;
985 struct sock_daemon_funcs daemon_funcs
;
986 struct sock_socket_funcs socket_funcs
;
990 /* Set default options */
993 pc
= poptGetContext(argv
[0], argc
, argv
, cmdline_options
,
994 POPT_CONTEXT_KEEP_FIRST
);
995 while ((opt
= poptGetNextOpt(pc
)) != -1) {
996 fprintf(stderr
, "Invalid options %s: %s\n",
997 poptBadOption(pc
, 0), poptStrerror(opt
));
1001 if (options
.socket
== NULL
) {
1002 fprintf(stderr
, "Please specify eventd socket (--socket)\n");
1006 if (options
.script_dir
== NULL
) {
1008 "Please specify script dir (--event_script_dir)\n");
1012 if (options
.logging
== NULL
) {
1014 "Please specify logging (--logging)\n");
1018 ret
= stat(options
.script_dir
, &statbuf
);
1021 fprintf(stderr
, "Error reading script_dir %s, ret=%d\n",
1022 options
.script_dir
, ret
);
1025 if (! S_ISDIR(statbuf
.st_mode
)) {
1026 fprintf(stderr
, "script_dir %s is not a directory\n",
1027 options
.script_dir
);
1031 mem_ctx
= talloc_new(NULL
);
1032 if (mem_ctx
== NULL
) {
1036 ev
= tevent_context_init(mem_ctx
);
1042 ret
= eventd_context_init(mem_ctx
, ev
, options
.script_dir
,
1043 options
.debug_script
, &ectx
);
1048 daemon_funcs
= (struct sock_daemon_funcs
) {
1049 .shutdown
= eventd_shutdown
,
1052 ret
= sock_daemon_setup(mem_ctx
, "ctdb-eventd", options
.logging
,
1053 options
.debug_level
,
1054 &daemon_funcs
, ectx
, &sockd
);
1059 socket_funcs
= (struct sock_socket_funcs
) {
1060 .connect
= client_connect
,
1061 .disconnect
= client_disconnect
,
1062 .read_send
= client_process_send
,
1063 .read_recv
= client_process_recv
,
1066 ret
= sock_daemon_add_unix(sockd
, options
.socket
, &socket_funcs
, ectx
);
1071 ret
= sock_daemon_run(ev
, sockd
,
1072 options
.pidfile
, false, false, options
.pid
);
1078 talloc_free(mem_ctx
);
1079 (void)poptFreeContext(pc
);