コード例 #1
0
ファイル: based_remote.c プロジェクト: ClusterLabs/pacemaker
static void
cib_handle_remote_msg(crm_client_t * client, xmlNode * command)
{
    const char *value = NULL;

    value = crm_element_name(command);
    if (safe_str_neq(value, "cib_command")) {
        crm_log_xml_trace(command, "Bad command: ");
        return;
    }

    if (client->name == NULL) {
        value = crm_element_value(command, F_CLIENTNAME);
        if (value == NULL) {
            client->name = strdup(client->id);
        } else {
            client->name = strdup(value);
        }
    }

    if (client->userdata == NULL) {
        value = crm_element_value(command, F_CIB_CALLBACK_TOKEN);
        if (value != NULL) {
            client->userdata = strdup(value);
            crm_trace("Callback channel for %s is %s", client->id, (char*)client->userdata);

        } else {
            client->userdata = strdup(client->id);
        }
    }

    /* unset dangerous options */
    xml_remove_prop(command, F_ORIG);
    xml_remove_prop(command, F_CIB_HOST);
    xml_remove_prop(command, F_CIB_GLOBAL_UPDATE);

    crm_xml_add(command, F_TYPE, T_CIB);
    crm_xml_add(command, F_CIB_CLIENTID, client->id);
    crm_xml_add(command, F_CIB_CLIENTNAME, client->name);
#if ENABLE_ACL
    crm_xml_add(command, F_CIB_USER, client->user);
#endif

    if (crm_element_value(command, F_CIB_CALLID) == NULL) {
        char *call_uuid = crm_generate_uuid();

        /* fix the command */
        crm_xml_add(command, F_CIB_CALLID, call_uuid);
        free(call_uuid);
    }

    if (crm_element_value(command, F_CIB_CALLOPTS) == NULL) {
        crm_xml_add_int(command, F_CIB_CALLOPTS, 0);
    }

    crm_log_xml_trace(command, "Remote command: ");
    cib_common_callback_worker(0, 0, command, client, TRUE);
}
コード例 #2
0
gboolean
process_te_message(xmlNode * msg, xmlNode * xml_data)
{
    const char *from = crm_element_value(msg, F_ORIG);
    const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO);
    const char *sys_from = crm_element_value(msg, F_CRM_SYS_FROM);
    const char *ref = crm_element_value(msg, F_CRM_REFERENCE);
    const char *op = crm_element_value(msg, F_CRM_TASK);
    const char *type = crm_element_value(msg, F_CRM_MSG_TYPE);

    crm_trace("Processing %s (%s) message", op, ref);
    crm_log_xml_trace(msg, "ipc");

    if (op == NULL) {
        /* error */

    } else if (sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_TENGINE) != 0) {
        crm_trace("Bad sys-to %s", crm_str(sys_to));
        return FALSE;

    } else if (safe_str_eq(op, CRM_OP_INVOKE_LRM)
               && safe_str_eq(sys_from, CRM_SYSTEM_LRMD)
/* 		  && safe_str_eq(type, XML_ATTR_RESPONSE) */
        ) {
        xmlXPathObject *xpathObj = NULL;

        crm_log_xml_trace(msg, "Processing (N)ACK");
        crm_debug("Processing (N)ACK %s from %s", crm_element_value(msg, F_CRM_REFERENCE), from);

        xpathObj = xpath_search(xml_data, "//" XML_LRM_TAG_RSC_OP);
        if (numXpathResults(xpathObj)) {
            int lpc = 0, max = numXpathResults(xpathObj);

            for (lpc = 0; lpc < max; lpc++) {
                xmlNode *rsc_op = getXpathResult(xpathObj, lpc);
                const char *node = get_node_id(rsc_op);

                process_graph_event(rsc_op, node);
            }
            freeXpathObject(xpathObj);

        } else {
            crm_log_xml_err(msg, "Invalid (N)ACK");
            freeXpathObject(xpathObj);
            return FALSE;
        }

    } else {
        crm_err("Unknown command: %s::%s from %s", type, op, sys_from);
    }

    crm_trace("finished processing message");

    return TRUE;
}
コード例 #3
0
ファイル: callbacks.c プロジェクト: kiranmurari/pacemaker
static gboolean
send_peer_reply(xmlNode * msg, xmlNode * result_diff, const char *originator, gboolean broadcast)
{
    CRM_ASSERT(msg != NULL);

    if (broadcast) {
        /* this (successful) call modified the CIB _and_ the
         * change needs to be broadcast...
         *   send via HA to other nodes
         */
        int diff_add_updates = 0;
        int diff_add_epoch = 0;
        int diff_add_admin_epoch = 0;

        int diff_del_updates = 0;
        int diff_del_epoch = 0;
        int diff_del_admin_epoch = 0;

        char *digest = NULL;

        cib_diff_version_details(result_diff,
                                 &diff_add_admin_epoch, &diff_add_epoch, &diff_add_updates,
                                 &diff_del_admin_epoch, &diff_del_epoch, &diff_del_updates);

        crm_trace("Sending update diff %d.%d.%d -> %d.%d.%d",
                    diff_del_admin_epoch, diff_del_epoch, diff_del_updates,
                    diff_add_admin_epoch, diff_add_epoch, diff_add_updates);

        crm_xml_add(msg, F_CIB_ISREPLY, originator);
        crm_xml_add(msg, F_CIB_GLOBAL_UPDATE, XML_BOOLEAN_TRUE);
        crm_xml_add(msg, F_CIB_OPERATION, CIB_OP_APPLY_DIFF);

        /* Its safe to always use the latest version since the election
         * ensures the software on this node is the oldest node in the cluster
         */
        digest = calculate_xml_versioned_digest(the_cib, FALSE, TRUE, CRM_FEATURE_SET);
        crm_xml_add(result_diff, XML_ATTR_DIGEST, digest);
        crm_log_xml_trace(the_cib, digest);
        free(digest);

        add_message_xml(msg, F_CIB_UPDATE_DIFF, result_diff);
        crm_log_xml_trace(msg, "copy");
        return send_cluster_message(NULL, crm_msg_cib, msg, TRUE);

    } else if (originator != NULL) {
        /* send reply via HA to originating node */
        crm_trace("Sending request result to originator only");
        crm_xml_add(msg, F_CIB_ISREPLY, originator);
        return send_cluster_message(originator, crm_msg_cib, msg, FALSE);
    }

    return FALSE;
}
コード例 #4
0
ファイル: te_callbacks.c プロジェクト: JamesGuthrie/pacemaker
gboolean
process_te_message(xmlNode * msg, xmlNode * xml_data)
{
    const char *from = crm_element_value(msg, F_ORIG);
    const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO);
    const char *sys_from = crm_element_value(msg, F_CRM_SYS_FROM);
    const char *ref = crm_element_value(msg, F_CRM_REFERENCE);
    const char *op = crm_element_value(msg, F_CRM_TASK);
    const char *type = crm_element_value(msg, F_CRM_MSG_TYPE);

    crm_trace("Processing %s (%s) message", op, ref);
    crm_log_xml_trace(msg, "ipc");

    if (op == NULL) {
        /* error */

    } else if (sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_TENGINE) != 0) {
        crm_trace("Bad sys-to %s", crm_str(sys_to));
        return FALSE;

    } else if (safe_str_eq(op, CRM_OP_INVOKE_LRM)
               && safe_str_eq(sys_from, CRM_SYSTEM_LRMD)
/* 		  && safe_str_eq(type, XML_ATTR_RESPONSE) */
        ) {
        xmlXPathObject *xpathObj = NULL;

        crm_log_xml_trace(msg, "Processing (N)ACK");
        crm_debug("Processing (N)ACK %s from %s", crm_element_value(msg, F_CRM_REFERENCE), from);

        xpathObj = xpath_search(xml_data, "//" XML_LRM_TAG_RSC_OP);
        if (xpathObj) {
            process_resource_updates(xpathObj);
            xmlXPathFreeObject(xpathObj);
            xpathObj = NULL;

        } else {
            crm_log_xml_err(msg, "Invalid (N)ACK");
            return FALSE;
        }

    } else {
        crm_err("Unknown command: %s::%s from %s", type, op, sys_from);
    }

    crm_trace("finished processing message");

    return TRUE;
}
コード例 #5
0
ファイル: main.c プロジェクト: beess/pacemaker
static int32_t
attrd_ipc_dispatch(qb_ipcs_connection_t * c, void *data, size_t size)
{
    uint32_t id = 0;
    uint32_t flags = 0;
    crm_client_t *client = crm_client_get(c);
    xmlNode *xml = crm_ipcs_recv(client, data, size, &id, &flags);
    const char *op;

    if (xml == NULL) {
        crm_debug("No msg from %d (%p)", crm_ipcs_client_pid(c), c);
        return 0;
    }
#if ENABLE_ACL
    CRM_ASSERT(client->user != NULL);
    crm_acl_get_set_user(xml, F_ATTRD_USER, client->user);
#endif

    crm_trace("Processing msg from %d (%p)", crm_ipcs_client_pid(c), c);
    crm_log_xml_trace(xml, __FUNCTION__);

    op = crm_element_value(xml, F_ATTRD_TASK);

    if (client->name == NULL) {
        const char *value = crm_element_value(xml, F_ORIG);
        client->name = crm_strdup_printf("%s.%d", value?value:"unknown", client->pid);
    }

    if (safe_str_eq(op, ATTRD_OP_PEER_REMOVE)) {
        attrd_send_ack(client, id, flags);
        attrd_client_peer_remove(client->name, xml);

    } else if (safe_str_eq(op, ATTRD_OP_UPDATE)) {
        attrd_send_ack(client, id, flags);
        attrd_client_update(xml);

    } else if (safe_str_eq(op, ATTRD_OP_UPDATE_BOTH)) {
        attrd_send_ack(client, id, flags);
        attrd_client_update(xml);

    } else if (safe_str_eq(op, ATTRD_OP_UPDATE_DELAY)) {
        attrd_send_ack(client, id, flags);
        attrd_client_update(xml);
  
    } else if (safe_str_eq(op, ATTRD_OP_REFRESH)) {
        attrd_send_ack(client, id, flags);
        attrd_client_refresh();

    } else if (safe_str_eq(op, ATTRD_OP_QUERY)) {
        /* queries will get reply, so no ack is necessary */
        attrd_client_query(client, id, flags, xml);

    } else {
        crm_info("Ignoring request from client %s with unknown operation %s",
                 client->name, op);
    }

    free_xml(xml);
    return 0;
}
コード例 #6
0
ファイル: main.c プロジェクト: SynetoNet/pacemaker
static int32_t
attrd_ipc_dispatch(qb_ipcs_connection_t * c, void *data, size_t size)
{
    uint32_t id = 0;
    uint32_t flags = 0;
    crm_client_t *client = crm_client_get(c);
    xmlNode *xml = crm_ipcs_recv(client, data, size, &id, &flags);

    crm_ipcs_send_ack(client, id, flags, "ack", __FUNCTION__, __LINE__);
    if (xml == NULL) {
        crm_debug("No msg from %d (%p)", crm_ipcs_client_pid(c), c);
        return 0;
    }
#if ENABLE_ACL
    CRM_ASSERT(client->user != NULL);
    crm_acl_get_set_user(xml, F_ATTRD_USER, client->user);
#endif

    crm_trace("Processing msg from %d (%p)", crm_ipcs_client_pid(c), c);
    crm_log_xml_trace(xml, __FUNCTION__);

    attrd_client_message(client, xml);

    free_xml(xml);
    return 0;
}
コード例 #7
0
ファイル: messages.c プロジェクト: JamesGuthrie/pacemaker
enum crmd_fsa_input
handle_shutdown_request(xmlNode * stored_msg)
{
    /* handle here to avoid potential version issues
     *   where the shutdown message/proceedure may have
     *   been changed in later versions.
     *
     * This way the DC is always in control of the shutdown
     */

    char *now_s = NULL;
    time_t now = time(NULL);
    const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM);

    if (host_from == NULL) {
        /* we're shutting down and the DC */
        host_from = fsa_our_uname;
    }

    crm_info("Creating shutdown request for %s (state=%s)", host_from, fsa_state2string(fsa_state));
    crm_log_xml_trace(stored_msg, "message");

    now_s = crm_itoa(now);
    update_attrd(host_from, XML_CIB_ATTR_SHUTDOWN, now_s, NULL, FALSE);
    free(now_s);

    /* will be picked up by the TE as long as its running */
    return I_NULL;
}
コード例 #8
0
ファイル: te_callbacks.c プロジェクト: Xarthisius/pacemaker
void
tengine_stonith_callback(stonith_t * stonith, const xmlNode * msg, int call_id, int rc,
                         xmlNode * output, void *userdata)
{
    char *uuid = NULL;
    int target_rc = -1;
    int stonith_id = -1;
    int transition_id = -1;
    crm_action_t *action = NULL;
    struct st_fail_rec *rec = NULL;

    CRM_CHECK(userdata != NULL, return);
    crm_log_xml_trace(output, "StonithOp");
    crm_notice("Stonith operation %d/%s: %s (%d)", call_id, (char *)userdata,
             pcmk_strerror(rc), rc);

    if (AM_I_DC == FALSE) {
        return;
    }

    /* crm_info("call=%d, optype=%d, node_name=%s, result=%d, node_list=%s, action=%s", */
    /*       op->call_id, op->optype, op->node_name, op->op_result, */
    /*       (char *)op->node_list, op->private_data); */

    /* filter out old STONITH actions */
    CRM_CHECK(decode_transition_key(userdata, &uuid, &transition_id, &stonith_id, &target_rc),
              crm_err("Invalid event detected");
              goto bail;
        );
コード例 #9
0
ファイル: attrd.c プロジェクト: Xarthisius/pacemaker
/* Exit code means? */
static int32_t
attrd_ipc_dispatch(qb_ipcs_connection_t *c, void *data, size_t size)
{
    uint32_t id = 0;
    uint32_t flags = 0;
#if ENABLE_ACL
    attrd_client_t *client = qb_ipcs_context_get(c);
#endif
    xmlNode *msg = crm_ipcs_recv(c, data, size, &id, &flags);

    if(flags & crm_ipc_client_response) {
        crm_trace("Ack'ing msg from %d (%p)", crm_ipcs_client_pid(c), c);
        crm_ipcs_send_ack(c, id, "ack", __FUNCTION__, __LINE__);
    }

    if (msg == NULL) {
        crm_debug("No msg from %d (%p)", crm_ipcs_client_pid(c), c);
        return 0;
    }

#if ENABLE_ACL
    determine_request_user(client->user, msg, F_ATTRD_USER);
#endif

    crm_trace("Processing msg from %d (%p)", crm_ipcs_client_pid(c), c);
    crm_log_xml_trace(msg, __PRETTY_FUNCTION__);
    
    attrd_local_callback(msg);
    
    free_xml(msg);
    return 0;
}
コード例 #10
0
ファイル: commands.c プロジェクト: Xarthisius/pacemaker
static async_command_t *create_async_command(xmlNode *msg)
{
    async_command_t *cmd = NULL;
    xmlNode *op = get_xpath_object("//@"F_STONITH_ACTION, msg, LOG_ERR);
    const char *action = crm_element_value(op, F_STONITH_ACTION);

    CRM_CHECK(action != NULL, crm_log_xml_warn(msg, "NoAction"); return NULL);

    crm_log_xml_trace(msg, "Command");
    cmd = calloc(1, sizeof(async_command_t));
    crm_element_value_int(msg, F_STONITH_CALLID,   &(cmd->id));
    crm_element_value_int(msg, F_STONITH_CALLOPTS, &(cmd->options));
    crm_element_value_int(msg, F_STONITH_TIMEOUT,  &(cmd->timeout));

    cmd->origin = crm_element_value_copy(msg, F_ORIG);
    cmd->remote = crm_element_value_copy(msg, F_STONITH_REMOTE);
    cmd->client = crm_element_value_copy(msg, F_STONITH_CLIENTID);
    cmd->client_name = crm_element_value_copy(msg, F_STONITH_CLIENTNAME);
    cmd->op     = crm_element_value_copy(msg, F_STONITH_OPERATION);
    cmd->action = strdup(action);
    cmd->victim = crm_element_value_copy(op, F_STONITH_TARGET);
    cmd->mode   = crm_element_value_copy(op, F_STONITH_MODE);
    cmd->device = crm_element_value_copy(op, F_STONITH_DEVICE);
    cmd->done   = st_child_done;

    CRM_CHECK(cmd->op != NULL, crm_log_xml_warn(msg, "NoOp"); free_async_command(cmd); return NULL);
    CRM_CHECK(cmd->client != NULL, crm_log_xml_warn(msg, "NoClient"));

    cmd_list = g_list_append(cmd_list, cmd);
    return cmd;
}
コード例 #11
0
ファイル: utils.c プロジェクト: esimone74/pacemaker
xmlNode *
create_node_state(const char *uname, const char *ha_state, const char *ccm_state,
                  const char *crmd_state, const char *join_state, const char *exp_state,
                  gboolean clear_shutdown, const char *src)
{
    xmlNode *node_state = create_xml_node(NULL, XML_CIB_TAG_STATE);

    crm_trace("%s Creating node state entry for %s", src, uname);
    set_uuid(node_state, XML_ATTR_UUID, uname);

    if (crm_element_value(node_state, XML_ATTR_UUID) == NULL) {
        crm_debug("Node %s is not a cluster member", uname);
        free_xml(node_state);
        return NULL;
    }

    crm_xml_add(node_state, XML_ATTR_UNAME, uname);
    crm_xml_add(node_state, XML_CIB_ATTR_HASTATE, ha_state);
    crm_xml_add(node_state, XML_CIB_ATTR_INCCM, ccm_state);
    crm_xml_add(node_state, XML_CIB_ATTR_CRMDSTATE, crmd_state);
    crm_xml_add(node_state, XML_CIB_ATTR_JOINSTATE, join_state);
    crm_xml_add(node_state, XML_CIB_ATTR_EXPSTATE, exp_state);
    crm_xml_add(node_state, XML_ATTR_ORIGIN, src);

    if (clear_shutdown) {
        crm_xml_add(node_state, XML_CIB_ATTR_SHUTDOWN, "0");
    }

    crm_log_xml_trace(node_state, "created");

    return node_state;
}
コード例 #12
0
ファイル: main.c プロジェクト: tserong/pacemaker
static void
stonith_peer_callback(xmlNode * msg, void* private_data)
{
    const char *remote = crm_element_value(msg, F_ORIG);
    crm_log_xml_trace(msg, "Peer[inbound]");
    stonith_command(NULL, msg, remote);
}
コード例 #13
0
ファイル: nvpair.c プロジェクト: wenningerk/pacemaker
/*!
 * \brief Retrieve XML attributes as a hash table
 *
 * Given an XML element, this will look for any \<attributes> element child,
 * creating a hash table of (newly allocated string) name/value pairs taken
 * first from the attributes element's NAME=VALUE XML attributes, and then
 * from any \<param name=NAME value=VALUE> children of attributes.
 *
 * \param[in]  XML node to parse
 *
 * \return Hash table with name/value pairs
 * \note It is the caller's responsibility to free the result using
 *       \c g_hash_table_destroy().
 */
GHashTable *
xml2list(xmlNode *parent)
{
    xmlNode *child = NULL;
    xmlAttrPtr pIter = NULL;
    xmlNode *nvpair_list = NULL;
    GHashTable *nvpair_hash = crm_str_table_new();

    CRM_CHECK(parent != NULL, return nvpair_hash);

    nvpair_list = find_xml_node(parent, XML_TAG_ATTRS, FALSE);
    if (nvpair_list == NULL) {
        crm_trace("No attributes in %s", crm_element_name(parent));
        crm_log_xml_trace(parent, "No attributes for resource op");
    }

    crm_log_xml_trace(nvpair_list, "Unpacking");

    for (pIter = pcmk__first_xml_attr(nvpair_list); pIter != NULL;
         pIter = pIter->next) {

        const char *p_name = (const char *)pIter->name;
        const char *p_value = pcmk__xml_attr_value(pIter);

        crm_trace("Added %s=%s", p_name, p_value);

        g_hash_table_insert(nvpair_hash, strdup(p_name), strdup(p_value));
    }

    for (child = __xml_first_child(nvpair_list); child != NULL;
         child = __xml_next(child)) {

        if (strcmp((const char *)child->name, XML_TAG_PARAM) == 0) {
            const char *key = crm_element_value(child, XML_NVPAIR_ATTR_NAME);
            const char *value = crm_element_value(child, XML_NVPAIR_ATTR_VALUE);

            crm_trace("Added %s=%s", key, value);
            if (key != NULL && value != NULL) {
                g_hash_table_insert(nvpair_hash, strdup(key), strdup(value));
            }
        }
    }

    return nvpair_hash;
}
コード例 #14
0
ファイル: unpack.c プロジェクト: beess/pacemaker
static crm_action_t *
unpack_action(synapse_t * parent, xmlNode * xml_action)
{
    crm_action_t *action = NULL;
    const char *value = crm_element_value(xml_action, XML_ATTR_ID);

    if (value == NULL) {
        crm_err("Actions must have an id!");
        crm_log_xml_trace(xml_action, "Action with missing id");
        return NULL;
    }

    action = calloc(1, sizeof(crm_action_t));
    CRM_CHECK(action != NULL, return NULL);

    action->id = crm_parse_int(value, NULL);
    action->type = action_type_rsc;
    action->xml = copy_xml(xml_action);
    action->synapse = parent;

    if (safe_str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_RSC_OP)) {
        action->type = action_type_rsc;

    } else if (safe_str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_PSEUDO_EVENT)) {
        action->type = action_type_pseudo;

    } else if (safe_str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_CRM_EVENT)) {
        action->type = action_type_crm;
    }

    action->params = xml2list(action->xml);

    value = g_hash_table_lookup(action->params, "CRM_meta_timeout");
    if (value != NULL) {
        action->timeout = crm_parse_int(value, NULL);
    }

    /* Take start-delay into account for the timeout of the action timer */
    value = g_hash_table_lookup(action->params, "CRM_meta_start_delay");
    if (value != NULL) {
        action->timeout += crm_parse_int(value, NULL);
    }

    value = g_hash_table_lookup(action->params, "CRM_meta_interval");
    if (value != NULL) {
        action->interval = crm_parse_int(value, NULL);
    }

    value = g_hash_table_lookup(action->params, "CRM_meta_can_fail");
    if (value != NULL) {
        crm_str_to_boolean(value, &(action->can_fail));
    }

    crm_trace("Action %d has timer set to %dms", action->id, action->timeout);

    return action;
}
コード例 #15
0
ファイル: main.c プロジェクト: tserong/pacemaker
static gboolean
stonith_client_callback(IPC_Channel *channel, gpointer user_data)
{
    int lpc = 0;
    const char *value = NULL;
    xmlNode *request = NULL;
    gboolean keep_channel = TRUE;
    stonith_client_t *stonith_client = user_data;
    
    CRM_CHECK(stonith_client != NULL, crm_err("Invalid client"); return FALSE);
    CRM_CHECK(stonith_client->id != NULL,
	      crm_err("Invalid client: %p", stonith_client); return FALSE);

    if(IPC_ISRCONN(channel) && channel->ops->is_message_pending(channel)) {

	lpc++;
	request = xmlfromIPC(channel, MAX_IPC_DELAY);
	if (request == NULL) {
	    goto bail;
	}

	if(stonith_client->name == NULL) {
	    value = crm_element_value(request, F_STONITH_CLIENTNAME);
	    if(value == NULL) {
		stonith_client->name = crm_itoa(channel->farside_pid);
	    } else {
		stonith_client->name = crm_strdup(value);
	    }
	}

	crm_xml_add(request, F_STONITH_CLIENTID, stonith_client->id);
	crm_xml_add(request, F_STONITH_CLIENTNAME, stonith_client->name);

	if(stonith_client->callback_id == NULL) {
	    value = crm_element_value(request, F_STONITH_CALLBACK_TOKEN);
	    if(value != NULL) {
		stonith_client->callback_id = crm_strdup(value);

	    } else {
		stonith_client->callback_id = crm_strdup(stonith_client->id);
	    }
	}

	crm_log_xml_trace(request, "Client[inbound]");
	stonith_command(stonith_client, request, NULL);

	free_xml(request);
    }
    
  bail:
    if(channel->ch_status != IPC_CONNECT) {
	crm_trace("Client disconnected");
	keep_channel = stonith_client_disconnect(channel, stonith_client);	
    }

    return keep_channel;
}
コード例 #16
0
ファイル: cibmon.c プロジェクト: miz-take/pacemaker
void
cibmon_diff(const char *event, xmlNode * msg)
{
    int rc = -1;
    const char *op = NULL;
    unsigned int log_level = LOG_INFO;

    xmlNode *diff = NULL;
    xmlNode *cib_last = NULL;
    xmlNode *update = get_message_xml(msg, F_CIB_UPDATE);

    if (msg == NULL) {
        crm_err("NULL update");
        return;
    }

    crm_element_value_int(msg, F_CIB_RC, &rc);
    op = crm_element_value(msg, F_CIB_OPERATION);
    diff = get_message_xml(msg, F_CIB_UPDATE_RESULT);

    if (rc < pcmk_ok) {
        log_level = LOG_WARNING;
        do_crm_log(log_level, "[%s] %s ABORTED: %s", event, op, pcmk_strerror(rc));
        return;
    }

    if (log_diffs) {
        xml_log_patchset(log_level, op, diff);
    }

    if (log_updates && update != NULL) {
        crm_log_xml_trace(update, "raw_update");
    }

    if (cib_copy != NULL) {
        cib_last = cib_copy;
        cib_copy = NULL;
        rc = cib_process_diff(op, cib_force_diff, NULL, NULL, diff, cib_last, &cib_copy, NULL);

        if (rc != pcmk_ok) {
            crm_debug("Update didn't apply, requesting full copy: %s", pcmk_strerror(rc));
            free_xml(cib_copy);
            cib_copy = NULL;
        }
    }

    if (cib_copy == NULL) {
        rc = cib->cmds->query(cib, NULL, &cib_copy, cib_scope_local | cib_sync_call);
    }

    if(rc == -EACCES) {
        crm_exit(CRM_EX_INSUFFICIENT_PRIV);
    }

    free_xml(cib_last);
}
コード例 #17
0
ファイル: callbacks.c プロジェクト: SynetoNet/pacemaker
int32_t
cib_common_callback(qb_ipcs_connection_t * c, void *data, size_t size, gboolean privileged)
{
    uint32_t id = 0;
    uint32_t flags = 0;
    int call_options = 0;
    crm_client_t *cib_client = crm_client_get(c);
    xmlNode *op_request = crm_ipcs_recv(cib_client, data, size, &id, &flags);

    if (op_request) {
        crm_element_value_int(op_request, F_CIB_CALLOPTS, &call_options);
    }

    if (op_request == NULL) {
        crm_trace("Invalid message from %p", c);
        crm_ipcs_send_ack(cib_client, id, flags, "nack", __FUNCTION__, __LINE__);
        return 0;

    } else if(cib_client == NULL) {
        crm_trace("Invalid client %p", c);
        return 0;
    }

    if (is_set(call_options, cib_sync_call)) {
        CRM_ASSERT(flags & crm_ipc_client_response);
        CRM_LOG_ASSERT(cib_client->request_id == 0);    /* This means the client has two synchronous events in-flight */
        cib_client->request_id = id;    /* Reply only to the last one */
    }

    if (cib_client->name == NULL) {
        const char *value = crm_element_value(op_request, F_CIB_CLIENTNAME);

        if (value == NULL) {
            cib_client->name = crm_itoa(cib_client->pid);
        } else {
            cib_client->name = strdup(value);
        }
    }

    crm_xml_add(op_request, F_CIB_CLIENTID, cib_client->id);
    crm_xml_add(op_request, F_CIB_CLIENTNAME, cib_client->name);

#if ENABLE_ACL
    CRM_ASSERT(cib_client->user != NULL);
    crm_acl_get_set_user(op_request, F_CIB_USER, cib_client->user);
#endif

    crm_log_xml_trace(op_request, "Client[inbound]");

    cib_common_callback_worker(id, flags, op_request, cib_client, privileged);
    free_xml(op_request);

    return 0;
}
コード例 #18
0
ファイル: lrm_state.c プロジェクト: MEShrek/pacemaker
static void
crmd_proxy_dispatch(const char *session, xmlNode *msg)
{

    crm_log_xml_trace(msg, "CRMd-PROXY[inbound]");

    crm_xml_add(msg, F_CRM_SYS_FROM, session);
    if (crmd_authorize_message(msg, NULL, session)) {
        route_message(C_IPC_MESSAGE, msg);
    }

    trigger_fsa(fsa_source);
}
コード例 #19
0
ファイル: main.c プロジェクト: SynetoNet/pacemaker
static void
stonith_peer_callback(xmlNode * msg, void *private_data)
{
    const char *remote_peer = crm_element_value(msg, F_ORIG);
    const char *op = crm_element_value(msg, F_STONITH_OPERATION);

    if (crm_str_eq(op, "poke", TRUE)) {
        return;
    }

    crm_log_xml_trace(msg, "Peer[inbound]");
    stonith_command(NULL, 0, 0, msg, remote_peer);
}
コード例 #20
0
ファイル: crmadmin.c プロジェクト: beess/pacemaker
int
admin_msg_callback(const char *buffer, ssize_t length, gpointer userdata)
{
    static int received_responses = 0;
    xmlNode *xml = string2xml(buffer);

    received_responses++;
    g_source_remove(message_timer_id);

    crm_log_xml_trace(xml, "ipc");

    if (xml == NULL) {
        crm_info("XML in IPC message was not valid... " "discarding.");

    } else if (validate_crm_message(xml, crm_system_name, admin_uuid, XML_ATTR_RESPONSE) == FALSE) {
        crm_trace("Message was not a CRM response. Discarding.");

    } else if (DO_HEALTH) {
        xmlNode *data = get_message_xml(xml, F_CRM_DATA);
        const char *state = crm_element_value(data, "crmd_state");

        printf("Status of %s@%s: %s (%s)\n",
               crm_element_value(data, XML_PING_ATTR_SYSFROM),
               crm_element_value(xml, F_CRM_HOST_FROM),
               state, crm_element_value(data, XML_PING_ATTR_STATUS));

        if (BE_SILENT && state != NULL) {
            fprintf(stderr, "%s\n", state);
        }

    } else if (DO_WHOIS_DC) {
        const char *dc = crm_element_value(xml, F_CRM_HOST_FROM);

        printf("Designated Controller is: %s\n", dc);
        if (BE_SILENT && dc != NULL) {
            fprintf(stderr, "%s\n", dc);
        }
        crm_exit(pcmk_ok);
    }

    free_xml(xml);

    if (received_responses >= expected_responses) {
        crm_trace("Received expected number (%d) of messages from Heartbeat."
                  "  Exiting normally.", expected_responses);
        crm_exit(pcmk_ok);
    }

    message_timer_id = g_timeout_add(message_timeout_ms, admin_message_timeout, NULL);
    return 0;
}
コード例 #21
0
ファイル: callbacks.c プロジェクト: tserong/pacemaker
/*
 * Apparently returning TRUE means "stay connected, keep doing stuff".
 * Returning FALSE means "we're all done, close the connection"
 */
