root/lib/cib/cib_attrs.c

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

DEFINITIONS

This source file includes following definitions.
  1. new_output_object
  2. find_attr
  3. handle_multiples
  4. cib__update_node_attr
  5. cib__get_node_attrs
  6. cib__delete_node_attr
  7. find_nvpair_attr_delegate
  8. update_attr_delegate
  9. read_attr_delegate
  10. delete_attr_delegate
  11. get_uuid_from_result
  12. query_node_uuid
  13. query_node_uname
  14. set_standby

   1 /*
   2  * Copyright 2004-2023 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU 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/common/output_internal.h>
  29 #include <crm/cib/internal.h>
  30 
  31 static pcmk__output_t *
  32 new_output_object(const char *ty)
     /* [previous][next][first][last][top][bottom][index][help] */
  33 {
  34     int rc = pcmk_rc_ok;
  35     pcmk__output_t *out = NULL;
  36     const char* argv[] = { "", NULL };
  37     pcmk__supported_format_t formats[] = {
  38         PCMK__SUPPORTED_FORMAT_LOG,
  39         PCMK__SUPPORTED_FORMAT_TEXT,
  40         { NULL, NULL, NULL }
  41     };
  42 
  43     pcmk__register_formats(NULL, formats);
  44     rc = pcmk__output_new(&out, ty, NULL, (char**)argv);
  45     if ((rc != pcmk_rc_ok) || (out == NULL)) {
  46         crm_err("Can't out due to internal error: %s", pcmk_rc_str(rc));
  47         return NULL;
  48     }
  49 
  50     return out;
  51 }
  52 
  53 static int
  54 find_attr(cib_t *cib, const char *section, const char *node_uuid,
     /* [previous][next][first][last][top][bottom][index][help] */
  55           const char *attr_set_type, const char *set_name, const char *attr_id,
  56           const char *attr_name, const char *user_name, xmlNode **result)
  57 {
  58     int rc = pcmk_rc_ok;
  59 
  60     const char *xpath_base = NULL;
  61     GString *xpath = NULL;
  62     xmlNode *xml_search = NULL;
  63     const char *set_type = NULL;
  64     const char *node_type = NULL;
  65 
  66     if (attr_set_type) {
  67         set_type = attr_set_type;
  68     } else {
  69         set_type = XML_TAG_ATTR_SETS;
  70     }
  71 
  72     if (pcmk__str_eq(section, XML_CIB_TAG_CRMCONFIG, pcmk__str_casei)) {
  73         node_uuid = NULL;
  74         set_type = XML_CIB_TAG_PROPSET;
  75 
  76     } else if (pcmk__strcase_any_of(section, XML_CIB_TAG_OPCONFIG, XML_CIB_TAG_RSCCONFIG,
  77                                     NULL)) {
  78         node_uuid = NULL;
  79         set_type = XML_TAG_META_SETS;
  80 
  81     } else if (pcmk__str_eq(section, XML_CIB_TAG_TICKETS, pcmk__str_casei)) {
  82         node_uuid = NULL;
  83         section = XML_CIB_TAG_STATUS;
  84         node_type = XML_CIB_TAG_TICKETS;
  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, XML_CIB_TAG_TICKETS, pcmk__str_casei)) {
 100         pcmk__g_strcat(xpath, "//", node_type, NULL);
 101 
 102     } else if (node_uuid) {
 103         const char *node_type = XML_CIB_TAG_NODE;
 104 
 105         if (pcmk__str_eq(section, XML_CIB_TAG_STATUS, pcmk__str_casei)) {
 106             node_type = XML_CIB_TAG_STATE;
 107             set_type = XML_TAG_TRANSIENT_NODEATTRS;
 108         }
 109         pcmk__g_strcat(xpath,
 110                        "//", node_type, "[@" XML_ATTR_ID "='", node_uuid, "']",
 111                        NULL);
 112     }
 113 
 114     pcmk__g_strcat(xpath, "//", set_type, NULL);
 115     if (set_name) {
 116         pcmk__g_strcat(xpath, "[@" XML_ATTR_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                        "[@" XML_ATTR_ID "='", attr_id, "' "
 124                        "and @" XML_ATTR_NAME "='", attr_name, "']", NULL);
 125 
 126     } else if (attr_id) {
 127         pcmk__g_strcat(xpath, "[@" XML_ATTR_ID "='", attr_id, "']", NULL);
 128 
 129     } else if (attr_name) {
 130         pcmk__g_strcat(xpath, "[@" XML_ATTR_NAME "='", attr_name, "']", NULL);
 131     }
 132 
 133     rc = cib_internal_op(cib, PCMK__CIB_REQUEST_QUERY, NULL,
 134                          (const char *) xpath->str, NULL, &xml_search,
 135                          cib_sync_call|cib_scope_local|cib_xpath, user_name);
 136     if (rc < 0) {
 137         rc = pcmk_legacy2rc(rc);
 138         crm_trace("Query failed for attribute %s (section=%s, node=%s, set=%s, xpath=%s): %s",
 139                   attr_name, section, pcmk__s(node_uuid, "<null>"),
 140                   pcmk__s(set_name, "<null>"), (const char *) xpath->str,
 141                   pcmk_rc_str(rc));
 142     } else {
 143         rc = pcmk_rc_ok;
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 154 {
 155     if ((search != NULL) && (search->children != NULL)) {
 156         xmlNode *child = NULL;
 157 
 158         out->info(out, "Multiple attributes match name=%s", attr_name);
 159         for (child = pcmk__xml_first_child(search); child != NULL;
 160              child = pcmk__xml_next(child)) {
 161             out->info(out, "  Value: %s \t(id=%s)",
 162                       crm_element_value(child, XML_NVPAIR_ATTR_VALUE), ID(child));
 163         }
 164         return ENOTUNIQ;
 165 
 166     } else {
 167         return pcmk_rc_ok;
 168     }
 169 }
 170 
 171 int
 172 cib__update_node_attr(pcmk__output_t *out, cib_t *cib, int call_options, const char *section,
     /* [previous][next][first][last][top][bottom][index][help] */
 173                       const char *node_uuid, const char *set_type, const char *set_name,
 174                       const char *attr_id, const char *attr_name, const char *attr_value,
 175                       const char *user_name, const char *node_type)
 176 {
 177     const char *tag = NULL;
 178     int rc = pcmk_rc_ok;
 179     xmlNode *xml_top = NULL;
 180     xmlNode *xml_obj = NULL;
 181     xmlNode *xml_search = NULL;
 182 
 183     char *local_attr_id = NULL;
 184     char *local_set_name = NULL;
 185 
 186     CRM_CHECK((out != NULL) && (cib != NULL) && (section != NULL)
 187               && ((attr_id != NULL) || (attr_name != NULL))
 188               && (attr_value != NULL), return EINVAL);
 189 
 190     rc = find_attr(cib, section, node_uuid, set_type, set_name, attr_id,
 191                    attr_name, user_name, &xml_search);
 192 
 193     if (rc == pcmk_rc_ok) {
 194         if (handle_multiples(out, xml_search, attr_name) == ENOTUNIQ) {
 195             free_xml(xml_search);
 196             return ENOTUNIQ;
 197         } else {
 198             pcmk__str_update(&local_attr_id, crm_element_value(xml_search, XML_ATTR_ID));
 199             attr_id = local_attr_id;
 200             free_xml(xml_search);
 201             goto do_modify;
 202         }
 203 
 204     } else if (rc != ENXIO) {
 205         free_xml(xml_search);
 206         return rc;
 207 
 208         /* } else if(attr_id == NULL) { */
 209         /*     return EINVAL; */
 210 
 211     } else {
 212         free_xml(xml_search);
 213         crm_trace("%s does not exist, create it", attr_name);
 214         if (pcmk__str_eq(section, XML_CIB_TAG_TICKETS, pcmk__str_casei)) {
 215             node_uuid = NULL;
 216             section = XML_CIB_TAG_STATUS;
 217             node_type = XML_CIB_TAG_TICKETS;
 218 
 219             xml_top = create_xml_node(xml_obj, XML_CIB_TAG_STATUS);
 220             xml_obj = create_xml_node(xml_top, XML_CIB_TAG_TICKETS);
 221 
 222         } else if (pcmk__str_eq(section, XML_CIB_TAG_NODES, pcmk__str_casei)) {
 223 
 224             if (node_uuid == NULL) {
 225                 return EINVAL;
 226             }
 227 
 228             if (pcmk__str_eq(node_type, "remote", pcmk__str_casei)) {
 229                 xml_top = create_xml_node(xml_obj, XML_CIB_TAG_NODES);
 230                 xml_obj = create_xml_node(xml_top, XML_CIB_TAG_NODE);
 231                 crm_xml_add(xml_obj, XML_ATTR_TYPE, "remote");
 232                 crm_xml_add(xml_obj, XML_ATTR_ID, node_uuid);
 233                 crm_xml_add(xml_obj, XML_ATTR_UNAME, node_uuid);
 234             } else {
 235                 tag = XML_CIB_TAG_NODE;
 236             }
 237 
 238         } else if (pcmk__str_eq(section, XML_CIB_TAG_STATUS, pcmk__str_casei)) {
 239             tag = XML_TAG_TRANSIENT_NODEATTRS;
 240             if (node_uuid == NULL) {
 241                 return EINVAL;
 242             }
 243 
 244             xml_top = create_xml_node(xml_obj, XML_CIB_TAG_STATE);
 245             crm_xml_add(xml_top, XML_ATTR_ID, node_uuid);
 246             xml_obj = xml_top;
 247 
 248         } else {
 249             tag = section;
 250             node_uuid = NULL;
 251         }
 252 
 253         if (set_name == NULL) {
 254             if (pcmk__str_eq(section, XML_CIB_TAG_CRMCONFIG, pcmk__str_casei)) {
 255                 local_set_name = strdup(CIB_OPTIONS_FIRST);
 256 
 257             } else if (pcmk__str_eq(node_type, XML_CIB_TAG_TICKETS, pcmk__str_casei)) {
 258                 local_set_name = crm_strdup_printf("%s-%s", section,
 259                                                    XML_CIB_TAG_TICKETS);
 260 
 261             } else if (node_uuid) {
 262                 local_set_name = crm_strdup_printf("%s-%s", section, node_uuid);
 263 
 264                 if (set_type) {
 265                     char *tmp_set_name = local_set_name;
 266 
 267                     local_set_name = crm_strdup_printf("%s-%s", tmp_set_name,
 268                                                        set_type);
 269                     free(tmp_set_name);
 270                 }
 271             } else {
 272                 local_set_name = crm_strdup_printf("%s-options", section);
 273             }
 274             set_name = local_set_name;
 275         }
 276 
 277         if (attr_id == NULL) {
 278             local_attr_id = crm_strdup_printf("%s-%s", set_name, attr_name);
 279             crm_xml_sanitize_id(local_attr_id);
 280             attr_id = local_attr_id;
 281 
 282         } else if (attr_name == NULL) {
 283             attr_name = attr_id;
 284         }
 285 
 286         crm_trace("Creating %s/%s", section, tag);
 287         if (tag != NULL) {
 288             xml_obj = create_xml_node(xml_obj, tag);
 289             crm_xml_add(xml_obj, XML_ATTR_ID, node_uuid);
 290             if (xml_top == NULL) {
 291                 xml_top = xml_obj;
 292             }
 293         }
 294 
 295         if (node_uuid == NULL && !pcmk__str_eq(node_type, XML_CIB_TAG_TICKETS, pcmk__str_casei)) {
 296             if (pcmk__str_eq(section, XML_CIB_TAG_CRMCONFIG, pcmk__str_casei)) {
 297                 xml_obj = create_xml_node(xml_obj, XML_CIB_TAG_PROPSET);
 298             } else {
 299                 xml_obj = create_xml_node(xml_obj, XML_TAG_META_SETS);
 300             }
 301 
 302         } else if (set_type) {
 303             xml_obj = create_xml_node(xml_obj, set_type);
 304 
 305         } else {
 306             xml_obj = create_xml_node(xml_obj, XML_TAG_ATTR_SETS);
 307         }
 308         crm_xml_add(xml_obj, XML_ATTR_ID, set_name);
 309 
 310         if (xml_top == NULL) {
 311             xml_top = xml_obj;
 312         }
 313     }
 314 
 315   do_modify:
 316     xml_obj = crm_create_nvpair_xml(xml_obj, attr_id, attr_name, attr_value);
 317     if (xml_top == NULL) {
 318         xml_top = xml_obj;
 319     }
 320 
 321     crm_log_xml_trace(xml_top, "update_attr");
 322     rc = cib_internal_op(cib, PCMK__CIB_REQUEST_MODIFY, NULL, section, xml_top,
 323                          NULL, call_options, user_name);
 324     if (rc < 0) {
 325         rc = pcmk_legacy2rc(rc);
 326 
 327         out->err(out, "Error setting %s=%s (section=%s, set=%s): %s",
 328                  attr_name, attr_value, section, pcmk__s(set_name, "<null>"),
 329                  pcmk_rc_str(rc));
 330         crm_log_xml_info(xml_top, "Update");
 331     } else {
 332         rc = pcmk_rc_ok;
 333     }
 334 
 335     free(local_set_name);
 336     free(local_attr_id);
 337     free_xml(xml_top);
 338 
 339     return rc;
 340 }
 341 
 342 int
 343 cib__get_node_attrs(pcmk__output_t *out, cib_t *cib, const char *section,
     /* [previous][next][first][last][top][bottom][index][help] */
 344                     const char *node_uuid, const char *set_type, const char *set_name,
 345                     const char *attr_id, const char *attr_name, const char *user_name,
 346                     xmlNode **result)
 347 {
 348     int rc = pcmk_rc_ok;
 349 
 350     CRM_ASSERT(result != NULL);
 351     CRM_CHECK(section != NULL, return EINVAL);
 352 
 353     *result = NULL;
 354 
 355     rc = find_attr(cib, section, node_uuid, set_type, set_name, attr_id, attr_name,
 356                    user_name, result);
 357 
 358     if (rc != pcmk_rc_ok) {
 359         crm_trace("Query failed for attribute %s (section=%s node=%s set=%s): %s",
 360                   pcmk__s(attr_name, "with unspecified name"),
 361                   section, pcmk__s(set_name, "<null>"),
 362                   pcmk__s(node_uuid, "<null>"), pcmk_rc_str(rc));
 363     }
 364 
 365     return rc;
 366 }
 367 
 368 int
 369 cib__delete_node_attr(pcmk__output_t *out, cib_t *cib, int options, const char *section,
     /* [previous][next][first][last][top][bottom][index][help] */
 370                       const char *node_uuid, const char *set_type, const char *set_name,
 371                       const char *attr_id, const char *attr_name, const char *attr_value,
 372                       const char *user_name)
 373 {
 374     int rc = pcmk_rc_ok;
 375     xmlNode *xml_obj = NULL;
 376     xmlNode *xml_search = NULL;
 377     char *local_attr_id = NULL;
 378 
 379     CRM_CHECK(section != NULL, return EINVAL);
 380     CRM_CHECK(attr_name != NULL || attr_id != NULL, return EINVAL);
 381 
 382     if (attr_id == NULL) {
 383         rc = find_attr(cib, section, node_uuid, set_type, set_name, attr_id,
 384                        attr_name, user_name, &xml_search);
 385 
 386         if (rc != pcmk_rc_ok || handle_multiples(out, xml_search, attr_name) == ENOTUNIQ) {
 387             free_xml(xml_search);
 388             return rc;
 389         } else {
 390             pcmk__str_update(&local_attr_id, crm_element_value(xml_search, XML_ATTR_ID));
 391             attr_id = local_attr_id;
 392             free_xml(xml_search);
 393         }
 394     }
 395 
 396     xml_obj = crm_create_nvpair_xml(NULL, attr_id, attr_name, attr_value);
 397 
 398     rc = cib_internal_op(cib, PCMK__CIB_REQUEST_DELETE, NULL, section, xml_obj,
 399                          NULL, options, user_name);
 400     if (rc < 0) {
 401         rc = pcmk_legacy2rc(rc);
 402     } else {
 403         rc = pcmk_rc_ok;
 404         out->info(out, "Deleted %s %s: id=%s%s%s%s%s",
 405                   section, node_uuid ? "attribute" : "option", local_attr_id,
 406                   set_name ? " set=" : "", set_name ? set_name : "",
 407                   attr_name ? " name=" : "", attr_name ? attr_name : "");
 408     }
 409 
 410     free(local_attr_id);
 411     free_xml(xml_obj);
 412     return rc;
 413 }
 414 
 415 int
 416 find_nvpair_attr_delegate(cib_t *cib, const char *attr, const char *section,
     /* [previous][next][first][last][top][bottom][index][help] */
 417                           const char *node_uuid, const char *attr_set_type, const char *set_name,
 418                           const char *attr_id, const char *attr_name, gboolean to_console,
 419                           char **value, const char *user_name)
 420 {
 421     pcmk__output_t *out = NULL;
 422     xmlNode *xml_search = NULL;
 423     int rc = pcmk_ok;
 424 
 425     out = new_output_object(to_console ? "text" : "log");
 426     if (out == NULL) {
 427         return pcmk_err_generic;
 428     }
 429 
 430     rc = find_attr(cib, section, node_uuid, attr_set_type, set_name, attr_id,
 431                    attr_name, user_name, &xml_search);
 432 
 433     if (rc == pcmk_rc_ok) {
 434         rc = handle_multiples(out, xml_search, attr_name);
 435 
 436         if (rc == pcmk_rc_ok) {
 437             pcmk__str_update(value, crm_element_value(xml_search, attr));
 438         }
 439     }
 440 
 441     out->finish(out, CRM_EX_OK, true, NULL);
 442     free_xml(xml_search);
 443     pcmk__output_free(out);
 444     return pcmk_rc2legacy(rc);
 445 }
 446 
 447 int
 448 update_attr_delegate(cib_t *cib, int call_options, const char *section,
     /* [previous][next][first][last][top][bottom][index][help] */
 449                      const char *node_uuid, const char *set_type, const char *set_name,
 450                      const char *attr_id, const char *attr_name, const char *attr_value,
 451                      gboolean to_console, const char *user_name, const char *node_type)
 452 {
 453     pcmk__output_t *out = NULL;
 454     int rc = pcmk_ok;
 455 
 456     out = new_output_object(to_console ? "text" : "log");
 457     if (out == NULL) {
 458         return pcmk_err_generic;
 459     }
 460 
 461     rc = cib__update_node_attr(out, cib, call_options, section, node_uuid, set_type,
 462                                set_name, attr_id, attr_name, attr_value, user_name,
 463                                node_type);
 464 
 465     out->finish(out, CRM_EX_OK, true, NULL);
 466     pcmk__output_free(out);
 467     return pcmk_rc2legacy(rc);
 468 }
 469 
 470 int
 471 read_attr_delegate(cib_t *cib, const char *section, const char *node_uuid,
     /* [previous][next][first][last][top][bottom][index][help] */
 472                    const char *set_type, const char *set_name, const char *attr_id,
 473                    const char *attr_name, char **attr_value, gboolean to_console,
 474                    const char *user_name)
 475 {
 476     pcmk__output_t *out = NULL;
 477     xmlNode *result = NULL;
 478     int rc = pcmk_ok;
 479 
 480     out = new_output_object(to_console ? "text" : "log");
 481     if (out == NULL) {
 482         return pcmk_err_generic;
 483     }
 484 
 485     rc = cib__get_node_attrs(out, cib, section, node_uuid, set_type, set_name,
 486                              attr_id, attr_name, user_name, &result);
 487 
 488     if (rc == pcmk_rc_ok) {
 489         if (result->children == NULL) {
 490             pcmk__str_update(attr_value, crm_element_value(result, XML_NVPAIR_ATTR_VALUE));
 491         } else {
 492             rc = ENOTUNIQ;
 493         }
 494     }
 495 
 496     out->finish(out, CRM_EX_OK, true, NULL);
 497     free_xml(result);
 498     pcmk__output_free(out);
 499     return pcmk_rc2legacy(rc);
 500 }
 501 
 502 int
 503 delete_attr_delegate(cib_t *cib, int options, const char *section, const char *node_uuid,
     /* [previous][next][first][last][top][bottom][index][help] */
 504                      const char *set_type, const char *set_name, const char *attr_id,
 505                      const char *attr_name, const char *attr_value, gboolean to_console,
 506                      const char *user_name)
 507 {
 508     pcmk__output_t *out = NULL;
 509     int rc = pcmk_ok;
 510 
 511     out = new_output_object(to_console ? "text" : "log");
 512     if (out == NULL) {
 513         return pcmk_err_generic;
 514     }
 515 
 516     rc = cib__delete_node_attr(out, cib, options, section, node_uuid, set_type,
 517                                set_name, attr_id, attr_name, attr_value, user_name);
 518 
 519     out->finish(out, CRM_EX_OK, true, NULL);
 520     pcmk__output_free(out);
 521     return pcmk_rc2legacy(rc);
 522 }
 523 
 524 /*!
 525  * \internal
 526  * \brief Parse node UUID from search result
 527  *
 528  * \param[in]  result     XML search result
 529  * \param[out] uuid       If non-NULL, where to store parsed UUID
 530  * \param[out] is_remote  If non-NULL, set TRUE if result is remote node
 531  *
 532  * \return pcmk_ok if UUID was successfully parsed, -ENXIO otherwise
 533  */
 534 static int
 535 get_uuid_from_result(const xmlNode *result, char **uuid, int *is_remote)
     /* [previous][next][first][last][top][bottom][index][help] */
 536 {
 537     int rc = -ENXIO;
 538     const char *tag;
 539     const char *parsed_uuid = NULL;
 540     int parsed_is_remote = FALSE;
 541 
 542     if (result == NULL) {
 543         return rc;
 544     }
 545 
 546     /* If there are multiple results, the first is sufficient */
 547     tag = (const char *) (result->name);
 548     if (pcmk__str_eq(tag, "xpath-query", pcmk__str_casei)) {
 549         result = pcmk__xml_first_child(result);
 550         CRM_CHECK(result != NULL, return rc);
 551         tag = (const char *) (result->name);
 552     }
 553 
 554     if (pcmk__str_eq(tag, XML_CIB_TAG_NODE, pcmk__str_casei)) {
 555         /* Result is <node> tag from <nodes> section */
 556 
 557         if (pcmk__str_eq(crm_element_value(result, XML_ATTR_TYPE), "remote", pcmk__str_casei)) {
 558             parsed_uuid = crm_element_value(result, XML_ATTR_UNAME);
 559             parsed_is_remote = TRUE;
 560         } else {
 561             parsed_uuid = ID(result);
 562             parsed_is_remote = FALSE;
 563         }
 564 
 565     } else if (pcmk__str_eq(tag, XML_CIB_TAG_RESOURCE, pcmk__str_casei)) {
 566         /* Result is <primitive> for ocf:pacemaker:remote resource */
 567 
 568         parsed_uuid = ID(result);
 569         parsed_is_remote = TRUE;
 570 
 571     } else if (pcmk__str_eq(tag, XML_CIB_TAG_NVPAIR, pcmk__str_casei)) {
 572         /* Result is remote-node parameter of <primitive> for guest node */
 573 
 574         parsed_uuid = crm_element_value(result, XML_NVPAIR_ATTR_VALUE);
 575         parsed_is_remote = TRUE;
 576 
 577     } else if (pcmk__str_eq(tag, XML_CIB_TAG_STATE, pcmk__str_casei)) {
 578         /* Result is <node_state> tag from <status> section */
 579 
 580         parsed_uuid = crm_element_value(result, XML_ATTR_UNAME);
 581         if (pcmk__xe_attr_is_true(result, XML_NODE_IS_REMOTE)) {
 582             parsed_is_remote = TRUE;
 583         }
 584     }
 585 
 586     if (parsed_uuid) {
 587         if (uuid) {
 588             *uuid = strdup(parsed_uuid);
 589         }
 590         if (is_remote) {
 591             *is_remote = parsed_is_remote;
 592         }
 593         rc = pcmk_ok;
 594     }
 595 
 596     return rc;
 597 }
 598 
 599 /* Search string to find a node by name, as:
 600  * - cluster or remote node in nodes section
 601  * - remote node in resources section
 602  * - guest node in resources section
 603  * - orphaned remote node or bundle guest node in status section
 604  */
 605 #define XPATH_UPPER_TRANS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 606 #define XPATH_LOWER_TRANS "abcdefghijklmnopqrstuvwxyz"
 607 #define XPATH_NODE \
 608     "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_NODES \
 609         "/" XML_CIB_TAG_NODE "[translate(@" XML_ATTR_UNAME ",'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \
 610     "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES \
 611         "/" XML_CIB_TAG_RESOURCE \
 612         "[@class='ocf'][@provider='pacemaker'][@type='remote'][translate(@id,'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \
 613     "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES \
 614         "/" XML_CIB_TAG_RESOURCE "/" XML_TAG_META_SETS "/" XML_CIB_TAG_NVPAIR \
 615         "[@name='" XML_RSC_ATTR_REMOTE_NODE "'][translate(@value,'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']" \
 616     "|/" XML_TAG_CIB "/" XML_CIB_TAG_STATUS "/" XML_CIB_TAG_STATE \
 617         "[@" XML_NODE_IS_REMOTE "='true'][translate(@" XML_ATTR_ID ",'" XPATH_UPPER_TRANS "','" XPATH_LOWER_TRANS "') ='%s']"
 618 
 619 int
 620 query_node_uuid(cib_t * the_cib, const char *uname, char **uuid, int *is_remote_node)
     /* [previous][next][first][last][top][bottom][index][help] */
 621 {
 622     int rc = pcmk_ok;
 623     char *xpath_string;
 624     xmlNode *xml_search = NULL;
 625     char *host_lowercase = NULL;
 626 
 627     CRM_ASSERT(uname != NULL);
 628 
 629     host_lowercase = g_ascii_strdown(uname, -1);
 630 
 631     if (uuid) {
 632         *uuid = NULL;
 633     }
 634     if (is_remote_node) {
 635         *is_remote_node = FALSE;
 636     }
 637 
 638     xpath_string = crm_strdup_printf(XPATH_NODE, host_lowercase, host_lowercase, host_lowercase, host_lowercase);
 639     if (cib_internal_op(the_cib, PCMK__CIB_REQUEST_QUERY, NULL, xpath_string,
 640                         NULL, &xml_search,
 641                         cib_sync_call|cib_scope_local|cib_xpath,
 642                         NULL) == pcmk_ok) {
 643         rc = get_uuid_from_result(xml_search, uuid, is_remote_node);
 644     } else {
 645         rc = -ENXIO;
 646     }
 647     free(xpath_string);
 648     free_xml(xml_search);
 649     g_free(host_lowercase);
 650 
 651     if (rc != pcmk_ok) {
 652         crm_debug("Could not map node name '%s' to a UUID: %s",
 653                   uname, pcmk_strerror(rc));
 654     } else {
 655         crm_info("Mapped node name '%s' to UUID %s", uname, (uuid? *uuid : ""));
 656     }
 657     return rc;
 658 }
 659 
 660 int
 661 query_node_uname(cib_t * the_cib, const char *uuid, char **uname)
     /* [previous][next][first][last][top][bottom][index][help] */
 662 {
 663     int rc = pcmk_ok;
 664     xmlNode *a_child = NULL;
 665     xmlNode *xml_obj = NULL;
 666     xmlNode *fragment = NULL;
 667     const char *child_name = NULL;
 668 
 669     CRM_ASSERT(uname != NULL);
 670     CRM_ASSERT(uuid != NULL);
 671 
 672     rc = the_cib->cmds->query(the_cib, XML_CIB_TAG_NODES, &fragment,
 673                               cib_sync_call | cib_scope_local);
 674     if (rc != pcmk_ok) {
 675         return rc;
 676     }
 677 
 678     xml_obj = fragment;
 679     CRM_CHECK(pcmk__xe_is(xml_obj, XML_CIB_TAG_NODES), return -ENOMSG);
 680     crm_log_xml_trace(xml_obj, "Result section");
 681 
 682     rc = -ENXIO;
 683     *uname = NULL;
 684 
 685     for (a_child = pcmk__xml_first_child(xml_obj); a_child != NULL;
 686          a_child = pcmk__xml_next(a_child)) {
 687 
 688         if (pcmk__str_eq((const char *)a_child->name, XML_CIB_TAG_NODE,
 689                          pcmk__str_none)) {
 690             child_name = ID(a_child);
 691             if (pcmk__str_eq(uuid, child_name, pcmk__str_casei)) {
 692                 child_name = crm_element_value(a_child, XML_ATTR_UNAME);
 693                 if (child_name != NULL) {
 694                     *uname = strdup(child_name);
 695                     rc = pcmk_ok;
 696                 }
 697                 break;
 698             }
 699         }
 700     }
 701 
 702     free_xml(fragment);
 703     return rc;
 704 }
 705 
 706 int
 707 set_standby(cib_t * the_cib, const char *uuid, const char *scope, const char *standby_value)
     /* [previous][next][first][last][top][bottom][index][help] */
 708 {
 709     int rc = pcmk_ok;
 710     char *attr_id = NULL;
 711 
 712     CRM_CHECK(uuid != NULL, return -EINVAL);
 713     CRM_CHECK(standby_value != NULL, return -EINVAL);
 714 
 715     if (pcmk__strcase_any_of(scope, "reboot", XML_CIB_TAG_STATUS, NULL)) {
 716         scope = XML_CIB_TAG_STATUS;
 717         attr_id = crm_strdup_printf("transient-standby-%.256s", uuid);
 718 
 719     } else {
 720         scope = XML_CIB_TAG_NODES;
 721         attr_id = crm_strdup_printf("standby-%.256s", uuid);
 722     }
 723 
 724     rc = update_attr_delegate(the_cib, cib_sync_call, scope, uuid, NULL, NULL,
 725                               attr_id, "standby", standby_value, TRUE, NULL, NULL);
 726 
 727     free(attr_id);
 728     return rc;
 729 }

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