pacemaker  2.0.3-4b1f869f0f
Scalable High-Availability cluster resource manager
pcmk_sched_utils.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2019 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This source code is licensed under the GNU General Public License version 2
5  * or later (GPLv2+) WITHOUT ANY WARRANTY.
6  */
7 
8 #include <crm_internal.h>
9 #include <crm/msg_xml.h>
10 #include <crm/lrmd.h> // lrmd_event_data_t
11 #include <pacemaker-internal.h>
12 
14 rsc2node_new(const char *id, pe_resource_t *rsc,
15  int node_weight, const char *discover_mode,
16  pe_node_t *foo_node, pe_working_set_t *data_set)
17 {
18  pe__location_t *new_con = NULL;
19 
20  if (rsc == NULL || id == NULL) {
21  pe_err("Invalid constraint %s for rsc=%p", crm_str(id), rsc);
22  return NULL;
23 
24  } else if (foo_node == NULL) {
25  CRM_CHECK(node_weight == 0, return NULL);
26  }
27 
28  new_con = calloc(1, sizeof(pe__location_t));
29  if (new_con != NULL) {
30  new_con->id = strdup(id);
31  new_con->rsc_lh = rsc;
32  new_con->node_list_rh = NULL;
33  new_con->role_filter = RSC_ROLE_UNKNOWN;
34 
35 
36  if (discover_mode == NULL || safe_str_eq(discover_mode, "always")) {
38  } else if (safe_str_eq(discover_mode, "never")) {
40  } else if (safe_str_eq(discover_mode, "exclusive")) {
42  rsc->exclusive_discover = TRUE;
43  } else {
44  pe_err("Invalid %s value %s in location constraint", XML_LOCATION_ATTR_DISCOVERY, discover_mode);
45  }
46 
47  if (foo_node != NULL) {
48  node_t *copy = node_copy(foo_node);
49 
50  copy->weight = node_weight;
51  new_con->node_list_rh = g_list_prepend(NULL, copy);
52  }
53 
54  data_set->placement_constraints = g_list_prepend(data_set->placement_constraints, new_con);
55  rsc->rsc_location = g_list_prepend(rsc->rsc_location, new_con);
56  }
57 
58  return new_con;
59 }
60 
61 gboolean
63 {
64  if (node == NULL) {
65  return FALSE;
66  }
67 #if 0
68  if (node->weight < 0) {
69  return FALSE;
70  }
71 #endif
72 
73  if (node->details->online == FALSE
74  || node->details->shutdown || node->details->unclean
75  || node->details->standby || node->details->maintenance) {
76  crm_trace("%s: online=%d, unclean=%d, standby=%d, maintenance=%d",
77  node->details->uname, node->details->online,
78  node->details->unclean, node->details->standby, node->details->maintenance);
79  return FALSE;
80  }
81  return TRUE;
82 }
83 
84 struct node_weight_s {
85  pe_node_t *active;
86  pe_working_set_t *data_set;
87 };
88 
89 /* return -1 if 'a' is more preferred
90  * return 1 if 'b' is more preferred
91  */
92 
93 static gint
94 sort_node_weight(gconstpointer a, gconstpointer b, gpointer data)
95 {
96  const node_t *node1 = (const node_t *)a;
97  const node_t *node2 = (const node_t *)b;
98  struct node_weight_s *nw = data;
99 
100  int node1_weight = 0;
101  int node2_weight = 0;
102 
103  int result = 0;
104 
105  if (a == NULL) {
106  return 1;
107  }
108  if (b == NULL) {
109  return -1;
110  }
111 
112  node1_weight = node1->weight;
113  node2_weight = node2->weight;
114 
115  if (can_run_resources(node1) == FALSE) {
116  node1_weight = -INFINITY;
117  }
118  if (can_run_resources(node2) == FALSE) {
119  node2_weight = -INFINITY;
120  }
121 
122  if (node1_weight > node2_weight) {
123  crm_trace("%s (%d) > %s (%d) : weight",
124  node1->details->uname, node1_weight, node2->details->uname, node2_weight);
125  return -1;
126  }
127 
128  if (node1_weight < node2_weight) {
129  crm_trace("%s (%d) < %s (%d) : weight",
130  node1->details->uname, node1_weight, node2->details->uname, node2_weight);
131  return 1;
132  }
133 
134  crm_trace("%s (%d) == %s (%d) : weight",
135  node1->details->uname, node1_weight, node2->details->uname, node2_weight);
136 
137  if (safe_str_eq(nw->data_set->placement_strategy, "minimal")) {
138  goto equal;
139  }
140 
141  if (safe_str_eq(nw->data_set->placement_strategy, "balanced")) {
142  result = compare_capacity(node1, node2);
143  if (result < 0) {
144  crm_trace("%s > %s : capacity (%d)",
145  node1->details->uname, node2->details->uname, result);
146  return -1;
147  } else if (result > 0) {
148  crm_trace("%s < %s : capacity (%d)",
149  node1->details->uname, node2->details->uname, result);
150  return 1;
151  }
152  }
153 
154  /* now try to balance resources across the cluster */
155  if (node1->details->num_resources < node2->details->num_resources) {
156  crm_trace("%s (%d) > %s (%d) : resources",
157  node1->details->uname, node1->details->num_resources,
158  node2->details->uname, node2->details->num_resources);
159  return -1;
160 
161  } else if (node1->details->num_resources > node2->details->num_resources) {
162  crm_trace("%s (%d) < %s (%d) : resources",
163  node1->details->uname, node1->details->num_resources,
164  node2->details->uname, node2->details->num_resources);
165  return 1;
166  }
167 
168  if (nw->active && nw->active->details == node1->details) {
169  crm_trace("%s (%d) > %s (%d) : active",
170  node1->details->uname, node1->details->num_resources,
171  node2->details->uname, node2->details->num_resources);
172  return -1;
173  } else if (nw->active && nw->active->details == node2->details) {
174  crm_trace("%s (%d) < %s (%d) : active",
175  node1->details->uname, node1->details->num_resources,
176  node2->details->uname, node2->details->num_resources);
177  return 1;
178  }
179  equal:
180  crm_trace("%s = %s", node1->details->uname, node2->details->uname);
181  return strcmp(node1->details->uname, node2->details->uname);
182 }
183 
184 GList *
185 sort_nodes_by_weight(GList *nodes, pe_node_t *active_node,
186  pe_working_set_t *data_set)
187 {
188  struct node_weight_s nw = { active_node, data_set };
189 
190  return g_list_sort_with_data(nodes, sort_node_weight, &nw);
191 }
192 
193 void
195 {
196  if (rsc->allocated_to) {
197  node_t *old = rsc->allocated_to;
198 
199  crm_info("Deallocating %s from %s", rsc->id, old->details->uname);
201  rsc->allocated_to = NULL;
202 
203  old->details->allocated_rsc = g_list_remove(old->details->allocated_rsc, rsc);
204  old->details->num_resources--;
205  /* old->count--; */
207  free(old);
208  }
209 }
210 
211 gboolean
212 native_assign_node(resource_t * rsc, GListPtr nodes, node_t * chosen, gboolean force)
213 {
214  CRM_ASSERT(rsc->variant == pe_native);
215 
216  if (force == FALSE && chosen != NULL) {
217  bool unset = FALSE;
218 
219  if(chosen->weight < 0) {
220  unset = TRUE;
221 
222  // Allow the graph to assume that the remote resource will come up
223  } else if (!can_run_resources(chosen) && !pe__is_guest_node(chosen)) {
224  unset = TRUE;
225  }
226 
227  if(unset) {
228  crm_debug("All nodes for resource %s are unavailable"
229  ", unclean or shutting down (%s: %d, %d)",
230  rsc->id, chosen->details->uname, can_run_resources(chosen), chosen->weight);
232  chosen = NULL;
233  }
234  }
235 
236  /* todo: update the old node for each resource to reflect its
237  * new resource count
238  */
239 
240  native_deallocate(rsc);
242 
243  if (chosen == NULL) {
244  GListPtr gIter = NULL;
245  char *rc_inactive = crm_itoa(PCMK_OCF_NOT_RUNNING);
246 
247  crm_debug("Could not allocate a node for %s", rsc->id);
249 
250  for (gIter = rsc->actions; gIter != NULL; gIter = gIter->next) {
251  action_t *op = (action_t *) gIter->data;
252  const char *interval_ms_s = g_hash_table_lookup(op->meta, XML_LRM_ATTR_INTERVAL_MS);
253 
254  crm_debug("Processing %s", op->uuid);
255  if(safe_str_eq(RSC_STOP, op->task)) {
256  update_action_flags(op, pe_action_optional | pe_action_clear, __FUNCTION__, __LINE__);
257 
258  } else if(safe_str_eq(RSC_START, op->task)) {
259  update_action_flags(op, pe_action_runnable | pe_action_clear, __FUNCTION__, __LINE__);
260  /* set_bit(rsc->flags, pe_rsc_block); */
261 
262  } else if (interval_ms_s && safe_str_neq(interval_ms_s, "0")) {
263  if(safe_str_eq(rc_inactive, g_hash_table_lookup(op->meta, XML_ATTR_TE_TARGET_RC))) {
264  /* This is a recurring monitor for the stopped state, leave it alone */
265 
266  } else {
267  /* Normal monitor operation, cancel it */
268  update_action_flags(op, pe_action_runnable | pe_action_clear, __FUNCTION__, __LINE__);
269  }
270  }
271  }
272 
273  free(rc_inactive);
274  return FALSE;
275  }
276 
277  crm_debug("Assigning %s to %s", chosen->details->uname, rsc->id);
278  rsc->allocated_to = node_copy(chosen);
279 
280  chosen->details->allocated_rsc = g_list_prepend(chosen->details->allocated_rsc, rsc);
281  chosen->details->num_resources++;
282  chosen->count++;
283  calculate_utilization(chosen->details->utilization, rsc->utilization, FALSE);
284  dump_rsc_utilization(show_utilization ? 0 : utilization_log_level, __FUNCTION__, rsc, chosen);
285 
286  return TRUE;
287 }
288 
289 void
290 log_action(unsigned int log_level, const char *pre_text, action_t * action, gboolean details)
291 {
292  const char *node_uname = NULL;
293  const char *node_uuid = NULL;
294 
295  if (action == NULL) {
296  crm_trace("%s%s: <NULL>", pre_text == NULL ? "" : pre_text, pre_text == NULL ? "" : ": ");
297  return;
298  }
299 
300  if (is_set(action->flags, pe_action_pseudo)) {
301  node_uname = NULL;
302  node_uuid = NULL;
303 
304  } else if (action->node != NULL) {
305  node_uname = action->node->details->uname;
306  node_uuid = action->node->details->id;
307  } else {
308  node_uname = "<none>";
309  node_uuid = NULL;
310  }
311 
312  switch (text2task(action->task)) {
313  case stonith_node:
314  case shutdown_crm:
315  crm_trace("%s%s%sAction %d: %s%s%s%s%s%s",
316  pre_text == NULL ? "" : pre_text,
317  pre_text == NULL ? "" : ": ",
318  is_set(action->flags,
319  pe_action_pseudo) ? "Pseudo " : is_set(action->flags,
321  "Optional " : is_set(action->flags,
322  pe_action_runnable) ? is_set(action->flags,
324  ? "" : "(Provisional) " : "!!Non-Startable!! ", action->id,
325  action->uuid, node_uname ? "\ton " : "",
326  node_uname ? node_uname : "", node_uuid ? "\t\t(" : "",
327  node_uuid ? node_uuid : "", node_uuid ? ")" : "");
328  break;
329  default:
330  crm_trace("%s%s%sAction %d: %s %s%s%s%s%s%s",
331  pre_text == NULL ? "" : pre_text,
332  pre_text == NULL ? "" : ": ",
333  is_set(action->flags,
334  pe_action_optional) ? "Optional " : is_set(action->flags,
336  ? "Pseudo " : is_set(action->flags,
337  pe_action_runnable) ? is_set(action->flags,
339  ? "" : "(Provisional) " : "!!Non-Startable!! ", action->id,
340  action->uuid, action->rsc ? action->rsc->id : "<none>",
341  node_uname ? "\ton " : "", node_uname ? node_uname : "",
342  node_uuid ? "\t\t(" : "", node_uuid ? node_uuid : "", node_uuid ? ")" : "");
343 
344  break;
345  }
346 
347  if (details) {
348  GListPtr gIter = NULL;
349 
350  crm_trace("\t\t====== Preceding Actions");
351 
352  gIter = action->actions_before;
353  for (; gIter != NULL; gIter = gIter->next) {
354  action_wrapper_t *other = (action_wrapper_t *) gIter->data;
355 
356  log_action(log_level + 1, "\t\t", other->action, FALSE);
357  }
358 
359  crm_trace("\t\t====== Subsequent Actions");
360 
361  gIter = action->actions_after;
362  for (; gIter != NULL; gIter = gIter->next) {
363  action_wrapper_t *other = (action_wrapper_t *) gIter->data;
364 
365  log_action(log_level + 1, "\t\t", other->action, FALSE);
366  }
367 
368  crm_trace("\t\t====== End");
369 
370  } else {
371  crm_trace("\t\t(before=%d, after=%d)",
372  g_list_length(action->actions_before), g_list_length(action->actions_after));
373  }
374 }
375 
376 gboolean
377 can_run_any(GHashTable * nodes)
378 {
379  GHashTableIter iter;
380  node_t *node = NULL;
381 
382  if (nodes == NULL) {
383  return FALSE;
384  }
385 
386  g_hash_table_iter_init(&iter, nodes);
387  while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
388  if (can_run_resources(node) && node->weight >= 0) {
389  return TRUE;
390  }
391  }
392 
393  return FALSE;
394 }
395 
396 pe_action_t *
397 create_pseudo_resource_op(resource_t * rsc, const char *task, bool optional, bool runnable, pe_working_set_t *data_set)
398 {
399  pe_action_t *action = custom_action(rsc, generate_op_key(rsc->id, task, 0), task, NULL, optional, TRUE, data_set);
400  update_action_flags(action, pe_action_pseudo, __FUNCTION__, __LINE__);
401  update_action_flags(action, pe_action_runnable, __FUNCTION__, __LINE__);
402  if(runnable) {
403  update_action_flags(action, pe_action_runnable, __FUNCTION__, __LINE__);
404  }
405  return action;
406 }
407 
420 pe_action_t *
421 pe_cancel_op(pe_resource_t *rsc, const char *task, guint interval_ms,
422  pe_node_t *node, pe_working_set_t *data_set)
423 {
424  pe_action_t *cancel_op;
425  char *interval_ms_s = crm_strdup_printf("%u", interval_ms);
426 
427  // @TODO dangerous if possible to schedule another action with this key
428  char *key = generate_op_key(rsc->id, task, interval_ms);
429 
430  cancel_op = custom_action(rsc, key, RSC_CANCEL, node, FALSE, TRUE,
431  data_set);
432 
433  free(cancel_op->task);
434  cancel_op->task = strdup(RSC_CANCEL);
435 
436  free(cancel_op->cancel_task);
437  cancel_op->cancel_task = strdup(task);
438 
439  add_hash_param(cancel_op->meta, XML_LRM_ATTR_TASK, task);
440  add_hash_param(cancel_op->meta, XML_LRM_ATTR_INTERVAL_MS, interval_ms_s);
441  free(interval_ms_s);
442 
443  return cancel_op;
444 }
445 
455 pe_action_t *
457 {
458  char *shutdown_id = crm_strdup_printf("%s-%s", CRM_OP_SHUTDOWN,
459  node->details->uname);
460 
461  pe_action_t *shutdown_op = custom_action(NULL, shutdown_id, CRM_OP_SHUTDOWN,
462  node, FALSE, TRUE, data_set);
463 
464  crm_notice("Scheduling shutdown of node %s", node->details->uname);
465  shutdown_constraints(node, shutdown_op, data_set);
467  return shutdown_op;
468 }
469 
470 static char *
471 generate_transition_magic(const char *transition_key, int op_status, int op_rc)
472 {
473  CRM_CHECK(transition_key != NULL, return NULL);
474  return crm_strdup_printf("%d:%d;%s", op_status, op_rc, transition_key);
475 }
476 
477 static void
478 append_digest(lrmd_event_data_t *op, xmlNode *update, const char *version,
479  const char *magic, int level)
480 {
481  /* this will enable us to later determine that the
482  * resource's parameters have changed and we should force
483  * a restart
484  */
485  char *digest = NULL;
486  xmlNode *args_xml = NULL;
487 
488  if (op->params == NULL) {
489  return;
490  }
491 
492  args_xml = create_xml_node(NULL, XML_TAG_PARAMS);
493  g_hash_table_foreach(op->params, hash2field, args_xml);
495  digest = calculate_operation_digest(args_xml, version);
496 
497 #if 0
498  if (level < get_crm_log_level()
499  && op->interval_ms == 0 && crm_str_eq(op->op_type, CRMD_ACTION_START, TRUE)) {
500  char *digest_source = dump_xml_unformatted(args_xml);
501 
502  do_crm_log(level, "Calculated digest %s for %s (%s). Source: %s\n",
503  digest, ID(update), magic, digest_source);
504  free(digest_source);
505  }
506 #endif
507  crm_xml_add(update, XML_LRM_ATTR_OP_DIGEST, digest);
508 
509  free_xml(args_xml);
510  free(digest);
511 }
512 
513 #define FAKE_TE_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
514 
529 xmlNode *
531  const char *caller_version, int target_rc,
532  const char *node, const char *origin, int level)
533 {
534  char *key = NULL;
535  char *magic = NULL;
536  char *op_id = NULL;
537  char *op_id_additional = NULL;
538  char *local_user_data = NULL;
539  const char *exit_reason = NULL;
540 
541  xmlNode *xml_op = NULL;
542  const char *task = NULL;
543 
544  CRM_CHECK(op != NULL, return NULL);
545  do_crm_log(level, "%s: Updating resource %s after %s op %s (interval=%u)",
546  origin, op->rsc_id, op->op_type, services_lrm_status_str(op->op_status),
547  op->interval_ms);
548 
549  crm_trace("DC version: %s", caller_version);
550 
551  task = op->op_type;
552 
553  /* Record a successful reload as a start, and a failed reload as a monitor,
554  * to make life easier for the scheduler when determining the current state.
555  */
556  if (crm_str_eq(task, "reload", TRUE)) {
557  if (op->op_status == PCMK_LRM_OP_DONE) {
558  task = CRMD_ACTION_START;
559  } else {
560  task = CRMD_ACTION_STATUS;
561  }
562  }
563 
564  key = generate_op_key(op->rsc_id, task, op->interval_ms);
565  if (crm_str_eq(task, CRMD_ACTION_NOTIFY, TRUE)) {
566  const char *n_type = crm_meta_value(op->params, "notify_type");
567  const char *n_task = crm_meta_value(op->params, "notify_operation");
568 
569  CRM_LOG_ASSERT(n_type != NULL);
570  CRM_LOG_ASSERT(n_task != NULL);
571  op_id = generate_notify_key(op->rsc_id, n_type, n_task);
572 
573  if (op->op_status != PCMK_LRM_OP_PENDING) {
574  /* Ignore notify errors.
575  *
576  * @TODO It might be better to keep the correct result here, and
577  * ignore it in process_graph_event().
578  */
580  op->rc = 0;
581  }
582 
583  } else if (did_rsc_op_fail(op, target_rc)) {
584  op_id = generate_op_key(op->rsc_id, "last_failure", 0);
585  if (op->interval_ms == 0) {
586  // Ensure 'last' gets updated, in case record-pending is true
587  op_id_additional = generate_op_key(op->rsc_id, "last", 0);
588  }
589  exit_reason = op->exit_reason;
590 
591  } else if (op->interval_ms > 0) {
592  op_id = strdup(key);
593 
594  } else {
595  op_id = generate_op_key(op->rsc_id, "last", 0);
596  }
597 
598  again:
599  xml_op = find_entity(parent, XML_LRM_TAG_RSC_OP, op_id);
600  if (xml_op == NULL) {
601  xml_op = create_xml_node(parent, XML_LRM_TAG_RSC_OP);
602  }
603 
604  if (op->user_data == NULL) {
605  crm_debug("Generating fake transition key for: " CRM_OP_FMT " %d from %s",
606  op->rsc_id, op->op_type, op->interval_ms,
607  op->call_id, origin);
608  local_user_data = generate_transition_key(-1, op->call_id, target_rc, FAKE_TE_ID);
609  op->user_data = local_user_data;
610  }
611 
612  if(magic == NULL) {
613  magic = generate_transition_magic(op->user_data, op->op_status, op->rc);
614  }
615 
616  crm_xml_add(xml_op, XML_ATTR_ID, op_id);
617  crm_xml_add(xml_op, XML_LRM_ATTR_TASK_KEY, key);
618  crm_xml_add(xml_op, XML_LRM_ATTR_TASK, task);
619  crm_xml_add(xml_op, XML_ATTR_ORIGIN, origin);
620  crm_xml_add(xml_op, XML_ATTR_CRM_VERSION, caller_version);
622  crm_xml_add(xml_op, XML_ATTR_TRANSITION_MAGIC, magic);
623  crm_xml_add(xml_op, XML_LRM_ATTR_EXIT_REASON, exit_reason == NULL ? "" : exit_reason);
624  crm_xml_add(xml_op, XML_LRM_ATTR_TARGET, node); /* For context during triage */
625 
627  crm_xml_add_int(xml_op, XML_LRM_ATTR_RC, op->rc);
630 
631  if (compare_version("2.1", caller_version) <= 0) {
632  if (op->t_run || op->t_rcchange || op->exec_time || op->queue_time) {
633  crm_trace("Timing data (" CRM_OP_FMT "): last=%u change=%u exec=%u queue=%u",
634  op->rsc_id, op->op_type, op->interval_ms,
635  op->t_run, op->t_rcchange, op->exec_time, op->queue_time);
636 
637  if (op->interval_ms == 0) {
639  (long long) op->t_run);
640 
641  // @COMPAT last-run is deprecated
643  (long long) op->t_run);
644 
645  } else if(op->t_rcchange) {
646  /* last-run is not accurate for recurring ops */
648  (long long) op->t_rcchange);
649 
650  } else {
651  /* ...but is better than nothing otherwise */
653  (long long) op->t_run);
654  }
655 
658  }
659  }
660 
661  if (crm_str_eq(op->op_type, CRMD_ACTION_MIGRATE, TRUE)
662  || crm_str_eq(op->op_type, CRMD_ACTION_MIGRATED, TRUE)) {
663  /*
664  * Record migrate_source and migrate_target always for migrate ops.
665  */
666  const char *name = XML_LRM_ATTR_MIGRATE_SOURCE;
667 
668  crm_xml_add(xml_op, name, crm_meta_value(op->params, name));
669 
671  crm_xml_add(xml_op, name, crm_meta_value(op->params, name));
672  }
673 
674  append_digest(op, xml_op, caller_version, magic, LOG_DEBUG);
675 
676  if (op_id_additional) {
677  free(op_id);
678  op_id = op_id_additional;
679  op_id_additional = NULL;
680  goto again;
681  }
682 
683  if (local_user_data) {
684  free(local_user_data);
685  op->user_data = NULL;
686  }
687  free(magic);
688  free(op_id);
689  free(key);
690  return xml_op;
691 }
pe_node_s::count
int count
Definition: pe_types.h:219
crm_xml_add_ll
const char * crm_xml_add_ll(xmlNode *node, const char *name, long long value)
Create an XML attribute with specified name and long long int value.
Definition: nvpair.c:471
calculate_operation_digest
char * calculate_operation_digest(xmlNode *local_cib, const char *version)
Calculate and return digest of XML operation.
Definition: digest.c:176
pe_native
@ pe_native
Definition: pe_types.h:37
RSC_CANCEL
#define RSC_CANCEL
Definition: crm.h:191
GListPtr
GList * GListPtr
Definition: crm.h:214
XML_LRM_ATTR_MIGRATE_SOURCE
#define XML_LRM_ATTR_MIGRATE_SOURCE
Definition: msg_xml.h:285
INFINITY
#define INFINITY
Definition: crm.h:95
XML_RSC_OP_T_EXEC
#define XML_RSC_OP_T_EXEC
Definition: msg_xml.h:282
XML_LRM_ATTR_TASK_KEY
#define XML_LRM_ATTR_TASK_KEY
Definition: msg_xml.h:261
pe_resource_s::exclusive_discover
gboolean exclusive_discover
Definition: pe_types.h:323
crm_str_eq
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
Definition: strings.c:224
pe_resource_s::variant
enum pe_obj_types variant
Definition: pe_types.h:301
dump_xml_unformatted
char * dump_xml_unformatted(xmlNode *msg)
Definition: xml.c:3306
XML_LRM_ATTR_OPSTATUS
#define XML_LRM_ATTR_OPSTATUS
Definition: msg_xml.h:270
pe__location_constraint_s::rsc_lh
pe_resource_t * rsc_lh
Definition: internal.h:30
pe_action_s::actions_before
GListPtr actions_before
Definition: pe_types.h:410
pe_resource_s::actions
GListPtr actions
Definition: pe_types.h:330
did_rsc_op_fail
gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc)
Definition: operations.c:343
pacemaker-internal.h
pe_resource_s::next_role
enum rsc_role_e next_role
Definition: pe_types.h:342
XML_LOCATION_ATTR_DISCOVERY
#define XML_LOCATION_ATTR_DISCOVERY
Definition: msg_xml.h:315
msg_xml.h
RSC_ROLE_STOPPED
@ RSC_ROLE_STOPPED
Definition: common.h:88
pe_resource_s::utilization
GHashTable * utilization
Definition: pe_types.h:346
data
char data[0]
Definition: internal.h:12
compare_capacity
int compare_capacity(const node_t *node1, const node_t *node2)
Definition: pcmk_sched_utilization.c:72
CRMD_ACTION_NOTIFY
#define CRMD_ACTION_NOTIFY
Definition: crm.h:182
XML_ATTR_TRANSITION_KEY
#define XML_ATTR_TRANSITION_KEY
Definition: msg_xml.h:358
pe_rsc_provisional
#define pe_rsc_provisional
Definition: pe_types.h:234
create_xml_node
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1970
pe_resource_s::id
char * id
Definition: pe_types.h:292
lrmd_event_data_s::rc
enum ocf_exitcode rc
Definition: lrmd.h:221
pe_resource_s::allocated_to
pe_node_t * allocated_to
Definition: pe_types.h:334
native_assign_node
gboolean native_assign_node(resource_t *rsc, GListPtr nodes, node_t *chosen, gboolean force)
Definition: pcmk_sched_utils.c:212
pe__location_constraint_s::id
char * id
Definition: internal.h:29
CRM_CHECK
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:157
pe_node_s::weight
int weight
Definition: pe_types.h:217
pe_action_pseudo
@ pe_action_pseudo
Definition: pe_types.h:266
clear_bit
#define clear_bit(word, bit)
Definition: crm_internal.h:168
pe_node_s::details
struct pe_node_shared_s * details
Definition: pe_types.h:220
custom_action
action_t * custom_action(resource_t *rsc, char *key, const char *task, node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Definition: utils.c:455
crm_notice
#define crm_notice(fmt, args...)
Definition: logging.h:243
pcmk__create_history_xml
xmlNode * pcmk__create_history_xml(xmlNode *parent, lrmd_event_data_t *op, const char *caller_version, int target_rc, const char *node, const char *origin, int level)
Definition: pcmk_sched_utils.c:530
pe_node_shared_s::id
const char * id
Definition: pe_types.h:185
pe_action_s::actions_after
GListPtr actions_after
Definition: pe_types.h:411
compare_version
int compare_version(const char *version1, const char *version2)
Definition: utils.c:461
crm_trace
#define crm_trace(fmt, args...)
Definition: logging.h:247
safe_str_eq
#define safe_str_eq(a, b)
Definition: util.h:61
text2task
enum action_tasks text2task(const char *task)
Definition: common.c:230
pe_cancel_op
pe_action_t * pe_cancel_op(pe_resource_t *rsc, const char *task, guint interval_ms, pe_node_t *node, pe_working_set_t *data_set)
Definition: pcmk_sched_utils.c:421
filter_action_parameters
void filter_action_parameters(xmlNode *param_set, const char *version)
Definition: operations.c:263
pe_action_s::flags
enum pe_action_flags flags
Definition: pe_types.h:382
free_xml
void free_xml(xmlNode *child)
Definition: xml.c:2130
XML_ATTR_CRM_VERSION
#define XML_ATTR_CRM_VERSION
Definition: msg_xml.h:79
pe_node_shared_s::utilization
GHashTable * utilization
Definition: pe_types.h:212
lrmd_event_data_s::call_id
int call_id
Definition: lrmd.h:210
pe_action_wrapper_s
Definition: pe_types.h:489
XML_LRM_ATTR_RC
#define XML_LRM_ATTR_RC
Definition: msg_xml.h:271
pe_action_s::cancel_task
char * cancel_task
Definition: pe_types.h:379
CRM_OP_SHUTDOWN
#define CRM_OP_SHUTDOWN
Definition: crm.h:140
native_deallocate
void native_deallocate(resource_t *rsc)
Definition: pcmk_sched_utils.c:194
set_bit
#define set_bit(word, bit)
Definition: crm_internal.h:167
lrmd_event_data_s::t_run
unsigned int t_run
Definition: lrmd.h:227
lrmd_event_data_s::exec_time
unsigned int exec_time
Definition: lrmd.h:231
lrmd_event_data_s::user_data
const char * user_data
Definition: lrmd.h:207
calculate_utilization
void calculate_utilization(GHashTable *current_utilization, GHashTable *utilization, gboolean plus)
Definition: pcmk_sched_utilization.c:113
XML_ATTR_ID
#define XML_ATTR_ID
Definition: msg_xml.h:96
pe_action_s::uuid
char * uuid
Definition: pe_types.h:378
ID
#define ID(x)
Definition: msg_xml.h:415
RSC_START
#define RSC_START
Definition: crm.h:196
XML_RSC_OP_T_QUEUE
#define XML_RSC_OP_T_QUEUE
Definition: msg_xml.h:283
pe_err
#define pe_err(fmt...)
Definition: internal.h:21
pe_node_shared_s::allocated_rsc
GListPtr allocated_rsc
Definition: pe_types.h:209
pe_action_s
Definition: pe_types.h:369
pe_node_shared_s::shutdown
gboolean shutdown
Definition: pe_types.h:196
find_entity
xmlNode * find_entity(xmlNode *parent, const char *node_name, const char *id)
Definition: xml.c:1823
crm_info
#define crm_info(fmt, args...)
Definition: logging.h:244
XML_RSC_OP_LAST_RUN
#define XML_RSC_OP_LAST_RUN
Definition: msg_xml.h:281
update_action_flags
gboolean update_action_flags(action_t *action, enum pe_action_flags flags, const char *source, int line)
Definition: pcmk_sched_allocate.c:119
pe__location_constraint_s::role_filter
enum rsc_role_e role_filter
Definition: internal.h:31
CRM_LOG_ASSERT
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:143
can_run_any
gboolean can_run_any(GHashTable *nodes)
Definition: pcmk_sched_utils.c:377
lrmd_event_data_s::rsc_id
const char * rsc_id
Definition: lrmd.h:203
CRMD_ACTION_MIGRATED
#define CRMD_ACTION_MIGRATED
Definition: crm.h:169
XML_ATTR_TE_TARGET_RC
#define XML_ATTR_TE_TARGET_RC
Definition: msg_xml.h:361
CRM_OP_FMT
#define CRM_OP_FMT
Definition: crm_internal.h:133
lrmd_event_data_s::t_rcchange
unsigned int t_rcchange
Definition: lrmd.h:229
XML_LRM_ATTR_TASK
#define XML_LRM_ATTR_TASK
Definition: msg_xml.h:260
get_crm_log_level
unsigned int get_crm_log_level(void)
Definition: logging.c:979
lrmd_event_data_s
Definition: lrmd.h:198
crm_strdup_printf
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
PCMK_LRM_OP_PENDING
@ PCMK_LRM_OP_PENDING
Definition: services.h:120
lrmd_event_data_s::op_type
const char * op_type
Definition: lrmd.h:205
CRMD_ACTION_START
#define CRMD_ACTION_START
Definition: crm.h:171
RSC_ROLE_UNKNOWN
@ RSC_ROLE_UNKNOWN
Definition: common.h:87
crm_debug
#define crm_debug(fmt, args...)
Definition: logging.h:246
CRMD_ACTION_MIGRATE
#define CRMD_ACTION_MIGRATE
Definition: crm.h:168
pe_action_s::node
pe_node_t * node
Definition: pe_types.h:374
show_utilization
gboolean show_utilization
Definition: pcmk_sched_messages.c:27
lrmd_event_data_s::queue_time
unsigned int queue_time
Definition: lrmd.h:233
lrmd_event_data_s::exit_reason
const char * exit_reason
Definition: lrmd.h:248
pe_node_shared_s::standby
gboolean standby
Definition: pe_types.h:191
pe_action_optional
@ pe_action_optional
Definition: pe_types.h:268
XML_RSC_OP_LAST_CHANGE
#define XML_RSC_OP_LAST_CHANGE
Definition: msg_xml.h:280
lrmd_event_data_s::op_status
int op_status
Definition: lrmd.h:223
pe_discover_always
@ pe_discover_always
Definition: pe_types.h:440
pe__location_constraint_s::discover_mode
enum pe_discover_e discover_mode
Definition: internal.h:32
do_crm_log
#define do_crm_log(level, fmt, args...)
Log a message.
Definition: logging.h:122
RSC_STOP
#define RSC_STOP
Definition: crm.h:199
crm_xml_add
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:313
shutdown_crm
@ shutdown_crm
Definition: common.h:70
XML_ATTR_TE_NOWAIT
#define XML_ATTR_TE_NOWAIT
Definition: msg_xml.h:360
pe_working_set_s
Definition: pe_types.h:117
XML_LRM_TAG_RSC_OP
#define XML_LRM_TAG_RSC_OP
Definition: msg_xml.h:228
lrmd.h
Resource agent executor.
pe_action_clear
@ pe_action_clear
Definition: pe_types.h:277
node_copy
node_t * node_copy(const node_t *this_node)
Definition: utils.c:132
lrmd_event_data_s::params
void * params
Definition: lrmd.h:240
pe_working_set_s::placement_constraints
GListPtr placement_constraints
Definition: pe_types.h:140
pe_action_s::id
int id
Definition: pe_types.h:370
XML_TAG_PARAMS
#define XML_TAG_PARAMS
Definition: msg_xml.h:169
utilization_log_level
int utilization_log_level
Definition: pcmk_sched_messages.c:28
add_hash_param
void add_hash_param(GHashTable *hash, const char *name, const char *value)
Definition: common.c:412
shutdown_constraints
gboolean shutdown_constraints(node_t *node, action_t *shutdown_op, pe_working_set_t *data_set)
Definition: pcmk_sched_graph.c:706
crm_meta_value
const char * crm_meta_value(GHashTable *hash, const char *field)
Definition: utils.c:761
pe__location_constraint_s::node_list_rh
GListPtr node_list_rh
Definition: internal.h:33
XML_ATTR_ORIGIN
#define XML_ATTR_ORIGIN
Definition: msg_xml.h:91
sort_nodes_by_weight
GList * sort_nodes_by_weight(GList *nodes, pe_node_t *active_node, pe_working_set_t *data_set)
Definition: pcmk_sched_utils.c:185
XML_LRM_ATTR_EXIT_REASON
#define XML_LRM_ATTR_EXIT_REASON
Definition: msg_xml.h:278
XML_LRM_ATTR_OP_DIGEST
#define XML_LRM_ATTR_OP_DIGEST
Definition: msg_xml.h:273
pe_resource_s::rsc_location
GListPtr rsc_location
Definition: pe_types.h:329
safe_str_neq
gboolean safe_str_neq(const char *a, const char *b)
Definition: strings.c:161
pe_action_s::rsc
pe_resource_t * rsc
Definition: pe_types.h:373
PCMK_LRM_OP_DONE
@ PCMK_LRM_OP_DONE
Definition: services.h:121
pe_action_processed
@ pe_action_processed
Definition: pe_types.h:276
XML_LRM_ATTR_MIGRATE_TARGET
#define XML_LRM_ATTR_MIGRATE_TARGET
Definition: msg_xml.h:286
crm_str
#define crm_str(x)
Definition: logging.h:267
crm_xml_add_int
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
Definition: nvpair.c:421
dump_rsc_utilization
void dump_rsc_utilization(int level, const char *comment, resource_t *rsc, node_t *node)
Definition: utils.c:384
pe_resource_s::flags
unsigned long long flags
Definition: pe_types.h:319
op_status
op_status
Definition: services.h:118
XML_ATTR_TRANSITION_MAGIC
#define XML_ATTR_TRANSITION_MAGIC
Definition: msg_xml.h:357
XML_LRM_ATTR_TARGET
#define XML_LRM_ATTR_TARGET
Definition: msg_xml.h:262
CRM_ASSERT
#define CRM_ASSERT(expr)
Definition: results.h:42
lrmd_event_data_s::interval_ms
guint interval_ms
Definition: lrmd.h:214
pe_action_runnable
@ pe_action_runnable
Definition: pe_types.h:267
CRMD_ACTION_STATUS
#define CRMD_ACTION_STATUS
Definition: crm.h:185
FAKE_TE_ID
#define FAKE_TE_ID
Definition: pcmk_sched_utils.c:513
pe_action_wrapper_s::action
pe_action_t * action
Definition: pe_types.h:492
XML_LRM_ATTR_INTERVAL_MS
#define XML_LRM_ATTR_INTERVAL_MS
Definition: msg_xml.h:258
PCMK_OCF_NOT_RUNNING
@ PCMK_OCF_NOT_RUNNING
Definition: services.h:97
version
uint32_t version
Definition: remote.c:3
create_pseudo_resource_op
pe_action_t * create_pseudo_resource_op(resource_t *rsc, const char *task, bool optional, bool runnable, pe_working_set_t *data_set)
Definition: pcmk_sched_utils.c:397
pe_node_shared_s::maintenance
gboolean maintenance
Definition: pe_types.h:199
can_run_resources
gboolean can_run_resources(const node_t *node)
Definition: pcmk_sched_utils.c:62
pe__is_guest_node
gboolean pe__is_guest_node(pe_node_t *node)
Definition: remote.c:47
pe_resource_s
Definition: pe_types.h:291
pe_node_shared_s::unclean
gboolean unclean
Definition: pe_types.h:194
pe__location_constraint_s
Definition: internal.h:28
stonith_node
@ stonith_node
Definition: common.h:71
generate_op_key
char * generate_op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key.
Definition: operations.c:39
rsc2node_new
pe__location_t * rsc2node_new(const char *id, pe_resource_t *rsc, int node_weight, const char *discover_mode, pe_node_t *foo_node, pe_working_set_t *data_set)
Definition: pcmk_sched_utils.c:14
XML_LRM_ATTR_CALLID
#define XML_LRM_ATTR_CALLID
Definition: msg_xml.h:272
hash2field
void hash2field(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry.
Definition: nvpair.c:768
pe_node_shared_s::online
gboolean online
Definition: pe_types.h:190
pe_action_s::task
char * task
Definition: pe_types.h:377
generate_transition_key
char * generate_transition_key(int action, int transition_id, int target_rc, const char *node)
Definition: operations.c:194
pe_node_shared_s::uname
const char * uname
Definition: pe_types.h:186
pe_discover_exclusive
@ pe_discover_exclusive
Definition: pe_types.h:442
sched_shutdown_op
pe_action_t * sched_shutdown_op(pe_node_t *node, pe_working_set_t *data_set)
Definition: pcmk_sched_utils.c:456
crm_xml_add_ms
const char * crm_xml_add_ms(xmlNode *node, const char *name, guint ms)
Create an XML attribute with specified name and unsigned value.
Definition: nvpair.c:443
crm_internal.h
pe_node_s
Definition: pe_types.h:216
generate_notify_key
char * generate_notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
Definition: operations.c:128
pe_discover_never
@ pe_discover_never
Definition: pe_types.h:441
pe_action_s::meta
GHashTable * meta
Definition: pe_types.h:387
XML_BOOLEAN_TRUE
#define XML_BOOLEAN_TRUE
Definition: msg_xml.h:107
log_action
void log_action(unsigned int log_level, const char *pre_text, action_t *action, gboolean details)
Definition: pcmk_sched_utils.c:290
pe_node_shared_s::num_resources
int num_resources
Definition: pe_types.h:206