17 #include <sys/param.h> 18 #include <sys/types.h> 36 #define XPATH_NODE_CONFIG "//" XML_CIB_TAG_NODE "[@" XML_ATTR_UNAME "='%s']" 37 #define XPATH_NODE_STATE "//" XML_CIB_TAG_STATE "[@" XML_ATTR_UNAME "='%s']" 38 #define XPATH_NODE_STATE_BY_ID "//" XML_CIB_TAG_STATE "[@" XML_ATTR_ID "='%s']" 39 #define XPATH_RSC_HISTORY XPATH_NODE_STATE \ 40 "//" XML_LRM_TAG_RESOURCE "[@" XML_ATTR_ID "='%s']" 54 const char *
name,
const char *value)
56 xmlNode *attrs = NULL;
57 xmlNode *instance_attrs = NULL;
58 const char *node_uuid =
ID(cib_node);
60 out->
message(out,
"inject-attr",
name, value, cib_node);
69 if (instance_attrs == NULL) {
91 const char *resource,
const char *task,
92 guint interval_ms,
int rc)
97 }
else if ((rc == 7) && (interval_ms == 0)) {
102 char *now = pcmk__ttoa(time(NULL));
104 name = pcmk__failcount_name(resource, task, interval_ms);
105 inject_transient_attr(out, cib_node,
name,
"value++");
108 name = pcmk__lastfailure_name(resource, task, interval_ms);
109 inject_transient_attr(out, cib_node,
name, now);
124 create_node_entry(
cib_t *cib_conn,
const char *node)
129 rc = cib_conn->
cmds->
query(cib_conn, xpath, NULL,
162 create_op(
const xmlNode *cib_resource,
const char *task, guint interval_ms,
171 op->
t_run = (
unsigned int) time(NULL);
176 for (xop = pcmk__xe_first_child(cib_resource); xop != NULL;
177 xop = pcmk__xe_next(xop)) {
226 xmlNode *cib_object = NULL;
228 bool duplicate =
false;
229 char *found_uuid = NULL;
232 create_node_entry(cib_conn, node);
235 rc = cib_conn->
cmds->
query(cib_conn, xpath, &cib_object,
238 if ((cib_object != NULL) && (
ID(cib_object) == NULL)) {
239 crm_err(
"Detected multiple node_state entries for xpath=%s, bailing",
249 found_uuid = strdup(uuid);
257 rc = cib_conn->
cmds->
query(cib_conn, xpath_by_uuid, &cib_object,
260 if ((cib_object != NULL) && (
ID(cib_object) == NULL)) {
261 crm_err(
"Can't inject node state for %s because multiple " 262 "state entries found for ID %s", node, found_uuid);
267 }
else if (cib_object != NULL) {
287 rc = cib_conn->
cmds->
query(cib_conn, xpath, &cib_object,
289 crm_trace(
"Injecting node state for %s (rc=%d)", node, rc);
351 find_resource_xml(xmlNode *cib_node,
const char *resource)
379 const char *resource,
const char *lrm_name,
380 const char *rclass,
const char *rtype,
381 const char *rprovider)
384 xmlNode *container = NULL;
385 xmlNode *cib_resource = NULL;
387 cib_resource = find_resource_xml(cib_node, resource);
388 if (cib_resource != NULL) {
396 if (strcmp(resource, lrm_name) != 0) {
397 cib_resource = find_resource_xml(cib_node, lrm_name);
398 if (cib_resource != NULL) {
403 if ((rclass == NULL) || (rtype == NULL)) {
406 "Resource %s not found in the status section of %s " 407 "(supply class and type to continue)",
408 resource,
ID(cib_node));
418 out->
err(out,
"Invalid class for %s: %s", resource, rclass);
422 && (rprovider == NULL)) {
424 out->
err(out,
"Please specify the provider for resource %s", resource);
428 crm_info(
"Injecting new resource %s into node state '%s'",
429 lrm_name,
ID(cib_node));
433 const char *node_uuid =
ID(cib_node);
440 if (container == NULL) {
458 xmlNode **ticket_state_xml)
461 xmlNode *xml_search = NULL;
463 GString *xpath = g_string_sized_new(256);
466 *ticket_state_xml = NULL;
468 g_string_append(xpath,
477 rc = the_cib->
cmds->
query(the_cib, (
const char *) xpath->str, &xml_search,
479 g_string_free(xpath, TRUE);
486 if ((xml_search->children != NULL) && (ticket_id != NULL)) {
487 out->
err(out,
"Multiple ticket_states match ticket_id=%s", ticket_id);
489 *ticket_state_xml = xml_search;
508 const char *attr_name,
bool attr_value,
cib_t *cib)
511 xmlNode *xml_top = NULL;
512 xmlNode *ticket_state_xml = NULL;
515 rc = find_ticket_state(out, cib, ticket_id, &ticket_state_xml);
519 crm_debug(
"Injecting attribute into existing ticket state %s",
521 xml_top = ticket_state_xml;
523 }
else if (rc == ENXIO) {
524 xmlNode *xml_obj = NULL;
563 guint interval_ms = 0;
568 char *resource = NULL;
570 const char *rtype = NULL;
571 const char *rclass = NULL;
572 const char *rprovider = NULL;
574 xmlNode *cib_op = NULL;
575 xmlNode *cib_node = NULL;
576 xmlNode *cib_resource = NULL;
580 out->
message(out,
"inject-spec", spec);
582 key = calloc(1, strlen(spec) + 1);
583 node = calloc(1, strlen(spec) + 1);
584 rc = sscanf(spec,
"%[^@]@%[^=]=%d", key, node, &outcome);
586 out->
err(out,
"Invalid operation spec: %s. Only found %d fields",
595 out->
err(out,
"Invalid resource name: %s", resource);
610 rclass, rtype, rprovider);
613 op = create_op(cib_resource, task, interval_ms, outcome);
643 const GList *iter = NULL;
644 xmlNode *cib_node = NULL;
647 out->
message(out,
"inject-modify-config", injections->
quorum,
649 if (injections->
quorum != NULL) {
667 for (iter = injections->
node_up; iter != NULL; iter = iter->next) {
668 const char *node = (
const char *) iter->data;
670 out->
message(out,
"inject-modify-node",
"Online", node);
681 for (iter = injections->
node_down; iter != NULL; iter = iter->next) {
682 const char *node = (
const char *) iter->data;
685 out->
message(out,
"inject-modify-node",
"Offline", node);
708 for (iter = injections->
node_fail; iter != NULL; iter = iter->next) {
709 const char *node = (
const char *) iter->data;
711 out->
message(out,
"inject-modify-node",
"Failing", node);
723 for (iter = injections->
ticket_grant; iter != NULL; iter = iter->next) {
724 const char *ticket_id = (
const char *) iter->data;
726 out->
message(out,
"inject-modify-ticket",
"Granting", ticket_id);
728 rc = set_ticket_state_attr(out, ticket_id,
"granted",
true, cib);
732 for (iter = injections->
ticket_revoke; iter != NULL; iter = iter->next) {
733 const char *ticket_id = (
const char *) iter->data;
735 out->
message(out,
"inject-modify-ticket",
"Revoking", ticket_id);
737 rc = set_ticket_state_attr(out, ticket_id,
"granted",
false, cib);
741 for (iter = injections->
ticket_standby; iter != NULL; iter = iter->next) {
742 const char *ticket_id = (
const char *) iter->data;
744 out->
message(out,
"inject-modify-ticket",
"Standby", ticket_id);
746 rc = set_ticket_state_attr(out, ticket_id,
"standby",
true, cib);
750 for (iter = injections->
ticket_activate; iter != NULL; iter = iter->next) {
751 const char *ticket_id = (
const char *) iter->data;
753 out->
message(out,
"inject-modify-ticket",
"Activating", ticket_id);
755 rc = set_ticket_state_attr(out, ticket_id,
"standby",
false, cib);
759 for (iter = injections->
op_inject; iter != NULL; iter = iter->next) {
760 inject_action(out, (
const char *) iter->data, cib,
scheduler);
771 if (injections == NULL) {
775 g_list_free_full(injections->
node_up, g_free);
776 g_list_free_full(injections->
node_down, g_free);
777 g_list_free_full(injections->
node_fail, g_free);
778 g_list_free_full(injections->
op_fail, g_free);
779 g_list_free_full(injections->
op_inject, g_free);
void(* end_list)(pcmk__output_t *out)
#define PCMK_RESOURCE_CLASS_SERVICE
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
int(* message)(pcmk__output_t *out, const char *message_id,...)
xmlNode * first_named_child(const xmlNode *parent, const char *name)
xmlNode * xml
Resource configuration (possibly expanded from template)
bool(* is_quiet)(pcmk__output_t *out)
#define XML_TAG_TRANSIENT_NODEATTRS
xmlNode * pcmk__inject_resource_history(pcmk__output_t *out, xmlNode *cib_node, const char *resource, const char *lrm_name, const char *rclass, const char *rtype, const char *rprovider)
#define XML_LRM_TAG_RESOURCE
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
int query_node_uuid(cib_t *the_cib, const char *uname, char **uuid, int *is_remote_node)
void pcmk__xe_set_bool_attr(xmlNodePtr node, const char *name, bool value)
#define PCMK_RESOURCE_CLASS_OCF
void pcmk__inject_scheduler_input(pcmk_scheduler_t *scheduler, cib_t *cib, const pcmk_injections_t *injections)
#define PCMK_RESOURCE_CLASS_SYSTEMD
xmlNode * pcmk__inject_action_result(xmlNode *cib_resource, lrmd_event_data_t *op, int target_rc)
#define XPATH_NODE_CONFIG
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
#define XML_CIB_TAG_NODES
Implementation of pcmk_scheduler_t.
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
GList * resources
Resources in cluster.
#define XML_TAG_ATTR_SETS
void pcmk_free_injections(pcmk_injections_t *injections)
Free a :pcmk_injections_t structure.
#define PCMK__XA_EXPECTED
#define CRMD_JOINSTATE_DOWN
pcmk_resource_t * pe_find_resource(GList *rsc_list, const char *id_rh)
#define PCMK_RESOURCE_CLASS_UPSTART
cib_api_operations_t * cmds
Implementation of pcmk_resource_t.
#define crm_debug(fmt, args...)
xmlNode * pcmk__create_history_xml(xmlNode *parent, lrmd_event_data_t *event, const char *caller_version, int target_rc, const char *node, const char *origin)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define XML_CIB_TAG_STATE
#define crm_trace(fmt, args...)
#define CRMD_JOINSTATE_MEMBER
#define PCMK_RESOURCE_CLASS_STONITH
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
void * priv
For Pacemaker use only.
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
int(* modify)(cib_t *cib, const char *section, xmlNode *data, int call_options)
int(*) int(*) void(* err)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
#define crm_log_xml_debug(xml, text)
int(* create)(cib_t *cib, const char *section, xmlNode *data, int call_options)
#define XML_AGENT_ATTR_PROVIDER
#define XML_ATTR_HAVE_QUORUM
xmlNode * create_xml_node(xmlNode *parent, const char *name)
#define crm_log_xml_warn(xml, text)
Action completed, result is known.
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
void pcmk__inject_failcount(pcmk__output_t *out, xmlNode *cib_node, const char *resource, const char *task, guint interval_ms, int rc)
int pcmk_legacy2rc(int legacy_rc)
void free_xml(xmlNode *child)
bool pcmk__simulate_node_config
void pcmk__xe_set_props(xmlNodePtr node,...) G_GNUC_NULL_TERMINATED
Cluster status and scheduling.
#define XML_LRM_TAG_RESOURCES
#define crm_err(fmt, args...)
pcmk_scheduler_t * scheduler
#define XML_CIB_TAG_TICKET_STATE
void lrmd__set_result(lrmd_event_data_t *event, enum ocf_exitcode rc, int op_status, const char *exit_reason)
#define XML_CIB_TAG_CRMCONFIG
Synthetic cluster events that can be injected into the cluster for running simulations.
#define PCMK_RESOURCE_CLASS_LSB
#define XML_ATTR_HAVE_WATCHDOG
void lrmd_free_event(lrmd_event_data_t *event)
Free an executor event.
This structure contains everything that makes up a single output formatter.
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
#define XML_LRM_ATTR_CALLID
int cib__update_node_attr(pcmk__output_t *out, cib_t *cib, int call_options, const char *section, const char *node_uuid, const char *set_type, const char *set_name, const char *attr_id, const char *attr_name, const char *attr_value, const char *user_name, const char *node_type)
#define XPATH_RSC_HISTORY
xmlNode * pcmk__inject_node_state_change(cib_t *cib_conn, const char *node, bool up)
#define XML_CIB_TAG_STATUS
uint32_t pcmk_get_ra_caps(const char *standard)
Get capabilities of a resource agent standard.
int(* remove)(cib_t *cib, const char *section, xmlNode *data, int call_options)
xmlNode * crm_create_nvpair_xml(xmlNode *parent, const char *id, const char *name, const char *value)
Create an XML name/value pair.
lrmd_event_data_t * lrmd_new_event(const char *rsc_id, const char *task, guint interval_ms)
Create a new lrmd_event_data_t object.
Resource agent executor events.
#define XPATH_NODE_STATE_BY_ID
#define XML_CIB_TAG_TICKETS
#define crm_info(fmt, args...)
xmlNode * pcmk__inject_node(cib_t *cib_conn, const char *node, const char *uuid)
#define XML_AGENT_ATTR_CLASS