gboolean
crmd_ipc_msg_callback(IPC_Channel * client, gpointer user_data)
{
    int lpc = 0;
    xmlNode *msg = NULL;
    crmd_client_t *curr_client = (crmd_client_t *) user_data;
    gboolean stay_connected = TRUE;

    crm_trace("Invoked: %s", curr_client->table_key);

    while (IPC_ISRCONN(client)) {
        if (client->ops->is_message_pending(client) == 0) {
            break;
        }

        msg = xmlfromIPC(client, MAX_IPC_DELAY);
        if (msg == NULL) {
            break;
        }
#if ENABLE_ACL
        determine_request_user(&curr_client->user, client, msg, F_CRM_USER);
#endif

        lpc++;
        crm_trace("Processing msg from %s", curr_client->table_key);
        crm_log_xml_trace(msg, "CRMd[inbound]");

        if (crmd_authorize_message(msg, curr_client)) {
            route_message(C_IPC_MESSAGE, msg);
        }

        free_xml(msg);
        msg = NULL;

        if (client->ch_status != IPC_CONNECT) {
            break;
        }
    }

    crm_trace("Processed %d messages", lpc);

    if (client->ch_status != IPC_CONNECT) {
        stay_connected = FALSE;
        process_client_disconnect(curr_client);
    }

    trigger_fsa(fsa_source);
    return stay_connected;
}
コード例 #22
0
ファイル: main.c プロジェクト: efenshi/pacemaker
/* Exit code means? */
static int32_t
st_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size)
{
    uint32_t id = 0;
    uint32_t flags = 0;
    int call_options = 0;
    xmlNode *request = NULL;
    crm_client_t *c = crm_client_get(qbc);

    if (c == NULL) {
        crm_info("Invalid client: %p", qbc);
        return 0;
    }

    request = crm_ipcs_recv(c, data, size, &id, &flags);
    if (request == NULL) {
        crm_ipcs_send_ack(c, id, flags, "nack", __FUNCTION__, __LINE__);
        return 0;
    }

    if (c->name == NULL) {
        const char *value = crm_element_value(request, F_STONITH_CLIENTNAME);

        if (value == NULL) {
            value = "unknown";
        }
        c->name = g_strdup_printf("%s.%u", value, c->pid);
    }

    crm_element_value_int(request, F_STONITH_CALLOPTS, &call_options);
    crm_trace("Flags %u/%u for command %u from %s", flags, call_options, id, crm_client_name(c));

    if (is_set(call_options, st_opt_sync_call)) {
        CRM_ASSERT(flags & crm_ipc_client_response);
        CRM_LOG_ASSERT(c->request_id == 0);     /* This means the client has two synchronous events in-flight */
        c->request_id = id;     /* Reply only to the last one */
    }

    crm_xml_add(request, F_STONITH_CLIENTID, c->id);
    crm_xml_add(request, F_STONITH_CLIENTNAME, crm_client_name(c));
    crm_xml_add(request, F_STONITH_CLIENTNODE, stonith_our_uname);

    crm_log_xml_trace(request, "Client[inbound]");
    stonith_command(c, id, flags, request, NULL);

    free_xml(request);
    return 0;
}
コード例 #23
0
ファイル: lrm_state.c プロジェクト: MEShrek/pacemaker
void
crmd_proxy_send(const char *session, xmlNode *msg)
{
    remote_proxy_t *proxy = g_hash_table_lookup(proxy_table, session);
    lrm_state_t *lrm_state = NULL;

    if (!proxy) {
        return;
    }
    crm_log_xml_trace(msg, "to-proxy");
    lrm_state = lrm_state_find(proxy->node_name);
    if (lrm_state) {
        crm_trace("Sending event to %.8s on %s", proxy->session_id, proxy->node_name);
        remote_proxy_relay_event(lrm_state->conn, session, msg);
    }
}
コード例 #24
0
ファイル: attrd.c プロジェクト: brhellman/pacemaker
static gboolean
attrd_ipc_callback(IPC_Channel * client, gpointer user_data)
{
    int lpc = 0;
    xmlNode *msg = NULL;
    attrd_client_t *curr_client = (attrd_client_t *) user_data;
    gboolean stay_connected = TRUE;

    crm_trace("Invoked: %s", curr_client->id);

    while (IPC_ISRCONN(client)) {
        if (client->ops->is_message_pending(client) == 0) {
            break;
        }

        msg = xmlfromIPC(client, MAX_IPC_DELAY);
        if (msg == NULL) {
            break;
        }

        lpc++;

#if ENABLE_ACL
        determine_request_user(&curr_client->user, client, msg, F_ATTRD_USER);
#endif

        crm_trace("Processing msg from %s", curr_client->id);
        crm_log_xml_trace(msg, __PRETTY_FUNCTION__);

        attrd_local_callback(msg);

        free_xml(msg);
        msg = NULL;

        if (client->ch_status != IPC_CONNECT) {
            break;
        }
    }

    crm_trace("Processed %d messages", lpc);
    if (client->ch_status != IPC_CONNECT) {
        stay_connected = FALSE;
    }

    return stay_connected;
}
コード例 #25
0
ファイル: te_callbacks.c プロジェクト: voitra/pacemaker
static void process_resource_updates(
    const char *node, xmlNode *xml, xmlNode *change, const char *op, const char *xpath) 
{
    xmlNode *cIter = NULL;
    xmlNode *rsc = NULL;
    xmlNode *rsc_op = NULL;
    int num_resources = 0;

    if(xml == NULL) {
        return;

    } else if(strcmp((const char*)xml->name, XML_CIB_TAG_LRM) == 0) {
        xml = first_named_child(xml, XML_LRM_TAG_RESOURCES);
        crm_trace("Got %p in %s", xml, XML_CIB_TAG_LRM);
    }

    CRM_ASSERT(strcmp((const char*)xml->name, XML_LRM_TAG_RESOURCES) == 0);

    for(cIter = xml->children; cIter; cIter = cIter->next) {
        num_resources++;
    }

    if(num_resources > 1) {
        /*
         * Check for and fast-track the processing of LRM refreshes
         * In large clusters this can result in _huge_ speedups
         *
         * Unfortunately we can only do so when there are no pending actions
         * Otherwise we could miss updates we're waiting for and stall
         *
         */

        crm_debug("Detected LRM refresh - %d resources updated", num_resources);
        crm_log_xml_trace(change, "lrm-refresh");
        abort_transition(INFINITY, tg_restart, "LRM Refresh", NULL);
        return;
    }

    for (rsc = __xml_first_child(xml); rsc != NULL; rsc = __xml_next(rsc)) {
        crm_trace("Processing %s", ID(rsc));
        for (rsc_op = __xml_first_child(rsc); rsc_op != NULL; rsc_op = __xml_next(rsc_op)) {
            crm_trace("Processing %s", ID(rsc_op));
            process_graph_event(rsc_op, node);
        }
    }
}
コード例 #26
0
ファイル: cib_attrs.c プロジェクト: bcavanagh/pacemaker
int
query_node_uname(cib_t * the_cib, const char *uuid, char **uname)
{
    int rc = pcmk_ok;
    xmlNode *a_child = NULL;
    xmlNode *xml_obj = NULL;
    xmlNode *fragment = NULL;
    const char *child_name = NULL;

    CRM_ASSERT(uname != NULL);
    CRM_ASSERT(uuid != NULL);

    rc = the_cib->cmds->query(the_cib, XML_CIB_TAG_NODES, &fragment,
                              cib_sync_call | cib_scope_local);
    if (rc != pcmk_ok) {
        return rc;
    }

    xml_obj = fragment;
    CRM_CHECK(safe_str_eq(crm_element_name(xml_obj), XML_CIB_TAG_NODES), return -ENOMSG);
    CRM_ASSERT(xml_obj != NULL);
    crm_log_xml_trace(xml_obj, "Result section");

    rc = -ENXIO;
    *uname = NULL;

    for (a_child = __xml_first_child(xml_obj); a_child != NULL; a_child = __xml_next(a_child)) {
        if (crm_str_eq((const char *)a_child->name, XML_CIB_TAG_NODE, TRUE)) {
            child_name = ID(a_child);
            if (safe_str_eq(uuid, child_name)) {
                child_name = crm_element_value(a_child, XML_ATTR_UNAME);
                if (child_name != NULL) {
                    *uname = strdup(child_name);
                    rc = pcmk_ok;
                }
                break;
            }
        }
    }

    free_xml(fragment);
    return rc;
}
コード例 #27
0
ファイル: cib_native.c プロジェクト: jjzhang/pacemaker
static int
cib_native_dispatch_internal(const char *buffer, ssize_t length, gpointer userdata)
{
    const char *type = NULL;
    xmlNode *msg = NULL;

    cib_t * cib = userdata;
    cib_native_opaque_t *native;

    crm_trace("dispatching %p", userdata);

    if (cib == NULL) {
        crm_err("No CIB!");
        return 0;
    }

    native = cib->variant_opaque;
    msg = string2xml(buffer);

    if (msg == NULL) {
        crm_warn("Received a NULL msg from CIB service.");
        return 0;
    }

    /* do callbacks */
    type = crm_element_value(msg, F_TYPE);
    crm_trace("Activating %s callbacks...", type);
    crm_log_xml_trace(msg, "cib-reply");

    if (safe_str_eq(type, T_CIB)) {
        cib_native_callback(cib, msg, 0, 0);

    } else if (safe_str_eq(type, T_CIB_NOTIFY)) {
        g_list_foreach(cib->notify_list, cib_native_notify, msg);

    } else {
        crm_err("Unknown message type: %s", type);
    }

    free_xml(msg);
    return 0;
}
コード例 #28
0
ファイル: crm_resource.c プロジェクト: wenningerk/pacemaker
static int
resource_ipc_callback(const char *buffer, ssize_t length, gpointer userdata)
{
    xmlNode *msg = string2xml(buffer);

    fprintf(stderr, ".");
    crm_log_xml_trace(msg, "[inbound]");

    crmd_replies_needed--;
    if ((crmd_replies_needed == 0) && mainloop
        && g_main_loop_is_running(mainloop)) {

        fprintf(stderr, " OK\n");
        crm_debug("Got all the replies we expected");
        return crm_exit(CRM_EX_OK);
    }

    free_xml(msg);
    return 0;
}
コード例 #29
0
static void
process_resource_updates(const char *node, xmlNode *xml, xmlNode *change,
                         const char *op, const char *xpath)
{
    xmlNode *rsc = NULL;

    if (xml == NULL) {
        return;

    } else if (strcmp((const char*)xml->name, XML_CIB_TAG_LRM) == 0) {
        xml = first_named_child(xml, XML_LRM_TAG_RESOURCES);
        crm_trace("Got %p in %s", xml, XML_CIB_TAG_LRM);
    }

    CRM_ASSERT(strcmp((const char*)xml->name, XML_LRM_TAG_RESOURCES) == 0);

    /*
     * Updates by, or in response to, TE actions will never contain updates
     * for more than one resource at a time, so such updates indicate an
     * LRM refresh.
     *
     * In that case, start a new transition rather than check each result
     * individually, which can result in _huge_ speedups in large clusters.
     *
     * Unfortunately, we can only do so when there are no pending actions.
     * Otherwise, we could mistakenly throw away those results here, and
     * the cluster will stall waiting for them and time out the operation.
     */
    if ((transition_graph->pending == 0)
        && xml->children && xml->children->next) {

        crm_log_xml_trace(change, "lrm-refresh");
        abort_transition(INFINITY, tg_restart, "History refresh", NULL);
        return;
    }

    for (rsc = __xml_first_child(xml); rsc != NULL; rsc = __xml_next(rsc)) {
        crm_trace("Processing %s", ID(rsc));
        process_lrm_resource_diff(rsc, node);
    }
}
コード例 #30
0
ファイル: notify.c プロジェクト: brhellman/pacemaker
void
cib_replace_notify(const char *origin, xmlNode * update, enum cib_errors result, xmlNode * diff)
{
    xmlNode *replace_msg = NULL;

    int add_updates = 0;
    int add_epoch = 0;
    int add_admin_epoch = 0;

    int del_updates = 0;
    int del_epoch = 0;
    int del_admin_epoch = 0;

    if (diff == NULL) {
        return;
    }

    cib_diff_version_details(diff, &add_admin_epoch, &add_epoch, &add_updates,
                             &del_admin_epoch, &del_epoch, &del_updates);

    if (add_updates != del_updates) {
        crm_info("Replaced: %d.%d.%d -> %d.%d.%d from %s",
                 del_admin_epoch, del_epoch, del_updates,
                 add_admin_epoch, add_epoch, add_updates, crm_str(origin));
    } else if (diff != NULL) {
        crm_info("Local-only Replace: %d.%d.%d from %s",
                 add_admin_epoch, add_epoch, add_updates, crm_str(origin));
    }

    replace_msg = create_xml_node(NULL, "notify-replace");
    crm_xml_add(replace_msg, F_TYPE, T_CIB_NOTIFY);
    crm_xml_add(replace_msg, F_SUBTYPE, T_CIB_REPLACE_NOTIFY);
    crm_xml_add(replace_msg, F_CIB_OPERATION, CIB_OP_REPLACE);
    crm_xml_add_int(replace_msg, F_CIB_RC, result);
    attach_cib_generation(replace_msg, "cib-replace-generation", update);

    crm_log_xml_trace(replace_msg, "CIB Replaced");

    g_hash_table_foreach_remove(client_list, cib_notify_client, replace_msg);
    free_xml(replace_msg);
}