pacemaker  2.1.9-49aab99839
Scalable High-Availability cluster resource manager
cib_attrs.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2024 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 Lesser General Public License
7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 
12 #include <sys/param.h>
13 
14 #include <crm/crm.h>
15 
16 #include <stdio.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <libgen.h>
24 
25 #include <crm/common/xml.h>
28 #include <crm/cib/internal.h>
29 
30 static pcmk__output_t *
31 new_output_object(const char *ty)
32 {
33  int rc = pcmk_rc_ok;
34  pcmk__output_t *out = NULL;
35  const char* argv[] = { "", NULL };
36  pcmk__supported_format_t formats[] = {
39  { NULL, NULL, NULL }
40  };
41 
42  pcmk__register_formats(NULL, formats);
43  rc = pcmk__output_new(&out, ty, NULL, (char**)argv);
44  if ((rc != pcmk_rc_ok) || (out == NULL)) {
45  crm_err("Can't out due to internal error: %s", pcmk_rc_str(rc));
46  return NULL;
47  }
48 
49  return out;
50 }
51 
52 static int
53 find_attr(cib_t *cib, const char *section, const char *node_uuid,
54  const char *attr_set_type, const char *set_name, const char *attr_id,
55  const char *attr_name, const char *user_name, xmlNode **result)
56 {
57  int rc = pcmk_rc_ok;
58 
59  const char *xpath_base = NULL;
60  GString *xpath = NULL;
61  xmlNode *xml_search = NULL;
62  const char *set_type = NULL;
63  const char *node_type = NULL;
64 
65  if (attr_set_type) {
66  set_type = attr_set_type;
67  } else {
68  set_type = PCMK_XE_INSTANCE_ATTRIBUTES;
69  }
70 
71  if (pcmk__str_eq(section, PCMK_XE_CRM_CONFIG, pcmk__str_casei)) {
72  node_uuid = NULL;
74 
75  } else if (pcmk__strcase_any_of(section,
77  NULL)) {
78  node_uuid = NULL;
79  set_type = PCMK_XE_META_ATTRIBUTES;
80 
81  } else if (pcmk__str_eq(section, PCMK_XE_TICKETS, pcmk__str_casei)) {
82  node_uuid = NULL;
83  section = PCMK_XE_STATUS;
85 
86  } else if (node_uuid == NULL) {
87  return EINVAL;
88  }
89 
90  xpath_base = pcmk_cib_xpath_for(section);
91  if (xpath_base == NULL) {
92  crm_warn("%s CIB section not known", section);
93  return ENOMSG;
94  }
95 
96  xpath = g_string_sized_new(1024);
97  g_string_append(xpath, xpath_base);
98 
99  if (pcmk__str_eq(node_type, PCMK_XE_TICKETS, pcmk__str_casei)) {
100  pcmk__g_strcat(xpath, "//", node_type, NULL);
101 
102  } else if (node_uuid) {
103  const char *node_type = PCMK_XE_NODE;
104 
105  if (pcmk__str_eq(section, PCMK_XE_STATUS, pcmk__str_casei)) {
108  }
109  pcmk__g_strcat(xpath,
110  "//", node_type, "[@" PCMK_XA_ID "='", node_uuid, "']",
111  NULL);
112  }
113 
114  pcmk__g_strcat(xpath, "//", set_type, NULL);
115  if (set_name) {
116  pcmk__g_strcat(xpath, "[@" PCMK_XA_ID "='", set_name, "']", NULL);
117  }
118 
119  g_string_append(xpath, "//nvpair");
120 
121  if (attr_id && attr_name) {
122  pcmk__g_strcat(xpath,
123  "[@" PCMK_XA_ID "='", attr_id, "' "
124  "and @" PCMK_XA_NAME "='", attr_name, "']", NULL);
125 
126  } else if (attr_id) {
127  pcmk__g_strcat(xpath, "[@" PCMK_XA_ID "='", attr_id, "']", NULL);
128 
129  } else if (attr_name) {
130  pcmk__g_strcat(xpath, "[@" PCMK_XA_NAME "='", attr_name, "']", NULL);
131  }
132 
134  (const char *) xpath->str, NULL, &xml_search,
136  rc = pcmk_legacy2rc(rc);
137 
138  if (rc != pcmk_rc_ok) {
139  crm_trace("Query failed for attribute %s (section=%s, node=%s, set=%s, xpath=%s): %s",
140  attr_name, section, pcmk__s(node_uuid, "<null>"),
141  pcmk__s(set_name, "<null>"), (const char *) xpath->str,
142  pcmk_rc_str(rc));
143  } else {
144  crm_log_xml_debug(xml_search, "Match");
145  }
146 
147  g_string_free(xpath, TRUE);
148  *result = xml_search;
149  return rc;
150 }
151 
152 static int
153 handle_multiples(pcmk__output_t *out, xmlNode *search, const char *attr_name)
154 {
155  if ((search != NULL) && (search->children != NULL)) {
156  pcmk__warn_multiple_name_matches(out, search, attr_name);
157  return ENOTUNIQ;
158  } else {
159  return pcmk_rc_ok;
160  }
161 }
162 
163 int
164 cib__update_node_attr(pcmk__output_t *out, cib_t *cib, int call_options, const char *section,
165  const char *node_uuid, const char *set_type, const char *set_name,
166  const char *attr_id, const char *attr_name, const char *attr_value,
167  const char *user_name, const char *node_type)
168 {
169  const char *tag = NULL;
170  int rc = pcmk_rc_ok;
171  xmlNode *xml_top = NULL;
172  xmlNode *xml_obj = NULL;
173  xmlNode *xml_search = NULL;
174 
175  char *local_attr_id = NULL;
176  char *local_set_name = NULL;
177 
178  CRM_CHECK((out != NULL) && (cib != NULL) && (section != NULL)
179  && ((attr_id != NULL) || (attr_name != NULL))
180  && (attr_value != NULL), return EINVAL);
181 
182  rc = find_attr(cib, section, node_uuid, set_type, set_name, attr_id,
183  attr_name, user_name, &xml_search);
184 
185  if (rc == pcmk_rc_ok) {
186  if (handle_multiples(out, xml_search, attr_name) == ENOTUNIQ) {
187  free_xml(xml_search);
188  return ENOTUNIQ;
189  } else {
190  local_attr_id = crm_element_value_copy(xml_search, PCMK_XA_ID);
191  attr_id = local_attr_id;
192  free_xml(xml_search);
193  goto do_modify;
194  }
195 
196  } else if (rc != ENXIO) {
197  free_xml(xml_search);
198  return rc;
199 
200  /* } else if(attr_id == NULL) { */
201  /* return EINVAL; */
202 
203  } else {
204  free_xml(xml_search);
205  crm_trace("%s does not exist, create it", attr_name);
206  if (pcmk__str_eq(section, PCMK_XE_TICKETS, pcmk__str_casei)) {
207  node_uuid = NULL;
208  section = PCMK_XE_STATUS;
210 
211  xml_top = pcmk__xe_create(xml_obj, PCMK_XE_STATUS);
212  xml_obj = pcmk__xe_create(xml_top, PCMK_XE_TICKETS);
213 
214  } else if (pcmk__str_eq(section, PCMK_XE_NODES, pcmk__str_casei)) {
215 
216  if (node_uuid == NULL) {
217  return EINVAL;
218  }
219 
220  if (pcmk__str_eq(node_type, PCMK_VALUE_REMOTE, pcmk__str_casei)) {
221  xml_top = pcmk__xe_create(xml_obj, PCMK_XE_NODES);
222  xml_obj = pcmk__xe_create(xml_top, PCMK_XE_NODE);
224  crm_xml_add(xml_obj, PCMK_XA_ID, node_uuid);
225  crm_xml_add(xml_obj, PCMK_XA_UNAME, node_uuid);
226  } else {
227  tag = PCMK_XE_NODE;
228  }
229 
230  } else if (pcmk__str_eq(section, PCMK_XE_STATUS, pcmk__str_casei)) {
232  if (node_uuid == NULL) {
233  return EINVAL;
234  }
235 
236  xml_top = pcmk__xe_create(xml_obj, PCMK__XE_NODE_STATE);
237  crm_xml_add(xml_top, PCMK_XA_ID, node_uuid);
238  xml_obj = xml_top;
239 
240  } else {
241  tag = section;
242  node_uuid = NULL;
243  }
244 
245  if (set_name == NULL) {
246  if (pcmk__str_eq(section, PCMK_XE_CRM_CONFIG, pcmk__str_casei)) {
247  local_set_name =
249 
250  } else if (pcmk__str_eq(node_type, PCMK_XE_TICKETS,
251  pcmk__str_casei)) {
252  local_set_name = crm_strdup_printf("%s-%s", section,
254 
255  } else if (node_uuid) {
256  local_set_name = crm_strdup_printf("%s-%s", section, node_uuid);
257 
258  if (set_type) {
259  char *tmp_set_name = local_set_name;
260 
261  local_set_name = crm_strdup_printf("%s-%s", tmp_set_name,
262  set_type);
263  free(tmp_set_name);
264  }
265  } else {
266  local_set_name = crm_strdup_printf("%s-options", section);
267  }
268  set_name = local_set_name;
269  }
270 
271  if (attr_id == NULL) {
272  local_attr_id = crm_strdup_printf("%s-%s", set_name, attr_name);
273  crm_xml_sanitize_id(local_attr_id);
274  attr_id = local_attr_id;
275 
276  } else if (attr_name == NULL) {
277  attr_name = attr_id;
278  }
279 
280  crm_trace("Creating %s/%s", section, tag);
281  if (tag != NULL) {
282  xml_obj = pcmk__xe_create(xml_obj, tag);
283  crm_xml_add(xml_obj, PCMK_XA_ID, node_uuid);
284  if (xml_top == NULL) {
285  xml_top = xml_obj;
286  }
287  }
288 
289  if ((node_uuid == NULL)
290  && !pcmk__str_eq(node_type, PCMK_XE_TICKETS, pcmk__str_casei)) {
291 
292  if (pcmk__str_eq(section, PCMK_XE_CRM_CONFIG, pcmk__str_casei)) {
293  xml_obj = pcmk__xe_create(xml_obj,
295  } else {
296  xml_obj = pcmk__xe_create(xml_obj, PCMK_XE_META_ATTRIBUTES);
297  }
298 
299  } else if (set_type) {
300  xml_obj = pcmk__xe_create(xml_obj, set_type);
301 
302  } else {
303  xml_obj = pcmk__xe_create(xml_obj, PCMK_XE_INSTANCE_ATTRIBUTES);
304  }
305  crm_xml_add(xml_obj, PCMK_XA_ID, set_name);
306 
307  if (xml_top == NULL) {
308  xml_top = xml_obj;
309  }
310  }
311 
312  do_modify:
313  xml_obj = crm_create_nvpair_xml(xml_obj, attr_id, attr_name, attr_value);
314  if (xml_top == NULL) {
315  xml_top = xml_obj;
316  }
317 
318  crm_log_xml_trace(xml_top, "update_attr");
319  rc = cib_internal_op(cib, PCMK__CIB_REQUEST_MODIFY, NULL, section, xml_top,
320  NULL, call_options, user_name);
321 
322  if (!pcmk_is_set(call_options, cib_sync_call) && (cib->variant != cib_file)
323  && (rc >= 0)) {
324  // For async call, positive rc is the call ID (file always synchronous)
325  rc = pcmk_rc_ok;
326  } else {
327  rc = pcmk_legacy2rc(rc);
328  }
329 
330  if (rc != pcmk_rc_ok) {
331  out->err(out, "Error setting %s=%s (section=%s, set=%s): %s",
332  attr_name, attr_value, section, pcmk__s(set_name, "<null>"),
333  pcmk_rc_str(rc));
334  crm_log_xml_info(xml_top, "Update");
335  }
336 
337  free(local_set_name);
338  free(local_attr_id);
339  free_xml(xml_top);
340 
341  return rc;
342 }
343 
344 int
345 cib__get_node_attrs(pcmk__output_t *out, cib_t *cib, const char *section,
346  const char *node_uuid, const char *set_type, const char *set_name,
347  const char *attr_id, const char *attr_name, const char *user_name,
348  xmlNode **result)
349 {
350  int rc = pcmk_rc_ok;
351 
352  pcmk__assert(result != NULL);
353  CRM_CHECK(section != NULL, return EINVAL);
354 
355  *result = NULL;
356 
357  rc = find_attr(cib, section, node_uuid, set_type, set_name, attr_id, attr_name,
358  user_name, result);
359 
360  if (rc != pcmk_rc_ok) {
361  crm_trace("Query failed for attribute %s (section=%s node=%s set=%s): %s",
362  pcmk__s(attr_name, "with unspecified name"),
363  section, pcmk__s(set_name, "<null>"),
364  pcmk__s(node_uuid, "<null>"), pcmk_rc_str(rc));
365  }
366 
367  return rc;
368 }
369 
370 int
371 cib__delete_node_attr(pcmk__output_t *out, cib_t *cib, int options, const char *section,
372  const char *node_uuid, const char *set_type, const char *set_name,
373  const char *attr_id, const char *attr_name, const char *attr_value,
374  const char *user_name)
375 {
376  int rc = pcmk_rc_ok;
377  xmlNode *xml_obj = NULL;
378  xmlNode *xml_search = NULL;
379  char *local_attr_id = NULL;
380 
381  CRM_CHECK(section != NULL, return EINVAL);
382  CRM_CHECK(attr_name != NULL || attr_id != NULL, return EINVAL);
383 
384  if (attr_id == NULL) {
385  rc = find_attr(cib, section, node_uuid, set_type, set_name, attr_id,
386  attr_name, user_name, &xml_search);
387 
388  if (rc != pcmk_rc_ok || handle_multiples(out, xml_search, attr_name) == ENOTUNIQ) {
389  free_xml(xml_search);
390  return rc;
391  } else {
392  local_attr_id = crm_element_value_copy(xml_search, PCMK_XA_ID);
393  attr_id = local_attr_id;
394  free_xml(xml_search);
395  }
396  }
397 
398  xml_obj = crm_create_nvpair_xml(NULL, attr_id, attr_name, attr_value);
399 
400  rc = cib_internal_op(cib, PCMK__CIB_REQUEST_DELETE, NULL, section, xml_obj,
401  NULL, options, user_name);
402 
403  if (!pcmk_is_set(options, cib_sync_call) && (cib->variant != cib_file)
404  && (rc >= 0)) {
405  // For async call, positive rc is the call ID (file always synchronous)
406  rc = pcmk_rc_ok;
407  } else {
408  rc = pcmk_legacy2rc(rc);
409  }
410 
411  if (rc == pcmk_rc_ok) {
412  out->info(out, "Deleted %s %s: id=%s%s%s%s%s",
413  section, node_uuid ? "attribute" : "option", local_attr_id,
414  set_name ? " set=" : "", set_name ? set_name : "",
415  attr_name ? " name=" : "", attr_name ? attr_name : "");
416  }
417  free(local_attr_id);
418  free_xml(xml_obj);
419  return rc;
420 }
421 
422 int
423 find_nvpair_attr_delegate(cib_t *cib, const char *attr, const char *section,
424  const char *node_uuid, const char *attr_set_type, const char *set_name,
425  const char *attr_id, const char *attr_name, gboolean to_console,
426  char **value, const char *user_name)
427 {
428  pcmk__output_t *out = NULL;
429  xmlNode *xml_search = NULL;
430  int rc = pcmk_ok;
431 
432  out = new_output_object(to_console ? "text" : "log");
433  if (out == NULL) {
434  return pcmk_err_generic;
435  }
436 
437  rc = find_attr(cib, section, node_uuid, attr_set_type, set_name, attr_id,
438  attr_name, user_name, &xml_search);
439 
440  if (rc == pcmk_rc_ok) {
441  rc = handle_multiples(out, xml_search, attr_name);
442 
443  if (rc == pcmk_rc_ok) {
444  pcmk__str_update(value, crm_element_value(xml_search, attr));
445  }
446  }
447 
448  out->finish(out, CRM_EX_OK, true, NULL);
449  free_xml(xml_search);
450  pcmk__output_free(out);
451  return pcmk_rc2legacy(rc);
452 }
453 
454 int
455 update_attr_delegate(cib_t *cib, int call_options, const char *section,
456  const char *node_uuid, const char *set_type, const char *set_name,
457  const char *attr_id, const char *attr_name, const char *attr_value,
458  gboolean to_console, const char *user_name, const char *node_type)
459 {
460  pcmk__output_t *out = NULL;
461  int rc = pcmk_ok;
462 
463  out = new_output_object(to_console ? "text" : "log");
464  if (out == NULL) {
465  return pcmk_err_generic;
466  }
467 
468  rc = cib__update_node_attr(out, cib, call_options, section, node_uuid, set_type,
469  set_name, attr_id, attr_name, attr_value, user_name,
470  node_type);
471 
472  out->finish(out, CRM_EX_OK, true, NULL);
473  pcmk__output_free(out);
474  return pcmk_rc2legacy(rc);
475 }
476 
477 int
478 read_attr_delegate(cib_t *cib, const char *section, const char *node_uuid,
479  const char *set_type, const char *set_name, const char *attr_id,
480  const char *attr_name, char **attr_value, gboolean to_console,
481  const char *user_name)
482 {
483  pcmk__output_t *out = NULL;
484  xmlNode *result = NULL;
485  int rc = pcmk_ok;
486 
487  out = new_output_object(to_console ? "text" : "log");
488  if (out == NULL) {
489  return pcmk_err_generic;
490  }
491 
492  rc = cib__get_node_attrs(out, cib, section, node_uuid, set_type, set_name,
493  attr_id, attr_name, user_name, &result);
494 
495  if (rc == pcmk_rc_ok) {
496  if (result->children == NULL) {
497  pcmk__str_update(attr_value,
499  } else {
500  rc = ENOTUNIQ;
501  }
502  }
503 
504  out->finish(out, CRM_EX_OK, true, NULL);
505  free_xml(result);
506  pcmk__output_free(out);
507  return pcmk_rc2legacy(rc);
508 }
509 
510 int
511 delete_attr_delegate(cib_t *cib, int options, const char *section, const char *node_uuid,
512  const char *set_type, const char *set_name, const char *attr_id,
513  const char *attr_name, const char *attr_value, gboolean to_console,
514  const char *user_name)
515 {
516  pcmk__output_t *out = NULL;
517  int rc = pcmk_ok;
518 
519  out = new_output_object(to_console ? "text" : "log");
520  if (out == NULL) {
521  return pcmk_err_generic;
522  }
523 
524  rc = cib__delete_node_attr(out, cib, options, section, node_uuid, set_type,
525  set_name, attr_id, attr_name, attr_value, user_name);
526 
527  out->finish(out, CRM_EX_OK, true, NULL);
528  pcmk__output_free(out);
529  return pcmk_rc2legacy(rc);
530 }
531 
542 static int
543 get_uuid_from_result(const xmlNode *result, char **uuid, int *is_remote)
544 {
545  int rc = -ENXIO;
546  const char *parsed_uuid = NULL;
547  int parsed_is_remote = FALSE;
548 
549  if (result == NULL) {
550  return rc;
551  }
552 
553  /* If there are multiple results, the first is sufficient */
554  if (pcmk__xe_is(result, PCMK__XE_XPATH_QUERY)) {
555  result = pcmk__xe_first_child(result, NULL, NULL, NULL);
556  CRM_CHECK(result != NULL, return rc);
557  }
558 
559  if (pcmk__xe_is(result, PCMK_XE_NODE)) {
560  // Result is PCMK_XE_NODE element from PCMK_XE_NODES section
561 
562  if (pcmk__str_eq(crm_element_value(result, PCMK_XA_TYPE),
564  parsed_uuid = crm_element_value(result, PCMK_XA_UNAME);
565  parsed_is_remote = TRUE;
566  } else {
567  parsed_uuid = pcmk__xe_id(result);
568  parsed_is_remote = FALSE;
569  }
570 
571  } else if (pcmk__xe_is(result, PCMK_XE_PRIMITIVE)) {
572  /* Result is <primitive> for ocf:pacemaker:remote resource */
573 
574  parsed_uuid = pcmk__xe_id(result);
575  parsed_is_remote = TRUE;
576 
577  } else if (pcmk__xe_is(result, PCMK_XE_NVPAIR)) {
578  /* Result is PCMK_META_REMOTE_NODE parameter of <primitive> for guest
579  * node
580  */
581 
582  parsed_uuid = crm_element_value(result, PCMK_XA_VALUE);
583  parsed_is_remote = TRUE;
584 
585  } else if (pcmk__xe_is(result, PCMK__XE_NODE_STATE)) {
586  // Result is PCMK__XE_NODE_STATE element from PCMK_XE_STATUS section
587 
588  parsed_uuid = crm_element_value(result, PCMK_XA_UNAME);
590  parsed_is_remote = TRUE;
591  }
592  }
593 
594  if (parsed_uuid) {
595  if (uuid) {
596  *uuid = strdup(parsed_uuid);
597  }
598  if (is_remote) {
599  *is_remote = parsed_is_remote;
600  }
601  rc = pcmk_ok;
602  }
603 
604  return rc;
605 }
606 
607 /* Search string to find a node by name, as:
608  * - cluster or remote node in nodes section
609  * - remote node in resources section
610  * - guest node in resources section
611  * - orphaned remote node or bundle guest node in status section
612  */
613 #define XPATH_UPPER_TRANS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
614 #define XPATH_LOWER_TRANS "abcdefghijklmnopqrstuvwxyz"
615 #define XPATH_NODE \
616  "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_NODES \
617  "/" PCMK_XE_NODE "[translate(@" PCMK_XA_UNAME ",'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \
618  "|/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_RESOURCES \
619  "/" PCMK_XE_PRIMITIVE \
620  "[@class='ocf'][@provider='pacemaker'][@type='remote'][translate(@id,'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \
621  "|/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_RESOURCES \
622  "/" PCMK_XE_PRIMITIVE "/" PCMK_XE_META_ATTRIBUTES "/" PCMK_XE_NVPAIR \
623  "[@name='" PCMK_META_REMOTE_NODE "'][translate(@value,'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \
624  "|/" PCMK_XE_CIB "/" PCMK_XE_STATUS "/" PCMK__XE_NODE_STATE \
625  "[@" PCMK_XA_REMOTE_NODE "='true'][translate(@" PCMK_XA_ID ",'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']"
626 
627 int
628 query_node_uuid(cib_t * the_cib, const char *uname, char **uuid, int *is_remote_node)
629 {
630  int rc = pcmk_ok;
631  char *xpath_string;
632  xmlNode *xml_search = NULL;
633  char *host_lowercase = NULL;
634 
635  pcmk__assert(uname != NULL);
636 
637  host_lowercase = g_ascii_strdown(uname, -1);
638 
639  if (uuid) {
640  *uuid = NULL;
641  }
642  if (is_remote_node) {
643  *is_remote_node = FALSE;
644  }
645 
646  xpath_string = crm_strdup_printf(XPATH_NODE, host_lowercase, host_lowercase, host_lowercase, host_lowercase);
647  if (cib_internal_op(the_cib, PCMK__CIB_REQUEST_QUERY, NULL, xpath_string,
648  NULL, &xml_search,
650  NULL) == pcmk_ok) {
651  rc = get_uuid_from_result(xml_search, uuid, is_remote_node);
652  } else {
653  rc = -ENXIO;
654  }
655  free(xpath_string);
656  free_xml(xml_search);
657  g_free(host_lowercase);
658 
659  if (rc != pcmk_ok) {
660  crm_debug("Could not map node name '%s' to a UUID: %s",
661  uname, pcmk_strerror(rc));
662  } else {
663  crm_info("Mapped node name '%s' to UUID %s", uname, (uuid? *uuid : ""));
664  }
665  return rc;
666 }
667 
668 // Deprecated functions kept only for backward API compatibility
669 // LCOV_EXCL_START
670 
671 #include <crm/cib/util_compat.h>
672 
673 int
674 query_node_uname(cib_t * the_cib, const char *uuid, char **uname)
675 {
676  int rc = pcmk_ok;
677  xmlNode *a_child = NULL;
678  xmlNode *xml_obj = NULL;
679  xmlNode *fragment = NULL;
680  const char *child_name = NULL;
681 
682  pcmk__assert(uname != NULL);
683  pcmk__assert(uuid != NULL);
684 
685  rc = the_cib->cmds->query(the_cib, PCMK_XE_NODES, &fragment,
687  if (rc != pcmk_ok) {
688  return rc;
689  }
690 
691  xml_obj = fragment;
692  CRM_CHECK(pcmk__xe_is(xml_obj, PCMK_XE_NODES), return -ENOMSG);
693  crm_log_xml_trace(xml_obj, "Result section");
694 
695  rc = -ENXIO;
696  *uname = NULL;
697 
698  for (a_child = pcmk__xe_first_child(xml_obj, PCMK_XE_NODE, NULL, NULL);
699  a_child != NULL; a_child = pcmk__xe_next_same(a_child)) {
700 
701  child_name = pcmk__xe_id(a_child);
702 
703  if (pcmk__str_eq(uuid, child_name, pcmk__str_casei)) {
704  child_name = crm_element_value(a_child, PCMK_XA_UNAME);
705  if (child_name != NULL) {
706  *uname = strdup(child_name);
707  rc = pcmk_ok;
708  }
709  break;
710  }
711  }
712 
713  free_xml(fragment);
714  return rc;
715 }
716 
717 int
718 set_standby(cib_t * the_cib, const char *uuid, const char *scope, const char *standby_value)
719 {
720  int rc = pcmk_ok;
721  char *attr_id = NULL;
722 
723  CRM_CHECK(uuid != NULL, return -EINVAL);
724  CRM_CHECK(standby_value != NULL, return -EINVAL);
725 
726  if (pcmk__strcase_any_of(scope, "reboot", PCMK_XE_STATUS, NULL)) {
727  scope = PCMK_XE_STATUS;
728  attr_id = crm_strdup_printf("transient-standby-%.256s", uuid);
729 
730  } else {
731  scope = PCMK_XE_NODES;
732  attr_id = crm_strdup_printf("standby-%.256s", uuid);
733  }
734 
735  rc = update_attr_delegate(the_cib, cib_sync_call, scope, uuid, NULL, NULL,
736  attr_id, PCMK_NODE_ATTR_STANDBY, standby_value,
737  TRUE, NULL, NULL);
738 
739  free(attr_id);
740  return rc;
741 }
742 
743 // LCOV_EXCL_STOP
744 // End deprecated API
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:245
#define PCMK__SUPPORTED_FORMAT_LOG
A dumping ground.
#define PCMK_XE_NVPAIR
Definition: xml_names.h:144
const char * pcmk_strerror(int rc)
Definition: results.c:151
#define PCMK_XA_NAME
Definition: xml_names.h:330
node_type
Definition: nodes.h:39
#define PCMK_XE_OP_DEFAULTS
Definition: xml_names.h:147
int pcmk_rc2legacy(int rc)
Definition: results.c:548
#define PCMK_XA_REMOTE_NODE
Definition: xml_names.h:376
#define PCMK_XE_STATUS
Definition: xml_names.h:204
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:1038
#define PCMK_XE_PRIMITIVE
Definition: xml_names.h:164
#define PCMK__SUPPORTED_FORMAT_TEXT
#define PCMK__CIB_REQUEST_QUERY
Definition: internal.h:23
#define PCMK_XE_RSC_DEFAULTS
Definition: xml_names.h:186
int set_standby(cib_t *the_cib, const char *uuid, const char *scope, const char *standby_value)
Definition: cib_attrs.c:718
#define PCMK__XE_XPATH_QUERY
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
#define pcmk_err_generic
Definition: results.h:69
int(* info)(pcmk__output_t *out, const char *format,...) G_GNUC_PRINTF(2
bool pcmk__xe_attr_is_true(const xmlNode *node, const char *name)
Definition: nvpair.c:1020
Deprecated Pacemaker configuration utilities.
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition: results.c:503
int cib__delete_node_attr(pcmk__output_t *out, cib_t *cib, int 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)
Definition: cib_attrs.c:371
#define PCMK_XA_TYPE
Definition: xml_names.h:430
void crm_xml_sanitize_id(char *id)
Sanitize a string so it is usable as an XML ID.
Definition: xml.c:1065
#define PCMK__XE_TRANSIENT_ATTRIBUTES
int cib__get_node_attrs(pcmk__output_t *out, cib_t *cib, 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 *user_name, xmlNode **result)
Definition: cib_attrs.c:345
#define crm_warn(fmt, args...)
Definition: logging.h:394
Formatted output for pacemaker tools.
void pcmk__register_formats(GOptionGroup *group, const pcmk__supported_format_t *table)
Definition: output.c:153
cib_api_operations_t * cmds
Definition: cib_types.h:399
#define crm_debug(fmt, args...)
Definition: logging.h:402
#define PCMK_XA_UNAME
Definition: xml_names.h:431
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:758
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:458
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
Definition: xml.c:481
int find_nvpair_attr_delegate(cib_t *cib, const char *attr, const char *section, const char *node_uuid, const char *attr_set_type, const char *set_name, const char *attr_id, const char *attr_name, gboolean to_console, char **value, const char *user_name)
Definition: cib_attrs.c:423
#define crm_trace(fmt, args...)
Definition: logging.h:404
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:1308
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:94
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:411
#define PCMK_XE_CLUSTER_PROPERTY_SET
Definition: xml_names.h:84
void pcmk__str_update(char **str, const char *value)
Definition: strings.c:1289
Wrappers for and extensions to libxml2.
void(* finish)(pcmk__output_t *out, crm_exit_t exit_status, bool print, void **copy_dest)
int(* query)(cib_t *cib, const char *section, xmlNode **output_data, int call_options)
Definition: cib_types.h:198
int query_node_uuid(cib_t *the_cib, const char *uname, char **uuid, int *is_remote_node)
Definition: cib_attrs.c:628
#define PCMK_XA_ID
Definition: xml_names.h:301
Success.
Definition: results.h:251
int pcmk_legacy2rc(int legacy_rc)
Definition: results.c:561
#define PCMK_NODE_ATTR_STANDBY
Definition: nodes.h:32
#define PCMK_XA_VALUE
Definition: xml_names.h:442
void free_xml(xmlNode *child)
Definition: xml.c:958
#define XPATH_NODE
Definition: cib_attrs.c:615
#define pcmk__str_copy(str)
#define PCMK_XE_TICKETS
Definition: xml_names.h:213
#define PCMK_XE_META_ATTRIBUTES
Definition: xml_names.h:130
void pcmk__output_free(pcmk__output_t *out)
Definition: output.c:30
const char * pcmk_cib_xpath_for(const char *element_name)
Get the relative XPath needed to find a specified CIB element name.
Definition: cib.c:112
#define pcmk__assert(expr)
int update_attr_delegate(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, gboolean to_console, const char *user_name, const char *node_type)
Definition: cib_attrs.c:455
#define PCMK_XE_NODE
Definition: xml_names.h:136
pcmk__action_result_t result
Definition: pcmk_fence.c:35
#define PCMK_VALUE_CIB_BOOTSTRAP_OPTIONS
Definition: options.h:137
#define crm_err(fmt, args...)
Definition: logging.h:391
#define ENOTUNIQ
Definition: portability.h:81
This structure contains everything that makes up a single output formatter.
#define crm_log_xml_info(xml, text)
Definition: logging.h:410
char uname[MAX_NAME]
Definition: cpg.c:53
enum cib_variant variant
Definition: cib_types.h:385
#define PCMK__XE_NODE_STATE
#define pcmk_ok
Definition: results.h:65
int read_attr_delegate(cib_t *cib, const char *section, const char *node_uuid, const char *set_type, const char *set_name, const char *attr_id, const char *attr_name, char **attr_value, gboolean to_console, const char *user_name)
Definition: cib_attrs.c:478
void pcmk__warn_multiple_name_matches(pcmk__output_t *out, xmlNode *search, const char *name)
Definition: xpath.c:332
#define PCMK_XE_NODES
Definition: xml_names.h:142
int pcmk__output_new(pcmk__output_t **out, const char *fmt_name, const char *filename, char **argv)
Definition: output.c:113
#define crm_log_xml_trace(xml, text)
Definition: logging.h:412
int delete_attr_delegate(cib_t *cib, int 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)
Definition: cib_attrs.c:511
#define PCMK__CIB_REQUEST_MODIFY
Definition: internal.h:25
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:883
int cib_internal_op(cib_t *cib, const char *op, const char *host, const char *section, xmlNode *data, xmlNode **output_data, int call_options, const char *user_name)
Definition: cib_utils.c:884
int query_node_uname(cib_t *the_cib, const char *uuid, char **uname)
Definition: cib_attrs.c:674
xmlNode * pcmk__xe_create(xmlNode *parent, const char *name)
Definition: xml.c:770
#define PCMK_XE_INSTANCE_ATTRIBUTES
Definition: xml_names.h:122
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:164
xmlNode * pcmk__xe_next_same(const xmlNode *node)
Definition: xml.c:2130
#define PCMK_VALUE_REMOTE
Definition: options.h:198
#define crm_info(fmt, args...)
Definition: logging.h:399
#define PCMK_XE_CRM_CONFIG
Definition: xml_names.h:91
#define PCMK__CIB_REQUEST_DELETE
Definition: internal.h:26