" adding all nodes", xmlGetProp(rule, XML_ATTR_ID));
" adding all nodes", crm_element_value(rule, XML_ATTR_ID));
unpack_rsc_location(	xmlNodePtr xml_obj,	GListPtr rsc_list, GListPtr node_list, GListPtr *placement_constraints){/*  <constraints>     <rsc_location rsc="Filesystem-whatever-1" timestamp="..." lifetime="...">     	<rule score="+50.0" result="can"><!ATTLIST node_expression	  id         CDATA #REQUIRED	  attribute  CDATA #REQUIRED	  operation  (lt|gt|lte|gte|eq|ne|exists|not_exists)	  value      CDATA #IMPLIED	  type	     (integer|string|version)    'string'>	</rule>     	<rule score="+500.0">       		<node_expression match="cpu:50GHz" />	</rule>     	<rule result="cannot">       		<node_expression not_match="san"/>	</rule>...   Translation:   Further translation:       */	gboolean were_rules = FALSE;	const char *id_lh   = xmlGetProp(xml_obj, "rsc");	const char *id      = xmlGetProp(xml_obj, XML_ATTR_ID);	resource_t *rsc_lh = pe_find_resource(rsc_list, id_lh);	if(rsc_lh == NULL) {		crm_err("No resource (con=%s, rsc=%s)",		       id, id_lh);		return FALSE;	}				xml_child_iter(		xml_obj, rule, XML_TAG_RULE,		gboolean first_expr = TRUE;		gboolean can_run    = FALSE;		gboolean do_and     = TRUE;		gboolean rule_has_expressions;		const char *rule_id = xmlGetProp(rule, XML_ATTR_ID);		const char *score   = xmlGetProp(rule, XML_RULE_ATTR_SCORE);		const char *result  = xmlGetProp(rule, XML_RULE_ATTR_RESULT);		const char *boolean = xmlGetProp(rule, XML_RULE_ATTR_BOOLEAN_OP);		GListPtr match_L    = NULL;		GListPtr old_list   = NULL;		float score_f       = atof(score?score:"0.0");		rsc_to_node_t *new_con = NULL;		were_rules = TRUE;				if(safe_str_eq(boolean, "or")) {			do_and = FALSE;		}		if(result == NULL || (safe_str_eq(result, "can"))) {			can_run = TRUE;		}		new_con = rsc2node_new(rule_id, rsc_lh, score_f,				       can_run, NULL, placement_constraints);		if(new_con == NULL) {			continue;		}				rule_has_expressions = FALSE;		xml_child_iter(			rule, expr, XML_TAG_EXPRESSION,			const char *attr  = xmlGetProp(				expr, XML_EXPR_ATTR_ATTRIBUTE);			const char *op    = xmlGetProp(				expr, XML_EXPR_ATTR_OPERATION);			const char *value = xmlGetProp(				expr, XML_EXPR_ATTR_VALUE);			const char *type  = xmlGetProp(				expr, XML_EXPR_ATTR_TYPE);						rule_has_expressions = TRUE;			crm_trace("processing expression: %s",				  xmlGetProp(expr, XML_ATTR_ID));			match_L = match_attrs(				attr, op, value, type, node_list);						if(first_expr) {				new_con->node_list_rh =	node_list_dup(					match_L, FALSE);				first_expr = FALSE;				continue;			}			old_list = new_con->node_list_rh;			if(do_and) {				crm_trace("do_and");								new_con->node_list_rh = node_list_and(					old_list, match_L, FALSE);			} else {				crm_trace("do_or");								new_con->node_list_rh = node_list_or(					old_list, match_L, FALSE);			}			pe_free_shallow_adv(match_L,  FALSE);			pe_free_shallow_adv(old_list, TRUE);			);		if(rule_has_expressions == FALSE) {			/* feels like a hack */			crm_debug("Rule %s had no expressions,"				  " adding all nodes", xmlGetProp(rule, XML_ATTR_ID));						new_con->node_list_rh = node_list_dup(node_list,FALSE);		}				if(new_con->node_list_rh == NULL) {			crm_warn("No matching nodes for constraint/rule %s/%s",				 id, xmlGetProp(rule, XML_ATTR_ID));		}				crm_debug_action(print_rsc_to_node("Added", new_con, FALSE));		);	if(were_rules == FALSE) {		crm_err("no rules for constraint %s", id);	}		return TRUE;}