~ubuntu-branches/ubuntu/vivid/ctdb/vivid-proposed

« back to all changes in this revision

Viewing changes to server/eventscript.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Parent
  • Date: 2010-02-10 19:39:13 UTC
  • mfrom: (1.2.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20100210193913-c2kyhrx49cj64z72
Tags: 1.0.111.really.1.0.108-1
* Back to 1.0.108 which works better with samba 3.4.x and 3.5.0
  (See <http://lists.alioth.debian.org/pipermail/pkg-samba-maint/
  2010-February/009100.html>)
* Cheery pick some commits from 1.0.108-3 to 1.0.111-1

Show diffs side-by-side

added added

removed removed

Lines of Context:
64
64
        pid_t child;
65
65
        /* Warning: this can free us! */
66
66
        void (*callback)(struct ctdb_context *, int, void *);
 
67
        int cb_status;
67
68
        int fd[2];
68
69
        void *private_data;
69
70
        bool from_user;
87
88
{
88
89
        struct ctdb_event_script_state *state
89
90
                = talloc_get_type(p, struct ctdb_event_script_state);
90
 
        struct ctdb_script_wire *current;
 
91
        struct ctdb_script_wire *current = get_current_script(state);
91
92
        unsigned int slen, min;
92
93
 
93
 
        /* We may have been aborted to run something else.  Discard */
94
 
        if (state->scripts == NULL) {
95
 
                return;
96
 
        }
97
 
 
98
 
        current = get_current_script(state);
99
 
 
100
94
        /* Append, but don't overfill buffer.  It starts zero-filled. */
101
95
        slen = strlen(current->output);
102
96
        min = MIN(len, sizeof(current->output) - slen - 1);
429
423
        return 0;
430
424
}
431
425
 
432
 
/*
433
 
 Summarize status of this run of scripts.
434
 
 */
435
 
static int script_status(struct ctdb_scripts_wire *scripts)
436
 
{
437
 
        unsigned int i;
438
 
 
439
 
        for (i = 0; i < scripts->num_scripts; i++) {
440
 
                switch (scripts->scripts[i].status) {
441
 
                case -ENOENT:
442
 
                case -ENOEXEC:
443
 
                        /* Disabled or missing; that's OK. */
444
 
                        break;
445
 
                case 0:
446
 
                        /* No problem. */
447
 
                        break;
448
 
                default:
449
 
                        return scripts->scripts[i].status;
450
 
                }
451
 
        }
452
 
 
453
 
        /* All OK! */
454
 
        return 0;
455
 
}
456
 
 
457
426
/* called when child is finished */
458
427
static void ctdb_event_script_handler(struct event_context *ev, struct fd_event *fde, 
459
428
                                      uint16_t flags, void *p)
462
431
                talloc_get_type(p, struct ctdb_event_script_state);
463
432
        struct ctdb_script_wire *current = get_current_script(state);
464
433
        struct ctdb_context *ctdb = state->ctdb;
465
 
        int r, status;
 
434
        int r;
466
435
 
467
436
        r = read(state->fd[0], &current->status, sizeof(current->status));
468
437
        if (r < 0) {
472
441
        }
473
442
 
474
443
        current->finished = timeval_current();
475
 
        /* valgrind gets overloaded if we run next script as it's still doing
476
 
         * post-execution analysis, so kill finished child here. */
477
 
        if (ctdb->valgrinding) {
478
 
                kill(state->child, SIGKILL);
 
444
 
 
445
        /* update overall status based on this script. */
 
446
        state->cb_status = current->status;
 
447
 
 
448
        /* don't stop just because it vanished or was disabled. */
 
449
        if (current->status == -ENOENT || current->status == -ENOEXEC) {
 
450
                state->cb_status = 0;
479
451
        }
480
452
 
481
453
        state->child = 0;
482
454
 
483
 
        status = script_status(state->scripts);
484
 
 
485
455
        /* Aborted or finished all scripts?  We're done. */
486
 
        if (status != 0 || state->current+1 == state->scripts->num_scripts) {
 
456
        if (state->cb_status != 0 || state->current+1 == state->scripts->num_scripts) {
487
457
                DEBUG(DEBUG_INFO,(__location__ " Eventscript %s %s finished with state %d\n",
488
 
                                  ctdb_eventscript_call_names[state->call], state->options, status));
 
458
                                  ctdb_eventscript_call_names[state->call], state->options, state->cb_status));
489
459
 
490
460
                ctdb->event_script_timeouts = 0;
491
461
                talloc_free(state);
497
467
 
498
468
        /* Next script! */
499
469
        state->current++;
500
 
        current++;
501
 
        current->status = fork_child_for_script(ctdb, state);
502
 
        if (current->status != 0) {
 
470
        state->cb_status = fork_child_for_script(ctdb, state);
 
471
        if (state->cb_status != 0) {
503
472
                /* This calls the callback. */
504
473
                talloc_free(state);
505
474
        }
511
480
{
512
481
        struct ctdb_event_script_state *state = talloc_get_type(p, struct ctdb_event_script_state);
513
482
        struct ctdb_context *ctdb = state->ctdb;
514
 
        struct ctdb_script_wire *current = get_current_script(state);
515
 
 
516
 
        DEBUG(DEBUG_ERR,("Event script timed out : %s %s %s count : %u  pid : %d\n",
517
 
                         current->name, ctdb_eventscript_call_names[state->call], state->options, ctdb->event_script_timeouts, state->child));
518
 
 
519
 
        state->scripts->scripts[state->current].status = -ETIME;
 
483
 
 
484
        DEBUG(DEBUG_ERR,("Event script timed out : %s %s count : %u  pid : %d\n",
 
485
                         ctdb_eventscript_call_names[state->call], state->options, ctdb->event_script_timeouts, state->child));
 
486
 
 
487
        state->cb_status = -ETIME;
520
488
 
521
489
        if (kill(state->child, 0) != 0) {
522
490
                DEBUG(DEBUG_ERR,("Event script child process already dead, errno %s(%d)\n", strerror(errno), errno));
523
491
                state->child = 0;
524
492
        }
525
493
 
 
494
        state->scripts->scripts[state->current].status = state->cb_status;
 
495
 
526
496
        talloc_free(state);
527
497
}
528
498
 
531
501
 */
532
502
static int event_script_destructor(struct ctdb_event_script_state *state)
533
503
{
534
 
        int status;
535
 
 
536
504
        if (state->child) {
537
505
                DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child pid:%d\n", state->child));
538
506
 
546
514
                state->ctdb->current_monitor = NULL;
547
515
        }
548
516
 
549
 
        /* Save our scripts as the last executed status, if we have them.
550
 
         * See ctdb_event_script_callback_v where we abort monitor event. */
551
 
        if (state->scripts) {
552
 
                talloc_free(state->ctdb->last_status[state->call]);
553
 
                state->ctdb->last_status[state->call] = state->scripts;
554
 
                if (state->current < state->ctdb->last_status[state->call]->num_scripts) {
555
 
                        state->ctdb->last_status[state->call]->num_scripts = state->current+1;
556
 
                }
557
 
        }
558
 
 
559
 
        /* Use last status as result, or "OK" if none. */
560
 
        if (state->ctdb->last_status[state->call]) {
561
 
                status = script_status(state->ctdb->last_status[state->call]);
562
 
        } else {
563
 
                status = 0;
 
517
        /* Save our status as the last executed status. */
 
518
        talloc_free(state->ctdb->last_status[state->call]);
 
519
        state->ctdb->last_status[state->call] = state->scripts;
 
520
        if (state->current < state->ctdb->last_status[state->call]->num_scripts) {
 
521
                state->ctdb->last_status[state->call]->num_scripts = state->current+1;
564
522
        }
565
523
 
566
524
        /* This is allowed to free us; talloc will prevent double free anyway,
567
525
         * but beware if you call this outside the destructor! */
568
526
        if (state->callback) {
569
 
                state->callback(state->ctdb, status, state->private_data);
 
527
                state->callback(state->ctdb, state->cb_status, state->private_data);
570
528
        }
571
529
 
572
530
        return 0;
621
579
                                        const char *fmt, va_list ap)
622
580
{
623
581
        struct ctdb_event_script_state *state;
 
582
        int ret;
624
583
 
625
584
        state = talloc(ctdb->event_script_ctx, struct ctdb_event_script_state);
626
585
        CTDB_NO_MEMORY(ctdb, state);
663
622
        }
664
623
 
665
624
        /* Kill off any running monitor events to run this event. */
666
 
        if (ctdb->current_monitor) {
667
 
                /* Discard script status so we don't save to last_status */
668
 
                talloc_free(ctdb->current_monitor->scripts);
669
 
                ctdb->current_monitor->scripts = NULL;
670
 
                talloc_free(ctdb->current_monitor);
671
 
                ctdb->current_monitor = NULL;
 
625
        talloc_free(ctdb->current_monitor);
 
626
        ctdb->current_monitor = NULL;
 
627
 
 
628
        if (!from_user && (call == CTDB_EVENT_MONITOR || call == CTDB_EVENT_STATUS)) {
 
629
                ctdb->current_monitor = state;
672
630
        }
673
631
 
674
632
        DEBUG(DEBUG_INFO,(__location__ " Starting eventscript %s %s\n",
683
641
        }
684
642
        state->current = 0;
685
643
 
686
 
        if (!from_user && (call == CTDB_EVENT_MONITOR || call == CTDB_EVENT_STATUS)) {
687
 
                ctdb->current_monitor = state;
688
 
        }
689
 
 
690
 
        talloc_set_destructor(state, event_script_destructor);
691
 
 
692
644
        /* Nothing to do? */
693
645
        if (state->scripts->num_scripts == 0) {
 
646
                ctdb->event_script_timeouts = 0;
694
647
                talloc_free(state);
695
648
                return 0;
696
649
        }
697
650
 
698
 
        state->scripts->scripts[0].status = fork_child_for_script(ctdb, state);
699
 
        if (state->scripts->scripts[0].status != 0) {
700
 
                /* Callback is called from destructor, with fail result. */
701
 
                talloc_free(state);
702
 
                return 0;
703
 
        }
 
651
        ret = fork_child_for_script(ctdb, state);
 
652
        if (ret != 0) {
 
653
                talloc_free(state->scripts);
 
654
                talloc_free(state);
 
655
                return -1;
 
656
        }
704
657
 
 
658
        talloc_set_destructor(state, event_script_destructor);
705
659
        if (!timeval_is_zero(&state->timeout)) {
706
660
                event_add_timed(ctdb->ev, state, timeval_current_ofs(state->timeout.tv_sec, state->timeout.tv_usec), ctdb_event_script_timeout, state);
707
661
        } else {