~ubuntu-branches/ubuntu/utopic/pacemaker/utopic-proposed

« back to all changes in this revision

Viewing changes to mcp/pacemaker.c

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2013-08-15 11:27:07 UTC
  • mfrom: (1.1.12) (2.1.24 sid)
  • Revision ID: package-import@ubuntu.com-20130815112707-5r864ink7jme3zl5
Tags: 1.1.10+git20130802-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - debian/control: Build-Depends on libqb-dev; Depends on libheartbeat2.
* Corosync's pacemaker plugin is disabled, hence not built:
  - debian/licrmcluster4-dev.install: Do not install plugin.h.
  - debian/pacemaker.install: Do not install pacemaker.lcrso.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include <pacemaker.h>
21
21
 
22
22
#include <pwd.h>
 
23
#include <grp.h>
23
24
#include <sys/stat.h>
24
25
#include <sys/types.h>
25
26
#include <sys/time.h>
26
27
#include <sys/resource.h>
 
28
#include <sys/reboot.h>
27
29
 
28
30
#include <crm/msg_xml.h>
29
31
#include <crm/common/ipcs.h>
30
32
#include <crm/common/mainloop.h>
 
33
#include <crm/cluster/internal.h>
31
34
#include <crm/cluster.h>
32
35
 
33
36
#include <dirent.h>
34
37
#include <ctype.h>
35
38
gboolean fatal_error = FALSE;
36
39
GMainLoop *mainloop = NULL;
37
 
GHashTable *peers = NULL;
38
40
 
39
41
#define PCMK_PROCESS_CHECK_INTERVAL 5
40
42
 
41
 
char *local_name = NULL;
 
43
const char *local_name = NULL;
42
44
uint32_t local_nodeid = 0;
43
45
crm_trigger_t *shutdown_trigger = NULL;
44
46
const char *pid_file = "/var/run/pacemaker.pid";
45
47
 
46
 
/* *INDENT-OFF* */
47
 
enum crm_proc_flag {
48
 
    crm_proc_none       = 0x00000001,
49
 
    crm_proc_plugin        = 0x00000002,
50
 
    crm_proc_lrmd       = 0x00000010,
51
 
    crm_proc_cib        = 0x00000100,
52
 
    crm_proc_crmd       = 0x00000200,
53
 
    crm_proc_attrd      = 0x00001000,
54
 
    crm_proc_stonithd   = 0x00002000,
55
 
    crm_proc_pe         = 0x00010000,
56
 
    crm_proc_te         = 0x00020000,
57
 
    crm_proc_mgmtd      = 0x00040000,
58
 
    crm_proc_stonith_ng = 0x00100000,
59
 
};
60
 
