ctdb-daemon: Fix valgrind hit in event code
[samba.git] / ctdb / server / eventscript.c
1 /*
2    event script handling
3
4    Copyright (C) Andrew Tridgell  2007
5
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.
10
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.
15
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/>.
18 */
19
20 #include "replace.h"
21 #include "system/filesys.h"
22 #include "system/network.h"
23 #include "system/wait.h"
24 #include "system/dir.h"
25 #include "system/locale.h"
26 #include "system/time.h"
27 #include "system/dir.h"
28
29 #include <talloc.h>
30 #include <tevent.h>
31
32 #include "lib/util/dlinklist.h"
33 #include "lib/util/debug.h"
34 #include "lib/util/samba_util.h"
35 #include "lib/util/sys_rw.h"
36
37 #include "ctdb_private.h"
38
39 #include "common/rb_tree.h"
40 #include "common/common.h"
41 #include "common/logging.h"
42 #include "common/reqid.h"
43 #include "common/sock_io.h"
44 #include "common/path.h"
45
46 #include "protocol/protocol_util.h"
47 #include "event/event_protocol_api.h"
48
49 /*
50  * Setting up event daemon
51  */
52
53 struct eventd_context {
54         struct tevent_context *ev;
55         const char *path;
56         const char *socket;
57
58         /* server state */
59         pid_t eventd_pid;
60         struct tevent_fd *eventd_fde;
61
62         /* client state */
63         struct reqid_context *idr;
64         struct sock_queue *queue;
65         struct eventd_client_state *calls;
66 };
67
68 static bool eventd_context_init(TALLOC_CTX *mem_ctx,
69                                 struct ctdb_context *ctdb,
70                                 struct eventd_context **out)
71 {
72         struct eventd_context *ectx;
73         const char *eventd = CTDB_HELPER_BINDIR "/ctdb-eventd";
74         const char *value;
75         int ret;
76
77         ectx = talloc_zero(mem_ctx, struct eventd_context);
78         if (ectx == NULL) {
79                 return false;
80         }
81
82         ectx->ev = ctdb->ev;
83
84         value = getenv("CTDB_EVENTD");
85         if (value != NULL) {
86                 eventd = value;
87         }
88
89         ectx->path = talloc_strdup(ectx, eventd);
90         if (ectx->path == NULL) {
91                 talloc_free(ectx);
92                 return false;
93         }
94
95         ectx->socket = path_socket(ectx, "eventd");
96         if (ectx->socket == NULL) {
97                 talloc_free(ectx);
98                 return false;
99         }
100
101         ret = reqid_init(ectx, 1, &ectx->idr);
102         if (ret != 0) {
103                 talloc_free(ectx);
104                 return false;
105         }
106
107         ectx->eventd_pid = -1;
108
109         *out = ectx;
110         return true;
111 }
112
113 struct eventd_startup_state {
114         bool done;
115         int ret;
116         int fd;
117 };
118
119 static void eventd_startup_timeout_handler(struct tevent_context *ev,
120                                            struct tevent_timer *te,
121                                            struct timeval t,
122                                            void *private_data)
123 {
124         struct eventd_startup_state *state =
125                 (struct eventd_startup_state *) private_data;
126
127         state->done = true;
128         state->ret = ETIMEDOUT;
129 }
130
131 static void eventd_startup_handler(struct tevent_context *ev,
132                                    struct tevent_fd *fde, uint16_t flags,
133                                    void *private_data)
134 {
135         struct eventd_startup_state *state =
136                 (struct eventd_startup_state *)private_data;
137         unsigned int data;
138         ssize_t num_read;
139
140         num_read = sys_read(state->fd, &data, sizeof(data));
141         if (num_read == sizeof(data)) {
142                 if (data == 0) {
143                         state->ret = 0;
144                 } else {
145                         state->ret = EIO;
146                 }
147         } else if (num_read == 0) {
148                 state->ret = EPIPE;
149         } else if (num_read == -1) {
150                 state->ret = errno;
151         } else {
152                 state->ret = EINVAL;
153         }
154
155         state->done = true;
156 }
157
158
159 static int wait_for_daemon_startup(struct tevent_context *ev,
160                                    int fd)
161 {
162         TALLOC_CTX *mem_ctx;
163         struct tevent_timer *timer;
164         struct tevent_fd *fde;
165         struct eventd_startup_state state = {
166                 .done = false,
167                 .ret = 0,
168                 .fd = fd,
169         };
170
171         mem_ctx = talloc_new(ev);
172         if (mem_ctx == NULL) {
173                 return ENOMEM;
174         }
175
176         timer = tevent_add_timer(ev,
177                                  mem_ctx,
178                                  tevent_timeval_current_ofs(10, 0),
179                                  eventd_startup_timeout_handler,
180                                  &state);
181         if (timer == NULL) {
182                 talloc_free(mem_ctx);
183                 return ENOMEM;
184         }
185
186         fde = tevent_add_fd(ev,
187                             mem_ctx,
188                             fd,
189                             TEVENT_FD_READ,
190                             eventd_startup_handler,
191                             &state);
192         if (fde == NULL) {
193                 talloc_free(mem_ctx);
194                 return ENOMEM;
195         }
196
197         while (! state.done) {
198                 tevent_loop_once(ev);
199         }
200
201         talloc_free(mem_ctx);
202
203         return state.ret;
204 }
205
206
207 /*
208  * Start and stop event daemon
209  */
210
211 static bool eventd_client_connect(struct eventd_context *ectx);
212 static void eventd_dead_handler(struct tevent_context *ev,
213                                 struct tevent_fd *fde, uint16_t flags,
214                                 void *private_data);
215
216 int ctdb_start_eventd(struct ctdb_context *ctdb)
217 {
218         struct eventd_context *ectx;
219         const char **argv;
220         int fd[2];
221         pid_t pid;
222         int ret;
223         bool status;
224
225         if (ctdb->ectx == NULL) {
226                 status = eventd_context_init(ctdb, ctdb, &ctdb->ectx);
227                 if (! status) {
228                         DEBUG(DEBUG_ERR,
229                               ("Failed to initialize eventd context\n"));
230                         return -1;
231                 }
232         }
233
234         ectx = ctdb->ectx;
235
236         if (! sock_clean(ectx->socket)) {
237                 return -1;
238         }
239
240         ret = pipe(fd);
241         if (ret != 0) {
242                 return -1;
243         }
244
245         argv = talloc_array(ectx, const char *, 6);
246         if (argv == NULL) {
247                 close(fd[0]);
248                 close(fd[1]);
249                 return -1;
250         }
251
252         argv[0] = ectx->path;
253         argv[1] = "-P";
254         argv[2] = talloc_asprintf(argv, "%d", ctdb->ctdbd_pid);
255         argv[3] = "-S";
256         argv[4] = talloc_asprintf(argv, "%d", fd[1]);
257         argv[5] = NULL;
258
259         if (argv[2] == NULL || argv[4] == NULL) {
260                 close(fd[0]);
261                 close(fd[1]);
262                 talloc_free(argv);
263                 return -1;
264         }
265
266         D_NOTICE("Starting event daemon %s %s %s %s %s\n",
267                  argv[0],
268                  argv[1],
269                  argv[2],
270                  argv[3],
271                  argv[4]);
272
273         pid = ctdb_fork(ctdb);
274         if (pid == -1) {
275                 close(fd[0]);
276                 close(fd[1]);
277                 talloc_free(argv);
278                 return -1;
279         }
280
281         if (pid == 0) {
282                 close(fd[0]);
283                 ret = execv(argv[0], discard_const(argv));
284                 if (ret == -1) {
285                         _exit(errno);
286                 }
287                 _exit(0);
288         }
289
290         talloc_free(argv);
291         close(fd[1]);
292
293         ret = wait_for_daemon_startup(ctdb->ev, fd[0]);
294         if (ret != 0) {
295                 ctdb_kill(ctdb, pid, SIGKILL);
296                 close(fd[0]);
297                 D_ERR("Failed to initialize event daemon (%d)\n", ret);
298                 return -1;
299         }
300
301         ectx->eventd_fde = tevent_add_fd(ctdb->ev, ectx, fd[0],
302                                          TEVENT_FD_READ,
303                                          eventd_dead_handler, ectx);
304         if (ectx->eventd_fde == NULL) {
305                 ctdb_kill(ctdb, pid, SIGKILL);
306                 close(fd[0]);
307                 return -1;
308         }
309
310         tevent_fd_set_auto_close(ectx->eventd_fde);
311         ectx->eventd_pid = pid;
312
313         status = eventd_client_connect(ectx);
314         if (! status) {
315                 DEBUG(DEBUG_ERR, ("Failed to connect to event daemon\n"));
316                 ctdb_stop_eventd(ctdb);
317                 return -1;
318         }
319
320         return 0;
321 }
322
323 static void eventd_dead_handler(struct tevent_context *ev,
324                                 struct tevent_fd *fde, uint16_t flags,
325                                 void *private_data)
326 {
327         D_ERR("Eventd went away - exiting\n");
328         exit(1);
329 }
330
331 void ctdb_stop_eventd(struct ctdb_context *ctdb)
332 {
333         struct eventd_context *ectx = ctdb->ectx;
334
335         if (ectx == NULL) {
336                 return;
337         }
338
339         TALLOC_FREE(ectx->eventd_fde);
340         if (ectx->eventd_pid != -1) {
341                 kill(ectx->eventd_pid, SIGTERM);
342                 ectx->eventd_pid = -1;
343         }
344         TALLOC_FREE(ctdb->ectx);
345 }
346
347 /*
348  * Connect to event daemon
349  */
350
351 struct eventd_client_state {
352         struct eventd_client_state *prev, *next;
353
354         struct eventd_context *ectx;
355         void (*callback)(struct ctdb_event_reply *reply, void *private_data);
356         void *private_data;
357
358         uint32_t reqid;
359         uint8_t *buf;
360         size_t buflen;
361 };
362
363 static void eventd_client_read(uint8_t *buf, size_t buflen,
364                                void *private_data);
365 static int eventd_client_state_destructor(struct eventd_client_state *state);
366
367 static bool eventd_client_connect(struct eventd_context *ectx)
368 {
369         int fd;
370
371         if (ectx->queue != NULL) {
372                 return true;
373         }
374
375         fd = sock_connect(ectx->socket);
376         if (fd == -1) {
377                 return false;
378         }
379
380         ectx->queue = sock_queue_setup(ectx, ectx->ev, fd,
381                                        eventd_client_read, ectx);
382         if (ectx->queue == NULL) {
383                 close(fd);
384                 return false;
385         }
386
387         return true;
388 }
389
390 static int eventd_client_write(struct eventd_context *ectx,
391                                TALLOC_CTX *mem_ctx,
392                                struct ctdb_event_request *request,
393                                void (*callback)(struct ctdb_event_reply *reply,
394                                                 void *private_data),
395                                void *private_data)
396 {
397         struct ctdb_event_header header = { 0 };
398         struct eventd_client_state *state;
399         int ret;
400
401         if (! eventd_client_connect(ectx)) {
402                 return -1;
403         }
404
405         state = talloc_zero(mem_ctx, struct eventd_client_state);
406         if (state == NULL) {
407                 return -1;
408         }
409
410         state->ectx = ectx;
411         state->callback = callback;
412         state->private_data = private_data;
413
414         state->reqid = reqid_new(ectx->idr, state);
415         if (state->reqid == REQID_INVALID) {
416                 talloc_free(state);
417                 return -1;
418         }
419
420         talloc_set_destructor(state, eventd_client_state_destructor);
421
422         header.reqid = state->reqid;
423
424         state->buflen = ctdb_event_request_len(&header, request);
425         state->buf = talloc_size(state, state->buflen);
426         if (state->buf == NULL) {
427                 talloc_free(state);
428                 return -1;
429         }
430
431         ret = ctdb_event_request_push(&header,
432                                       request,
433                                       state->buf,
434                                       &state->buflen);
435         if (ret != 0) {
436                 talloc_free(state);
437                 return -1;
438         }
439
440         ret = sock_queue_write(ectx->queue, state->buf, state->buflen);
441         if (ret != 0) {
442                 talloc_free(state);
443                 return -1;
444         }
445
446         DLIST_ADD(ectx->calls, state);
447
448         return 0;
449 }
450
451 static int eventd_client_state_destructor(struct eventd_client_state *state)
452 {
453         struct eventd_context *ectx = state->ectx;
454
455         reqid_remove(ectx->idr, state->reqid);
456         DLIST_REMOVE(ectx->calls, state);
457         return 0;
458 }
459
460 static void eventd_client_read(uint8_t *buf, size_t buflen,
461                                void *private_data)
462 {
463         struct eventd_context *ectx = talloc_get_type_abort(
464                 private_data, struct eventd_context);
465         struct eventd_client_state *state;
466         struct ctdb_event_header header;
467         struct ctdb_event_reply *reply;
468         int ret;
469
470         if (buf == NULL) {
471                 /* connection lost */
472                 TALLOC_FREE(ectx->queue);
473                 return;
474         }
475
476         ret = ctdb_event_reply_pull(buf, buflen, &header, ectx, &reply);
477         if (ret != 0) {
478                 D_ERR("Invalid packet received, ret=%d\n", ret);
479                 return;
480         }
481
482         if (buflen != header.length) {
483                 D_ERR("Packet size mismatch %zu != %"PRIu32"\n",
484                       buflen, header.length);
485                 talloc_free(reply);
486                 return;
487         }
488
489         state = reqid_find(ectx->idr, header.reqid,
490                            struct eventd_client_state);
491         if (state == NULL) {
492                 talloc_free(reply);
493                 return;
494         }
495
496         if (state->reqid != header.reqid) {
497                 talloc_free(reply);
498                 return;
499         }
500
501         state = talloc_steal(reply, state);
502         state->callback(reply, state->private_data);
503         talloc_free(reply);
504 }
505
506 /*
507  * Run an event
508  */
509
510 struct eventd_client_run_state {
511         struct eventd_context *ectx;
512         void (*callback)(int result, void *private_data);
513         void *private_data;
514 };
515
516 static void eventd_client_run_done(struct ctdb_event_reply *reply,
517                                    void *private_data);
518
519 static int eventd_client_run(struct eventd_context *ectx,
520                              TALLOC_CTX *mem_ctx,
521                              void (*callback)(int result,
522                                               void *private_data),
523                              void *private_data,
524                              enum ctdb_event event,
525                              const char *arg_str,
526                              uint32_t timeout)
527 {
528         struct eventd_client_run_state *state;
529         struct ctdb_event_request request;
530         struct ctdb_event_request_run rdata;
531         int ret;
532
533         state = talloc_zero(mem_ctx, struct eventd_client_run_state);
534         if (state == NULL) {
535                 return -1;
536         }
537
538         state->ectx = ectx;
539         state->callback = callback;
540         state->private_data = private_data;
541
542         rdata.component = "legacy";
543         rdata.event = ctdb_event_to_string(event);
544         rdata.args = arg_str;
545         rdata.timeout = timeout;
546         rdata.flags = 0;
547
548         request.cmd = CTDB_EVENT_CMD_RUN;
549         request.data.run = &rdata;
550
551         ret = eventd_client_write(ectx, state, &request,
552                                   eventd_client_run_done, state);
553         if (ret != 0) {
554                 talloc_free(state);
555                 return ret;
556         }
557
558         return 0;
559 }
560
561 static void eventd_client_run_done(struct ctdb_event_reply *reply,
562                                    void *private_data)
563 {
564         struct eventd_client_run_state *state = talloc_get_type_abort(
565                 private_data, struct eventd_client_run_state);
566
567         state = talloc_steal(state->ectx, state);
568         state->callback(reply->result, state->private_data);
569         talloc_free(state);
570 }
571
572 /*
573  * CTDB event script functions
574  */
575
576 int ctdb_event_script_run(struct ctdb_context *ctdb,
577                           TALLOC_CTX *mem_ctx,
578                           void (*callback)(struct ctdb_context *ctdb,
579                                            int result, void *private_data),
580                           void *private_data,
581                           enum ctdb_event event,
582                           const char *fmt, va_list ap)
583                           PRINTF_ATTRIBUTE(6,0);
584
585 struct ctdb_event_script_run_state {
586         struct ctdb_context *ctdb;
587         void (*callback)(struct ctdb_context *ctdb, int result,
588                          void *private_data);
589         void *private_data;
590         enum ctdb_event event;
591 };
592
593 static bool event_allowed_during_recovery(enum ctdb_event event);
594 static void ctdb_event_script_run_done(int result, void *private_data);
595 static bool check_options(enum ctdb_event call, const char *options);
596
597 int ctdb_event_script_run(struct ctdb_context *ctdb,
598                           TALLOC_CTX *mem_ctx,
599                           void (*callback)(struct ctdb_context *ctdb,
600                                            int result, void *private_data),
601                           void *private_data,
602                           enum ctdb_event event,
603                           const char *fmt, va_list ap)
604 {
605         struct ctdb_event_script_run_state *state;
606         char *arg_str;
607         int ret;
608
609         if ( (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) &&
610              (! event_allowed_during_recovery(event)) ) {
611                 DEBUG(DEBUG_ERR,
612                       ("Refusing to run event '%s' while in recovery\n",
613                        ctdb_eventscript_call_names[event]));
614                 return -1;
615         }
616
617         state = talloc_zero(mem_ctx, struct ctdb_event_script_run_state);
618         if (state == NULL) {
619                 return -1;
620         }
621
622         state->ctdb = ctdb;
623         state->callback = callback;
624         state->private_data = private_data;
625         state->event = event;
626
627         if (fmt != NULL) {
628                 arg_str = talloc_vasprintf(state, fmt, ap);
629                 if (arg_str == NULL) {
630                         talloc_free(state);
631                         return -1;
632                 }
633         } else {
634                 arg_str = NULL;
635         }
636
637         if (! check_options(event, arg_str)) {
638                 DEBUG(DEBUG_ERR,
639                       ("Bad event script arguments '%s' for '%s'\n",
640                        arg_str, ctdb_eventscript_call_names[event]));
641                 talloc_free(arg_str);
642                 return -1;
643         }
644
645         ret = eventd_client_run(ctdb->ectx, state,
646                                 ctdb_event_script_run_done, state,
647                                 event, arg_str, ctdb->tunable.script_timeout);
648         if (ret != 0) {
649                 talloc_free(state);
650                 return ret;
651         }
652
653         DEBUG(DEBUG_INFO,
654               (__location__ " Running event %s with arguments %s\n",
655                ctdb_eventscript_call_names[event], arg_str));
656
657         talloc_free(arg_str);
658         return 0;
659 }
660
661 static void ctdb_event_script_run_done(int result, void *private_data)
662 {
663         struct ctdb_event_script_run_state *state = talloc_get_type_abort(
664                 private_data, struct ctdb_event_script_run_state);
665
666         if (result == ETIMEDOUT) {
667                 switch (state->event) {
668                 case CTDB_EVENT_START_RECOVERY:
669                 case CTDB_EVENT_RECOVERED:
670                 case CTDB_EVENT_TAKE_IP:
671                 case CTDB_EVENT_RELEASE_IP:
672                         DEBUG(DEBUG_ERR,
673                               ("Ignoring hung script for %s event\n",
674                                ctdb_eventscript_call_names[state->event]));
675                         result = 0;
676                         break;
677
678                 default:
679                         break;
680                 }
681         }
682
683         state = talloc_steal(state->ctdb, state);
684         state->callback(state->ctdb, result, state->private_data);
685         talloc_free(state);
686 }
687
688
689 static unsigned int count_words(const char *options)
690 {
691         unsigned int words = 0;
692
693         if (options == NULL) {
694                 return 0;
695         }
696
697         options += strspn(options, " \t");
698         while (*options) {
699                 words++;
700                 options += strcspn(options, " \t");
701                 options += strspn(options, " \t");
702         }
703         return words;
704 }
705
706 static bool check_options(enum ctdb_event call, const char *options)
707 {
708         switch (call) {
709         /* These all take no arguments. */
710         case CTDB_EVENT_INIT:
711         case CTDB_EVENT_SETUP:
712         case CTDB_EVENT_STARTUP:
713         case CTDB_EVENT_START_RECOVERY:
714         case CTDB_EVENT_RECOVERED:
715         case CTDB_EVENT_MONITOR:
716         case CTDB_EVENT_SHUTDOWN:
717         case CTDB_EVENT_IPREALLOCATED:
718                 return count_words(options) == 0;
719
720         case CTDB_EVENT_TAKE_IP: /* interface, IP address, netmask bits. */
721         case CTDB_EVENT_RELEASE_IP:
722                 return count_words(options) == 3;
723
724         case CTDB_EVENT_UPDATE_IP: /* old interface, new interface, IP address, netmask bits. */
725                 return count_words(options) == 4;
726
727         default:
728                 DEBUG(DEBUG_ERR,(__location__ "Unknown ctdb_event %u\n", call));
729                 return false;
730         }
731 }
732
733 /* only specific events are allowed while in recovery */
734 static bool event_allowed_during_recovery(enum ctdb_event event)
735 {
736         const enum ctdb_event allowed_events[] = {
737                 CTDB_EVENT_INIT,
738                 CTDB_EVENT_SETUP,
739                 CTDB_EVENT_START_RECOVERY,
740                 CTDB_EVENT_SHUTDOWN,
741                 CTDB_EVENT_RELEASE_IP,
742                 CTDB_EVENT_IPREALLOCATED,
743         };
744         int i;
745
746         for (i = 0; i < ARRAY_SIZE(allowed_events); i++) {
747                 if (event == allowed_events[i]) {
748                         return true;
749                 }
750         }
751
752         return false;
753 }
754
755 /*
756   run the event script in the background, calling the callback when
757   finished.  If mem_ctx is freed, callback will never be called.
758  */
759 int ctdb_event_script_callback(struct ctdb_context *ctdb,
760                                TALLOC_CTX *mem_ctx,
761                                void (*callback)(struct ctdb_context *, int, void *),
762                                void *private_data,
763                                enum ctdb_event call,
764                                const char *fmt, ...)
765 {
766         va_list ap;
767         int ret;
768
769         va_start(ap, fmt);
770         ret = ctdb_event_script_run(ctdb, mem_ctx, callback, private_data,
771                                     call, fmt, ap);
772         va_end(ap);
773
774         return ret;
775 }
776
777
778 struct ctdb_event_script_args_state {
779         bool done;
780         int status;
781 };
782
783 static void ctdb_event_script_args_done(struct ctdb_context *ctdb,
784                                         int status, void *private_data)
785 {
786         struct ctdb_event_script_args_state *s =
787                 (struct ctdb_event_script_args_state *)private_data;
788
789         s->done = true;
790         s->status = status;
791 }
792
793 /*
794   run the event script, waiting for it to complete. Used when the caller
795   doesn't want to continue till the event script has finished.
796  */
797 int ctdb_event_script_args(struct ctdb_context *ctdb, enum ctdb_event call,
798                            const char *fmt, ...)
799 {
800         va_list ap;
801         int ret;
802         struct ctdb_event_script_args_state state = {
803                 .status = -1,
804                 .done = false,
805         };
806
807         va_start(ap, fmt);
808         ret = ctdb_event_script_run(ctdb, ctdb,
809                                     ctdb_event_script_args_done, &state,
810                                     call, fmt, ap);
811         va_end(ap);
812         if (ret != 0) {
813                 return ret;
814         }
815
816         while (! state.done) {
817                 tevent_loop_once(ctdb->ev);
818         }
819
820         if (state.status == ETIMEDOUT) {
821                 /* Don't ban self if CTDB is starting up or shutting down */
822                 if (call != CTDB_EVENT_INIT && call != CTDB_EVENT_SHUTDOWN) {
823                         DEBUG(DEBUG_ERR,
824                               (__location__ " eventscript for '%s' timed out."
825                                " Immediately banning ourself for %d seconds\n",
826                                ctdb_eventscript_call_names[call],
827                                ctdb->tunable.recovery_ban_period));
828                         ctdb_ban_self(ctdb);
829                 }
830         }
831
832         return state.status;
833 }
834
835 int ctdb_event_script(struct ctdb_context *ctdb, enum ctdb_event call)
836 {
837         /* GCC complains about empty format string, so use %s and "". */
838         return ctdb_event_script_args(ctdb, call, NULL);
839 }