root/lib/cib/cib_attrs.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_nvpair_attr_delegate
  2. update_attr_delegate
  3. read_attr_delegate
  4. delete_attr_delegate
  5. get_uuid_from_result
  6. query_node_uuid
  7. query_node_uname
  8. set_standby

   1 /*
   2  * Copyright 2004-2020 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/msg_xml.h>
  26 #include <crm/common/xml.h>
  27 #include <crm/common/xml_internal.h>
  28 #include <crm/cib/internal.h>
  29 
  30 #define attr_msg(level, fmt, args...) do {      \
  31         if(to_console) {                        \
  32             printf(fmt"\n", ##args);            \
  33         } else {                                \
  34             do_crm_log(level, fmt , ##args);    \
  35         }                                       \
  36     } while(0)
  37 
  38 /* could also check for possible truncation */
  39 #define attr_snprintf(_str, _offset, _limit, ...) do {              \
  40     _offset += snprintf(_str + _offset,                             \
  41                         (_limit > _offset) ? _limit - _offset : 0,  \
  42                         __VA_ARGS__);                               \
  43     } while(0)
  44 
  45 #define XPATH_MAX 1024
  46 
  47 extern int
  48 find_nvpair_attr_delegate(cib_t * the_cib, const char *attr, const char *section,
     /* [previous][next][first][last][top][bottom][index][help] */
  49                           const char *node_uuid, const char *attr_set_type, const char *set_name,
  50                           const char *attr_id, const char *attr_name, gboolean to_console,
  51                           char **value, const char *user_name)
  52 {
  53     int offset = 0;
  54     int rc = pcmk_ok;
  55 
  56     char *xpath_string = NULL;
  57     xmlNode *xml_search = NULL;
  58     const char *set_type = NULL;
  59     const char *node_type = NULL;
  60 
  61     if (attr_set_type) {
  62         set_type = attr_set_type;
  63     } else {
  64         set_type = XML_TAG_ATTR_SETS;
  65     }
  66 
  67     CRM_ASSERT(value != NULL);
  68     *value = NULL;
  69 
  70     if (pcmk__str_eq(section, XML_CIB_TAG_CRMCONFIG, pcmk__str_casei)) {
  71         node_uuid = NULL;
  72         set_type = XML_CIB_TAG_PROPSET;
  73 
  74     } else if (pcmk__strcase_any_of(section, XML_CIB_TAG_OPCONFIG, XML_CIB_TAG_RSCCONFIG,
  75                                     NULL)) {
  76         node_uuid = NULL;
  77         set_type = XML_TAG_META_SETS;
  78 
  79     } else if (pcmk__str_eq(section, XML_CIB_TAG_TICKETS, pcmk__str_casei)) {
  80         node_uuid = NULL;
  81         section = XML_CIB_TAG_STATUS;
  82         node_type = XML_CIB_TAG_TICKETS;
  83 
  84     } else if (node_uuid == NULL) {
  85         return -EINVAL;
  86     }
  87 
  88     xpath_string = calloc(1, XPATH_MAX);
  89     if (xpath_string == NULL) {
  90         crm_perror(LOG_CRIT, "Could not create xpath");
  91         return -ENOMEM;
  92     }
  93 
  94     attr_snprintf(xpath_string, offset, XPATH_MAX, "%.128s", get_object_path(section));
  95 
  96     if (pcmk__str_eq(node_type, XML_CIB_TAG_TICKETS, pcmk__str_casei)) {
  97         attr_snprintf(xpath_string, offset, XPATH_MAX, "//%s", node_type);
  98 
  99     } else if (node_uuid) {
 100         const char *node_type = XML_CIB_TAG_NODE;
 101 
 102         if (pcmk__str_eq(section, XML_CIB_TAG_STATUS, pcmk__str_casei)) {
 103             node_type = XML_CIB_TAG_STATE;
 104             set_type = XML_TAG_TRANSIENT_NODEATTRS;
 105         }
 106         attr_snprintf(xpath_string, offset, XPATH_MAX, "//%s[@id='%s']", node_type,
 107                       node_uuid);
 108     }
 109 
 110     if (set_name) {
 111         attr_snprintf(xpath_string, offset, XPATH_MAX, "//%s[@id='%.128s']", set_type,
 112                       set_name);
 113     } else {
 114         attr_snprintf(xpath_string, offset, XPATH_MAX, "//%s", set_type);
 115     }
 116 
 117     attr_snprintf(xpath_string, offset, XPATH_MAX, "//nvpair[");
 118     if (attr_id) {
 119         attr_snprintf(xpath_string, offset, XPATH_MAX, "@id='%s'", attr_id);
 120     }
 121 
 122     if (attr_name) {
 123         if (attr_id) {
 124             attr_snprintf(xpath_string, offset, XPATH_MAX, " and ");
 125         }
 126         attr_snprintf(xpath_string, offset, XPATH_MAX, "@name='%.128s'", attr_name);
 127     }
 128     attr_snprintf(xpath_string, offset, XPATH_MAX, "]");
 129     CRM_LOG_ASSERT(offset > 0);
 130 
 131     rc = cib_internal_op(the_cib, CIB_OP_QUERY, NULL, xpath_string, NULL, &xml_search,
 132                          cib_sync_call | cib_scope_local | cib_xpath, user_name);
 133 
 134     if (rc != pcmk_ok) {
 135         crm_trace("Query failed for attribute %s (section=%s, node=%s, set=%s, xpath=%s): %s",
 136                   attr_name, section, crm_str(node_uuid), crm_str(set_name), xpath_string,
 137                   pcmk_strerror(rc));
 138         goto done;
 139     }
 140 
 141     crm_log_xml_debug(xml_search, "Match");
 142     if (xml_has_children(xml_search)) {
 143         xmlNode *child = NULL;
 144 
 145         rc = -ENOTUNIQ;
 146         attr_msg(LOG_WARNING, "Multiple attributes match name=%s", attr_name);
 147 
 148         for (child = pcmk__xml_first_child(xml_search); child != NULL;
 149              child = pcmk__xml_next(child)) {
 150             attr_msg(LOG_INFO, "  Value: %s \t(id=%s)",
 151                      crm_element_value(child, XML_NVPAIR_ATTR_VALUE), ID(child));
 152         }
 153 
 154     } else {
 155         const char *tmp = crm_element_value(xml_search, attr);
 156 
 157         if (tmp) {
 158             *value = strdup(tmp);
 159         }
 160     }
 161 
 162   done:
 163     free(xpath_string);
 164     free_xml(xml_search);
 165     return rc;
 166 }
 167 
 168 int
 169 update_attr_delegate(cib_t * the_cib, int call_options,
     /* [previous][next][first][last][top][bottom][index][help] */
 170                      const char *section, const char *node_uuid, const char *set_type,
 171                      const char *set_name, const char *attr_id, const char *attr_name,
 172                      const char *attr_value, gboolean to_console, const char *user_name,
 173                      const char *node_type)
 174 {
 175     const char *tag = NULL;
 176     int rc = pcmk_ok;
 177     xmlNode *xml_top = NULL;
 178     xmlNode *xml_obj = NULL;
 179 
 180     char *local_attr_id = NULL;
 181     char *local_set_name = NULL;
 182 
 183     CRM_CHECK(section != NULL, return -EINVAL);
 184     CRM_CHECK(attr_value != NULL, return -EINVAL);
 185     CRM_CHECK(attr_name != NULL || attr_id != NULL, return -EINVAL);
 186 
 187     rc = find_nvpair_attr_delegate(the_cib, XML_ATTR_ID, section, node_uuid, set_type, set_name,
 188                                    attr_id, attr_name, to_console, &local_attr_id, user_name);
 189     if (rc == pcmk_ok) {
 190         attr_id = local_attr_id;
 191         goto do_modify;
 192 
 193     } else if (rc != -ENXIO) {
 194         return rc;
 195 
 196         /* } else if(attr_id == NULL) { */
 197         /*     return -EINVAL; */
 198 
 199     } else {
 200         crm_trace("%s does not exist, create it", attr_name);
 201         if (pcmk__str_eq(section, XML_CIB_TAG_TICKETS, pcmk__str_casei)) {
 202             node_uuid = NULL;
 203             section = XML_CIB_TAG_STATUS;
 204             node_type = XML_CIB_TAG_TICKETS;
 205 
 206             xml_top = create_xml_node(xml_obj, XML_CIB_TAG_STATUS);
 207             xml_obj = create_xml_node(xml_top, XML_CIB_TAG_TICKETS);
 208 
 209         } else if (pcmk__str_eq(section, XML_CIB_TAG_NODES, pcmk__str_casei)) {
 210 
 211             if (node_uuid == NULL) {
 212                 return -EINVAL;
 213             }
 214 
 215             if (pcmk__str_eq(node_type, "remote", pcmk__str_casei)) {
 216                 xml_top = create_xml_node(xml_obj, XML_CIB_TAG_NODES);
 217                 xml_obj = create_xml_node(xml_top, XML_CIB_TAG_NODE);
 218                 crm_xml_add(xml_obj, XML_ATTR_TYPE, "remote");
 219                 crm_xml_add(xml_obj, XML_ATTR_ID, node_uuid);
 220                 crm_xml_add(xml_obj, XML_ATTR_UNAME, node_uuid);
 221             } else {
 222                 tag = XML_CIB_TAG_NODE;
 223             }
 224 
 225         } else if (pcmk__str_eq(section, XML_CIB_TAG_STATUS, pcmk__str_casei)) {
 226             tag = XML_TAG_TRANSIENT_NODEATTRS;
 227             if (node_uuid == NULL) {
 228                 return -EINVAL;
 229             }
 230 
 231             xml_top = create_xml_node(xml_obj, XML_CIB_TAG_STATE);
 232             crm_xml_add(xml_top, XML_ATTR_ID, node_uuid);
 233             xml_obj = xml_top;
 234 
 235         } else {
 236             tag = section;
 237             node_uuid = NULL;
 238         }
 239 
 240         if (set_name == NULL) {
 241             if (pcmk__str_eq(section, XML_CIB_TAG_CRMCONFIG, pcmk__str_casei)) {
 242                 local_set_name = strdup(CIB_OPTIONS_FIRST);
 243 
 244             } else if (pcmk__str_eq(node_type, XML_CIB_TAG_TICKETS, pcmk__str_casei)) {
 245                 local_set_name = crm_strdup_printf("%s-%s", section,
 246                                                    XML_CIB_TAG_TICKETS);
 247 
 248             } else if (node_uuid) {
 249                 local_set_name = crm_strdup_printf("%s-%s", section, node_uuid);
 250 
 251                 if (set_type) {
 252                     char *tmp_set_name = local_set_name;
 253 
 254                     local_set_name = crm_strdup_printf("%s-%s", tmp_set_name,
 255                                                        set_type);
 256                     free(tmp_set_name);
 257                 }
 258             } else {
 259                 local_set_name = crm_strdup_printf("%s-options", section);
 260             }
 261             set_name = local_set_name;
 262         }
 263 
 264         if (attr_id == NULL) {
 265             local_attr_id = crm_strdup_printf("%s-%s", set_name, attr_name);
 266             crm_xml_sanitize_id(local_attr_id);
 267             attr_id = local_attr_id;
 268 
 269         } else if (attr_name == NULL) {
 270             attr_name = attr_id;
 271         }
 272 
 273         crm_trace("Creating %s/%s", section, tag);
 274         if (tag != NULL) {
 275             xml_obj = create_xml_node(xml_obj, tag);
 276             crm_xml_add(xml_obj, XML_ATTR_ID, node_uuid);
 277             if (xml_top == NULL) {
 278                 xml_top = xml_obj;
 279             }
 280         }
 281 
 282         if (node_uuid == NULL && !pcmk__str_eq(node_type, XML_CIB_TAG_TICKETS, pcmk__str_casei)) {
 283             if (pcmk__str_eq(section, XML_CIB_TAG_CRMCONFIG, pcmk__str_casei)) {
 284                 xml_obj = create_xml_node(xml_obj, XML_CIB_TAG_PROPSET);
 285             } else {
 286                 xml_obj = create_xml_node(xml_obj, XML_TAG_META_SETS);
 287             }
 288 
 289         } else if (set_type) {
 290             xml_obj = create_xml_node(xml_obj, set_type);
 291 
 292         } else {
 293             xml_obj = create_xml_node(xml_obj, XML_TAG_ATTR_SETS);
 294         }
 295         crm_xml_add(xml_obj, XML_ATTR_ID, set_name);
 296 
 297         if (xml_top == NULL) {
 298             xml_top = xml_obj;
 299         }
 300     }
 301 
 302   do_modify:
 303     xml_obj = crm_create_nvpair_xml(xml_obj, attr_id, attr_name, attr_value);
 304     if (xml_top == NULL) {
 305         xml_top = xml_obj;
 306     }
 307 
 308     crm_log_xml_trace(xml_top, "update_attr");
 309     rc = cib_internal_op(the_cib, CIB_OP_MODIFY, NULL, section, xml_top, NULL,
 310                          call_options | cib_quorum_override, user_name);
 311 
 312     if (rc < pcmk_ok) {
 313         attr_msg(LOG_ERR, "Error setting %s=%s (section=%s, set=%s): %s",
 314                  attr_name, attr_value, section, crm_str(set_name), pcmk_strerror(rc));
 315         crm_log_xml_info(xml_top, "Update");
 316     }
 317 
 318     free(local_set_name);
 319     free(local_attr_id);
 320     free_xml(xml_top);
 321 
 322     return rc;
 323 }
 324 
 325 int
 326 read_attr_delegate(cib_t * the_cib,
     /* [previous][next][first][last][top][bottom][index][help] */
 327                    const char *section, const char *node_uuid, const char *set_type,
 328                    const char *set_name, const char *attr_id, const char *attr_name,
 329                    char **attr_value, gboolean to_console, const char *user_name)
 330 {
 331     int rc = pcmk_ok;
 332 
 333     CRM_ASSERT(attr_value != NULL);
 334     CRM_CHECK(section != NULL, return -EINVAL);
 335     CRM_CHECK(attr_name != NULL || attr_id != NULL, return -EINVAL);
 336 
 337     *attr_value = NULL;
 338 
 339     rc = find_nvpair_attr_delegate(the_cib, XML_NVPAIR_ATTR_VALUE, section, node_uuid, set_type,
 340                                    set_name, attr_id, attr_name, to_console, attr_value, user_name);
 341     if (rc != pcmk_ok) {
 342         crm_trace("Query failed for attribute %s (section=%s, node=%s, set=%s): %s",
 343                   attr_name, section, crm_str(set_name), crm_str(node_uuid), pcmk_strerror(rc));
 344     }
 345     return rc;
 346 }
 347 
 348 int
 349 delete_attr_delegate(cib_t * the_cib, int options,
     /* [previous][next][first][last][top][bottom][index][help] */
 350                      const char *section, const char *node_uuid, const char *set_type,
 351                      const char *set_name, const char *attr_id, const char *attr_name,
 352                      const char *attr_value, gboolean to_console, const char *user_name)
 353 {
 354     int rc = pcmk_ok;
 355     xmlNode *xml_obj = NULL;
 356     char *local_attr_id = NULL;
 357 
 358     CRM_CHECK(section != NULL, return -EINVAL);
 359     CRM_CHECK(attr_name != NULL || attr_id != NULL, return -EINVAL);
 360 
 361     if (attr_id == NULL) {
 362         rc = find_nvpair_attr_delegate(the_cib, XML_ATTR_ID, section, node_uuid, set_type,
 363                                        set_name, attr_id, attr_name, to_console, &local_attr_id,
 364                                        user_name);
 365         if (rc != pcmk_ok) {
 366             return rc;
 367         }
 368         attr_id = local_attr_id;
 369     }
 370 
 371     xml_obj = crm_create_nvpair_xml(NULL, attr_id, attr_name, attr_value);
 372 
 373     rc = cib_internal_op(the_cib, CIB_OP_DELETE, NULL, section, xml_obj, NULL,
 374                          options | cib_quorum_override, user_name);
 375 
 376     if (rc == pcmk_ok) {
 377         attr_msg(LOG_DEBUG, "Deleted %s %s: id=%s%s%s%s%s\n",
 378                  section, node_uuid ? "attribute" : "option", local_attr_id,
 379                  set_name ? " set=" : "", set_name ? set_name : "",
 380                  attr_name ? " name=" : "", attr_name ? attr_name : "");
 381     }
 382 
 383     free(local_attr_id);
 384     free_xml(xml_obj);
 385     return rc;
 386 }
 387 
 388 /*!
 389  * \internal
 390  * \brief Parse node UUID from search result
 391  *
 392  * \param[in]  result     XML search result
 393  * \param[out] uuid       If non-NULL, where to store parsed UUID
 394  * \param[out] is_remote  If non-NULL, set TRUE if result is remote node
 395  *
 396  * \return pcmk_ok if UUID was successfully parsed, -ENXIO otherwise
 397  */
 398 static int
 399 get_uuid_from_result(xmlNode *result, char **uuid, int *is_remote)
     /* [previous][next][first][last][top][bottom][index][help] */
 400 {
 401     int rc = -ENXIO;
 402     const char *tag;
 403     const char *parsed_uuid = NULL;
 404     int parsed_is_remote = FALSE;
 405 
 406     if (result == NULL) {
 407         return rc;
 408     }
 409 
 410     /* If there are multiple results, the first is sufficient */
 411     tag = (const char *) (result->name);
 412     if (pcmk__str_eq(tag, "xpath-query", pcmk__str_casei)) {
 413         result = pcmk__xml_first_child(result);
 414         CRM_CHECK(result != NULL, return rc);
 415         tag = (const char *) (result->name);
 416     }
 417 
 418     if (pcmk__str_eq(tag, XML_CIB_TAG_NODE, pcmk__str_casei)) {
 419         /* Result is <node> tag from <nodes> section */
 420 
 421         if (pcmk__str_eq(crm_element_value(result, XML_ATTR_TYPE), "remote", pcmk__str_casei)) {
 422             parsed_uuid = crm_element_value(result, XML_ATTR_UNAME);
 423             parsed_is_remote = TRUE;
 424         } else {
 425             parsed_uuid = ID(result);
 426             parsed_is_remote = FALSE;
 427         }
 428 
 429     } else if (pcmk__str_eq(tag, XML_CIB_TAG_RESOURCE, pcmk__str_casei)) {
 430         /* Result is <primitive> for ocf:pacemaker:remote resource */
 431 
 432         parsed_uuid = ID(result);
 433         parsed_is_remote = TRUE;
 434 
 435     } else if (pcmk__str_eq(tag, XML_CIB_TAG_NVPAIR, pcmk__str_casei)) {
 436         /* Result is remote-node parameter of <primitive> for guest node */
 437 
 438         parsed_uuid = crm_element_value(result, XML_NVPAIR_ATTR_VALUE);
 439         parsed_is_remote = TRUE;
 440 
 441     } else if (pcmk__str_eq(tag, XML_CIB_TAG_STATE, pcmk__str_casei)) {
 442         /* Result is <node_state> tag from <status> section */
 443 
 444         parsed_uuid = crm_element_value(result, XML_ATTR_UNAME);
 445         if (crm_is_true(crm_element_value(result, XML_NODE_IS_REMOTE))) {
 446             parsed_is_remote = TRUE;
 447         }
 448     }
 449 
 450     if (parsed_uuid) {
 451         if (uuid) {
 452             *uuid = strdup(parsed_uuid);
 453         }
 454         if (is_remote) {
 455             *is_remote = parsed_is_remote;
 456         }
 457         rc = pcmk_ok;
 458     }
 459 
 460     return rc;
 461 }
 462 
 463 /* Search string to find a node by name, as:
 464  * - cluster or remote node in nodes section
 465  * - remote node in resources section
 466  * - guest node in resources section
 467  * - orphaned remote node or bundle guest node in status section
 468  */
 469 #define XPATH_UPPER_TRANS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 470 #define XPATH_LOWER_TRANS "abcdefghijklmnopqrstuvwxyz"
 471 #define XPATH_NODE \
 472     "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_NODES \
 473         "/" XML_CIB_TAG_NODE "[translate(@" XML_ATTR_UNAME ",'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \
 474     "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES \
 475         "/" XML_CIB_TAG_RESOURCE \
 476         "[@class='ocf'][@provider='pacemaker'][@type='remote'][translate(@id,'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \
 477     "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES \
 478         "/" XML_CIB_TAG_RESOURCE "/" XML_TAG_META_SETS "/" XML_CIB_TAG_NVPAIR \
 479         "[@name='" XML_RSC_ATTR_REMOTE_NODE "'][translate(@value,'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \
 480     "|/" XML_TAG_CIB "/" XML_CIB_TAG_STATUS "/" XML_CIB_TAG_STATE \
 481         "[@" XML_NODE_IS_REMOTE "='true'][translate(@" XML_ATTR_UUID ",'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']"
 482 
 483 int
 484 query_node_uuid(cib_t * the_cib, const char *uname, char **uuid, int *is_remote_node)
     /* [previous][next][first][last][top][bottom][index][help] */
 485 {
 486     int rc = pcmk_ok;
 487     char *xpath_string;
 488     xmlNode *xml_search = NULL;
 489     char *host_lowercase = g_ascii_strdown(uname, -1);
 490 
 491     CRM_ASSERT(uname != NULL);
 492 
 493     if (uuid) {
 494         *uuid = NULL;
 495     }
 496     if (is_remote_node) {
 497         *is_remote_node = FALSE;
 498     }
 499 
 500     xpath_string = crm_strdup_printf(XPATH_NODE, host_lowercase, host_lowercase, host_lowercase, host_lowercase);
 501     if (cib_internal_op(the_cib, CIB_OP_QUERY, NULL, xpath_string, NULL,
 502                         &xml_search, cib_sync_call|cib_scope_local|cib_xpath,
 503                         NULL) == pcmk_ok) {
 504         rc = get_uuid_from_result(xml_search, uuid, is_remote_node);
 505     } else {
 506         rc = -ENXIO;
 507     }
 508     free(xpath_string);
 509     free_xml(xml_search);
 510     g_free(host_lowercase);
 511 
 512     if (rc != pcmk_ok) {
 513         crm_debug("Could not map node name '%s' to a UUID: %s",
 514                   uname, pcmk_strerror(rc));
 515     } else {
 516         crm_info("Mapped node name '%s' to UUID %s", uname, (uuid? *uuid : ""));
 517     }
 518     return rc;
 519 }
 520 
 521 int
 522 query_node_uname(cib_t * the_cib, const char *uuid, char **uname)
     /* [previous][next][first][last][top][bottom][index][help] */
 523 {
 524     int rc = pcmk_ok;
 525     xmlNode *a_child = NULL;
 526     xmlNode *xml_obj = NULL;
 527     xmlNode *fragment = NULL;
 528     const char *child_name = NULL;
 529 
 530     CRM_ASSERT(uname != NULL);
 531     CRM_ASSERT(uuid != NULL);
 532 
 533     rc = the_cib->cmds->query(the_cib, XML_CIB_TAG_NODES, &fragment,
 534                               cib_sync_call | cib_scope_local);
 535     if (rc != pcmk_ok) {
 536         return rc;
 537     }
 538 
 539     xml_obj = fragment;
 540     CRM_CHECK(pcmk__str_eq(crm_element_name(xml_obj), XML_CIB_TAG_NODES, pcmk__str_casei),
 541               return -ENOMSG);
 542     CRM_ASSERT(xml_obj != NULL);
 543     crm_log_xml_trace(xml_obj, "Result section");
 544 
 545     rc = -ENXIO;
 546     *uname = NULL;
 547 
 548     for (a_child = pcmk__xml_first_child(xml_obj); a_child != NULL;
 549          a_child = pcmk__xml_next(a_child)) {
 550 
 551         if (pcmk__str_eq((const char *)a_child->name, XML_CIB_TAG_NODE,
 552                          pcmk__str_none)) {
 553             child_name = ID(a_child);
 554             if (pcmk__str_eq(uuid, child_name, pcmk__str_casei)) {
 555                 child_name = crm_element_value(a_child, XML_ATTR_UNAME);
 556                 if (child_name != NULL) {
 557                     *uname = strdup(child_name);
 558                     rc = pcmk_ok;
 559                 }
 560                 break;
 561             }
 562         }
 563     }
 564 
 565     free_xml(fragment);
 566     return rc;
 567 }
 568 
 569 int
 570 set_standby(cib_t * the_cib, const char *uuid, const char *scope, const char *standby_value)
     /* [previous][next][first][last][top][bottom][index][help] */
 571 {
 572     int rc = pcmk_ok;
 573     char *attr_id = NULL;
 574 
 575     CRM_CHECK(uuid != NULL, return -EINVAL);
 576     CRM_CHECK(standby_value != NULL, return -EINVAL);
 577 
 578     if (pcmk__strcase_any_of(scope, "reboot", XML_CIB_TAG_STATUS, NULL)) {
 579         scope = XML_CIB_TAG_STATUS;
 580         attr_id = crm_strdup_printf("transient-standby-%.256s", uuid);
 581 
 582     } else {
 583         scope = XML_CIB_TAG_NODES;
 584         attr_id = crm_strdup_printf("standby-%.256s", uuid);
 585     }
 586 
 587     rc = update_attr_delegate(the_cib, cib_sync_call, scope, uuid, NULL, NULL,
 588                               attr_id, "standby", standby_value, TRUE, NULL, NULL);
 589 
 590     free(attr_id);
 591     return rc;
 592 }

/* [previous][next][first][last][top][bottom][index][help] */