/* *INDENT-ON* */
61
 
 
62
48
typedef struct pcmk_child_s {
63
49
    int pid;
64
50
    long flag;
92
78
 
93
79
static gboolean start_child(pcmk_child_t * child);
94
80
static gboolean check_active_before_startup_processes(gpointer user_data);
 
81
void update_process_clients(crm_client_t *client);
 
82
void update_process_peers(void);
95
83
 
96
84
void
97
85
enable_crmd_as_root(gboolean enable)
117
105
get_process_list(void)
118
106
{
119
107
    int lpc = 0;
120
 
    uint32_t procs = crm_proc_plugin;
 
108
    uint32_t procs = 0;
 
109
 
 
110
    if(is_classic_ais_cluster()) {
 
111
        procs |= crm_proc_plugin;
 
112
    }
121
113
 
122
114
    for (lpc = 0; lpc < SIZEOF(pcmk_children); lpc++) {
123
115
        if (pcmk_children[lpc].pid != 0) {
154
146
        update_node_processes(local_nodeid, NULL, get_process_list());
155
147
 
156
148
    } else if (child->respawn) {
 
149
        gboolean fail_fast = crm_is_true(getenv("PCMK_fail_fast"));
 
150
 
157
151
        crm_notice("Respawning failed child process: %s", child->name);
 
152
 
 
153
#ifdef RB_HALT_SYSTEM
 
154
        if (fail_fast) {
 
155
            crm_err("Rebooting system", child->name);
 
156
            sync();
 
157
            reboot(RB_HALT_SYSTEM);
 
158
            crm_exit(DAEMON_RESPAWN_STOP);
 
159
        }
 
160
#endif
158
161
        start_child(child);
159
162
    }
160
163
}
161
164
 
162
165
static void
163
 
pcmk_child_exit(GPid pid, gint status, gpointer user_data)
 
166
pcmk_child_exit(mainloop_child_t * p, pid_t pid, int core, int signo, int exitcode)
164
167
{
165
 
    int exitcode = 0;
166
 
    pcmk_child_t *child = user_data;
167
 
 
168
 
    if (WIFSIGNALED(status)) {
169
 
        int signo = WTERMSIG(status);
170
 
        int core = WCOREDUMP(status);
171
 
 
 
168
    pcmk_child_t *child = mainloop_child_userdata(p);
 
169
    const char *name = mainloop_child_name(p);
 
170
 
 
171
    if (signo) {
172
172
        crm_notice("Child process %s terminated with signal %d (pid=%d, core=%d)",
173
 
                   child->name, signo, child->pid, core);
 
173
                   name, signo, pid, core);
174
174
 
175
 
    } else if (WIFEXITED(status)) {
176
 
        exitcode = WEXITSTATUS(status);
 
175
    } else {
177
176
        do_crm_log(exitcode == 0 ? LOG_INFO : LOG_ERR,
178
 
                   "Child process %s exited (pid=%d, rc=%d)", child->name, child->pid, exitcode);
 
177
                   "Child process %s (%d) exited: %s (%d)", name, pid, pcmk_strerror(exitcode), exitcode);
179
178
    }
180
179
 
181
180
    if (exitcode == 100) {
182
181
        crm_warn("Pacemaker child process %s no longer wishes to be respawned. "
183
 
                 "Shutting ourselves down.", child->name);
 
182
                 "Shutting ourselves down.", name);
184
183
        child->respawn = FALSE;
185
184
        fatal_error = TRUE;
186
185
        pcmk_shutdown(15);
226
225
{
227
226
    int lpc = 0;
228
227
    uid_t uid = 0;
 
228
    gid_t gid = 0;
229
229
    struct rlimit oflimits;
230
230
    gboolean use_valgrind = FALSE;
231
231
    gboolean use_callgrind = FALSE;
232
232
    const char *devnull = "/dev/null";
233
233
    const char *env_valgrind = getenv("PCMK_valgrind_enabled");
234
234
    const char *env_callgrind = getenv("PCMK_callgrind_enabled");
 
235
    enum cluster_type_e stack = get_cluster_type();
235
236
 
236
237
    child->active_before_startup = FALSE;
237
238
 
261
262
        use_valgrind = FALSE;
262
263
    }
263
264
 
 
265
    if (child->uid) {
 
266
        if (crm_user_lookup(child->uid, &uid, &gid) < 0) {
 
267
            crm_err("Invalid user (%s) for %s: not found", child->uid, child->name);
 
268
            return FALSE;
 
269
        }
 
270
        crm_info("Using uid=%u and group=%u for process %s", uid, gid, child->name);
 
271
    }
 
272
 
264
273
    child->pid = fork();
265
274
    CRM_ASSERT(child->pid != -1);
266
275
 
267
276
    if (child->pid > 0) {
268
277
        /* parent */
269
 
        g_child_watch_add(child->pid, pcmk_child_exit, child);
 
278
        mainloop_child_add(child->pid, 0, child->name, child, pcmk_child_exit);
270
279
 
271
280
        crm_info("Forked child %d for process %s%s", child->pid, child->name,
272
281
                 use_valgrind ? " (valgrind enabled: " VALGRIND_BIN ")" : "");
292
301
        }
293
302
        opts_default[0] = strdup(child->command);;
294
303
 
295
 
#if 0
296
 
        /* Dont set the group for now - it prevents connection to the cluster */
297
 
        if (gid && setgid(gid) < 0) {
298
 
            crm_perror("Could not set group to %d", gid);
299
 
        }
300
 
#endif
 
304
        if(gid) {
 
305
            if(stack == pcmk_cluster_corosync) {
 
306
                /* Drop root privileges completely
 
307
                 *
 
308
                 * We can do this because we set uidgid.gid.${gid}=1
 
309
                 * via CMAP which allows these processes to connect to
 
310
                 * corosync
 
311
                 */
 
312
                if (setgid(gid) < 0) {
 
313
                    crm_perror(LOG_ERR, "Could not set group to %d", gid);
 
314
                }
301
315
 
302
 
        if (child->uid) {
303
 
            if (crm_user_lookup(child->uid, &uid, NULL) < 0) {
304
 
                crm_err("Invalid uid (%s) specified for %s", child->uid, child->name);
305
 
                return TRUE;
 
316
                /* Keep the root group (so we can access corosync), but add the haclient group (so we can access ipc) */
 
317
            } else if (initgroups(child->uid, gid) < 0) {
 
318
                crm_err("Cannot initalize groups for %s: %s (%d)", child->uid, pcmk_strerror(errno), errno);
306
319
            }
307
320
        }
308
321
 
326
339
            (void)execvp(child->command, opts_default);
327
340
        }
328
341
        crm_perror(LOG_ERR, "FATAL: Cannot exec %s", child->command);
329
 
        crm_exit(100);
 
342
        crm_exit(DAEMON_RESPAWN_STOP);
330
343
    }
331
344
    return TRUE;                /* never reached */
332
345
}
403
416
 
404
417
    if (fatal_error) {
405
418
        crm_notice("Attempting to inhibit respawning after fatal error");
406
 
        crm_exit(100);
 
419
        crm_exit(DAEMON_RESPAWN_STOP);
407
420
    }
408
421
 
409
422
    return TRUE;
418
431
    mainloop_set_trigger(shutdown_trigger);
419
432
}
420
433
 
