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-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>
  26 #include <crm/common/xml_internal.h>
  27 #include <crm/common/output_internal.h>
  28 #include <crm/cib/internal.h>
  29 
  30 static pcmk__output_t *
  31 new_output_object(const char *ty)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33     int rc = pcmk_rc_ok;
  34     pcmk__output_t *out = NULL;
  35     const char* argv[] = { "", NULL };
  36     pcmk__supported_format_t formats[] = {
  37         PCMK__SUPPORTED_FORMAT_LOG,
  38         PCMK__SUPPORTED_FORMAT_TEXT,
  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,
     /* [previous][next][first][last][top][bottom][index][help] */
  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;
  73         set_type = PCMK_XE_CLUSTER_PROPERTY_SET;
  74 
  75     } else if (pcmk__strcase_any_of(section,
  76                                     PCMK_XE_OP_DEFAULTS, PCMK_XE_RSC_DEFAULTS,
  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;
  84         node_type = PCMK_XE_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, 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)) {
 106             node_type = PCMK__XE_NODE_STATE;
 107             set_type = PCMK__XE_TRANSIENT_ATTRIBUTES;
 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 
 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     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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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;
 209             node_type = PCMK_XE_TICKETS;
 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);
 223                 crm_xml_add(xml_obj, PCMK_XA_TYPE, PCMK_VALUE_REMOTE);
 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)) {
 231             tag = PCMK__XE_TRANSIENT_ATTRIBUTES;
 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 =
 248                     pcmk__str_copy(PCMK_VALUE_CIB_BOOTSTRAP_OPTIONS);
 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,
 253                                                    PCMK_XE_TICKETS);
 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,
 294                                           PCMK_XE_CLUSTER_PROPERTY_SET);
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
 498                              crm_element_value(result, PCMK_XA_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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 532 /*!
 533  * \internal
 534  * \brief Parse node UUID from search result
 535  *
 536  * \param[in]  result     XML search result
 537  * \param[out] uuid       If non-NULL, where to store parsed UUID
 538  * \param[out] is_remote  If non-NULL, set TRUE if result is remote node
 539  *
 540  * \return pcmk_ok if UUID was successfully parsed, -ENXIO otherwise
 541  */
 542 static int
 543 get_uuid_from_result(const xmlNode *result, char **uuid, int *is_remote)
     /* [previous][next][first][last][top][bottom][index][help] */
 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),
 563                          PCMK_VALUE_REMOTE, pcmk__str_casei)) {
 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);
 589         if (pcmk__xe_attr_is_true(result, PCMK_XA_REMOTE_NODE)) {
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
 649                         cib_sync_call|cib_scope_local|cib_xpath,
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
 686                               cib_sync_call | cib_scope_local);
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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

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