Esempio n. 1
0
int
stonith__list_lha_agents(stonith_key_value_t **devices)
{
    static gboolean need_init = TRUE;

    int count = 0;
    char **entry = NULL;
    char **type_list = NULL;
    static char **(*type_list_fn) (void) = NULL;
    static void (*type_free_fn) (char **) = NULL;

    if (need_init) {
        need_init = FALSE;
        type_list_fn =
            find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY, "stonith_types", FALSE);
        type_free_fn =
            find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY, "stonith_free_hostlist",
                                  FALSE);
    }

    if (type_list_fn) {
        type_list = (*type_list_fn) ();
    }

    for (entry = type_list; entry != NULL && *entry; ++entry) {
        crm_trace("Added: %s", *entry);
        *devices = stonith_key_value_add(*devices, NULL, *entry);
        count++;
    }
    if (type_list && type_free_fn) {
        (*type_free_fn) (type_list);
    }
    return count;
}
Esempio n. 2
0
/*!
 * \brief Determine namespace of a fence agent
 *
 * \param[in] agent        Fence agent type
 * \param[in] namespace_s  Name of agent namespace as string, if known
 *
 * \return Namespace of specified agent, as enum value
 */
bool
stonith__agent_is_lha(const char *agent)
{
    Stonith *stonith_obj = NULL;

    static gboolean need_init = TRUE;
    static Stonith *(*st_new_fn) (const char *) = NULL;
    static void (*st_del_fn) (Stonith *) = NULL;

    if (need_init) {
        need_init = FALSE;
        st_new_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
                                          "stonith_new", FALSE);
        st_del_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
                                          "stonith_delete", FALSE);
    }

    if (lha_agents_lib && st_new_fn && st_del_fn) {
        stonith_obj = (*st_new_fn) (agent);
        if (stonith_obj) {
            (*st_del_fn) (stonith_obj);
            return TRUE;
        }
    }
    return FALSE;
}
Esempio n. 3
0
gboolean
crm_cluster_connect(crm_cluster_t * cluster)
{
    enum cluster_type_e type = get_cluster_type();

    crm_notice("Connecting to cluster infrastructure: %s", name_for_cluster_type(type));
#if SUPPORT_COROSYNC
    if (is_openais_cluster()) {
        crm_peer_init();
        return init_cs_connection(cluster);
    }
#endif

#if SUPPORT_HEARTBEAT
    if (is_heartbeat_cluster()) {
        int rv;

        /* coverity[var_deref_op] False positive */
        if (cluster->hb_conn == NULL) {
            /* No object passed in, create a new one. */
            ll_cluster_t *(*new_cluster) (const char *llctype) =
                find_library_function(&hb_library, HEARTBEAT_LIBRARY, "ll_cluster_new", 1);

            cluster->hb_conn = (*new_cluster) ("heartbeat");
            /* dlclose(handle); */

        } else {
            /* Object passed in. Disconnect first, then reconnect below. */
            cluster->hb_conn->llc_ops->signoff(cluster->hb_conn, FALSE);
        }

        /* make sure we are disconnected first with the old object, if any. */
        if (heartbeat_cluster && heartbeat_cluster != cluster->hb_conn) {
            heartbeat_cluster->llc_ops->signoff(heartbeat_cluster, FALSE);
        }

        CRM_ASSERT(cluster->hb_conn != NULL);
        heartbeat_cluster = cluster->hb_conn;

        rv = register_heartbeat_conn(cluster);
        if (rv) {
            /* we'll benefit from a bigger queue length on heartbeat side.
             * Otherwise, if peers send messages faster than we can consume
             * them right now, heartbeat messaging layer will kick us out once
             * it's (small) default queue fills up :(
             * If we fail to adjust the sendq length, that's not yet fatal, though.
             */
            if (HA_OK != heartbeat_cluster->llc_ops->set_sendq_len(heartbeat_cluster, 1024)) {
                crm_warn("Cannot set sendq length: %s",
                         heartbeat_cluster->llc_ops->errmsg(heartbeat_cluster));
            }
        }
        return rv;
    }
#endif
    crm_info("Unsupported cluster stack: %s", getenv("HA_cluster_type"));
    return FALSE;
}
Esempio n. 4
0
int
stonith__lha_metadata(const char *agent, int timeout, char **output)
{
    int rc = 0;
    char *buffer = NULL;
    static const char *no_parameter_info = "<!-- no value -->";

    Stonith *stonith_obj = NULL;

    static gboolean need_init = TRUE;
    static Stonith *(*st_new_fn) (const char *) = NULL;
    static const char *(*st_info_fn) (Stonith *, int) = NULL;
    static void (*st_del_fn) (Stonith *) = NULL;
    static void (*st_log_fn) (Stonith *, PILLogFun) = NULL;

    if (need_init) {
        need_init = FALSE;
        st_new_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
                                          "stonith_new", FALSE);
        st_del_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
                                          "stonith_delete", FALSE);
        st_log_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
                                          "stonith_set_log", FALSE);
        st_info_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
                                           "stonith_get_info", FALSE);
    }

    if (lha_agents_lib && st_new_fn && st_del_fn && st_info_fn && st_log_fn) {
        char *xml_meta_longdesc = NULL;
        char *xml_meta_shortdesc = NULL;

        char *meta_param = NULL;
        char *meta_longdesc = NULL;
        char *meta_shortdesc = NULL;

        stonith_obj = (*st_new_fn) (agent);
        if (stonith_obj) {
            (*st_log_fn) (stonith_obj, (PILLogFun) & stonith_plugin);
            meta_longdesc = strdup_null((*st_info_fn) (stonith_obj, ST_DEVICEDESCR));
            if (meta_longdesc == NULL) {
                crm_warn("no long description in %s's metadata.", agent);
                meta_longdesc = strdup(no_parameter_info);
            }

            meta_shortdesc = strdup_null((*st_info_fn) (stonith_obj, ST_DEVICEID));
            if (meta_shortdesc == NULL) {
                crm_warn("no short description in %s's metadata.", agent);
                meta_shortdesc = strdup(no_parameter_info);
            }

            meta_param = strdup_null((*st_info_fn) (stonith_obj, ST_CONF_XML));
            if (meta_param == NULL) {
                crm_warn("no list of parameters in %s's metadata.", agent);
                meta_param = strdup(no_parameter_info);
            }
            (*st_del_fn) (stonith_obj);
        } else {
            errno = EINVAL;
            crm_perror(LOG_ERR, "Agent %s not found", agent);
            return -EINVAL;
        }

        xml_meta_longdesc =
            (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_longdesc);
        xml_meta_shortdesc =
            (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_shortdesc);

        buffer = crm_strdup_printf(META_TEMPLATE, agent, xml_meta_longdesc,
                                   xml_meta_shortdesc, meta_param);

        xmlFree(xml_meta_longdesc);
        xmlFree(xml_meta_shortdesc);

        free(meta_shortdesc);
        free(meta_longdesc);
        free(meta_param);
    }
    if (output) {
        *output = buffer;
    } else {
        free(buffer);
    }
    return rc;
}
Esempio n. 5
0
enum cluster_type_e
get_cluster_type(void)
{
    bool detected = FALSE;
    const char *cluster = NULL;

    /* Return the previous calculation, if any */
    if (cluster_type != pcmk_cluster_unknown) {
        return cluster_type;
    }

    cluster = getenv("HA_cluster_type");

#if SUPPORT_HEARTBEAT
    /* If nothing is defined in the environment, try heartbeat (if supported) */
    if(cluster == NULL) {
        ll_cluster_t *hb;
        ll_cluster_t *(*new_cluster) (const char *llctype) = find_library_function(
            &hb_library, HEARTBEAT_LIBRARY, "ll_cluster_new", 1);

        hb = (*new_cluster) ("heartbeat");

        crm_debug("Testing with Heartbeat");
        /*
         * Test as "casual" client (clientid == NULL; will be replaced by
         * current pid).  We are trying to detect if we can communicate with
         * heartbeat, not if we can register as some specific service.
         * Otherwise all but one of several concurrent invocations will get
         * HA_FAIL because of:
         * WARN: duplicate client add request
         * ERROR: api_process_registration_msg: cannot add client()
         * and then likely fail :(
         */
        if (hb->llc_ops->signon(hb, NULL) == HA_OK) {
            hb->llc_ops->signoff(hb, FALSE);

            cluster_type = pcmk_cluster_heartbeat;
            detected = TRUE;
            goto done;
        }
    }
#endif

#if SUPPORT_COROSYNC
    /* If nothing is defined in the environment, try corosync (if supported) */
    if(cluster == NULL) {
        crm_debug("Testing with Corosync");
        cluster_type = find_corosync_variant();
        if (cluster_type != pcmk_cluster_unknown) {
            detected = TRUE;
            goto done;
        }
    }
#endif

    /* Something was defined in the environment, test it against what we support */
    crm_info("Verifying cluster type: '%s'", cluster?cluster:"-unspecified-");
    if (cluster == NULL) {

#if SUPPORT_HEARTBEAT
    } else if (safe_str_eq(cluster, "heartbeat")) {
        cluster_type = pcmk_cluster_heartbeat;
#endif

#if SUPPORT_COROSYNC
    } else if (safe_str_eq(cluster, "openais")
               || safe_str_eq(cluster, "classic openais (with plugin)")) {
        cluster_type = pcmk_cluster_classic_ais;

    } else if (safe_str_eq(cluster, "corosync")) {
        cluster_type = pcmk_cluster_corosync;
#endif

#if SUPPORT_CMAN
    } else if (safe_str_eq(cluster, "cman")) {
        cluster_type = pcmk_cluster_cman;
#endif

    } else {
        cluster_type = pcmk_cluster_invalid;
        goto done; /* Keep the compiler happy when no stacks are supported */
    }

  done:
    if (cluster_type == pcmk_cluster_unknown) {
        crm_notice("Could not determine the current cluster type");

    } else if (cluster_type == pcmk_cluster_invalid) {
        crm_notice("This installation does not support the '%s' cluster infrastructure: terminating.",
                   cluster);
        crm_exit(DAEMON_RESPAWN_STOP);

    } else {
        crm_info("%s an active '%s' cluster", detected?"Detected":"Assuming", name_for_cluster_type(cluster_type));
    }

    return cluster_type;
}