421
 
static void
422
 
build_path(const char *path_c, mode_t mode)
423
 
{
424
 
    int offset = 1, len = 0;
425
 
    char *path = strdup(path_c);
426
 
 
427
 
    CRM_CHECK(path != NULL, return);
428
 
    for (len = strlen(path); offset < len; offset++) {
429
 
        if (path[offset] == '/') {
430
 
            path[offset] = 0;
431
 
            if (mkdir(path, mode) < 0 && errno != EEXIST) {
432
 
                crm_perror(LOG_ERR, "Could not create directory '%s'", path);
433
 
                break;
434
 
            }
435
 
            path[offset] = '/';
436
 
        }
437
 
    }
438
 
    if (mkdir(path, mode) < 0 && errno != EEXIST) {
439
 
        crm_perror(LOG_ERR, "Could not create directory '%s'", path);
440
 
    }
441
 
    free(path);
442
 
}
443
 
 
444
434
static int32_t
445
435
pcmk_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
446
436
{
482
472
                   crm_element_value(msg, F_CRM_REFERENCE), crm_element_value(msg, F_CRM_ORIGIN));
483
473
        pcmk_shutdown(15);
484
474
 
 
475
    } else if (crm_str_eq(task, CRM_OP_RM_NODE_CACHE, TRUE)) {
 
476
        /* Send to everyone */
 
477
        struct iovec *iov;
 
478
        int id = 0;
 
479
        const char *name = NULL;
 
480
 
 
481
        crm_element_value_int(msg, XML_ATTR_ID, &id);
 
482
        name = crm_element_value(msg, XML_ATTR_UNAME);
 
483
        crm_notice("Instructing peers to remove references to node %s/%u", name, id);
 
484
 
 
485
        iov = calloc(1, sizeof(struct iovec));
 
486
        iov->iov_base = dump_xml_unformatted(msg);
 
487
        iov->iov_len = 1 + strlen(iov->iov_base);
 
488
        send_cpg_iov(iov);
 
489
 
485
490
    } else {
486
 
        /* Just send to everyone */
487
 
        update_process_clients();
 
491
        update_process_clients(c);
488
492
    }
489
493
 
490
494
    free_xml(msg);
508
512
    crm_trace("Connection %p", c);
509
513
}
510
514
 
511
 
