コード例 #1
0
ファイル: sbd-cluster.c プロジェクト: ClusterLabs/sbd
void
sbd_cpg_membership_health_update()
{
    if(cpg_membership_entries > 0) {
        bool quorum_is_suspect =
            (two_node && ever_seen_both && cpg_membership_entries == 1);

        if (!quorum_is_suspect) {
            set_servant_health(pcmk_health_online, LOG_INFO,
                           "Connected to %s (%u members)",
                           name_for_cluster_type(get_cluster_type()),
                           cpg_membership_entries
                          );
        } else {
            /* Alternative would be asking votequorum for number of votes.
             * Using pacemaker's cpg as source for number of active nodes
             * avoids binding to an additional library, is definitely
             * less code to write and we wouldn't have to combine data
             * from 3 sources (cmap, cpq & votequorum) in a potentially
             * racy environment.
             */
            set_servant_health(pcmk_health_noquorum, LOG_WARNING,
                           "Connected to %s but requires both nodes present",
                           name_for_cluster_type(get_cluster_type())
                          );
        }

        if (cpg_membership_entries > 1) {
            ever_seen_both = true;
        }
    } else {
        set_servant_health(pcmk_health_unclean, LOG_WARNING,
                           "Empty %s membership", name_for_cluster_type(get_cluster_type()));
    }
}
コード例 #2
0
ファイル: sbd-cluster.c プロジェクト: krig/sbd
static void
sbd_plugin_membership_dispatch(cpg_handle_t handle,
                           const struct cpg_name *groupName,
                           uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len)
{
    if(msg_len > 0) {
        set_servant_health(pcmk_health_online, LOG_INFO,
                           "Connected to %s", name_for_cluster_type(get_cluster_type()));
    } else {
        set_servant_health(pcmk_health_unclean, LOG_WARNING,
                           "Broken %s message", name_for_cluster_type(get_cluster_type()));
    }
    notify_parent();
    return;
}
コード例 #3
0
ファイル: sbd-cluster.c プロジェクト: krig/sbd
void
sbd_cpg_membership_dispatch(cpg_handle_t handle,
                    const struct cpg_name *groupName,
                    const struct cpg_address *member_list, size_t member_list_entries,
                    const struct cpg_address *left_list, size_t left_list_entries,
                    const struct cpg_address *joined_list, size_t joined_list_entries)
{
    if(member_list_entries > 0) {
        set_servant_health(pcmk_health_online, LOG_INFO,
                           "Connected to %s", name_for_cluster_type(get_cluster_type()));
    } else {
        set_servant_health(pcmk_health_unclean, LOG_WARNING,
                           "Empty %s membership", name_for_cluster_type(get_cluster_type()));
    }
    notify_parent();
}
コード例 #4
0
ファイル: sbd-cluster.c プロジェクト: krig/sbd
static void
sbd_membership_destroy(gpointer user_data)
{
    cl_log(LOG_WARNING, "Lost connection to %s", name_for_cluster_type(get_cluster_type()));

    set_servant_health(pcmk_health_unclean, LOG_ERR, "Cluster connection terminated");
    notify_parent();

    /* Attempt to reconnect, the watchdog will take the node down if the problem isn't transient */
    sbd_membership_connect();
}
コード例 #5
0
ファイル: sbd-cluster.c プロジェクト: ClusterLabs/sbd
static void
sbd_membership_connect(void)
{
    bool connected = false;

    cl_log(LOG_INFO, "Attempting cluster connection");

    cluster.destroy = sbd_membership_destroy;

#if SUPPORT_PLUGIN
    cluster.cpg.cpg_deliver_fn = sbd_plugin_membership_dispatch;
#endif

#if SUPPORT_COROSYNC
    cluster.cpg.cpg_confchg_fn = sbd_cpg_membership_dispatch;
#endif

    while(connected == false) {

        enum cluster_type_e stack = get_cluster_type();
        if(get_cluster_type() == pcmk_cluster_unknown) {
            crm_debug("Attempting pacemaker remote connection");
            /* Nothing is up, go looking for the pacemaker remote process */
            if(find_pacemaker_remote() > 0) {
                connected = true;
            }

        } else {
            cl_log(LOG_INFO, "Attempting connection to %s", name_for_cluster_type(stack));

#if SUPPORT_COROSYNC && CHECK_TWO_NODE
            if (sbd_get_two_node()) {
#endif

                if(crm_cluster_connect(&cluster)) {
                    connected = true;
                }

#if SUPPORT_COROSYNC && CHECK_TWO_NODE
            }
#endif
        }

        if(connected == false) {
            cl_log(LOG_INFO, "Failed, retrying in %ds", reconnect_msec / 1000);
            sleep(reconnect_msec / 1000);
        }
    }

    set_servant_health(pcmk_health_transient, LOG_INFO, "Connected, waiting for initial membership");
    notify_parent();

    notify_timer_cb(NULL);
}
コード例 #6
0
ファイル: sbd-cluster.c プロジェクト: ClusterLabs/sbd
static void
sbd_membership_destroy(gpointer user_data)
{
    cl_log(LOG_WARNING, "Lost connection to %s", name_for_cluster_type(get_cluster_type()));

    if (get_cluster_type() != pcmk_cluster_unknown) {
#if SUPPORT_COROSYNC && CHECK_TWO_NODE
        cmap_destroy();
#endif
    }

    set_servant_health(pcmk_health_unclean, LOG_ERR, "Cluster connection terminated");
    notify_parent();

    /* Attempt to reconnect, the watchdog will take the node down if the problem isn't transient */
    sbd_membership_connect();
}
コード例 #7
0
ファイル: sbd-cluster.c プロジェクト: krig/sbd
static gboolean
sbd_remote_check(gpointer user_data)
{
    static int have_proc_pid = 0;

    int running = 0;

    cl_log(LOG_DEBUG, "Checking pacemaker remote connection: %d/%d", have_proc_pid, remoted_pid);
    
    if(have_proc_pid == 0) {
        char proc_path[PATH_MAX], exe_path[PATH_MAX];

        /* check to make sure pid hasn't been reused by another process */
        snprintf(proc_path, sizeof(proc_path), "/proc/%lu/exe", (long unsigned int)getpid());

        have_proc_pid = 1;
        if(readlink(proc_path, exe_path, PATH_MAX - 1) < 0) {
            have_proc_pid = -1;
        }
    }
    
    if (remoted_pid <= 0) {
        set_servant_health(pcmk_health_transient, LOG_WARNING, "No Pacemaker Remote connection");
        goto notify;

    } else if (kill(remoted_pid, 0) < 0 && errno == ESRCH) {
        /* Not running */

    } else if(have_proc_pid == -1) {
        running = 1;
        cl_log(LOG_DEBUG, "Poccess %ld is active", (long)remoted_pid);

    } else {
        int rc = 0;
        char proc_path[PATH_MAX], exe_path[PATH_MAX], expected_path[PATH_MAX];

        /* check to make sure pid hasn't been reused by another process */
        snprintf(proc_path, sizeof(proc_path), "/proc/%lu/exe", (long unsigned int)remoted_pid);

        rc = readlink(proc_path, exe_path, PATH_MAX - 1);
        if (rc < 0) {
            crm_perror(LOG_ERR, "Could not read from %s", proc_path);
            goto done;
        }
        exe_path[rc] = 0;

        rc = snprintf(expected_path, sizeof(proc_path), "%s/pacemaker_remoted", SBINDIR);
        expected_path[rc] = 0;

        if (strcmp(exe_path, expected_path) == 0) {
            cl_log(LOG_DEBUG, "Process %s (%ld) is active",
                   exe_path, (long)remoted_pid);
            running = 1;
        }
    }

  done:
    
    if(running) {
        set_servant_health(pcmk_health_online, LOG_INFO,
                           "Connected to Pacemaker Remote %lu", (long unsigned int)remoted_pid);
    } else {
        set_servant_health(pcmk_health_unclean, LOG_WARNING,
                           "Connection to Pacemaker Remote %lu lost", (long unsigned int)remoted_pid);
    }

  notify:    
    notify_parent();

    if(running == 0) {
        sbd_membership_connect();
    }
    return true;
}