pacemaker  2.1.3-ea053b43a
Scalable High-Availability cluster resource manager
nvpair.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2022 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 <stdio.h>
13 #include <sys/types.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <glib.h>
17 #include <libxml/tree.h>
18 
19 #include <crm/crm.h>
20 #include <crm/msg_xml.h>
21 #include <crm/common/xml.h>
23 #include "crmcommon_private.h"
24 
25 /*
26  * This file isolates handling of three types of name/value pairs:
27  *
28  * - pcmk_nvpair_t data type
29  * - XML attributes (<TAG ... NAME=VALUE ...>)
30  * - XML nvpair elements (<nvpair id=ID name=NAME value=VALUE>)
31  */
32 
33 // pcmk_nvpair_t handling
34 
46 static pcmk_nvpair_t *
47 pcmk__new_nvpair(const char *name, const char *value)
48 {
49  pcmk_nvpair_t *nvpair = NULL;
50 
52 
53  nvpair = calloc(1, sizeof(pcmk_nvpair_t));
54  CRM_ASSERT(nvpair);
55 
56  pcmk__str_update(&nvpair->name, name);
57  pcmk__str_update(&nvpair->value, value);
58  return nvpair;
59 }
60 
67 static void
68 pcmk__free_nvpair(gpointer data)
69 {
70  if (data) {
71  pcmk_nvpair_t *nvpair = data;
72 
73  free(nvpair->name);
74  free(nvpair->value);
75  free(nvpair);
76  }
77 }
78 
90 GSList *
91 pcmk_prepend_nvpair(GSList *nvpairs, const char *name, const char *value)
92 {
93  return g_slist_prepend(nvpairs, pcmk__new_nvpair(name, value));
94 }
95 
101 void
102 pcmk_free_nvpairs(GSList *nvpairs)
103 {
104  g_slist_free_full(nvpairs, pcmk__free_nvpair);
105 }
106 
116 static gint
117 pcmk__compare_nvpair(gconstpointer a, gconstpointer b)
118 {
119  int rc = 0;
120  const pcmk_nvpair_t *pair_a = a;
121  const pcmk_nvpair_t *pair_b = b;
122 
123  CRM_ASSERT(a != NULL);
124  CRM_ASSERT(pair_a->name != NULL);
125 
126  CRM_ASSERT(b != NULL);
127  CRM_ASSERT(pair_b->name != NULL);
128 
129  rc = strcmp(pair_a->name, pair_b->name);
130  if (rc < 0) {
131  return -1;
132  } else if (rc > 0) {
133  return 1;
134  }
135  return 0;
136 }
137 
145 GSList *
146 pcmk_sort_nvpairs(GSList *list)
147 {
148  return g_slist_sort(list, pcmk__compare_nvpair);
149 }
150 
160 GSList *
162 {
163  GSList *result = NULL;
164 
165  for (xmlAttrPtr iter = pcmk__xe_first_attr(xml); iter != NULL;
166  iter = iter->next) {
167 
169  (const char *) iter->name,
170  (const char *) pcmk__xml_attr_value(iter));
171  }
172  return result;
173 }
174 
185 static void
186 pcmk__nvpair_add_xml_attr(gpointer data, gpointer user_data)
187 {
188  pcmk_nvpair_t *pair = data;
189  xmlNode *parent = user_data;
190 
191  crm_xml_add(parent, pair->name, pair->value);
192 }
193 
200 void
201 pcmk_nvpairs2xml_attrs(GSList *list, xmlNode *xml)
202 {
203  g_slist_foreach(list, pcmk__nvpair_add_xml_attr, xml);
204 }
205 
206 // convenience function for name=value strings
207 
220 int
221 pcmk__scan_nvpair(const char *input, char **name, char **value)
222 {
223 #ifdef SSCANF_HAS_M
224  *name = NULL;
225  *value = NULL;
226  if (sscanf(input, "%m[^=]=%m[^\n]", name, value) <= 0) {
227  return -pcmk_err_bad_nvpair;
228  }
229 #else
230  char *sep = NULL;
231  *name = NULL;
232  *value = NULL;
233 
234  sep = strstr(optarg, "=");
235  if (sep == NULL) {
236  return -pcmk_err_bad_nvpair;
237  }
238 
239  *name = strndup(input, sep-input);
240 
241  if (*name == NULL) {
242  return -ENOMEM;
243  }
244 
245  /* If the last char in optarg is =, the user gave no
246  * value for the option. Leave it as NULL.
247  */
248  if (*(sep+1) != '\0') {
249  *value = strdup(sep+1);
250 
251  if (*value == NULL) {
252  return -ENOMEM;
253  }
254  }
255 #endif
256 
257  if (*name != NULL && *value != NULL) {
258  return 2;
259  } else if (*name != NULL || *value != NULL) {
260  return 1;
261  } else {
262  return -pcmk_err_bad_nvpair;
263  }
264 }
265 
283 char *
284 pcmk__format_nvpair(const char *name, const char *value, const char *units)
285 {
286  return crm_strdup_printf("%s=\"%s%s\"", name, value, units ? units : "");
287 }
288 
302 char *
303 pcmk__format_named_time(const char *name, time_t epoch_time)
304 {
305  const char *now_str = pcmk__epoch2str(&epoch_time);
306 
307  return crm_strdup_printf("%s=\"%s\"", name, now_str ? now_str : "");
308 }
309 
310 // XML attribute handling
311 
322 const char *
323 crm_xml_add(xmlNode *node, const char *name, const char *value)
324 {
325  bool dirty = FALSE;
326  xmlAttr *attr = NULL;
327 
328  CRM_CHECK(node != NULL, return NULL);
329  CRM_CHECK(name != NULL, return NULL);
330 
331  if (value == NULL) {
332  return NULL;
333  }
334 #if XML_PARANOIA_CHECKS
335  {
336  const char *old_value = NULL;
337 
338  old_value = crm_element_value(node, name);
339 
340  /* Could be re-setting the same value */
341  CRM_CHECK(old_value != value,
342  crm_err("Cannot reset %s with crm_xml_add(%s)", name, value);
343  return value);
344  }
345 #endif
346 
347  if (pcmk__tracking_xml_changes(node, FALSE)) {
348  const char *old = crm_element_value(node, name);
349 
350  if (old == NULL || value == NULL || strcmp(old, value) != 0) {
351  dirty = TRUE;
352  }
353  }
354 
355  if (dirty && (pcmk__check_acl(node, name, pcmk__xf_acl_create) == FALSE)) {
356  crm_trace("Cannot add %s=%s to %s", name, value, node->name);
357  return NULL;
358  }
359 
360  attr = xmlSetProp(node, (pcmkXmlStr) name, (pcmkXmlStr) value);
361  if (dirty) {
363  }
364 
365  CRM_CHECK(attr && attr->children && attr->children->content, return NULL);
366  return (char *)attr->children->content;
367 }
368 
379 const char *
380 crm_xml_replace(xmlNode *node, const char *name, const char *value)
381 {
382  bool dirty = FALSE;
383  xmlAttr *attr = NULL;
384  const char *old_value = NULL;
385 
386  CRM_CHECK(node != NULL, return NULL);
387  CRM_CHECK(name != NULL && name[0] != 0, return NULL);
388 
389  old_value = crm_element_value(node, name);
390 
391  /* Could be re-setting the same value */
392  CRM_CHECK(old_value != value, return value);
393 
394  if (pcmk__check_acl(node, name, pcmk__xf_acl_write) == FALSE) {
395  /* Create a fake object linked to doc->_private instead? */
396  crm_trace("Cannot replace %s=%s to %s", name, value, node->name);
397  return NULL;
398 
399  } else if (old_value && !value) {
400  xml_remove_prop(node, name);
401  return NULL;
402  }
403 
404  if (pcmk__tracking_xml_changes(node, FALSE)) {
405  if (!old_value || !value || !strcmp(old_value, value)) {
406  dirty = TRUE;
407  }
408  }
409 
410  attr = xmlSetProp(node, (pcmkXmlStr) name, (pcmkXmlStr) value);
411  if (dirty) {
413  }
414  CRM_CHECK(attr && attr->children && attr->children->content, return NULL);
415  return (char *) attr->children->content;
416 }
417 
430 const char *
431 crm_xml_add_int(xmlNode *node, const char *name, int value)
432 {
433  char *number = pcmk__itoa(value);
434  const char *added = crm_xml_add(node, name, number);
435 
436  free(number);
437  return added;
438 }
439 
452 const char *
453 crm_xml_add_ms(xmlNode *node, const char *name, guint ms)
454 {
455  char *number = crm_strdup_printf("%u", ms);
456  const char *added = crm_xml_add(node, name, number);
457 
458  free(number);
459  return added;
460 }
461 
462 // Maximum size of null-terminated string representation of 64-bit integer
463 // -9223372036854775808
464 #define LLSTRSIZE 21
465 
480 const char *
481 crm_xml_add_ll(xmlNode *xml, const char *name, long long value)
482 {
483  char s[LLSTRSIZE] = { '\0', };
484 
485  if (snprintf(s, LLSTRSIZE, "%lld", (long long) value) == LLSTRSIZE) {
486  return NULL;
487  }
488  return crm_xml_add(xml, name, s);
489 }
490 
504 const char *
505 crm_xml_add_timeval(xmlNode *xml, const char *name_sec, const char *name_usec,
506  const struct timeval *value)
507 {
508  const char *added = NULL;
509 
510  if (xml && name_sec && value) {
511  added = crm_xml_add_ll(xml, name_sec, (long long) value->tv_sec);
512  if (added && name_usec) {
513  // Any error is ignored (we successfully added seconds)
514  crm_xml_add_ll(xml, name_usec, (long long) value->tv_usec);
515  }
516  }
517  return added;
518 }
519 
528 const char *
529 crm_element_value(const xmlNode *data, const char *name)
530 {
531  xmlAttr *attr = NULL;
532 
533  if (data == NULL) {
534  crm_err("Couldn't find %s in NULL", name ? name : "<null>");
535  CRM_LOG_ASSERT(data != NULL);
536  return NULL;
537 
538  } else if (name == NULL) {
539  crm_err("Couldn't find NULL in %s", crm_element_name(data));
540  return NULL;
541  }
542 
543  /* The first argument to xmlHasProp() has always been const,
544  * but libxml2 <2.9.2 didn't declare that, so cast it
545  */
546  attr = xmlHasProp((xmlNode *) data, (pcmkXmlStr) name);
547  if (!attr || !attr->children) {
548  return NULL;
549  }
550  return (const char *) attr->children->content;
551 }
552 
564 int
565 crm_element_value_int(const xmlNode *data, const char *name, int *dest)
566 {
567  const char *value = NULL;
568 
569  CRM_CHECK(dest != NULL, return -1);
570  value = crm_element_value(data, name);
571  if (value) {
572  long long value_ll;
573 
574  if ((pcmk__scan_ll(value, &value_ll, 0LL) != pcmk_rc_ok)
575  || (value_ll < INT_MIN) || (value_ll > INT_MAX)) {
576  *dest = PCMK__PARSE_INT_DEFAULT;
577  } else {
578  *dest = (int) value_ll;
579  return 0;
580  }
581  }
582  return -1;
583 }
584 
596 int
597 crm_element_value_ll(const xmlNode *data, const char *name, long long *dest)
598 {
599  const char *value = NULL;
600 
601  CRM_CHECK(dest != NULL, return -1);
602  value = crm_element_value(data, name);
603  if ((value != NULL)
604  && (pcmk__scan_ll(value, dest, PCMK__PARSE_INT_DEFAULT) == pcmk_rc_ok)) {
605  return 0;
606  }
607  return -1;
608 }
609 
621 int
622 crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
623 {
624  const char *value = NULL;
625  long long value_ll;
626 
627  CRM_CHECK(dest != NULL, return -1);
628  *dest = 0;
629  value = crm_element_value(data, name);
630  if ((pcmk__scan_ll(value, &value_ll, 0LL) != pcmk_rc_ok)
631  || (value_ll < 0) || (value_ll > G_MAXUINT)) {
632  return -1;
633  }
634  *dest = (guint) value_ll;
635  return pcmk_ok;
636 }
637 
649 int
650 crm_element_value_epoch(const xmlNode *xml, const char *name, time_t *dest)
651 {
652  long long value_ll = 0;
653 
654  if (crm_element_value_ll(xml, name, &value_ll) < 0) {
655  return -1;
656  }
657 
658  /* Unfortunately, we can't do any bounds checking, since time_t has neither
659  * standardized bounds nor constants defined for them.
660  */
661  *dest = (time_t) value_ll;
662  return pcmk_ok;
663 }
664 
678 int
679 crm_element_value_timeval(const xmlNode *xml, const char *name_sec,
680  const char *name_usec, struct timeval *dest)
681 {
682  long long value_i = 0;
683 
684  CRM_CHECK(dest != NULL, return -EINVAL);
685  dest->tv_sec = 0;
686  dest->tv_usec = 0;
687 
688  if (xml == NULL) {
689  return pcmk_ok;
690  }
691 
692  /* Unfortunately, we can't do any bounds checking, since there are no
693  * constants provided for the bounds of time_t and suseconds_t, and
694  * calculating them isn't worth the effort. If there are XML values
695  * beyond the native sizes, there will probably be worse problems anyway.
696  */
697 
698  // Parse seconds
699  errno = 0;
700  if (crm_element_value_ll(xml, name_sec, &value_i) < 0) {
701  return -errno;
702  }
703  dest->tv_sec = (time_t) value_i;
704 
705  // Parse microseconds
706  if (crm_element_value_ll(xml, name_usec, &value_i) < 0) {
707  return -errno;
708  }
709  dest->tv_usec = (suseconds_t) value_i;
710 
711  return pcmk_ok;
712 }
713 
725 char *
726 crm_element_value_copy(const xmlNode *data, const char *name)
727 {
728  char *value_copy = NULL;
729 
731  return value_copy;
732 }
733 
747 void
748 hash2smartfield(gpointer key, gpointer value, gpointer user_data)
749 {
750  const char *name = key;
751  const char *s_value = value;
752 
753  xmlNode *xml_node = user_data;
754 
755  if (isdigit(name[0])) {
756  xmlNode *tmp = create_xml_node(xml_node, XML_TAG_PARAM);
757 
759  crm_xml_add(tmp, XML_NVPAIR_ATTR_VALUE, s_value);
760 
761  } else if (crm_element_value(xml_node, name) == NULL) {
762  crm_xml_add(xml_node, name, s_value);
763  crm_trace("dumped: %s=%s", name, s_value);
764 
765  } else {
766  crm_trace("duplicate: %s=%s", name, s_value);
767  }
768 }
769 
781 void
782 hash2field(gpointer key, gpointer value, gpointer user_data)
783 {
784  const char *name = key;
785  const char *s_value = value;
786 
787  xmlNode *xml_node = user_data;
788 
789  if (crm_element_value(xml_node, name) == NULL) {
790  crm_xml_add(xml_node, name, s_value);
791 
792  } else {
793  crm_trace("duplicate: %s=%s", name, s_value);
794  }
795 }
796 
809 void
810 hash2metafield(gpointer key, gpointer value, gpointer user_data)
811 {
812  char *crm_name = NULL;
813 
814  if (key == NULL || value == NULL) {
815  return;
816  }
817 
818  /* Filter out cluster-generated attributes that contain a '#' or ':'
819  * (like fail-count and last-failure).
820  */
821  for (crm_name = key; *crm_name; ++crm_name) {
822  if ((*crm_name == '#') || (*crm_name == ':')) {
823  return;
824  }
825  }
826 
827  crm_name = crm_meta_name(key);
828  hash2field(crm_name, value, user_data);
829  free(crm_name);
830 }
831 
832 // nvpair handling
833 
844 xmlNode *
845 crm_create_nvpair_xml(xmlNode *parent, const char *id, const char *name,
846  const char *value)
847 {
848  xmlNode *nvp;
849 
850  /* id can be NULL so we auto-generate one, and name can be NULL if this
851  * will be used to delete a name/value pair by ID, but both can't be NULL
852  */
853  CRM_CHECK(id || name, return NULL);
854 
856  CRM_CHECK(nvp, return NULL);
857 
858  if (id) {
859  crm_xml_add(nvp, XML_ATTR_ID, id);
860  } else {
861  const char *parent_id = ID(parent);
862 
863  crm_xml_set_id(nvp, "%s-%s",
864  (parent_id? parent_id : XML_CIB_TAG_NVPAIR), name);
865  }
867  crm_xml_add(nvp, XML_NVPAIR_ATTR_VALUE, value);
868  return nvp;
869 }
870 
882 void
883 hash2nvpair(gpointer key, gpointer value, gpointer user_data)
884 {
885  const char *name = key;
886  const char *s_value = value;
887  xmlNode *xml_node = user_data;
888 
889  crm_create_nvpair_xml(xml_node, name, name, s_value);
890  crm_trace("dumped: name=%s value=%s", name, s_value);
891 }
892 
907 GHashTable *
908 xml2list(xmlNode *parent)
909 {
910  xmlNode *child = NULL;
911  xmlAttrPtr pIter = NULL;
912  xmlNode *nvpair_list = NULL;
913  GHashTable *nvpair_hash = pcmk__strkey_table(free, free);
914 
915  CRM_CHECK(parent != NULL, return nvpair_hash);
916 
917  nvpair_list = find_xml_node(parent, XML_TAG_ATTRS, FALSE);
918  if (nvpair_list == NULL) {
919  crm_trace("No attributes in %s", crm_element_name(parent));
920  crm_log_xml_trace(parent, "No attributes for resource op");
921  }
922 
923  crm_log_xml_trace(nvpair_list, "Unpacking");
924 
925  for (pIter = pcmk__xe_first_attr(nvpair_list); pIter != NULL;
926  pIter = pIter->next) {
927 
928  const char *p_name = (const char *)pIter->name;
929  const char *p_value = pcmk__xml_attr_value(pIter);
930 
931  crm_trace("Added %s=%s", p_name, p_value);
932 
933  g_hash_table_insert(nvpair_hash, strdup(p_name), strdup(p_value));
934  }
935 
936  for (child = pcmk__xml_first_child(nvpair_list); child != NULL;
937  child = pcmk__xml_next(child)) {
938 
939  if (strcmp((const char *)child->name, XML_TAG_PARAM) == 0) {
940  const char *key = crm_element_value(child, XML_NVPAIR_ATTR_NAME);
941  const char *value = crm_element_value(child, XML_NVPAIR_ATTR_VALUE);
942 
943  crm_trace("Added %s=%s", key, value);
944  if (key != NULL && value != NULL) {
945  g_hash_table_insert(nvpair_hash, strdup(key), strdup(value));
946  }
947  }
948  }
949 
950  return nvpair_hash;
951 }
952 
953 void
954 pcmk__xe_set_bool_attr(xmlNodePtr node, const char *name, bool value)
955 {
957 }
958 
959 int
960 pcmk__xe_get_bool_attr(xmlNodePtr node, const char *name, bool *value) {
961  const char *xml_value = NULL;
962  int ret, rc;
963 
964  if (node == NULL) {
965  return ENODATA;
966  } else if (name == NULL || value == NULL) {
967  return EINVAL;
968  }
969 
970  xml_value = crm_element_value(node, name);
971 
972  if (xml_value == NULL) {
973  return ENODATA;
974  }
975 
976  rc = crm_str_to_boolean(xml_value, &ret);
977  if (rc == 1) {
978  *value = ret;
979  return pcmk_rc_ok;
980  } else {
981  return pcmk_rc_unknown_format;
982  }
983 }
984 
985 bool
986 pcmk__xe_attr_is_true(xmlNodePtr node, const char *name)
987 {
988  bool value = false;
989  int rc;
990 
991  rc = pcmk__xe_get_bool_attr(node, name, &value);
992  return rc == pcmk_rc_ok && value == true;
993 }
994 
995 // Deprecated functions kept only for backward API compatibility
996 // LCOV_EXCL_START
997 
998 #include <crm/common/util_compat.h>
999 
1000 int
1001 pcmk_scan_nvpair(const char *input, char **name, char **value)
1002 {
1003  return pcmk__scan_nvpair(input, name, value);
1004 }
1005 
1006 char *
1007 pcmk_format_nvpair(const char *name, const char *value,
1008  const char *units)
1009 {
1010  return pcmk__format_nvpair(name, value, units);
1011 }
1012 
1013 char *
1014 pcmk_format_named_time(const char *name, time_t epoch_time)
1015 {
1016  return pcmk__format_named_time(name, epoch_time);
1017 }
1018 
1019 // LCOV_EXCL_STOP
1020 // End deprecated API
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:226
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
Definition: xml.c:445
GSList * pcmk_prepend_nvpair(GSList *nvpairs, const char *name, const char *value)
Prepend a name/value pair to a list.
Definition: nvpair.c:91
A dumping ground.
char * name
Definition: nvpair.h:30
char data[0]
Definition: cpg.c:55
int crm_element_value_ll(const xmlNode *data, const char *name, long long *dest)
Retrieve the long long integer value of an XML attribute.
Definition: nvpair.c:597
GSList * pcmk_xml_attrs2nvpairs(xmlNode *xml)
Create a list of name/value pairs from an XML node&#39;s attributes.
Definition: nvpair.c:161
const char * name
Definition: cib.c:24
bool pcmk__xe_attr_is_true(xmlNodePtr node, const char *name)
Definition: nvpair.c:986
char * value
Definition: nvpair.h:31
char * pcmk__format_nvpair(const char *name, const char *value, const char *units)
Definition: nvpair.c:284
G_GNUC_INTERNAL void pcmk__mark_xml_attr_dirty(xmlAttr *a)
Definition: xml.c:173
#define XML_BOOLEAN_FALSE
Definition: msg_xml.h:147
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Retrieve the millisecond value of an XML attribute.
Definition: nvpair.c:622
#define XML_TAG_ATTRS
Definition: msg_xml.h:211
#define XML_NVPAIR_ATTR_NAME
Definition: msg_xml.h:383
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:210
#define XML_CIB_TAG_NVPAIR
Definition: msg_xml.h:206
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:845
char * strndup(const char *str, size_t len)
char * crm_meta_name(const char *field)
Definition: utils.c:439
int crm_element_value_timeval(const xmlNode *xml, const char *name_sec, const char *name_usec, struct timeval *dest)
Retrieve the value of XML second/microsecond attributes as time.
Definition: nvpair.c:679
#define PCMK__PARSE_INT_DEFAULT
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
Definition: strings.c:97
void hash2metafield(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry, as meta-attribute name.
Definition: nvpair.c:810
GHashTable * xml2list(xmlNode *parent)
Retrieve XML attributes as a hash table.
Definition: nvpair.c:908
void pcmk_nvpairs2xml_attrs(GSList *list, xmlNode *xml)
Add XML attributes based on a list of name/value pairs.
Definition: nvpair.c:201
void pcmk__xe_set_bool_attr(xmlNodePtr node, const char *name, bool value)
Definition: nvpair.c:954
#define XML_ATTR_ID
Definition: msg_xml.h:135
#define XML_BOOLEAN_TRUE
Definition: msg_xml.h:146
char * pcmk_format_nvpair(const char *name, const char *value, const char *units)
Definition: nvpair.c:1007
#define crm_trace(fmt, args...)
Definition: logging.h:364
void hash2field(gpointer key, gpointer value, gpointer user_data)
Set XML attribute based on hash table entry.
Definition: nvpair.c:782
void pcmk_free_nvpairs(GSList *nvpairs)
Free a list of name/value pairs.
Definition: nvpair.c:102
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
void crm_xml_set_id(xmlNode *xml, const char *format,...) G_GNUC_PRINTF(2
void hash2smartfield(gpointer key, gpointer value, gpointer user_data)
Add hash table entry to XML as (possibly legacy) name/value.
Definition: nvpair.c:748
void pcmk__str_update(char **str, const char *value)
Definition: strings.c:1188
Wrappers for and extensions to libxml2.
char * pcmk_format_named_time(const char *name, time_t epoch_time)
Definition: nvpair.c:1014
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:696
#define LLSTRSIZE
Definition: nvpair.c:464
void hash2nvpair(gpointer key, gpointer value, gpointer user_data)
Add XML nvpair element based on hash table entry.
Definition: nvpair.c:883
const char * pcmk__epoch2str(time_t *when)
Definition: iso8601.c:1715
GSList * pcmk_sort_nvpairs(GSList *list)
Sort a list of name/value pairs.
Definition: nvpair.c:146
const xmlChar * pcmkXmlStr
Definition: xml.h:52
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:529
int crm_str_to_boolean(const char *s, int *ret)
Definition: strings.c:427
const char * crm_xml_replace(xmlNode *node, const char *name, const char *value)
Replace an XML attribute with specified name and (possibly NULL) value.
Definition: nvpair.c:380
#define ENODATA
Definition: portability.h:145
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
Definition: strings.c:611
char * pcmk__format_named_time(const char *name, time_t epoch_time)
Definition: nvpair.c:303
pcmk__action_result_t result
Definition: pcmk_fence.c:34
#define crm_err(fmt, args...)
Definition: logging.h:358
#define CRM_ASSERT(expr)
Definition: results.h:42
Deprecated Pacemaker utilities.
xmlNode * input
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:431
int crm_element_value_epoch(const xmlNode *xml, const char *name, time_t *dest)
Retrieve the seconds-since-epoch value of an XML attribute.
Definition: nvpair.c:650
void xml_remove_prop(xmlNode *obj, const char *name)
Definition: xml.c:2037
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:323
#define XML_NVPAIR_ATTR_VALUE
Definition: msg_xml.h:384
const char * crm_xml_add_ll(xmlNode *xml, const char *name, long long value)
Create an XML attribute with specified name and long long int value.
Definition: nvpair.c:481
#define pcmk_ok
Definition: results.h:68
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:726
const char * crm_xml_add_timeval(xmlNode *xml, const char *name_sec, const char *name_usec, const struct timeval *value)
Create XML attributes for seconds and microseconds.
Definition: nvpair.c:505
#define crm_log_xml_trace(xml, text)
Definition: logging.h:372
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:453
G_GNUC_INTERNAL bool pcmk__tracking_xml_changes(xmlNode *xml, bool lazy)
Definition: xml.c:51
bool pcmk__check_acl(xmlNode *xml, const char *name, enum xml_private_flags mode)
Definition: acl.c:611
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
Definition: nvpair.c:565
#define ID(x)
Definition: msg_xml.h:460
const char * parent
Definition: cib.c:25
int pcmk__xe_get_bool_attr(xmlNodePtr node, const char *name, bool *value)
Definition: nvpair.c:960
int pcmk_scan_nvpair(const char *input, char **name, char **value)
Definition: nvpair.c:1001
#define pcmk_err_bad_nvpair
Definition: results.h:91
#define XML_TAG_PARAM
Definition: msg_xml.h:216
int pcmk__scan_nvpair(const char *input, char **name, char **value)
Definition: nvpair.c:221