struct qb_ipcs_service_handlers ipc_callbacks = {
 
515
struct qb_ipcs_service_handlers mcp_ipc_callbacks = {
512
516
    .connection_accept = pcmk_ipc_accept,
513
517
    .connection_created = pcmk_ipc_created,
514
518
    .msg_process = pcmk_ipc_dispatch,
516
520
    .connection_destroyed = pcmk_ipc_destroy
517
521
};
518
522
 
519
 
static void
520
 
ghash_send_proc_details(gpointer key, gpointer value, gpointer data)
521
 
{
522
 
    crm_ipcs_send(value, 0, data, TRUE);
523
 
}
524
 
 
525
 
static void
526
 
peer_loop_fn(gpointer key, gpointer value, gpointer user_data)
527
 
{
528
 
    pcmk_peer_t *node = value;
529
 
    xmlNode *update = user_data;
530
 
 
531
 
    xmlNode *xml = create_xml_node(update, "node");
532
 
 
533
 
    crm_xml_add_int(xml, "id", node->id);
534
 
    crm_xml_add(xml, "uname", node->uname);
535
 
    crm_xml_add_int(xml, "processes", node->processes);
536
 
}
537
 
 
538
523
void
539
 
update_process_clients(void)
 
524
update_process_clients(crm_client_t *client)
540
525
{
 
526
    GHashTableIter iter;
 
527
    crm_node_t *node = NULL;
541
528
    xmlNode *update = create_xml_node(NULL, "nodes");
542
529
 
543
530
    crm_trace("Sending process list to %d children", crm_hash_table_size(client_connections));
544
531
 
545
 
    g_hash_table_foreach(peers, peer_loop_fn, update);
546
 
    g_hash_table_foreach(client_connections, ghash_send_proc_details, update);
 
532
    g_hash_table_iter_init(&iter, crm_peer_cache);
 
533
    while (g_hash_table_iter_next(&iter, NULL, (gpointer *) & node)) {
 
534
        xmlNode *xml = create_xml_node(update, "node");
 
535
 
 
536
        crm_xml_add_int(xml, "id", node->id);
 
537
        crm_xml_add(xml, "uname", node->uname);
 
538
        crm_xml_add(xml, "state", node->state);
 
539
        crm_xml_add_int(xml, "processes", node->processes);
 
540
    }
 
541
 
 
542
    if(client) {
 
543
        crm_ipcs_send(client, 0, update, TRUE);
 
544
 
 
545
    } else {
 
546
        g_hash_table_iter_init(&iter, client_connections);
 
547
        while (g_hash_table_iter_next(&iter, NULL, (gpointer *) & client)) {
 
548
            crm_ipcs_send(client, 0, update, TRUE);
 
549
        }
 
550
    }
547
551
 
548
552
    free_xml(update);
549
553
}
551
555
void
552
556
update_process_peers(void)
553
557
{
 
558
    /* Do nothing for corosync-2 based clusters */
 
559
 
554
560
    char buffer[1024];
555
 
    struct iovec iov;
 
561
    struct iovec *iov;
556
562
    int rc = 0;
557
563
 
558
564
    memset(buffer, 0, SIZEOF(buffer));
564
570
        rc = snprintf(buffer, SIZEOF(buffer) - 1, "<node proclist=\"%u\"/>", get_process_list());
565
571
    }
566
572
 
567
 
    iov.iov_base = buffer;
568
 
    iov.iov_len = rc + 1;
569
 
 
570
573
    crm_trace("Sending %s", buffer);
571
 
    send_cpg_message(&iov);
 
574
    iov = calloc(1, sizeof(struct iovec));
 
575
    iov->iov_base = strdup(buffer);
 
576
    iov->iov_len = rc + 1;
 
577
    send_cpg_iov(iov);
572
578
}
573
579
 
