17 #include <sys/param.h>    18 #include <sys/types.h>    32 static cib_t *fake_cib = NULL;
    33 static GList *fake_resource_list = NULL;
    34 static GList *fake_op_fail_list = NULL;
    37 #define STATUS_PATH_MAX 512    39 #define NEW_NODE_TEMPLATE "//"XML_CIB_TAG_NODE"[@uname='%s']"    40 #define NODE_TEMPLATE "//"XML_CIB_TAG_STATE"[@uname='%s']"    41 #define RSC_TEMPLATE "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']"    45 inject_transient_attr(xmlNode * cib_node, 
const char *
name, 
const char *value)
    47     xmlNode *attrs = NULL;
    48     xmlNode *instance_attrs = NULL;
    49     const char *node_uuid = 
ID(cib_node);
    51     out->
message(out, 
"inject-attr", 
name, value, cib_node);
    60     if (instance_attrs == NULL) {
    69 update_failcounts(xmlNode * cib_node, 
const char *resource, 
const char *task,
    70                   guint interval_ms, 
int rc)
    75     } 
else if ((
rc == 7) && (interval_ms == 0)) {
    80         char *now = pcmk__ttoa(time(NULL));
    82         name = pcmk__failcount_name(resource, task, interval_ms);
    83         inject_transient_attr(cib_node, 
name, 
"value++");
    86         name = pcmk__lastfailure_name(resource, task, interval_ms);
    87         inject_transient_attr(cib_node, 
name, now);
    94 create_node_entry(
cib_t * cib_conn, 
const char *node)
   118 create_op(xmlNode *cib_resource, 
const char *task, guint interval_ms,
   127     op->
t_run = (
unsigned int) time(NULL);
   131     for (xop = pcmk__xe_first_child(cib_resource); xop != NULL;
   132          xop = pcmk__xe_next(xop)) {
   155 inject_node_state(
cib_t * cib_conn, 
const char *node, 
const char *uuid)
   158     xmlNode *cib_object = NULL;
   162         create_node_entry(cib_conn, node);
   165     rc = cib_conn->
cmds->
query(cib_conn, xpath, &cib_object,
   168     if (cib_object && 
ID(cib_object) == NULL) {
   169         crm_err(
"Detected multiple node_state entries for xpath=%s, bailing", xpath);
   177         char *found_uuid = NULL;
   182             found_uuid = strdup(uuid);
   193         rc = cib_conn->
cmds->
query(cib_conn, xpath, &cib_object,
   195         crm_trace(
"injecting node state for %s. rc is %d", node, 
rc);
   204 modify_node(
cib_t * cib_conn, 
char *node, gboolean up)
   206     xmlNode *cib_node = inject_node_state(cib_conn, node, NULL);
   226 find_resource_xml(xmlNode * cib_node, 
const char *resource)
   228     xmlNode *match = NULL;
   239 inject_resource(xmlNode * cib_node, 
const char *resource, 
const char *lrm_name,
   240                 const char *rclass, 
const char *rtype, 
const char *rprovider)
   243     xmlNode *container = NULL;
   244     xmlNode *cib_resource = NULL;
   247     cib_resource = find_resource_xml(cib_node, resource);
   248     if (cib_resource != NULL) {
   256     if (strcmp(resource, lrm_name)) {
   257         cib_resource = find_resource_xml(cib_node, lrm_name);
   258         if (cib_resource != NULL) {
   265     if (rclass == NULL || rtype == NULL) {
   266         out->
err(out, 
"Resource %s not found in the status section of %s."   267                  "  Please supply the class and type to continue", resource, 
ID(cib_node));
   273         out->
err(out, 
"Invalid class for %s: %s", resource, rclass);
   277                 && (rprovider == NULL)) {
   278         out->
err(out, 
"Please specify the provider for resource %s", resource);
   282     xpath = (
char *)xmlGetNodePath(cib_node);
   283     crm_info(
"Injecting new resource %s into %s '%s'", lrm_name, xpath, 
ID(cib_node));
   288         const char *node_uuid = 
ID(cib_node);
   295     if (container == NULL) {
   311 #define XPATH_MAX 1024   314 find_ticket_state(
cib_t * the_cib, 
const char *ticket_id, xmlNode ** ticket_state_xml)
   318     xmlNode *xml_search = NULL;
   320     char *xpath_string = NULL;
   323     *ticket_state_xml = NULL;
   326     offset += snprintf(xpath_string + offset, 
XPATH_MAX - offset, 
"%s", 
"/cib/status/tickets");
   329         offset += snprintf(xpath_string + offset, 
XPATH_MAX - offset, 
"/%s[@id=\"%s\"]",
   333     rc = the_cib->
cmds->
query(the_cib, xpath_string, &xml_search,
   343             out->
err(out, 
"Multiple ticket_states match ticket_id=%s", ticket_id);
   345         *ticket_state_xml = xml_search;
   347         *ticket_state_xml = xml_search;
   356 set_ticket_state_attr(
const char *ticket_id, 
const char *attr_name,
   357                       const char *attr_value, 
cib_t * cib, 
int cib_options)
   360     xmlNode *xml_top = NULL;
   361     xmlNode *ticket_state_xml = NULL;
   363     rc = find_ticket_state(cib, ticket_id, &ticket_state_xml);
   365         crm_debug(
"Found a match state for ticket: id=%s", ticket_id);
   366         xml_top = ticket_state_xml;
   368     } 
else if (
rc != -ENXIO) {
   372         xmlNode *xml_obj = NULL;
   380     crm_xml_add(ticket_state_xml, attr_name, attr_value);
   397     xmlNode *cib_op = NULL;
   398     xmlNode *cib_node = NULL;
   399     xmlNode *cib_resource = NULL;
   403     out = data_set->
priv;
   425     for (gIter = injections->
node_up; gIter != NULL; gIter = gIter->next) {
   426         char *node = (
char *)gIter->data;
   428         out->
message(out, 
"inject-modify-node", 
"Online", node);
   430         cib_node = modify_node(cib, node, TRUE);
   439     for (gIter = injections->
node_down; gIter != NULL; gIter = gIter->next) {
   441         char *node = (
char *)gIter->data;
   443         out->
message(out, 
"inject-modify-node", 
"Offline", node);
   445         cib_node = modify_node(cib, node, FALSE);
   464     for (gIter = injections->
node_fail; gIter != NULL; gIter = gIter->next) {
   465         char *node = (
char *)gIter->data;
   467         out->
message(out, 
"inject-modify-node", 
"Failing", node);
   469         cib_node = modify_node(cib, node, TRUE);
   479     for (gIter = injections->
ticket_grant; gIter != NULL; gIter = gIter->next) {
   480         char *ticket_id = (
char *)gIter->data;
   482         out->
message(out, 
"inject-modify-ticket", 
"Granting", ticket_id);
   484         rc = set_ticket_state_attr(ticket_id, 
"granted", 
"true",
   490     for (gIter = injections->
ticket_revoke; gIter != NULL; gIter = gIter->next) {
   491         char *ticket_id = (
char *)gIter->data;
   493         out->
message(out, 
"inject-modify-ticket", 
"Revoking", ticket_id);
   495         rc = set_ticket_state_attr(ticket_id, 
"granted", 
"false",
   501     for (gIter = injections->
ticket_standby; gIter != NULL; gIter = gIter->next) {
   502         char *ticket_id = (
char *)gIter->data;
   504         out->
message(out, 
"inject-modify-ticket", 
"Standby", ticket_id);
   506         rc = set_ticket_state_attr(ticket_id, 
"standby", 
"true",
   512     for (gIter = injections->
ticket_activate; gIter != NULL; gIter = gIter->next) {
   513         char *ticket_id = (
char *)gIter->data;
   515         out->
message(out, 
"inject-modify-ticket", 
"Activating", ticket_id);
   517         rc = set_ticket_state_attr(ticket_id, 
"standby", 
"false",
   523     for (gIter = injections->
op_inject; gIter != NULL; gIter = gIter->next) {
   524         char *spec = (
char *)gIter->data;
   528         guint interval_ms = 0;
   533         char *resource = NULL;
   535         const char *rtype = NULL;
   536         const char *rclass = NULL;
   537         const char *rprovider = NULL;
   541         out->
message(out, 
"inject-spec", spec);
   543         key = calloc(1, strlen(spec) + 1);
   544         node = calloc(1, strlen(spec) + 1);
   545         rc = sscanf(spec, 
"%[^@]@%[^=]=%d", key, node, &outcome);
   547             out->
err(out, 
"Invalid operation spec: %s.  Only found %d fields", spec, 
rc);
   557             out->
err(out, 
"Invalid resource name: %s", resource);
   563             cib_node = inject_node_state(cib, node, NULL);
   566             update_failcounts(cib_node, resource, task, interval_ms, outcome);
   568             cib_resource = inject_resource(cib_node, resource, resource,
   569                                            rclass, rtype, rprovider);
   572             op = create_op(cib_resource, task, interval_ms, outcome);
   575             cib_op = inject_op(cib_resource, op, 0);
   600     out->
message(out, 
"inject-pseudo-action", node, task);
   614     const char *rtype = NULL;
   615     const char *rclass = NULL;
   616     const char *resource = NULL;
   617     const char *rprovider = NULL;
   618     const char *lrm_name = NULL;
   622     xmlNode *cib_node = NULL;
   623     xmlNode *cib_resource = NULL;
   631         crm_info(
"Skipping %s op for %s", operation, node);
   635     if (action_rsc == NULL) {
   637         free(node); free(uuid);
   657         out->
message(out, 
"inject-rsc-action", resource, operation, node, (guint) 0);
   670     cib_node = inject_node_state(fake_cib, node, (router_node? node : uuid));
   673     cib_resource = inject_resource(cib_node, resource, lrm_name,
   674                                    rclass, rtype, rprovider);
   675     if (cib_resource == NULL) {
   676         crm_err(
"invalid resource in transition");
   677         free(node); free(uuid);
   683                                        target_outcome, 
"User-injected result");
   687     for (gIter = fake_op_fail_list; gIter != NULL; gIter = gIter->next) {
   688         char *spec = (
char *)gIter->data;
   690         const char *match_name = NULL;
   695         if (strncasecmp(key, spec, strlen(key)) == 0) {
   696             match_name = resource;
   700         if ((match_name == NULL) && strcmp(resource, lrm_name)) {
   703             if (strncasecmp(key, spec, strlen(key)) == 0) {
   704                 match_name = lrm_name;
   709         if (match_name != NULL) {
   711             rc = sscanf(spec, 
"%*[^=]=%d", (
int *) &op->
rc);
   716                          "Invalid failed operation spec: %s. Result code must be integer",
   722             out->
info(out, 
"Pretending action %d failed with rc=%d", 
action->id, op->
rc);
   723             update_failcounts(cib_node, match_name, op->
op_type,
   729     inject_op(cib_resource, op, target_outcome);
   737     free(node); free(uuid);
   752     out->
message(out, 
"inject-cluster-action", node, task, rsc);
   768         xmlNode *cib_node = modify_node(fake_cib, 
target, FALSE);
   808     out = data_set->
priv;
   811     fake_op_fail_list = op_fail_list;
   814         out->
begin_list(out, NULL, NULL, 
"Executing Cluster Transition");
   821     fake_resource_list = data_set->
resources;
   826     fake_resource_list = NULL;
   829         out->
err(out, 
"Transition failed: %s",
   835         out->
err(out, 
"An invalid transition was produced");
   839         xmlNode *cib_object = NULL;
   844         data_set->
input = cib_object;
 
void(* end_list)(pcmk__output_t *out)
 
void pcmk__update_graph(crm_graph_t *graph, crm_action_t *action)
 
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
 
const char * pcmk__graph_status2text(enum transition_status state)
 
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
 
int pcmk__scan_min_int(const char *text, int *result, int minimum)
 
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)
 
#define PCMK_RESOURCE_CLASS_SYSTEMD
 
bool(* is_quiet)(pcmk__output_t *out)
 
#define XML_TAG_TRANSIENT_NODEATTRS
 
const char * crm_meta_value(GHashTable *hash, const char *field)
 
#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. 
 
void lrmd_free_event(lrmd_event_data_t *event)
Free an executor event. 
 
#define XML_NODE_EXPECTED
 
int query_node_uuid(cib_t *the_cib, const char *uname, char **uuid, int *is_remote_node)
 
pe_resource_t * pe_find_resource(GList *rsc_list, const char *id_rh)
 
#define CRM_LOG_ASSERT(expr)
 
int(* info)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
 
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
 
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
 
#define XML_LRM_ATTR_TASK_KEY
 
#define XML_TAG_ATTR_SETS
 
#define XML_LRM_ATTR_TASK
 
void pe_reset_working_set(pe_working_set_t *data_set)
Reset a working set to default state without freeing it. 
 
#define CRMD_JOINSTATE_DOWN
 
#define PCMK_RESOURCE_CLASS_OCF
 
cib_api_operations_t * cmds
 
#define crm_debug(fmt, args...)
 
lrmd_event_data_t * pcmk__event_from_graph_action(xmlNode *resource, crm_action_t *action, int status, int rc, const char *exit_reason)
 
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute. 
 
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute. 
 
#define XML_CIB_TAG_RESOURCE
 
#define XML_CIB_TAG_STATE
 
gboolean bringing_nodes_online
 
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, int level)
 
#define PCMK_RESOURCE_CLASS_SERVICE
 
#define crm_trace(fmt, args...)
 
#define CRMD_JOINSTATE_MEMBER
 
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)
 
void pcmk__set_graph_functions(crm_graph_functions_t *fns)
 
#define crm_log_xml_debug(xml, text)
 
enum transition_status run_simulation(pe_working_set_t *data_set, cib_t *cib, GList *op_fail_list)
 
int(* create)(cib_t *cib, const char *section, xmlNode *data, int call_options)
 
#define XML_AGENT_ATTR_PROVIDER
 
#define XML_ATTR_HAVE_QUORUM
 
int(*) void(* err)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
 
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__free_graph(crm_graph_t *graph)
 
#define crm__set_graph_action_flags(action, flags_to_set)
 
int(* replace)(cib_t *cib, const char *section, xmlNode *data, int call_options)
 
#define XML_LRM_ATTR_ROUTER_NODE
 
#define NEW_NODE_TEMPLATE
 
void free_xml(xmlNode *child)
 
gboolean xml_has_children(const xmlNode *root)
 
#define XML_LRM_ATTR_TARGET_UUID
 
void pcmk__log_graph(unsigned int log_level, crm_graph_t *graph)
 
#define PCMK_RESOURCE_CLASS_STONITH
 
lrmd_event_data_t * lrmd_new_event(const char *rsc_id, const char *task, guint interval_ms)
 
#define crm_log_xml_err(xml, text)
 
Cluster status and scheduling. 
 
#define PCMK_RESOURCE_CLASS_LSB
 
#define XML_LRM_TAG_RESOURCES
 
#define crm_err(fmt, args...)
 
#define XML_CIB_TAG_TICKET_STATE
 
void modify_configuration(pe_working_set_t *data_set, cib_t *cib, pcmk_injections_t *injections)
 
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_UPSTART
 
#define XML_ATTR_HAVE_WATCHDOG
 
This structure contains everything that makes up a single output formatter. 
 
int update_attr_delegate(cib_t *the_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, gboolean to_console, const char *user_name, const char *node_type)
 
#define XML_LRM_ATTR_CALLID
 
void(* begin_list)(pcmk__output_t *out, const char *singular_noun, const char *plural_noun, const char *format,...) G_GNUC_PRINTF(4
 
enum transition_status pcmk__execute_graph(crm_graph_t *graph)
 
crm_graph_t * pcmk__unpack_graph(xmlNode *xml_graph, const char *reference)
 
#define XML_NODE_JOIN_STATE
 
#define XML_CIB_TAG_STATUS
 
#define XML_NODE_IN_CLUSTER
 
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)
 
#define XML_LRM_ATTR_TARGET
 
xmlNode * crm_create_nvpair_xml(xmlNode *parent, const char *id, const char *name, const char *value)
Create an XML name/value pair. 
 
#define XML_CIB_TAG_TICKETS
 
#define crm_info(fmt, args...)
 
#define XML_ATTR_TE_TARGET_RC
 
#define XML_AGENT_ATTR_CLASS