pacemaker  2.1.6-802a72226b
Scalable High-Availability cluster resource manager
pcmk_injections.c
Go to the documentation of this file.
1 /*
2  * Copyright 2009-2023 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU General Public License version 2
7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <stdlib.h>
15 
16 #include <sys/stat.h>
17 #include <sys/param.h>
18 #include <sys/types.h>
19 #include <dirent.h>
20 
21 #include <crm/crm.h>
22 #include <crm/lrmd.h> // lrmd_event_data_t, lrmd_free_event()
23 #include <crm/cib.h>
24 #include <crm/cib/internal.h>
25 #include <crm/common/util.h>
26 #include <crm/common/iso8601.h>
28 #include <crm/lrmd_internal.h>
29 #include <crm/pengine/status.h>
30 #include <pacemaker-internal.h>
31 
32 #include "libpacemaker_private.h"
33 
35 
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_RSC_HISTORY XPATH_NODE_STATE \
39  "//" XML_LRM_TAG_RESOURCE "[@" XML_ATTR_ID "='%s']"
40 
41 
51 static void
52 inject_transient_attr(pcmk__output_t *out, xmlNode *cib_node,
53  const char *name, const char *value)
54 {
55  xmlNode *attrs = NULL;
56  xmlNode *instance_attrs = NULL;
57  const char *node_uuid = ID(cib_node);
58 
59  out->message(out, "inject-attr", name, value, cib_node);
60 
62  if (attrs == NULL) {
64  crm_xml_add(attrs, XML_ATTR_ID, node_uuid);
65  }
66 
67  instance_attrs = first_named_child(attrs, XML_TAG_ATTR_SETS);
68  if (instance_attrs == NULL) {
69  instance_attrs = create_xml_node(attrs, XML_TAG_ATTR_SETS);
70  crm_xml_add(instance_attrs, XML_ATTR_ID, node_uuid);
71  }
72 
73  crm_create_nvpair_xml(instance_attrs, NULL, name, value);
74 }
75 
88 void
89 pcmk__inject_failcount(pcmk__output_t *out, xmlNode *cib_node,
90  const char *resource, const char *task,
91  guint interval_ms, int rc)
92 {
93  if (rc == 0) {
94  return;
95 
96  } else if ((rc == 7) && (interval_ms == 0)) {
97  return;
98 
99  } else {
100  char *name = NULL;
101  char *now = pcmk__ttoa(time(NULL));
102 
103  name = pcmk__failcount_name(resource, task, interval_ms);
104  inject_transient_attr(out, cib_node, name, "value++");
105  free(name);
106 
107  name = pcmk__lastfailure_name(resource, task, interval_ms);
108  inject_transient_attr(out, cib_node, name, now);
109  free(name);
110 
111  free(now);
112  }
113 }
114 
122 static void
123 create_node_entry(cib_t *cib_conn, const char *node)
124 {
125  int rc = pcmk_ok;
126  char *xpath = crm_strdup_printf(XPATH_NODE_CONFIG, node);
127 
128  rc = cib_conn->cmds->query(cib_conn, xpath, NULL,
130 
131  if (rc == -ENXIO) { // Only add if not already existing
132  xmlNode *cib_object = create_xml_node(NULL, XML_CIB_TAG_NODE);
133 
134  crm_xml_add(cib_object, XML_ATTR_ID, node); // Use node name as ID
135  crm_xml_add(cib_object, XML_ATTR_UNAME, node);
136  cib_conn->cmds->create(cib_conn, XML_CIB_TAG_NODES, cib_object,
138  /* Not bothering with subsequent query to see if it exists,
139  we'll bomb out later in the call to query_node_uuid()... */
140 
141  free_xml(cib_object);
142  }
143 
144  free(xpath);
145 }
146 
160 static lrmd_event_data_t *
161 create_op(const xmlNode *cib_resource, const char *task, guint interval_ms,
162  int outcome)
163 {
164  lrmd_event_data_t *op = NULL;
165  xmlNode *xop = NULL;
166 
167  op = lrmd_new_event(ID(cib_resource), task, interval_ms);
168  lrmd__set_result(op, outcome, PCMK_EXEC_DONE, "Simulated action result");
169  op->params = NULL; // Not needed for simulation purposes
170  op->t_run = (unsigned int) time(NULL);
171  op->t_rcchange = op->t_run;
172 
173  // Use a call ID higher than any existing history entries
174  op->call_id = 0;
175  for (xop = pcmk__xe_first_child(cib_resource); xop != NULL;
176  xop = pcmk__xe_next(xop)) {
177 
178  int tmp = 0;
179 
181  if (tmp > op->call_id) {
182  op->call_id = tmp;
183  }
184  }
185  op->call_id++;
186 
187  return op;
188 }
189 
200 xmlNode *
202  int target_rc)
203 {
204  return pcmk__create_history_xml(cib_resource, op, CRM_FEATURE_SET,
205  target_rc, NULL, crm_system_name);
206 }
207 
221 xmlNode *
222 pcmk__inject_node(cib_t *cib_conn, const char *node, const char *uuid)
223 {
224  int rc = pcmk_ok;
225  xmlNode *cib_object = NULL;
226  char *xpath = crm_strdup_printf(XPATH_NODE_STATE, node);
227  bool duplicate = false;
228  char *found_uuid = NULL;
229 
231  create_node_entry(cib_conn, node);
232  }
233 
234  rc = cib_conn->cmds->query(cib_conn, xpath, &cib_object,
236 
237  if ((cib_object != NULL) && (ID(cib_object) == NULL)) {
238  crm_err("Detected multiple node_state entries for xpath=%s, bailing",
239  xpath);
240  duplicate = true;
241  goto done;
242  }
243 
244  if (rc == -ENXIO) {
245  if (uuid == NULL) {
246  query_node_uuid(cib_conn, node, &found_uuid, NULL);
247  } else {
248  found_uuid = strdup(uuid);
249  }
250 
251  if (found_uuid) {
252  char *xpath_by_uuid = crm_strdup_printf("//" XML_CIB_TAG_STATE "[@" XML_ATTR_ID "='%s']",
253  found_uuid);
254 
255  // It's possible that a node_state entry doesn't have an uname yet.
256  rc = cib_conn->cmds->query(cib_conn, xpath_by_uuid, &cib_object,
258 
259  if ((cib_object != NULL) && (ID(cib_object) == NULL)) {
260  crm_err("Detected multiple node_state entries for xpath=%s, bailing",
261  xpath_by_uuid);
262  duplicate = true;
263  free(xpath_by_uuid);
264  goto done;
265 
266  } else if (cib_object != NULL) {
267  crm_xml_add(cib_object, XML_ATTR_UNAME, node);
268 
269  rc = cib_conn->cmds->modify(cib_conn, XML_CIB_TAG_STATUS, cib_object,
271  }
272 
273  free(xpath_by_uuid);
274  }
275  }
276 
277  if (rc == -ENXIO) {
278  cib_object = create_xml_node(NULL, XML_CIB_TAG_STATE);
279  crm_xml_add(cib_object, XML_ATTR_ID, found_uuid);
280  crm_xml_add(cib_object, XML_ATTR_UNAME, node);
281  cib_conn->cmds->create(cib_conn, XML_CIB_TAG_STATUS, cib_object,
283  free_xml(cib_object);
284 
285  rc = cib_conn->cmds->query(cib_conn, xpath, &cib_object,
287  crm_trace("Injecting node state for %s (rc=%d)", node, rc);
288  }
289 
290 done:
291  free(found_uuid);
292  free(xpath);
293 
294  if (duplicate) {
295  crm_log_xml_warn(cib_object, "Duplicates");
297  return NULL; // not reached, but makes static analysis happy
298  }
299 
300  CRM_ASSERT(rc == pcmk_ok);
301  return cib_object;
302 }
303 
314 xmlNode *
315 pcmk__inject_node_state_change(cib_t *cib_conn, const char *node, bool up)
316 {
317  xmlNode *cib_node = pcmk__inject_node(cib_conn, node, NULL);
318 
319  if (up) {
320  pcmk__xe_set_props(cib_node,
325  NULL);
326  } else {
327  pcmk__xe_set_props(cib_node,
332  NULL);
333  }
335  return cib_node;
336 }
337 
348 static xmlNode *
349 find_resource_xml(xmlNode *cib_node, const char *resource)
350 {
351  const char *node = crm_element_value(cib_node, XML_ATTR_UNAME);
352  char *xpath = crm_strdup_printf(XPATH_RSC_HISTORY, node, resource);
353  xmlNode *match = get_xpath_object(xpath, cib_node, LOG_TRACE);
354 
355  free(xpath);
356  return match;
357 }
358 
375 xmlNode *
377  const char *resource, const char *lrm_name,
378  const char *rclass, const char *rtype,
379  const char *rprovider)
380 {
381  xmlNode *lrm = NULL;
382  xmlNode *container = NULL;
383  xmlNode *cib_resource = NULL;
384 
385  cib_resource = find_resource_xml(cib_node, resource);
386  if (cib_resource != NULL) {
387  /* If an existing LRM history entry uses the resource name,
388  * continue using it, even if lrm_name is different.
389  */
390  return cib_resource;
391  }
392 
393  // Check for history entry under preferred name
394  if (strcmp(resource, lrm_name) != 0) {
395  cib_resource = find_resource_xml(cib_node, lrm_name);
396  if (cib_resource != NULL) {
397  return cib_resource;
398  }
399  }
400 
401  if ((rclass == NULL) || (rtype == NULL)) {
402  // @TODO query configuration for class, provider, type
403  out->err(out, "Resource %s not found in the status section of %s."
404  " Please supply the class and type to continue", resource, ID(cib_node));
405  return NULL;
406 
407  } else if (!pcmk__strcase_any_of(rclass,
413  PCMK_RESOURCE_CLASS_LSB, NULL)) {
414  out->err(out, "Invalid class for %s: %s", resource, rclass);
415  return NULL;
416 
418  && (rprovider == NULL)) {
419  // @TODO query configuration for provider
420  out->err(out, "Please specify the provider for resource %s", resource);
421  return NULL;
422  }
423 
424  crm_info("Injecting new resource %s into node state '%s'",
425  lrm_name, ID(cib_node));
426 
427  lrm = first_named_child(cib_node, XML_CIB_TAG_LRM);
428  if (lrm == NULL) {
429  const char *node_uuid = ID(cib_node);
430 
431  lrm = create_xml_node(cib_node, XML_CIB_TAG_LRM);
432  crm_xml_add(lrm, XML_ATTR_ID, node_uuid);
433  }
434 
435  container = first_named_child(lrm, XML_LRM_TAG_RESOURCES);
436  if (container == NULL) {
437  container = create_xml_node(lrm, XML_LRM_TAG_RESOURCES);
438  }
439 
440  cib_resource = create_xml_node(container, XML_LRM_TAG_RESOURCE);
441 
442  // If we're creating a new entry, use the preferred name
443  crm_xml_add(cib_resource, XML_ATTR_ID, lrm_name);
444 
445  crm_xml_add(cib_resource, XML_AGENT_ATTR_CLASS, rclass);
446  crm_xml_add(cib_resource, XML_AGENT_ATTR_PROVIDER, rprovider);
447  crm_xml_add(cib_resource, XML_ATTR_TYPE, rtype);
448 
449  return cib_resource;
450 }
451 
452 static int
453 find_ticket_state(pcmk__output_t *out, cib_t *the_cib, const char *ticket_id,
454  xmlNode **ticket_state_xml)
455 {
456  int rc = pcmk_ok;
457  xmlNode *xml_search = NULL;
458 
459  GString *xpath = g_string_sized_new(256);
460 
461  CRM_ASSERT(ticket_state_xml != NULL);
462  *ticket_state_xml = NULL;
463 
464  g_string_append(xpath,
466  "/" XML_CIB_TAG_TICKETS);
467 
468  if (ticket_id) {
469  pcmk__g_strcat(xpath,
471  "[@" XML_ATTR_ID "=\"", ticket_id, "\"]", NULL);
472  }
473  rc = the_cib->cmds->query(the_cib, (const char *) xpath->str, &xml_search,
475  g_string_free(xpath, TRUE);
476 
477  if (rc != pcmk_ok) {
478  return rc;
479  }
480 
481  crm_log_xml_debug(xml_search, "Match");
482  if (xml_has_children(xml_search) && (ticket_id != NULL)) {
483  out->err(out, "Multiple ticket_states match ticket_id=%s", ticket_id);
484  }
485  *ticket_state_xml = xml_search;
486 
487  return rc;
488 }
489 
502 static int
503 set_ticket_state_attr(pcmk__output_t *out, const char *ticket_id,
504  const char *attr_name, bool attr_value, cib_t *cib)
505 {
506  int rc = pcmk_rc_ok;
507  xmlNode *xml_top = NULL;
508  xmlNode *ticket_state_xml = NULL;
509 
510  // Check for an existing ticket state entry
511  rc = find_ticket_state(out, cib, ticket_id, &ticket_state_xml);
512  rc = pcmk_legacy2rc(rc);
513 
514  if (rc == pcmk_rc_ok) { // Ticket state found, use it
515  crm_debug("Injecting attribute into existing ticket state %s",
516  ticket_id);
517  xml_top = ticket_state_xml;
518 
519  } else if (rc == ENXIO) { // No ticket state, create it
520  xmlNode *xml_obj = NULL;
521 
522  xml_top = create_xml_node(NULL, XML_CIB_TAG_STATUS);
523  xml_obj = create_xml_node(xml_top, XML_CIB_TAG_TICKETS);
524  ticket_state_xml = create_xml_node(xml_obj, XML_CIB_TAG_TICKET_STATE);
525  crm_xml_add(ticket_state_xml, XML_ATTR_ID, ticket_id);
526 
527  } else { // Error
528  return rc;
529  }
530 
531  // Add the attribute to the ticket state
532  pcmk__xe_set_bool_attr(ticket_state_xml, attr_name, attr_value);
533  crm_log_xml_debug(xml_top, "Update");
534 
535  // Commit the change to the CIB
536  rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, xml_top,
538  rc = pcmk_legacy2rc(rc);
539 
540  free_xml(xml_top);
541  return rc;
542 }
543 
553 static void
554 inject_action(pcmk__output_t *out, const char *spec, cib_t *cib,
555  const pe_working_set_t *data_set)
556 {
557  int rc;
558  int outcome = PCMK_OCF_OK;
559  guint interval_ms = 0;
560 
561  char *key = NULL;
562  char *node = NULL;
563  char *task = NULL;
564  char *resource = NULL;
565 
566  const char *rtype = NULL;
567  const char *rclass = NULL;
568  const char *rprovider = NULL;
569 
570  xmlNode *cib_op = NULL;
571  xmlNode *cib_node = NULL;
572  xmlNode *cib_resource = NULL;
573  const pe_resource_t *rsc = NULL;
574  lrmd_event_data_t *op = NULL;
575 
576  out->message(out, "inject-spec", spec);
577 
578  key = calloc(1, strlen(spec) + 1);
579  node = calloc(1, strlen(spec) + 1);
580  rc = sscanf(spec, "%[^@]@%[^=]=%d", key, node, &outcome);
581  if (rc != 3) {
582  out->err(out, "Invalid operation spec: %s. Only found %d fields",
583  spec, rc);
584  goto done;
585  }
586 
587  parse_op_key(key, &resource, &task, &interval_ms);
588 
589  rsc = pe_find_resource(data_set->resources, resource);
590  if (rsc == NULL) {
591  out->err(out, "Invalid resource name: %s", resource);
592  goto done;
593  }
594 
596  rtype = crm_element_value(rsc->xml, XML_ATTR_TYPE);
597  rprovider = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER);
598 
599  cib_node = pcmk__inject_node(cib, node, NULL);
600  CRM_ASSERT(cib_node != NULL);
601 
602  pcmk__inject_failcount(out, cib_node, resource, task, interval_ms, outcome);
603 
604  cib_resource = pcmk__inject_resource_history(out, cib_node,
605  resource, resource,
606  rclass, rtype, rprovider);
607  CRM_ASSERT(cib_resource != NULL);
608 
609  op = create_op(cib_resource, task, interval_ms, outcome);
610  CRM_ASSERT(op != NULL);
611 
612  cib_op = pcmk__inject_action_result(cib_resource, op, 0);
613  CRM_ASSERT(cib_op != NULL);
614  lrmd_free_event(op);
615 
616  rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, cib_node,
618  CRM_ASSERT(rc == pcmk_ok);
619 
620 done:
621  free(task);
622  free(node);
623  free(key);
624 }
625 
634 void
636  const pcmk_injections_t *injections)
637 {
638  int rc = pcmk_ok;
639  const GList *iter = NULL;
640  xmlNode *cib_node = NULL;
641  pcmk__output_t *out = data_set->priv;
642 
643  out->message(out, "inject-modify-config", injections->quorum,
644  injections->watchdog);
645  if (injections->quorum != NULL) {
646  xmlNode *top = create_xml_node(NULL, XML_TAG_CIB);
647 
648  /* crm_xml_add(top, XML_ATTR_DC_UUID, dc_uuid); */
649  crm_xml_add(top, XML_ATTR_HAVE_QUORUM, injections->quorum);
650 
651  rc = cib->cmds->modify(cib, NULL, top, cib_sync_call|cib_scope_local);
652  CRM_ASSERT(rc == pcmk_ok);
653  }
654 
655  if (injections->watchdog != NULL) {
657  XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL,
658  XML_ATTR_HAVE_WATCHDOG, injections->watchdog,
659  NULL, NULL);
660  CRM_ASSERT(rc == pcmk_rc_ok);
661  }
662 
663  for (iter = injections->node_up; iter != NULL; iter = iter->next) {
664  const char *node = (const char *) iter->data;
665 
666  out->message(out, "inject-modify-node", "Online", node);
667 
668  cib_node = pcmk__inject_node_state_change(cib, node, true);
669  CRM_ASSERT(cib_node != NULL);
670 
671  rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, cib_node,
673  CRM_ASSERT(rc == pcmk_ok);
674  free_xml(cib_node);
675  }
676 
677  for (iter = injections->node_down; iter != NULL; iter = iter->next) {
678  const char *node = (const char *) iter->data;
679  char *xpath = NULL;
680 
681  out->message(out, "inject-modify-node", "Offline", node);
682 
683  cib_node = pcmk__inject_node_state_change(cib, node, false);
684  CRM_ASSERT(cib_node != NULL);
685 
686  rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, cib_node,
688  CRM_ASSERT(rc == pcmk_ok);
689  free_xml(cib_node);
690 
691  xpath = crm_strdup_printf("//node_state[@uname='%s']/%s",
692  node, XML_CIB_TAG_LRM);
693  cib->cmds->remove(cib, xpath, NULL,
695  free(xpath);
696 
697  xpath = crm_strdup_printf("//node_state[@uname='%s']/%s",
699  cib->cmds->remove(cib, xpath, NULL,
701  free(xpath);
702  }
703 
704  for (iter = injections->node_fail; iter != NULL; iter = iter->next) {
705  const char *node = (const char *) iter->data;
706 
707  out->message(out, "inject-modify-node", "Failing", node);
708 
709  cib_node = pcmk__inject_node_state_change(cib, node, true);
711  CRM_ASSERT(cib_node != NULL);
712 
713  rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, cib_node,
715  CRM_ASSERT(rc == pcmk_ok);
716  free_xml(cib_node);
717  }
718 
719  for (iter = injections->ticket_grant; iter != NULL; iter = iter->next) {
720  const char *ticket_id = (const char *) iter->data;
721 
722  out->message(out, "inject-modify-ticket", "Granting", ticket_id);
723 
724  rc = set_ticket_state_attr(out, ticket_id, "granted", true, cib);
725  CRM_ASSERT(rc == pcmk_rc_ok);
726  }
727 
728  for (iter = injections->ticket_revoke; iter != NULL; iter = iter->next) {
729  const char *ticket_id = (const char *) iter->data;
730 
731  out->message(out, "inject-modify-ticket", "Revoking", ticket_id);
732 
733  rc = set_ticket_state_attr(out, ticket_id, "granted", false, cib);
734  CRM_ASSERT(rc == pcmk_rc_ok);
735  }
736 
737  for (iter = injections->ticket_standby; iter != NULL; iter = iter->next) {
738  const char *ticket_id = (const char *) iter->data;
739 
740  out->message(out, "inject-modify-ticket", "Standby", ticket_id);
741 
742  rc = set_ticket_state_attr(out, ticket_id, "standby", true, cib);
743  CRM_ASSERT(rc == pcmk_rc_ok);
744  }
745 
746  for (iter = injections->ticket_activate; iter != NULL; iter = iter->next) {
747  const char *ticket_id = (const char *) iter->data;
748 
749  out->message(out, "inject-modify-ticket", "Activating", ticket_id);
750 
751  rc = set_ticket_state_attr(out, ticket_id, "standby", false, cib);
752  CRM_ASSERT(rc == pcmk_rc_ok);
753  }
754 
755  for (iter = injections->op_inject; iter != NULL; iter = iter->next) {
756  inject_action(out, (const char *) iter->data, cib, data_set);
757  }
758 
759  if (!out->is_quiet(out)) {
760  out->end_list(out);
761  }
762 }
763 
764 void
766 {
767  if (injections == NULL) {
768  return;
769  }
770 
771  g_list_free_full(injections->node_up, g_free);
772  g_list_free_full(injections->node_down, g_free);
773  g_list_free_full(injections->node_fail, g_free);
774  g_list_free_full(injections->op_fail, g_free);
775  g_list_free_full(injections->op_inject, g_free);
776  g_list_free_full(injections->ticket_grant, g_free);
777  g_list_free_full(injections->ticket_revoke, g_free);
778  g_list_free_full(injections->ticket_standby, g_free);
779  g_list_free_full(injections->ticket_activate, g_free);
780  free(injections->quorum);
781  free(injections->watchdog);
782 
783  free(injections);
784 }
void(* end_list)(pcmk__output_t *out)
#define LOG_TRACE
Definition: logging.h:37
A dumping ground.
gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms)
Definition: operations.c:96
GList * op_inject
Definition: pacemaker.h:61
Internal software bug.
Definition: results.h:257
#define PCMK_RESOURCE_CLASS_SERVICE
Definition: agents.h:28
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
Definition: results.c:874
const char * name
Definition: cib.c:24
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:933
int(* message)(pcmk__output_t *out, const char *message_id,...)
#define XML_ATTR_TYPE
Definition: msg_xml.h:151
void pcmk__inject_scheduler_input(pe_working_set_t *data_set, cib_t *cib, const pcmk_injections_t *injections)
GList * ticket_activate
Definition: pacemaker.h:74
xmlNode * first_named_child(const xmlNode *parent, const char *name)
Definition: xml.c:2521
xmlNode * xml
Definition: pe_types.h:349
bool(* is_quiet)(pcmk__output_t *out)
#define CRM_FEATURE_SET
Definition: crm.h:69
#define XML_TAG_TRANSIENT_NODEATTRS
Definition: msg_xml.h:429
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
Definition: msg_xml.h:280
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:302
GList * node_up
Definition: pacemaker.h:52
void lrmd_free_event(lrmd_event_data_t *event)
Free an executor event.
Definition: lrmd_client.c:243
Resource agent executor.
#define XML_NODE_EXPECTED
Definition: msg_xml.h:294
unsigned int t_rcchange
Definition: lrmd.h:247
int query_node_uuid(cib_t *the_cib, const char *uname, char **uuid, int *is_remote_node)
Definition: cib_attrs.c:621
void pcmk__xe_set_bool_attr(xmlNodePtr node, const char *name, bool value)
Definition: nvpair.c:921
char * crm_system_name
Definition: utils.c:51
#define PCMK_RESOURCE_CLASS_OCF
Definition: agents.h:27
pe_resource_t * pe_find_resource(GList *rsc_list, const char *id_rh)
Definition: status.c:391
GList * ticket_grant
Definition: pacemaker.h:68
#define PCMK_RESOURCE_CLASS_SYSTEMD
Definition: agents.h:30
xmlNode * pcmk__inject_action_result(xmlNode *cib_resource, lrmd_event_data_t *op, int target_rc)
#define XPATH_NODE_CONFIG
#define XML_CIB_TAG_LRM
Definition: msg_xml.h:278
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
Definition: nvpair.c:532
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:200
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:214
GList * resources
Definition: pe_types.h:181
#define XML_ATTR_ORIGIN
Definition: msg_xml.h:142
#define XML_TAG_ATTR_SETS
Definition: msg_xml.h:222
void pcmk_free_injections(pcmk_injections_t *injections)
Free a :pcmk_injections_t structure.
void * params
Definition: lrmd.h:258
#define CRMD_JOINSTATE_DOWN
Definition: crm.h:161
#define PCMK_RESOURCE_CLASS_UPSTART
Definition: agents.h:36
cib_api_operations_t * cmds
Definition: cib_types.h:216
#define crm_debug(fmt, args...)
Definition: logging.h:382
#define XML_BOOLEAN_NO
Definition: msg_xml.h:162
Utility functions.
#define XML_ATTR_ID
Definition: msg_xml.h:147
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:496
#define XML_CIB_TAG_STATE
Definition: msg_xml.h:217
GList * ticket_standby
Definition: pacemaker.h:72
#define XML_NODE_IS_PEER
Definition: msg_xml.h:296
#define crm_trace(fmt, args...)
Definition: logging.h:383
#define CRMD_JOINSTATE_MEMBER
Definition: crm.h:163
#define PCMK_RESOURCE_CLASS_STONITH
Definition: agents.h:31
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:1217
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.
Definition: util.h:121
int(* modify)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition: cib_types.h:127
int(*) int(*) void(* err)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
#define crm_log_xml_debug(xml, text)
Definition: logging.h:390
int(* create)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition: cib_types.h:125
#define XML_AGENT_ATTR_PROVIDER
Definition: msg_xml.h:283
#define XML_ATTR_HAVE_QUORUM
Definition: msg_xml.h:136
pe_working_set_t * data_set
#define XML_ATTR_UNAME
Definition: msg_xml.h:170
#define XML_BOOLEAN_YES
Definition: msg_xml.h:161
ISO_8601 Date handling.
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:677
#define crm_log_xml_warn(xml, text)
Definition: logging.h:387
Action completed, result is known.
Definition: results.h:315
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
Definition: cib_types.h:103
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)
Definition: results.c:546
void free_xml(xmlNode *child)
Definition: xml.c:813
gboolean xml_has_children(const xmlNode *root)
Definition: xml.c:1726
#define XML_CIB_TAG_NODE
Definition: msg_xml.h:218
bool pcmk__simulate_node_config
void pcmk__xe_set_props(xmlNodePtr node,...) G_GNUC_NULL_TERMINATED
Definition: xml.c:2695
unsigned int t_run
Definition: lrmd.h:245
#define XML_TAG_CIB
Definition: msg_xml.h:128
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.
Definition: lrmd_client.c:195
Cluster status and scheduling.
GList * ticket_revoke
Definition: pacemaker.h:70
#define XML_LRM_TAG_RESOURCES
Definition: msg_xml.h:279
#define crm_err(fmt, args...)
Definition: logging.h:377
#define XML_CIB_TAG_TICKET_STATE
Definition: msg_xml.h:453
#define CRM_ASSERT(expr)
Definition: results.h:42
Success.
Definition: results.h:167
Cluster Configuration.
void lrmd__set_result(lrmd_event_data_t *event, enum ocf_exitcode rc, int op_status, const char *exit_reason)
Definition: lrmd_client.c:2481
#define XML_CIB_TAG_CRMCONFIG
Definition: msg_xml.h:203
Synthetic cluster events that can be injected into the cluster for running simulations.
Definition: pacemaker.h:50
#define OFFLINESTATUS
Definition: util.h:40
#define PCMK_RESOURCE_CLASS_LSB
Definition: agents.h:29
#define XML_ATTR_HAVE_WATCHDOG
Definition: msg_xml.h:137
GList * node_fail
Definition: pacemaker.h:56
This structure contains everything that makes up a single output formatter.
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)
#define XML_LRM_ATTR_CALLID
Definition: msg_xml.h:327
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)
Definition: cib_attrs.c:173
#define XPATH_RSC_HISTORY
xmlNode * pcmk__inject_node_state_change(cib_t *cib_conn, const char *node, bool up)
#define pcmk_ok
Definition: results.h:68
#define XPATH_NODE_STATE
GList * op_fail
Definition: pacemaker.h:66
#define XML_NODE_JOIN_STATE
Definition: msg_xml.h:293
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:198
#define XML_NODE_IN_CLUSTER
Definition: msg_xml.h:295
uint32_t pcmk_get_ra_caps(const char *standard)
Get capabilities of a resource agent standard.
Definition: agents.c:31
int(* remove)(cib_t *cib, const char *section, xmlNode *data, int call_options)
Definition: cib_types.h:136
xmlNode * crm_create_nvpair_xml(xmlNode *parent, const char *id, const char *name, const char *value)
Create an XML name/value pair.
Definition: nvpair.c:812
#define ID(x)
Definition: msg_xml.h:480
#define ONLINESTATUS
Definition: util.h:39
#define XML_CIB_TAG_TICKETS
Definition: msg_xml.h:452
#define crm_info(fmt, args...)
Definition: logging.h:380
xmlNode * pcmk__inject_node(cib_t *cib_conn, const char *node, const char *uuid)
GList * node_down
Definition: pacemaker.h:54
#define XML_AGENT_ATTR_CLASS
Definition: msg_xml.h:282