574
580
gboolean
575
581
update_node_processes(uint32_t id, const char *uname, uint32_t procs)
576
582
{
577
583
    gboolean changed = FALSE;
578
 
    pcmk_peer_t *node = g_hash_table_lookup(peers, GUINT_TO_POINTER(id));
579
 
 
580
 
    if (node == NULL) {
581
 
        changed = TRUE;
582
 
 
583
 
        node = calloc(1, sizeof(pcmk_peer_t));
584
 
        node->id = id;
585
 
 
586
 
        g_hash_table_insert(peers, GUINT_TO_POINTER(id), node);
587
 
        node = g_hash_table_lookup(peers, GUINT_TO_POINTER(id));
588
 
        CRM_ASSERT(node != NULL);
589
 
    }
590
 
 
591
 
    if (uname != NULL) {
592
 
        if (node->uname == NULL || safe_str_eq(node->uname, uname) == FALSE) {
593
 
            int lpc, len = strlen(uname);
594
 
 
595
 
            crm_notice("%p Node %u now known as %s%s%s", node, id, uname,
596
 
                       node->uname ? node->uname : ", was: ", node->uname ? node->uname : "");
597
 
            free(node->uname);
598
 
            node->uname = strdup(uname);
599
 
            changed = TRUE;
600
 
 
601
 
            for (lpc = 0; lpc < len; lpc++) {
602
 
                if (uname[lpc] >= 'A' && uname[lpc] <= 'Z') {
603
 
                    crm_warn
604
 
                        ("Node names with capitals are discouraged, consider changing '%s' to something else",
605
 
                         uname);
606
 
                    break;
607
 
                }
608
 
            }
609
 
        }
610
 
 
611
 
    } else {
612
 
        crm_trace("Empty uname for node %u", id);
613
 
    }
 
584
    crm_node_t *node = crm_get_peer(id, uname);
614
585
 
615
586
    if (procs != 0) {
616
587
        if (procs != node->processes) {
625
596
    }
626
597
 
627
598
    if (changed && id == local_nodeid) {
628
 
        update_process_clients();
 
599
        update_process_clients(NULL);
629
600
        update_process_peers();
630
601
    }
631
602
    return changed;
632
603
}
633
604
 
 
605
 
634
606
/* *INDENT-OFF* */
635
607
static struct crm_option long_options[] = {
636
608
    /* Top-level Options */
641
613
    {"features",       0, 0, 'F', "\tDisplay the full version and list of features Pacemaker was built with"},
642
614
 
643
615
    {"-spacer-",       1, 0, '-', "\nAdditional Options:"},
644
 
    {"foreground",     0, 0, 'f', "\tRun in the foreground instead of as a daemon"},
645
 
    {"pid-file",       1, 0, 'p', "\t(Advanced) Daemon pid file location"},
 
616
    {"foreground",     0, 0, 'f', "\t(Ignored) Pacemaker always runs in the foreground"},
 
617
    {"pid-file",       1, 0, 'p', "\t(Ignored) Daemon pid file location"},
646
618
 
647
619
    {NULL, 0, 0, 0}
648
620
};
791
763
    }
792
764
}
793
765
 
 
766
static void
 
767
mcp_cpg_destroy(gpointer user_data)
 
768
{
 
769
    crm_err("Connection destroyed");
 
770
    crm_exit(ENOTCONN);
 
771
}
 
772
 
 
773
static void
 
774
mcp_cpg_deliver(cpg_handle_t handle,
 
775
                 const struct cpg_name *groupName,
 
776
                 uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len)
 
777
{
 
778
    xmlNode *xml = string2xml(msg);
 
779
    const char *task = crm_element_value(xml, F_CRM_TASK);
 
780
 
 
781
    crm_trace("Recieved %s %.200s", task, msg);
 
782
    if (task == NULL && nodeid != local_nodeid) {
 
783
        uint32_t procs = 0;
 
784
        const char *uname = crm_element_value(xml, "uname");
 
785
 
 
786
        crm_element_value_int(xml, "proclist", (int *)&procs);
 
787
        /* crm_debug("Got proclist %.32x from %s", procs, uname); */
 
788
        if (update_node_processes(nodeid, uname, procs)) {
 
789
            update_process_clients(NULL);
 
790
        }
 
791
 
 
792
    } else if (crm_str_eq(task, CRM_OP_RM_NODE_CACHE, TRUE)) {
 
793
        int id = 0;
 
794
        const char *name = NULL;
 
795
 
 
796
        crm_element_value_int(xml, XML_ATTR_ID, &id);
 
797
        name = crm_element_value(xml, XML_ATTR_UNAME);
 
798
        reap_crm_member(id, name);
 
799
    }
 
800
}
 
