コード例 #1
0
ファイル: common.c プロジェクト: JamesGuthrie/pacemaker
static xmlNode *
cib_prepare_common(xmlNode * root, const char *section)
{
    xmlNode *data = NULL;

    /* extract the CIB from the fragment */
    if (root == NULL) {
        return NULL;

    } else if (safe_str_eq(crm_element_name(root), XML_TAG_FRAGMENT)
               || safe_str_eq(crm_element_name(root), F_CRM_DATA)
               || safe_str_eq(crm_element_name(root), F_CIB_CALLDATA)) {
        data = first_named_child(root, XML_TAG_CIB);

    } else {
        data = root;
    }

    /* grab the section specified for the command */
    if (section != NULL && data != NULL && crm_str_eq(crm_element_name(data), XML_TAG_CIB, TRUE)) {
        data = get_object_root(section, data);
    }

    /* crm_log_xml_trace(root, "cib:input"); */
    return data;
}
コード例 #2
0
ファイル: notify.c プロジェクト: ClusterLabs/pacemaker-1.0
void
cib_pre_notify(
	int options, const char *op, xmlNode *existing, xmlNode *update) 
{
	xmlNode *update_msg = NULL;
	const char *type = NULL;
	const char *id = NULL;
	gboolean needed = FALSE;

	g_hash_table_foreach(client_list, need_pre_notify, &needed);
	if(needed == FALSE) {
	    return;
	}

	/* TODO: consider pre-notification for removal */
	update_msg = create_xml_node(NULL, "pre-notify");

	if(update != NULL) {
		id = crm_element_value(update, XML_ATTR_ID);
	}
	
	crm_xml_add(update_msg, F_TYPE, T_CIB_NOTIFY);
	crm_xml_add(update_msg, F_SUBTYPE, T_CIB_PRE_NOTIFY);
	crm_xml_add(update_msg, F_CIB_OPERATION, op);

	if(id != NULL) {
		crm_xml_add(update_msg, F_CIB_OBJID, id);
	}

	if(update != NULL) {
		crm_xml_add(update_msg, F_CIB_OBJTYPE, crm_element_name(update));
	} else if(existing != NULL) {
		crm_xml_add(update_msg, F_CIB_OBJTYPE, crm_element_name(existing));
	}

	type = crm_element_value(update_msg, F_CIB_OBJTYPE);	
	attach_cib_generation(update_msg, "cib_generation", the_cib);
	
	if(existing != NULL) {
		add_message_xml(update_msg, F_CIB_EXISTING, existing);
	}
	if(update != NULL) {
		add_message_xml(update_msg, F_CIB_UPDATE, update);
	}

	g_hash_table_foreach(client_list, cib_notify_client, update_msg);
	
	if(update == NULL) {
		crm_debug_2("Performing operation %s (on section=%s)",
			    op, type);

	} else {
		crm_debug_2("Performing %s on <%s%s%s>",
			    op, type, id?" id=":"", id?id:"");
	}
		
	free_xml(update_msg);
}
コード例 #3
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;
}
コード例 #4
0
ファイル: cib.c プロジェクト: sipwise/heartbeat
static void
revision_check_callback(const HA_Message *msg, int call_id, int rc,
			crm_data_t *output, void *user_data)
{
	int cmp = -1;
	const char *revision = NULL;
	crm_data_t *generation = NULL;
#if CRM_DEPRECATED_SINCE_2_0_4
	if(safe_str_eq(crm_element_name(output), XML_TAG_CIB)) {
		generation = output;
	} else {
		generation = find_xml_node(output, XML_TAG_CIB, TRUE);
	}
#else
	generation = output;
	CRM_DEV_ASSERT(safe_str_eq(crm_element_name(generation), XML_TAG_CIB));
#endif
	
	if(rc != cib_ok) {
		fsa_data_t *msg_data = NULL;
		register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
		return;
	}
	
	crm_debug_3("Checking our feature revision is allowed: %s",
		    CIB_FEATURE_SET);

	revision = crm_element_value(generation, XML_ATTR_CIB_REVISION);
	cmp = compare_version(revision, CIB_FEATURE_SET);
	
	if(cmp > 0) {
		crm_err("This build (%s) does not support the current"
			" resource configuration", VERSION);
		crm_err("We can support up to CIB feature set %s (current=%s)",
			CIB_FEATURE_SET, revision);
		crm_err("Shutting down the CRM");
		/* go into a stall state */
		register_fsa_error_adv(
			C_FSA_INTERNAL, I_SHUTDOWN, NULL, NULL, __FUNCTION__);
		return;
	}

	revision = crm_element_value(generation, XML_ATTR_CRM_VERSION);
	cmp = compare_version(revision, CRM_FEATURE_SET);
	
	if(cmp > 0) {
		crm_err("This build (%s) does not support the current"
			" resource configuration", VERSION);
		crm_err("We can support up to CRM feature set %s (current=%s)",
			revision, CRM_FEATURE_SET);
		crm_err("Shutting down the CRM");
		/* go into a stall state */
		register_fsa_error_adv(
			C_FSA_INTERNAL, I_SHUTDOWN, NULL, NULL, __FUNCTION__);
		return;
	}
}
コード例 #5
0
ファイル: notify.c プロジェクト: sipwise/heartbeat
void
cib_pre_notify(
	int options, const char *op, crm_data_t *existing, crm_data_t *update) 
{
	HA_Message *update_msg = NULL;
	const char *type = NULL;
	const char *id = NULL;

	update_msg = ha_msg_new(6);

	if(update != NULL) {
		id = crm_element_value(update, XML_ATTR_ID);
	}
	
	ha_msg_add(update_msg, F_TYPE, T_CIB_NOTIFY);
	ha_msg_add(update_msg, F_SUBTYPE, T_CIB_PRE_NOTIFY);
	ha_msg_add(update_msg, F_CIB_OPERATION, op);

	if(id != NULL) {
		ha_msg_add(update_msg, F_CIB_OBJID, id);
	}

	if(update != NULL) {
		ha_msg_add(update_msg, F_CIB_OBJTYPE, crm_element_name(update));
	} else if(existing != NULL) {
		ha_msg_add(update_msg, F_CIB_OBJTYPE, crm_element_name(existing));
	}

	type = cl_get_string(update_msg, F_CIB_OBJTYPE);	
	attach_cib_generation(update_msg, "cib_generation", the_cib);
	
	if(existing != NULL) {
		add_message_xml(update_msg, F_CIB_EXISTING, existing);
	}
	if(update != NULL) {
		add_message_xml(update_msg, F_CIB_UPDATE, update);
	}

	g_hash_table_foreach(client_list, cib_notify_client, update_msg);
	
	if(update == NULL) {
		crm_debug_2("Performing operation %s (on section=%s)",
			    op, type);

	} else {
		crm_debug_2("Performing %s on <%s%s%s>",
			    op, type, id?" id=":"", id?id:"");
	}
		
	crm_msg_del(update_msg);
}
コード例 #6
0
ファイル: acl.c プロジェクト: HideoYamauchi/pacemaker
void
pcmk__post_process_acl(xmlNode *xml)
{
    xmlNode *cIter = __xml_first_child(xml);
    xml_private_t *p = xml->_private;

    if (is_set(p->flags, xpf_created)) {
        xmlAttr *xIter = NULL;
        char *path = xml_get_path(xml);

        /* Always allow new scaffolding (e.g. node with no attributes or only an
         * 'id'), except in the ACLs section
         */

        for (xIter = xml->properties; xIter != NULL; xIter = xIter->next) {
            const char *prop_name = (const char *)xIter->name;

            if (!strcmp(prop_name, XML_ATTR_ID)
                && !strstr(path, "/"XML_CIB_TAG_ACLS"/")) {
                /* Delay the acl check */
                continue;

            } else if (pcmk__check_acl(xml, NULL, xpf_acl_write)) {
                crm_trace("Creation of %s=%s is allowed",
                          crm_element_name(xml), ID(xml));
                break;

            } else {
                crm_trace("Cannot add new node %s at %s",
                          crm_element_name(xml), path);

                if (xml != xmlDocGetRootElement(xml->doc)) {
                    xmlUnlinkNode(xml);
                    xmlFreeNode(xml);
                }
                free(path);
                return;
            }
        }
        free(path);
    }

    while (cIter != NULL) {
        xmlNode *child = cIter;
        cIter = __xml_next(cIter); /* In case it is free'd */
        pcmk__post_process_acl(child);
    }
}
コード例 #7
0
ファイル: graph.c プロジェクト: brhellman/pacemaker
static gboolean
fire_synapse(crm_graph_t * graph, synapse_t * synapse)
{
    GListPtr lpc = NULL;

    CRM_CHECK(synapse != NULL, return FALSE);
    CRM_CHECK(synapse->ready, return FALSE);
    CRM_CHECK(synapse->confirmed == FALSE, return TRUE);

    crm_trace("Synapse %d fired", synapse->id);
    synapse->executed = TRUE;
    for (lpc = synapse->actions; lpc != NULL; lpc = lpc->next) {
        crm_action_t *action = (crm_action_t *) lpc->data;

        /* allow some leeway */
        gboolean passed = FALSE;

        /* Invoke the action and start the timer */
        passed = initiate_action(graph, action);
        if (passed == FALSE) {
            crm_err("Failed initiating <%s id=%d> in synapse %d",
                    crm_element_name(action->xml), action->id, synapse->id);
            synapse->confirmed = TRUE;
            action->confirmed = TRUE;
            action->failed = TRUE;
            return FALSE;
        }
    }

    return TRUE;
}
コード例 #8
0
ファイル: heartbeat.c プロジェクト: bubble75/pacemaker
xmlNode *
convert_ha_message(xmlNode * parent, HA_Message * msg, const char *field)
{
    int lpc = 0;
    xmlNode *child = NULL;
    const char *tag = NULL;

    CRM_CHECK(msg != NULL, crm_err("Empty message for %s", field);
              return parent);

    tag = cl_get_string(msg, F_XML_TAGNAME);
    if (tag == NULL) {
        tag = field;

    } else if (parent && safe_str_neq(field, tag)) {
        /* For compatibility with 0.6.x */
        crm_debug("Creating intermediate parent %s between %s and %s", field,
                  crm_element_name(parent), tag);
        parent = create_xml_node(parent, field);
    }

    if (parent == NULL) {
        parent = create_xml_node(NULL, tag);
        child = parent;

    } else {
        child = create_xml_node(parent, tag);
    }

    for (lpc = 0; lpc < msg->nfields; lpc++) {
        convert_ha_field(child, msg, lpc);
    }

    return parent;
}
コード例 #9
0
ファイル: cibadmin.c プロジェクト: jnewland/pacemaker
int
do_work(xmlNode * input, int call_options, xmlNode ** output)
{
    /* construct the request */
    the_cib->call_timeout = message_timeout_ms;
    if (strcasecmp(CIB_OP_REPLACE, cib_action) == 0
        && safe_str_eq(crm_element_name(input), XML_TAG_CIB)) {
        xmlNode *status = get_object_root(XML_CIB_TAG_STATUS, input);

        if (status == NULL) {
            create_xml_node(input, XML_CIB_TAG_STATUS);
        }
    }

    if (strcasecmp(CIB_OP_SYNC, cib_action) == 0) {
        crm_trace("Performing %s op...", cib_action);
        return the_cib->cmds->sync_from(the_cib, host, obj_type, call_options);

    } else if (strcasecmp(CIB_OP_SLAVE, cib_action) == 0 && (call_options ^ cib_scope_local)) {
        crm_trace("Performing %s op on all nodes...", cib_action);
        return the_cib->cmds->set_slave_all(the_cib, call_options);

    } else if (strcasecmp(CIB_OP_MASTER, cib_action) == 0) {
        crm_trace("Performing %s op on all nodes...", cib_action);
        return the_cib->cmds->set_master(the_cib, call_options);

    } else if (cib_action != NULL) {
        crm_trace("Passing \"%s\" to variant_op...", cib_action);
        return cib_internal_op(the_cib, cib_action, host, obj_type, input, output, call_options, NULL);

    } else {
        crm_err("You must specify an operation");
    }
    return -EINVAL;
}
コード例 #10
0
ファイル: rules.c プロジェクト: aspiers/pacemaker
enum expression_type
find_expression_type(xmlNode * expr)
{
    const char *tag = NULL;
    const char *attr = NULL;

    attr = crm_element_value(expr, XML_EXPR_ATTR_ATTRIBUTE);
    tag = crm_element_name(expr);

    if (safe_str_eq(tag, "date_expression")) {
        return time_expr;

    } else if (safe_str_eq(tag, XML_TAG_RULE)) {
        return nested_rule;

    } else if (safe_str_neq(tag, "expression")) {
        return not_expr;

    } else if (safe_str_eq(attr, "#uname") || safe_str_eq(attr, "#kind") || safe_str_eq(attr, "#id")) {
        return loc_expr;

    } else if (safe_str_eq(attr, "#role")) {
        return role_expr;
    }

    return attr_expr;
}
コード例 #11
0
ファイル: cib.c プロジェクト: ClusterLabs/pacemaker-1.0
static void
revision_check_callback(xmlNode *msg, int call_id, int rc,
			xmlNode *output, void *user_data)
{
	int cmp = -1;
	const char *revision = NULL;
	xmlNode *generation = NULL;
	
	if(rc != cib_ok) {
		fsa_data_t *msg_data = NULL;
		register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
		return;
	}

	generation = output;
	CRM_CHECK(safe_str_eq(crm_element_name(generation), XML_TAG_CIB), crm_log_xml_err(output, __FUNCTION__); return);
	
	crm_debug_3("Checking our feature revision is allowed: %s", CIB_FEATURE_SET);

	revision = crm_element_value(generation, XML_ATTR_CRM_VERSION);
	cmp = compare_version(revision, CRM_FEATURE_SET);
	
	if(cmp > 0) {
		crm_err("This build (%s) does not support the current"
			" resource configuration", VERSION);
		crm_err("We can support up to CRM feature set %s (current=%s)",
			revision, CRM_FEATURE_SET);
		crm_err("Shutting down the CRM");
		/* go into a stall state */
		register_fsa_error_adv(
			C_FSA_INTERNAL, I_SHUTDOWN, NULL, NULL, __FUNCTION__);
		return;
	}
}
コード例 #12
0
void
cli_resource_print_cts(resource_t * rsc)
{
    GListPtr lpc = NULL;
    const char *host = NULL;
    bool needs_quorum = TRUE;
    const char *rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE);
    const char *rprov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
    const char *rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
    pe_node_t *node = pe__current_node(rsc);

    if (safe_str_eq(rclass, PCMK_RESOURCE_CLASS_STONITH)) {
        needs_quorum = FALSE;
    } else {
        // @TODO check requires in resource meta-data and rsc_defaults
    }

    if (node != NULL) {
        host = node->details->uname;
    }

    printf("Resource: %s %s %s %s %s %s %s %s %d %lld 0x%.16llx\n",
           crm_element_name(rsc->xml), rsc->id,
           rsc->clone_name ? rsc->clone_name : rsc->id, rsc->parent ? rsc->parent->id : "NA",
           rprov ? rprov : "NA", rclass, rtype, host ? host : "NA", needs_quorum, rsc->flags,
           rsc->flags);

    for (lpc = rsc->children; lpc != NULL; lpc = lpc->next) {
        resource_t *child = (resource_t *) lpc->data;

        cli_resource_print_cts(child);
    }
}
コード例 #13
0
ファイル: messages.c プロジェクト: sipwise/heartbeat
enum cib_errors
updateList(crm_data_t *local_cib, crm_data_t *xml_section, crm_data_t *failed,
	   int operation, const char *section)
{
	int rc = cib_ok;
	crm_data_t *this_section = get_object_root(section, local_cib);
	
	if (section == NULL || xml_section == NULL) {
		crm_err("Section %s not found in message."
			"  CIB update is corrupt, ignoring.",
			crm_str(section));
		return cib_NOSECTION;
	}

	if((CIB_UPDATE_OP_NONE > operation)
	   || (operation > CIB_UPDATE_OP_MAX)){
		crm_err("Invalid operation on section %s", crm_str(section));
		return cib_operation;
	}

	if(safe_str_eq(crm_element_name(xml_section), section)) {
		xml_child_iter(xml_section, a_child, 
			       rc = cib_ok;
			       cib_update_xml_macro(this_section, a_child);
			);

	} else {
コード例 #14
0
ファイル: cib_ops.c プロジェクト: davidvossel/pacemaker
int
cib_process_delete(const char *op, int options, const char *section, xmlNode * req, xmlNode * input,
                   xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer)
{
    xmlNode *obj_root = NULL;

    crm_trace("Processing \"%s\" event", op);

    if (options & cib_xpath) {
        return cib_process_xpath(op, options, section, req, input,
                                 existing_cib, result_cib, answer);
    }

    if (input == NULL) {
        crm_err("Cannot perform modification with no data");
        return -EINVAL;
    }

    obj_root = get_object_root(section, *result_cib);
    if(safe_str_eq(crm_element_name(input), section)) {
        xmlNode *child = NULL;
        for(child = __xml_first_child(input); child; child = __xml_next(child)) {
            if (replace_xml_child(NULL, obj_root, child, TRUE) == FALSE) {
                crm_trace("No matching object to delete: %s=%s", child->name, ID(child));
            }
        }

    } else if (replace_xml_child(NULL, obj_root, input, TRUE) == FALSE) {
            crm_trace("No matching object to delete: %s=%s", input->name, ID(input));
    }

    return pcmk_ok;
}
コード例 #15
0
ファイル: crm_mon.c プロジェクト: sipwise/heartbeat
void
mon_update(const HA_Message *msg, int call_id, int rc,
	   crm_data_t *output, void*user_data) 
{
	const char *prefix = NULL;
	if(rc == cib_ok) {
		crm_data_t *cib = NULL;
#if CRM_DEPRECATED_SINCE_2_0_4
		if( safe_str_eq(crm_element_name(output), XML_TAG_CIB) ) {
			cib = output;
		} else {
			cib = find_xml_node(output,XML_TAG_CIB,TRUE);
		}
#else
		cib = output;
		CRM_DEV_ASSERT(safe_str_eq(crm_element_name(cib), XML_TAG_CIB));
#endif		
		if(as_html_file || web_cgi) {
			print_html_status(cib, as_html_file, web_cgi);
		} else if (simple_status) {
			print_simple_status(cib);
			if (has_warnings) {
				exit(1); 
			}
		} else {
			print_status(cib);
		}
		if(one_shot) {
			exit(LSB_EXIT_OK);
		}
		
			
	} else if(simple_status) {
		fprintf(stderr, "Critical: query failed: %s", cib_error2string(rc));
		exit(2);
	} else if(one_shot) {
		fprintf(stderr, "Query failed: %s", cib_error2string(rc));
		exit(LSB_EXIT_OK);

	} else {
		CRM_DEV_ASSERT(cib_conn->cmds->signoff(cib_conn) == cib_ok);
		crm_err("Query failed: %s", cib_error2string(rc));
		prefix = "Query failed! ";
		
	}
	wait_for_refresh(0, prefix, interval);
}
コード例 #16
0
ファイル: notify.c プロジェクト: brhellman/pacemaker
void
do_cib_notify(int options, const char *op, xmlNode * update,
              enum cib_errors result, xmlNode * result_data, const char *msg_type)
{
    xmlNode *update_msg = NULL;
    const char *id = NULL;

    update_msg = create_xml_node(NULL, "notify");

    if (result_data != NULL) {
        id = crm_element_value(result_data, XML_ATTR_ID);
    }

    crm_xml_add(update_msg, F_TYPE, T_CIB_NOTIFY);
    crm_xml_add(update_msg, F_SUBTYPE, msg_type);
    crm_xml_add(update_msg, F_CIB_OPERATION, op);
    crm_xml_add_int(update_msg, F_CIB_RC, result);

    if (id != NULL) {
        crm_xml_add(update_msg, F_CIB_OBJID, id);
    }

    if (update != NULL) {
        crm_trace("Setting type to update->name: %s", crm_element_name(update));
        crm_xml_add(update_msg, F_CIB_OBJTYPE, crm_element_name(update));

    } else if (result_data != NULL) {
        crm_trace("Setting type to new_obj->name: %s", crm_element_name(result_data));
        crm_xml_add(update_msg, F_CIB_OBJTYPE, crm_element_name(result_data));

    } else {
        crm_trace("Not Setting type");
    }

    attach_cib_generation(update_msg, "cib_generation", the_cib);
    if (update != NULL) {
        add_message_xml(update_msg, F_CIB_UPDATE, update);
    }
    if (result_data != NULL) {
        add_message_xml(update_msg, F_CIB_UPDATE_RESULT, result_data);
    }

    crm_trace("Notifying clients");
    g_hash_table_foreach_remove(client_list, cib_notify_client, update_msg);
    free_xml(update_msg);
    crm_trace("Notify complete");
}
コード例 #17
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);
}
コード例 #18
0
ファイル: acl.c プロジェクト: HideoYamauchi/pacemaker
void
pcmk__apply_acl(xmlNode *xml)
{
    GListPtr aIter = NULL;
    xml_private_t *p = xml->doc->_private;
    xmlXPathObjectPtr xpathObj = NULL;

    if (xml_acl_enabled(xml) == FALSE) {
        crm_trace("Not applying ACLs for %s", p->user);
        return;
    }

    for (aIter = p->acls; aIter != NULL; aIter = aIter->next) {
        int max = 0, lpc = 0;
        xml_acl_t *acl = aIter->data;

        xpathObj = xpath_search(xml, acl->xpath);
        max = numXpathResults(xpathObj);

        for (lpc = 0; lpc < max; lpc++) {
            xmlNode *match = getXpathResult(xpathObj, lpc);
            char *path = xml_get_path(match);

            p = match->_private;
            crm_trace("Applying %x to %s for %s", acl->mode, path, acl->xpath);

#ifdef SUSE_ACL_COMPAT
            if (is_not_set(p->flags, acl->mode)
                && (is_set(p->flags, xpf_acl_read)
                    || is_set(p->flags, xpf_acl_write)
                    || is_set(p->flags, xpf_acl_deny))) {
                crm_config_warn("Configuration element %s is matched by "
                                "multiple ACL rules, only the first applies "
                                "('%s' wins over '%s')",
                                path, __xml_acl_to_text(p->flags),
                                __xml_acl_to_text(acl->mode));
                free(path);
                continue;
            }
#endif
            p->flags |= acl->mode;
            free(path);
        }
        crm_trace("Now enforcing ACL: %s (%d matches)", acl->xpath, max);
        freeXpathObject(xpathObj);
    }

    p = xml->_private;
    if (is_not_set(p->flags, xpf_acl_read)
        && is_not_set(p->flags, xpf_acl_write)) {

        p->flags |= xpf_acl_deny;
        p = xml->doc->_private;
        crm_info("Enforcing default ACL for %s to %s",
                 p->user, crm_element_name(xml));
    }

}
コード例 #19
0
static int
delete_cib_object(xmlNode * parent, xmlNode * delete_spec)
{
    const char *object_name = NULL;
    const char *object_id = NULL;
    xmlNode *equiv_node = NULL;
    int result = pcmk_ok;

    if (delete_spec != NULL) {
        object_name = crm_element_name(delete_spec);
    }
    object_id = crm_element_value(delete_spec, XML_ATTR_ID);

    crm_trace("Processing: <%s id=%s>", crm_str(object_name), crm_str(object_id));

    if (delete_spec == NULL) {
        result = -EINVAL;

    } else if (parent == NULL) {
        result = -EINVAL;

    } else if (object_id == NULL) {
        /*  placeholder object */
        equiv_node = find_xml_node(parent, object_name, FALSE);

    } else {
        equiv_node = find_entity(parent, object_name, object_id);
    }

    if (result != pcmk_ok) {
        ;                       /* nothing */

    } else if (equiv_node == NULL) {
        result = pcmk_ok;

    } else if (xml_has_children(delete_spec) == FALSE) {
        /*  only leaves are deleted */
        crm_debug("Removing leaf: <%s id=%s>", crm_str(object_name), crm_str(object_id));
        free_xml(equiv_node);
        equiv_node = NULL;

    } else {
        xmlNode *child = NULL;

        for (child = __xml_first_child(delete_spec); child != NULL; child = __xml_next(child)) {
            int tmp_result = delete_cib_object(equiv_node, child);

            /*  only the first error is likely to be interesting */
            if (tmp_result != pcmk_ok && result == pcmk_ok) {
                result = tmp_result;
            }
        }
    }

    return result;
}
コード例 #20
0
ファイル: acl.c プロジェクト: HideoYamauchi/pacemaker
static GList *
__xml_acl_parse_entry(xmlNode *acl_top, xmlNode *acl_entry, GList *acls)
{
    xmlNode *child = NULL;

    for (child = __xml_first_child(acl_entry); child;
         child = __xml_next(child)) {
        const char *tag = crm_element_name(child);
        const char *kind = crm_element_value(child, XML_ACL_ATTR_KIND);

        if (strcmp(XML_ACL_TAG_PERMISSION, tag) == 0){
            tag = kind;
        }

        crm_trace("Processing %s %p", tag, child);
        if (tag == NULL) {
            CRM_ASSERT(tag != NULL);

        } else if (strcmp(XML_ACL_TAG_ROLE_REF, tag) == 0
                   || strcmp(XML_ACL_TAG_ROLE_REFv1, tag) == 0) {
            const char *ref_role = crm_element_value(child, XML_ATTR_ID);

            if (ref_role) {
                xmlNode *role = NULL;

                for (role = __xml_first_child(acl_top); role;
                     role = __xml_next(role)) {
                    if (!strcmp(XML_ACL_TAG_ROLE, (const char *) role->name)) {
                        const char *role_id = crm_element_value(role,
                                                                XML_ATTR_ID);

                        if (role_id && strcmp(ref_role, role_id) == 0) {
                            crm_debug("Unpacking referenced role: %s", role_id);
                            acls = __xml_acl_parse_entry(acl_top, role, acls);
                            break;
                        }
                    }
                }
            }

        } else if (strcmp(XML_ACL_TAG_READ, tag) == 0) {
            acls = __xml_acl_create(child, acls, xpf_acl_read);

        } else if (strcmp(XML_ACL_TAG_WRITE, tag) == 0) {
            acls = __xml_acl_create(child, acls, xpf_acl_write);

        } else if (strcmp(XML_ACL_TAG_DENY, tag) == 0) {
            acls = __xml_acl_create(child, acls, xpf_acl_deny);

        } else {
            crm_warn("Unknown ACL entry: %s/%s", tag, kind);
        }
    }

    return acls;
}
コード例 #21
0
ファイル: common.c プロジェクト: JamesGuthrie/pacemaker
static int
cib_cleanup_query(int options, xmlNode ** data, xmlNode ** output)
{
    CRM_LOG_ASSERT(*data == NULL);
    if ((options & cib_no_children)
        || safe_str_eq(crm_element_name(*output), "xpath-query")) {
        free_xml(*output);
    }
    return pcmk_ok;
}
コード例 #22
0
ファイル: te_events.c プロジェクト: HyunKwangYong/pacemaker
static void
process_remote_node_action(crm_action_t *action, xmlNode *event)
{
    xmlNode *child = NULL;

    /* The whole point of this function is to detect when a remote-node
     * is integrated into the cluster, and abort the transition if that remote-node
     * was fenced earlier in the transition. This allows a new transition to be
     * generated so resources can be placed on the new node.
     */

    if (crm_remote_peer_cache_size() == 0) {
        return;
    } else if (action->type != action_type_rsc) {
        return;
    } else if (action->failed || action->confirmed == FALSE) {
        return;
    } else if (safe_str_neq(crm_element_value(action->xml, XML_LRM_ATTR_TASK), "start")) {
        return;
    }

    for (child = __xml_first_child(action->xml); child != NULL; child = __xml_next(child)) {
        const char *provider;
        const char *type;
        const char *rsc;
        crm_node_t *remote_peer;

        if (safe_str_neq(crm_element_name(child), XML_CIB_TAG_RESOURCE)) {
            continue;
        }

        provider = crm_element_value(child, XML_AGENT_ATTR_PROVIDER);
        type = crm_element_value(child, XML_ATTR_TYPE);
        rsc = ID(child);

        if (safe_str_neq(provider, "pacemaker") || safe_str_neq(type, "remote") || rsc == NULL) {
            break;
        }

        remote_peer = crm_get_peer_full(0, rsc, CRM_GET_PEER_REMOTE);
        if (remote_peer == NULL) {
            break;
        }

        /* A remote node will be placed in the "lost" state after
         * it has been successfully fenced.  After successfully connecting
         * to a remote-node after being fenced, we need to abort the transition
         * so resources can be placed on the newly integrated remote-node */
        if (safe_str_eq(remote_peer->state, CRM_NODE_LOST)) {
            abort_transition(INFINITY, tg_restart, "Remote-node re-discovered.", event);
        }

        return;
    }
}
コード例 #23
0
ファイル: rules.c プロジェクト: aspiers/pacemaker
static void
populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlNode * top)
{
    const char *name = NULL;
    const char *value = NULL;
    const char *old_value = NULL;
    xmlNode *list = nvpair_list;
    xmlNode *an_attr = NULL;

    name = crm_element_name(list->children);
    if (safe_str_eq(XML_TAG_ATTRS, name)) {
        list = list->children;
    }

    for (an_attr = __xml_first_child(list); an_attr != NULL; an_attr = __xml_next_element(an_attr)) {
        if (crm_str_eq((const char *)an_attr->name, XML_CIB_TAG_NVPAIR, TRUE)) {
            xmlNode *ref_nvpair = expand_idref(an_attr, top);

            name = crm_element_value(an_attr, XML_NVPAIR_ATTR_NAME);
            if (name == NULL) {
                name = crm_element_value(ref_nvpair, XML_NVPAIR_ATTR_NAME);
            }

            crm_trace("Setting attribute: %s", name);
            value = crm_element_value(an_attr, XML_NVPAIR_ATTR_VALUE);
            if (value == NULL) {
                value = crm_element_value(ref_nvpair, XML_NVPAIR_ATTR_VALUE);
            }

            if (name == NULL || value == NULL) {
                continue;

            }

            old_value = g_hash_table_lookup(hash, name);

            if (safe_str_eq(value, "#default")) {
                if (old_value) {
                    crm_trace("Removing value for %s (%s)", name, value);
                    g_hash_table_remove(hash, name);
                }
                continue;

            } else if (old_value == NULL) {
                g_hash_table_insert(hash, strdup(name), strdup(value));

            } else if (overwrite) {
                crm_debug("Overwriting value of %s: %s -> %s", name, old_value, value);
                g_hash_table_replace(hash, strdup(name), strdup(value));
            }
        }
    }
}
コード例 #24
0
int
cib_process_replace_svr(const char *op, int options, const char *section, xmlNode * req,
                        xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
                        xmlNode ** answer)
{
    const char *tag = crm_element_name(input);
    int rc =
        cib_process_replace(op, options, section, req, input, existing_cib, result_cib, answer);
    if (rc == pcmk_ok && safe_str_eq(tag, XML_TAG_CIB)) {
        sync_in_progress = 0;
    }
    return rc;
}
コード例 #25
0
ファイル: cib_attrs.c プロジェクト: bcavanagh/pacemaker
int
query_node_uuid(cib_t * the_cib, const char *uname, char **uuid)
{
    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_debug(xml_obj, "Result section");

    rc = -ENXIO;
    *uuid = 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 = crm_element_value(a_child, XML_ATTR_UNAME);
            if (safe_str_eq(uname, child_name)) {
                child_name = ID(a_child);
                if (child_name != NULL) {
                    *uuid = strdup(child_name);
                    rc = pcmk_ok;
                }
                break;
            }
        }
    }

    if (rc != pcmk_ok) {
        crm_debug("Could not map name=%s to a UUID: %s\n", uname, pcmk_strerror(rc));
    } else {
        crm_info("Mapped %s to %s", uname, *uuid);
    }

    free_xml(fragment);
    return rc;
}
コード例 #26
0
void
cli_resource_print_cts(resource_t * rsc)
{
    GListPtr lpc = NULL;
    const char *host = NULL;
    bool needs_quorum = TRUE;
    const char *rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE);
    const char *rprov = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
    const char *rclass = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);

    if (safe_str_eq(rclass, PCMK_RESOURCE_CLASS_STONITH)) {
        xmlNode *op = NULL;

        needs_quorum = FALSE;

        for (op = __xml_first_child(rsc->ops_xml); op != NULL; op = __xml_next(op)) {
            if (crm_str_eq((const char *)op->name, "op", TRUE)) {
                const char *name = crm_element_value(op, "name");

                if (safe_str_neq(name, CRMD_ACTION_START)) {
                    const char *value = crm_element_value(op, "requires");

                    if (safe_str_eq(value, "nothing")) {
                        needs_quorum = FALSE;
                    }
                    break;
                }
            }
        }
    }

    if (rsc->running_on != NULL && g_list_length(rsc->running_on) == 1) {
        node_t *tmp = rsc->running_on->data;

        host = tmp->details->uname;
    }

    printf("Resource: %s %s %s %s %s %s %s %s %d %lld 0x%.16llx\n",
           crm_element_name(rsc->xml), rsc->id,
           rsc->clone_name ? rsc->clone_name : rsc->id, rsc->parent ? rsc->parent->id : "NA",
           rprov ? rprov : "NA", rclass, rtype, host ? host : "NA", needs_quorum, rsc->flags,
           rsc->flags);

    for (lpc = rsc->children; lpc != NULL; lpc = lpc->next) {
        resource_t *child = (resource_t *) lpc->data;

        cli_resource_print_cts(child);
    }
}
コード例 #27
0
void
cli_resource_print_cts_constraints(pe_working_set_t * data_set)
{
    xmlNode *xml_obj = NULL;
    xmlNode *lifetime = NULL;
    xmlNode *cib_constraints = get_object_root(XML_CIB_TAG_CONSTRAINTS, data_set->input);

    for (xml_obj = __xml_first_child(cib_constraints); xml_obj != NULL;
         xml_obj = __xml_next(xml_obj)) {
        const char *id = crm_element_value(xml_obj, XML_ATTR_ID);

        if (id == NULL) {
            continue;
        }

        lifetime = first_named_child(xml_obj, "lifetime");

        if (test_ruleset(lifetime, NULL, data_set->now) == FALSE) {
            continue;
        }

        if (safe_str_eq(XML_CONS_TAG_RSC_DEPEND, crm_element_name(xml_obj))) {
            printf("Constraint %s %s %s %s %s %s %s\n",
                   crm_element_name(xml_obj),
                   cons_string(crm_element_value(xml_obj, XML_ATTR_ID)),
                   cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE)),
                   cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET)),
                   cons_string(crm_element_value(xml_obj, XML_RULE_ATTR_SCORE)),
                   cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_SOURCE_ROLE)),
                   cons_string(crm_element_value(xml_obj, XML_COLOC_ATTR_TARGET_ROLE)));

        } else if (safe_str_eq(XML_CONS_TAG_RSC_LOCATION, crm_element_name(xml_obj))) {
            /* unpack_location(xml_obj, data_set); */
        }
    }
}
コード例 #28
0
int
cib_process_delete_absolute(const char *op, int options, const char *section, xmlNode * req,
                            xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib,
                            xmlNode ** answer)
{
    xmlNode *failed = NULL;
    int result = pcmk_ok;
    xmlNode *update_section = NULL;

    crm_trace("Processing \"%s\" event for section=%s", op, crm_str(section));
    if (safe_str_eq(XML_CIB_TAG_SECTION_ALL, section)) {
        section = NULL;

    } else if (safe_str_eq(XML_TAG_CIB, section)) {
        section = NULL;

    } else if (safe_str_eq(crm_element_name(input), XML_TAG_CIB)) {
        section = NULL;
    }

    CRM_CHECK(strcasecmp(CIB_OP_DELETE, op) == 0, return -EINVAL);

    if (input == NULL) {
        crm_err("Cannot perform modification with no data");
        return -EINVAL;
    }

    failed = create_xml_node(NULL, XML_TAG_FAILED);

    update_section = get_object_root(section, *result_cib);
    result = delete_cib_object(update_section, input);
    update_results(failed, input, op, result);

    if (xml_has_children(failed)) {
        CRM_CHECK(result != pcmk_ok, result = -EINVAL);
    }

    if (result != pcmk_ok) {
        crm_log_xml_err(failed, "CIB Update failures");
        *answer = failed;

    } else {
        free_xml(failed);
    }

    return result;
}
コード例 #29
0
ファイル: cib_attrs.c プロジェクト: sashatoday/pacemaker
static int
get_cluster_node_uuid(cib_t * the_cib, const char *uname, char **uuid)
{
    int rc = pcmk_ok;
    xmlNode *a_child = NULL;
    xmlNode *xml_obj = NULL;
    xmlNode *fragment = NULL;
    const char *child_name = 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_debug(xml_obj, "Result section");

    rc = -ENXIO;
    *uuid = 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)) {
            const char *node_type = crm_element_value(a_child, XML_ATTR_TYPE);
            /* Only if it's a cluster node */
            if (safe_str_eq(node_type, "remote")) {
                continue;
            }

            child_name = crm_element_value(a_child, XML_ATTR_UNAME);
            if (safe_str_eq(uname, child_name)) {
                child_name = ID(a_child);
                if (child_name != NULL) {
                    *uuid = strdup(child_name);
                    rc = pcmk_ok;
                }
                break;
            }
        }
    }

    free_xml(fragment);
    return rc;
}
コード例 #30
0
ファイル: based_remote.c プロジェクト: ClusterLabs/pacemaker
static gboolean
cib_remote_auth(xmlNode * login)
{
    const char *user = NULL;
    const char *pass = NULL;
    const char *tmp = NULL;

    crm_log_xml_info(login, "Login: "******"cib_command")) {
        crm_err("Wrong tag: %s", tmp);
        return FALSE;
    }

    tmp = crm_element_value(login, "op");
    if (safe_str_neq(tmp, "authenticate")) {
        crm_err("Wrong operation: %s", tmp);
        return FALSE;
    }

    user = crm_element_value(login, "user");
    pass = crm_element_value(login, "password");

    if (!user || !pass) {
        crm_err("missing auth credentials");
        return FALSE;
    }

    /* Non-root daemons can only validate the password of the
     * user they're running as
     */
    if (check_group_membership(user, CRM_DAEMON_GROUP) == FALSE) {
        crm_err("User is not a member of the required group");
        return FALSE;

    } else if (authenticate_user(user, pass) == FALSE) {
        crm_err("PAM auth failed");
        return FALSE;
    }

    return TRUE;
}