801
 
 
802
static void
 
803
mcp_cpg_membership(cpg_handle_t handle,
 
804
                    const struct cpg_name *groupName,
 
805
                    const struct cpg_address *member_list, size_t member_list_entries,
 
806
                    const struct cpg_address *left_list, size_t left_list_entries,
 
807
                    const struct cpg_address *joined_list, size_t joined_list_entries)
 
808
{
 
809
    /* Don't care about CPG membership, but we do want to broadcast our own presence */
 
810
    update_process_peers();
 
811
}
 
812
 
 
813
static gboolean
 
814
mcp_quorum_callback(unsigned long long seq, gboolean quorate)
 
815
{
 
816
    /* Nothing to do */
 
817
    return TRUE;
 
818
}
 
819
 
 
820
static void
 
821
mcp_quorum_destroy(gpointer user_data)
 
822
{
 
823
    crm_info("connection closed");
 
824
}
 
825
 
794
826
int
795
827
main(int argc, char **argv)
796
828
{
807
839
    crm_ipc_t *old_instance = NULL;
808
840
    qb_ipcs_service_t *ipcs = NULL;
809
841
    const char *facility = daemon_option("logfacility");
 
842
    static crm_cluster_t cluster;
810
843
 
811
844
    setenv("LC_ALL", "C", 1);
812
845
    setenv("HA_LOGD", "no", 1);
817
850
    crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
818
851
    crm_set_options(NULL, "mode [options]", long_options, "Start/Stop Pacemaker\n");
819
852
 
820
 
    /* Restore the original facility so that read_config() does the right thing */
 
853
    /* Restore the original facility so that mcp_read_config() does the right thing */
821
854
    set_daemon_option("logfacility", facility);
822
855
 
823
856
    while (1) {
843
876
                shutdown = TRUE;
844
877
                break;
845
878
            case 'F':
846
 
                printf("Pacemaker %s (Build: %s)\n Supporting: %s\n", VERSION, BUILD_VERSION,
847
 
                       CRM_FEATURES);
848
 
                crm_exit(0);
 
879
                printf("Pacemaker %s (Build: %s)\n Supporting v%s: %s\n", VERSION, BUILD_VERSION,
 
880
                       CRM_FEATURE_SET, CRM_FEATURES);
 
881
                crm_exit(pcmk_ok);
849
882
            default:
850
883
                printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag);
851
884
                ++argerr;
881
914
        }
882
915
        crm_ipc_close(old_instance);
883
916
        crm_ipc_destroy(old_instance);
884
 
        crm_exit(0);
 
917
        crm_exit(pcmk_ok);
885
918
 
886
919
    } else if (crm_ipc_connected(old_instance)) {
887
920
        crm_ipc_close(old_instance);
888
921
        crm_ipc_destroy(old_instance);
889
922
        crm_err("Pacemaker is already active, aborting startup");
890
 
        crm_exit(100);
 
923
        crm_exit(DAEMON_RESPAWN_STOP);
891
924
    }
892
925
 
893
926
    crm_ipc_close(old_instance);
894
927
    crm_ipc_destroy(old_instance);
895
928
 
896
 
    if (read_config() == FALSE) {
 
929
    if (mcp_read_config() == FALSE) {
897
930
        crm_notice("Could not obtain corosync config data, exiting");
898
 
        crm_exit(1);
 
931
        crm_exit(ENODATA);
899
932
    }
900
933
 
901
934
    crm_notice("Starting Pacemaker %s (Build: %s): %s", VERSION, BUILD_VERSION, CRM_FEATURES);
931
964
 
932
965
    if (crm_user_lookup(CRM_DAEMON_USER, &pcmk_uid, &pcmk_gid) < 0) {
933
966
        crm_err("Cluster user %s does not exist, aborting Pacemaker startup", CRM_DAEMON_USER);
934
 
        crm_exit(1);
 
967
        crm_exit(ENOKEY);
935
968
    }
936
969
 
937
970
    mkdir(CRM_STATE_DIR, 0750);
938
971
    mcp_chown(CRM_STATE_DIR, pcmk_uid, pcmk_gid);
939
972
 
940
 
    /* Used by stonithd */
941
 
    build_path(HA_STATE_DIR "/heartbeat", 0755);
942
 
    mcp_chown(HA_STATE_DIR "/heartbeat", pcmk_uid, pcmk_gid);
943
 
 
944
 
    /* Used by RAs - Leave owned by root */
945
 
    build_path(CRM_RSCTMP_DIR, 0755);
946
 
 
947
973
    /* Used to store core files in */
948
 
    build_path(CRM_CORE_DIR, 0755);
 
974
    crm_build_path(CRM_CORE_DIR, 0775);
949
975
    mcp_chown(CRM_CORE_DIR, pcmk_uid, pcmk_gid);
950
976
 
951
977
    /* Used to store blackbox dumps in */
952
 
    build_path(CRM_BLACKBOX_DIR, 0755);
 
978
    crm_build_path(CRM_BLACKBOX_DIR, 0755);
953
979
    mcp_chown(CRM_BLACKBOX_DIR, pcmk_uid, pcmk_gid);
954
980
 
955
981
    /* Used to store policy engine inputs in */
956
 
    build_path(PE_STATE_DIR, 0755);
 
982
    crm_build_path(PE_STATE_DIR, 0755);
957
983
    mcp_chown(PE_STATE_DIR, pcmk_uid, pcmk_gid);
958
984
 
959
985
    /* Used to store the cluster configuration */
960
 
    build_path(CRM_CONFIG_DIR, 0755);
 
986
    crm_build_path(CRM_CONFIG_DIR, 0755);
961
987
    mcp_chown(CRM_CONFIG_DIR, pcmk_uid, pcmk_gid);
962
988
 
963
 
    peers = g_hash_table_new(g_direct_hash, g_direct_equal);
 
989
    /* Resource agent paths are constructed by the lrmd */
964
990
 
965
 
    ipcs = mainloop_add_ipc_server(CRM_SYSTEM_MCP, QB_IPC_NATIVE, &ipc_callbacks);
 
991
    ipcs = mainloop_add_ipc_server(CRM_SYSTEM_MCP, QB_IPC_NATIVE, &mcp_ipc_callbacks);
966
992
    if (ipcs == NULL) {
967
993
        crm_err("Couldn't start IPC server");
968
 
        crm_exit(1);
 
994
        crm_exit(EIO);
969
995
    }
970
996
 
 
997
    /* Allows us to block shutdown */
971
998
    if (cluster_connect_cfg(&local_nodeid) == FALSE) {
972
999
        crm_err("Couldn't connect to Corosync's CFG service");
973
 
        crm_exit(1);
 
1000
        crm_exit(ENOPROTOOPT);
974
1001
    }
975
1002
 
976
 
    if (cluster_connect_cpg() == FALSE) {
 
1003
    cluster.destroy = mcp_cpg_destroy;
 
1004
    cluster.cpg.cpg_deliver_fn = mcp_cpg_deliver;
 
1005
    cluster.cpg.cpg_confchg_fn = mcp_cpg_membership;
 
1006
 
 
1007
    if(cluster_connect_cpg(&cluster) == FALSE) {
977
1008
        crm_err("Couldn't connect to Corosync's CPG service");
978
 
        crm_exit(1);
 
1009
        crm_exit(ENOPROTOOPT);
 
1010
    }
 
1011
 
 
1012
    if (is_corosync_cluster()) {
 
1013
        /* Keep the membership list up-to-date for crm_node to query */
 
1014
        rc = cluster_connect_quorum(mcp_quorum_callback, mcp_quorum_destroy);
979
1015
    }
980
1016
 
981
1017
    local_name = get_local_node_name();
999
1035
 
1000
1036
    g_main_destroy(mainloop);
1001
1037
 
1002
 
    cluster_disconnect_cpg();
 
1038
    cluster_disconnect_cpg(&cluster);
1003
1039
    cluster_disconnect_cfg();
1004
1040
 
1005
1041
    crm_info("Exiting %s", crm_system_name);
1006
1042
 
1007
 
    crm_exit(0);
 
1043
    crm_exit(pcmk_ok);
1008
1044
}