LCOV - code coverage report
Current view: top level - cib - cib_attrs.c (source / functions) Hit Total Coverage
Test: Pacemaker code coverage Lines: 0 311 0.0 %
Date: 2024-05-07 11:09:47 Functions: 0 12 0.0 %

          Line data    Source code
       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           0 : new_output_object(const char *ty)
      32             : {
      33           0 :     int rc = pcmk_rc_ok;
      34           0 :     pcmk__output_t *out = NULL;
      35           0 :     const char* argv[] = { "", NULL };
      36           0 :     pcmk__supported_format_t formats[] = {
      37             :         PCMK__SUPPORTED_FORMAT_LOG,
      38             :         PCMK__SUPPORTED_FORMAT_TEXT,
      39             :         { NULL, NULL, NULL }
      40             :     };
      41             : 
      42           0 :     pcmk__register_formats(NULL, formats);
      43           0 :     rc = pcmk__output_new(&out, ty, NULL, (char**)argv);
      44           0 :     if ((rc != pcmk_rc_ok) || (out == NULL)) {
      45           0 :         crm_err("Can't out due to internal error: %s", pcmk_rc_str(rc));
      46           0 :         return NULL;
      47             :     }
      48             : 
      49           0 :     return out;
      50             : }
      51             : 
      52             : static int
      53           0 : find_attr(cib_t *cib, const char *section, const char *node_uuid,
      54             :           const char *attr_set_type, const char *set_name, const char *attr_id,
      55             :           const char *attr_name, const char *user_name, xmlNode **result)
      56             : {
      57           0 :     int rc = pcmk_rc_ok;
      58             : 
      59           0 :     const char *xpath_base = NULL;
      60           0 :     GString *xpath = NULL;
      61           0 :     xmlNode *xml_search = NULL;
      62           0 :     const char *set_type = NULL;
      63           0 :     const char *node_type = NULL;
      64             : 
      65           0 :     if (attr_set_type) {
      66           0 :         set_type = attr_set_type;
      67             :     } else {
      68           0 :         set_type = PCMK_XE_INSTANCE_ATTRIBUTES;
      69             :     }
      70             : 
      71           0 :     if (pcmk__str_eq(section, PCMK_XE_CRM_CONFIG, pcmk__str_casei)) {
      72           0 :         node_uuid = NULL;
      73           0 :         set_type = PCMK_XE_CLUSTER_PROPERTY_SET;
      74             : 
      75           0 :     } else if (pcmk__strcase_any_of(section,
      76             :                                     PCMK_XE_OP_DEFAULTS, PCMK_XE_RSC_DEFAULTS,
      77             :                                     NULL)) {
      78           0 :         node_uuid = NULL;
      79           0 :         set_type = PCMK_XE_META_ATTRIBUTES;
      80             : 
      81           0 :     } else if (pcmk__str_eq(section, PCMK_XE_TICKETS, pcmk__str_casei)) {
      82           0 :         node_uuid = NULL;
      83           0 :         section = PCMK_XE_STATUS;
      84           0 :         node_type = PCMK_XE_TICKETS;
      85             : 
      86           0 :     } else if (node_uuid == NULL) {
      87           0 :         return EINVAL;
      88             :     }
      89             : 
      90           0 :     xpath_base = pcmk_cib_xpath_for(section);
      91           0 :     if (xpath_base == NULL) {
      92           0 :         crm_warn("%s CIB section not known", section);
      93           0 :         return ENOMSG;
      94             :     }
      95             : 
      96           0 :     xpath = g_string_sized_new(1024);
      97             :     g_string_append(xpath, xpath_base);
      98             : 
      99           0 :     if (pcmk__str_eq(node_type, PCMK_XE_TICKETS, pcmk__str_casei)) {
     100           0 :         pcmk__g_strcat(xpath, "//", node_type, NULL);
     101             : 
     102           0 :     } else if (node_uuid) {
     103           0 :         const char *node_type = PCMK_XE_NODE;
     104             : 
     105           0 :         if (pcmk__str_eq(section, PCMK_XE_STATUS, pcmk__str_casei)) {
     106           0 :             node_type = PCMK__XE_NODE_STATE;
     107           0 :             set_type = PCMK__XE_TRANSIENT_ATTRIBUTES;
     108             :         }
     109           0 :         pcmk__g_strcat(xpath,
     110             :                        "//", node_type, "[@" PCMK_XA_ID "='", node_uuid, "']",
     111             :                        NULL);
     112             :     }
     113             : 
     114           0 :     pcmk__g_strcat(xpath, "//", set_type, NULL);
     115           0 :     if (set_name) {
     116           0 :         pcmk__g_strcat(xpath, "[@" PCMK_XA_ID "='", set_name, "']", NULL);
     117             :     }
     118             : 
     119           0 :     g_string_append(xpath, "//nvpair");
     120             : 
     121           0 :     if (attr_id && attr_name) {
     122           0 :         pcmk__g_strcat(xpath,
     123             :                        "[@" PCMK_XA_ID "='", attr_id, "' "
     124             :                        "and @" PCMK_XA_NAME "='", attr_name, "']", NULL);
     125             : 
     126           0 :     } else if (attr_id) {
     127           0 :         pcmk__g_strcat(xpath, "[@" PCMK_XA_ID "='", attr_id, "']", NULL);
     128             : 
     129           0 :     } else if (attr_name) {
     130           0 :         pcmk__g_strcat(xpath, "[@" PCMK_XA_NAME "='", attr_name, "']", NULL);
     131             :     }
     132             : 
     133           0 :     rc = cib_internal_op(cib, PCMK__CIB_REQUEST_QUERY, NULL,
     134           0 :                          (const char *) xpath->str, NULL, &xml_search,
     135             :                          cib_sync_call|cib_scope_local|cib_xpath, user_name);
     136           0 :     rc = pcmk_legacy2rc(rc);
     137             : 
     138           0 :     if (rc != pcmk_rc_ok) {
     139           0 :         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           0 :         crm_log_xml_debug(xml_search, "Match");
     145             :     }
     146             : 
     147           0 :     g_string_free(xpath, TRUE);
     148           0 :     *result = xml_search;
     149           0 :     return rc;
     150             : }
     151             : 
     152             : static int
     153           0 : handle_multiples(pcmk__output_t *out, xmlNode *search, const char *attr_name)
     154             : {
     155           0 :     if ((search != NULL) && (search->children != NULL)) {
     156           0 :         pcmk__warn_multiple_name_matches(out, search, attr_name);
     157           0 :         return ENOTUNIQ;
     158             :     } else {
     159           0 :         return pcmk_rc_ok;
     160             :     }
     161             : }
     162             : 
     163             : int
     164           0 : cib__update_node_attr(pcmk__output_t *out, cib_t *cib, int call_options, const char *section,
     165             :                       const char *node_uuid, const char *set_type, const char *set_name,
     166             :                       const char *attr_id, const char *attr_name, const char *attr_value,
     167             :                       const char *user_name, const char *node_type)
     168             : {
     169           0 :     const char *tag = NULL;
     170           0 :     int rc = pcmk_rc_ok;
     171           0 :     xmlNode *xml_top = NULL;
     172           0 :     xmlNode *xml_obj = NULL;
     173           0 :     xmlNode *xml_search = NULL;
     174             : 
     175           0 :     char *local_attr_id = NULL;
     176           0 :     char *local_set_name = NULL;
     177             : 
     178           0 :     CRM_CHECK((out != NULL) && (cib != NULL) && (section != NULL)
     179             :               && ((attr_id != NULL) || (attr_name != NULL))
     180             :               && (attr_value != NULL), return EINVAL);
     181             : 
     182           0 :     rc = find_attr(cib, section, node_uuid, set_type, set_name, attr_id,
     183             :                    attr_name, user_name, &xml_search);
     184             : 
     185           0 :     if (rc == pcmk_rc_ok) {
     186           0 :         if (handle_multiples(out, xml_search, attr_name) == ENOTUNIQ) {
     187           0 :             free_xml(xml_search);
     188           0 :             return ENOTUNIQ;
     189             :         } else {
     190           0 :             local_attr_id = crm_element_value_copy(xml_search, PCMK_XA_ID);
     191           0 :             attr_id = local_attr_id;
     192           0 :             free_xml(xml_search);
     193           0 :             goto do_modify;
     194             :         }
     195             : 
     196           0 :     } else if (rc != ENXIO) {
     197           0 :         free_xml(xml_search);
     198           0 :         return rc;
     199             : 
     200             :         /* } else if(attr_id == NULL) { */
     201             :         /*     return EINVAL; */
     202             : 
     203             :     } else {
     204           0 :         free_xml(xml_search);
     205           0 :         crm_trace("%s does not exist, create it", attr_name);
     206           0 :         if (pcmk__str_eq(section, PCMK_XE_TICKETS, pcmk__str_casei)) {
     207           0 :             node_uuid = NULL;
     208           0 :             section = PCMK_XE_STATUS;
     209           0 :             node_type = PCMK_XE_TICKETS;
     210             : 
     211           0 :             xml_top = pcmk__xe_create(xml_obj, PCMK_XE_STATUS);
     212           0 :             xml_obj = pcmk__xe_create(xml_top, PCMK_XE_TICKETS);
     213             : 
     214           0 :         } else if (pcmk__str_eq(section, PCMK_XE_NODES, pcmk__str_casei)) {
     215             : 
     216           0 :             if (node_uuid == NULL) {
     217           0 :                 return EINVAL;
     218             :             }
     219             : 
     220           0 :             if (pcmk__str_eq(node_type, PCMK_VALUE_REMOTE, pcmk__str_casei)) {
     221           0 :                 xml_top = pcmk__xe_create(xml_obj, PCMK_XE_NODES);
     222           0 :                 xml_obj = pcmk__xe_create(xml_top, PCMK_XE_NODE);
     223           0 :                 crm_xml_add(xml_obj, PCMK_XA_TYPE, PCMK_VALUE_REMOTE);
     224           0 :                 crm_xml_add(xml_obj, PCMK_XA_ID, node_uuid);
     225           0 :                 crm_xml_add(xml_obj, PCMK_XA_UNAME, node_uuid);
     226             :             } else {
     227           0 :                 tag = PCMK_XE_NODE;
     228             :             }
     229             : 
     230           0 :         } else if (pcmk__str_eq(section, PCMK_XE_STATUS, pcmk__str_casei)) {
     231           0 :             tag = PCMK__XE_TRANSIENT_ATTRIBUTES;
     232           0 :             if (node_uuid == NULL) {
     233           0 :                 return EINVAL;
     234             :             }
     235             : 
     236           0 :             xml_top = pcmk__xe_create(xml_obj, PCMK__XE_NODE_STATE);
     237           0 :             crm_xml_add(xml_top, PCMK_XA_ID, node_uuid);
     238           0 :             xml_obj = xml_top;
     239             : 
     240             :         } else {
     241           0 :             tag = section;
     242           0 :             node_uuid = NULL;
     243             :         }
     244             : 
     245           0 :         if (set_name == NULL) {
     246           0 :             if (pcmk__str_eq(section, PCMK_XE_CRM_CONFIG, pcmk__str_casei)) {
     247             :                 local_set_name =
     248           0 :                     pcmk__str_copy(PCMK_VALUE_CIB_BOOTSTRAP_OPTIONS);
     249             : 
     250           0 :             } else if (pcmk__str_eq(node_type, PCMK_XE_TICKETS,
     251             :                                     pcmk__str_casei)) {
     252           0 :                 local_set_name = crm_strdup_printf("%s-%s", section,
     253             :                                                    PCMK_XE_TICKETS);
     254             : 
     255           0 :             } else if (node_uuid) {
     256           0 :                 local_set_name = crm_strdup_printf("%s-%s", section, node_uuid);
     257             : 
     258           0 :                 if (set_type) {
     259           0 :                     char *tmp_set_name = local_set_name;
     260             : 
     261           0 :                     local_set_name = crm_strdup_printf("%s-%s", tmp_set_name,
     262             :                                                        set_type);
     263           0 :                     free(tmp_set_name);
     264             :                 }
     265             :             } else {
     266           0 :                 local_set_name = crm_strdup_printf("%s-options", section);
     267             :             }
     268           0 :             set_name = local_set_name;
     269             :         }
     270             : 
     271           0 :         if (attr_id == NULL) {
     272           0 :             local_attr_id = crm_strdup_printf("%s-%s", set_name, attr_name);
     273           0 :             crm_xml_sanitize_id(local_attr_id);
     274           0 :             attr_id = local_attr_id;
     275             : 
     276           0 :         } else if (attr_name == NULL) {
     277           0 :             attr_name = attr_id;
     278             :         }
     279             : 
     280           0 :         crm_trace("Creating %s/%s", section, tag);
     281           0 :         if (tag != NULL) {
     282           0 :             xml_obj = pcmk__xe_create(xml_obj, tag);
     283           0 :             crm_xml_add(xml_obj, PCMK_XA_ID, node_uuid);
     284           0 :             if (xml_top == NULL) {
     285           0 :                 xml_top = xml_obj;
     286             :             }
     287             :         }
     288             : 
     289           0 :         if ((node_uuid == NULL)
     290           0 :             && !pcmk__str_eq(node_type, PCMK_XE_TICKETS, pcmk__str_casei)) {
     291             : 
     292           0 :             if (pcmk__str_eq(section, PCMK_XE_CRM_CONFIG, pcmk__str_casei)) {
     293           0 :                 xml_obj = pcmk__xe_create(xml_obj,
     294             :                                           PCMK_XE_CLUSTER_PROPERTY_SET);
     295             :             } else {
     296           0 :                 xml_obj = pcmk__xe_create(xml_obj, PCMK_XE_META_ATTRIBUTES);
     297             :             }
     298             : 
     299           0 :         } else if (set_type) {
     300           0 :             xml_obj = pcmk__xe_create(xml_obj, set_type);
     301             : 
     302             :         } else {
     303           0 :             xml_obj = pcmk__xe_create(xml_obj, PCMK_XE_INSTANCE_ATTRIBUTES);
     304             :         }
     305           0 :         crm_xml_add(xml_obj, PCMK_XA_ID, set_name);
     306             : 
     307           0 :         if (xml_top == NULL) {
     308           0 :             xml_top = xml_obj;
     309             :         }
     310             :     }
     311             : 
     312           0 :   do_modify:
     313           0 :     xml_obj = crm_create_nvpair_xml(xml_obj, attr_id, attr_name, attr_value);
     314           0 :     if (xml_top == NULL) {
     315           0 :         xml_top = xml_obj;
     316             :     }
     317             : 
     318           0 :     crm_log_xml_trace(xml_top, "update_attr");
     319           0 :     rc = cib_internal_op(cib, PCMK__CIB_REQUEST_MODIFY, NULL, section, xml_top,
     320             :                          NULL, call_options, user_name);
     321             : 
     322           0 :     if (!pcmk_is_set(call_options, cib_sync_call) && (cib->variant != cib_file)
     323           0 :         && (rc >= 0)) {
     324             :         // For async call, positive rc is the call ID (file always synchronous)
     325           0 :         rc = pcmk_rc_ok;
     326             :     } else {
     327           0 :         rc = pcmk_legacy2rc(rc);
     328             :     }
     329             : 
     330           0 :     if (rc != pcmk_rc_ok) {
     331           0 :         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           0 :         crm_log_xml_info(xml_top, "Update");
     335             :     }
     336             : 
     337           0 :     free(local_set_name);
     338           0 :     free(local_attr_id);
     339           0 :     free_xml(xml_top);
     340             : 
     341           0 :     return rc;
     342             : }
     343             : 
     344             : int
     345           0 : cib__get_node_attrs(pcmk__output_t *out, cib_t *cib, const char *section,
     346             :                     const char *node_uuid, const char *set_type, const char *set_name,
     347             :                     const char *attr_id, const char *attr_name, const char *user_name,
     348             :                     xmlNode **result)
     349             : {
     350           0 :     int rc = pcmk_rc_ok;
     351             : 
     352           0 :     CRM_ASSERT(result != NULL);
     353           0 :     CRM_CHECK(section != NULL, return EINVAL);
     354             : 
     355           0 :     *result = NULL;
     356             : 
     357           0 :     rc = find_attr(cib, section, node_uuid, set_type, set_name, attr_id, attr_name,
     358             :                    user_name, result);
     359             : 
     360           0 :     if (rc != pcmk_rc_ok) {
     361           0 :         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           0 :     return rc;
     368             : }
     369             : 
     370             : int
     371           0 : cib__delete_node_attr(pcmk__output_t *out, cib_t *cib, int options, const char *section,
     372             :                       const char *node_uuid, const char *set_type, const char *set_name,
     373             :                       const char *attr_id, const char *attr_name, const char *attr_value,
     374             :                       const char *user_name)
     375             : {
     376           0 :     int rc = pcmk_rc_ok;
     377           0 :     xmlNode *xml_obj = NULL;
     378           0 :     xmlNode *xml_search = NULL;
     379           0 :     char *local_attr_id = NULL;
     380             : 
     381           0 :     CRM_CHECK(section != NULL, return EINVAL);
     382           0 :     CRM_CHECK(attr_name != NULL || attr_id != NULL, return EINVAL);
     383             : 
     384           0 :     if (attr_id == NULL) {
     385           0 :         rc = find_attr(cib, section, node_uuid, set_type, set_name, attr_id,
     386             :                        attr_name, user_name, &xml_search);
     387             : 
     388           0 :         if (rc != pcmk_rc_ok || handle_multiples(out, xml_search, attr_name) == ENOTUNIQ) {
     389           0 :             free_xml(xml_search);
     390           0 :             return rc;
     391             :         } else {
     392           0 :             local_attr_id = crm_element_value_copy(xml_search, PCMK_XA_ID);
     393           0 :             attr_id = local_attr_id;
     394           0 :             free_xml(xml_search);
     395             :         }
     396             :     }
     397             : 
     398           0 :     xml_obj = crm_create_nvpair_xml(NULL, attr_id, attr_name, attr_value);
     399             : 
     400           0 :     rc = cib_internal_op(cib, PCMK__CIB_REQUEST_DELETE, NULL, section, xml_obj,
     401             :                          NULL, options, user_name);
     402             : 
     403           0 :     if (!pcmk_is_set(options, cib_sync_call) && (cib->variant != cib_file)
     404           0 :         && (rc >= 0)) {
     405             :         // For async call, positive rc is the call ID (file always synchronous)
     406           0 :         rc = pcmk_rc_ok;
     407             :     } else {
     408           0 :         rc = pcmk_legacy2rc(rc);
     409             :     }
     410             : 
     411           0 :     if (rc == pcmk_rc_ok) {
     412           0 :         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           0 :     free(local_attr_id);
     418           0 :     free_xml(xml_obj);
     419           0 :     return rc;
     420             : }
     421             : 
     422             : int
     423           0 : find_nvpair_attr_delegate(cib_t *cib, const char *attr, const char *section,
     424             :                           const char *node_uuid, const char *attr_set_type, const char *set_name,
     425             :                           const char *attr_id, const char *attr_name, gboolean to_console,
     426             :                           char **value, const char *user_name)
     427             : {
     428           0 :     pcmk__output_t *out = NULL;
     429           0 :     xmlNode *xml_search = NULL;
     430           0 :     int rc = pcmk_ok;
     431             : 
     432           0 :     out = new_output_object(to_console ? "text" : "log");
     433           0 :     if (out == NULL) {
     434           0 :         return pcmk_err_generic;
     435             :     }
     436             : 
     437           0 :     rc = find_attr(cib, section, node_uuid, attr_set_type, set_name, attr_id,
     438             :                    attr_name, user_name, &xml_search);
     439             : 
     440           0 :     if (rc == pcmk_rc_ok) {
     441           0 :         rc = handle_multiples(out, xml_search, attr_name);
     442             : 
     443           0 :         if (rc == pcmk_rc_ok) {
     444           0 :             pcmk__str_update(value, crm_element_value(xml_search, attr));
     445             :         }
     446             :     }
     447             : 
     448           0 :     out->finish(out, CRM_EX_OK, true, NULL);
     449           0 :     free_xml(xml_search);
     450           0 :     pcmk__output_free(out);
     451           0 :     return pcmk_rc2legacy(rc);
     452             : }
     453             : 
     454             : int
     455           0 : update_attr_delegate(cib_t *cib, int call_options, const char *section,
     456             :                      const char *node_uuid, const char *set_type, const char *set_name,
     457             :                      const char *attr_id, const char *attr_name, const char *attr_value,
     458             :                      gboolean to_console, const char *user_name, const char *node_type)
     459             : {
     460           0 :     pcmk__output_t *out = NULL;
     461           0 :     int rc = pcmk_ok;
     462             : 
     463           0 :     out = new_output_object(to_console ? "text" : "log");
     464           0 :     if (out == NULL) {
     465           0 :         return pcmk_err_generic;
     466             :     }
     467             : 
     468           0 :     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           0 :     out->finish(out, CRM_EX_OK, true, NULL);
     473           0 :     pcmk__output_free(out);
     474           0 :     return pcmk_rc2legacy(rc);
     475             : }
     476             : 
     477             : int
     478           0 : read_attr_delegate(cib_t *cib, const char *section, const char *node_uuid,
     479             :                    const char *set_type, const char *set_name, const char *attr_id,
     480             :                    const char *attr_name, char **attr_value, gboolean to_console,
     481             :                    const char *user_name)
     482             : {
     483           0 :     pcmk__output_t *out = NULL;
     484           0 :     xmlNode *result = NULL;
     485           0 :     int rc = pcmk_ok;
     486             : 
     487           0 :     out = new_output_object(to_console ? "text" : "log");
     488           0 :     if (out == NULL) {
     489           0 :         return pcmk_err_generic;
     490             :     }
     491             : 
     492           0 :     rc = cib__get_node_attrs(out, cib, section, node_uuid, set_type, set_name,
     493             :                              attr_id, attr_name, user_name, &result);
     494             : 
     495           0 :     if (rc == pcmk_rc_ok) {
     496           0 :         if (result->children == NULL) {
     497           0 :             pcmk__str_update(attr_value,
     498             :                              crm_element_value(result, PCMK_XA_VALUE));
     499             :         } else {
     500           0 :             rc = ENOTUNIQ;
     501             :         }
     502             :     }
     503             : 
     504           0 :     out->finish(out, CRM_EX_OK, true, NULL);
     505           0 :     free_xml(result);
     506           0 :     pcmk__output_free(out);
     507           0 :     return pcmk_rc2legacy(rc);
     508             : }
     509             : 
     510             : int
     511           0 : delete_attr_delegate(cib_t *cib, int options, const char *section, const char *node_uuid,
     512             :                      const char *set_type, const char *set_name, const char *attr_id,
     513             :                      const char *attr_name, const char *attr_value, gboolean to_console,
     514             :                      const char *user_name)
     515             : {
     516           0 :     pcmk__output_t *out = NULL;
     517           0 :     int rc = pcmk_ok;
     518             : 
     519           0 :     out = new_output_object(to_console ? "text" : "log");
     520           0 :     if (out == NULL) {
     521           0 :         return pcmk_err_generic;
     522             :     }
     523             : 
     524           0 :     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           0 :     out->finish(out, CRM_EX_OK, true, NULL);
     528           0 :     pcmk__output_free(out);
     529           0 :     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           0 : get_uuid_from_result(const xmlNode *result, char **uuid, int *is_remote)
     544             : {
     545           0 :     int rc = -ENXIO;
     546           0 :     const char *parsed_uuid = NULL;
     547           0 :     int parsed_is_remote = FALSE;
     548             : 
     549           0 :     if (result == NULL) {
     550           0 :         return rc;
     551             :     }
     552             : 
     553             :     /* If there are multiple results, the first is sufficient */
     554           0 :     if (pcmk__xe_is(result, PCMK__XE_XPATH_QUERY)) {
     555           0 :         result = pcmk__xe_first_child(result, NULL, NULL, NULL);
     556           0 :         CRM_CHECK(result != NULL, return rc);
     557             :     }
     558             : 
     559           0 :     if (pcmk__xe_is(result, PCMK_XE_NODE)) {
     560             :         // Result is PCMK_XE_NODE element from PCMK_XE_NODES section
     561             : 
     562           0 :         if (pcmk__str_eq(crm_element_value(result, PCMK_XA_TYPE),
     563             :                          PCMK_VALUE_REMOTE, pcmk__str_casei)) {
     564           0 :             parsed_uuid = crm_element_value(result, PCMK_XA_UNAME);
     565           0 :             parsed_is_remote = TRUE;
     566             :         } else {
     567           0 :             parsed_uuid = pcmk__xe_id(result);
     568           0 :             parsed_is_remote = FALSE;
     569             :         }
     570             : 
     571           0 :     } else if (pcmk__xe_is(result, PCMK_XE_PRIMITIVE)) {
     572             :         /* Result is <primitive> for ocf:pacemaker:remote resource */
     573             : 
     574           0 :         parsed_uuid = pcmk__xe_id(result);
     575           0 :         parsed_is_remote = TRUE;
     576             : 
     577           0 :     } 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           0 :         parsed_uuid = crm_element_value(result, PCMK_XA_VALUE);
     583           0 :         parsed_is_remote = TRUE;
     584             : 
     585           0 :     } 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           0 :         parsed_uuid = crm_element_value(result, PCMK_XA_UNAME);
     589           0 :         if (pcmk__xe_attr_is_true(result, PCMK_XA_REMOTE_NODE)) {
     590           0 :             parsed_is_remote = TRUE;
     591             :         }
     592             :     }
     593             : 
     594           0 :     if (parsed_uuid) {
     595           0 :         if (uuid) {
     596           0 :             *uuid = strdup(parsed_uuid);
     597             :         }
     598           0 :         if (is_remote) {
     599           0 :             *is_remote = parsed_is_remote;
     600             :         }
     601           0 :         rc = pcmk_ok;
     602             :     }
     603             : 
     604           0 :     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           0 : query_node_uuid(cib_t * the_cib, const char *uname, char **uuid, int *is_remote_node)
     629             : {
     630           0 :     int rc = pcmk_ok;
     631             :     char *xpath_string;
     632           0 :     xmlNode *xml_search = NULL;
     633           0 :     char *host_lowercase = NULL;
     634             : 
     635           0 :     CRM_ASSERT(uname != NULL);
     636             : 
     637           0 :     host_lowercase = g_ascii_strdown(uname, -1);
     638             : 
     639           0 :     if (uuid) {
     640           0 :         *uuid = NULL;
     641             :     }
     642           0 :     if (is_remote_node) {
     643           0 :         *is_remote_node = FALSE;
     644             :     }
     645             : 
     646           0 :     xpath_string = crm_strdup_printf(XPATH_NODE, host_lowercase, host_lowercase, host_lowercase, host_lowercase);
     647           0 :     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           0 :         rc = get_uuid_from_result(xml_search, uuid, is_remote_node);
     652             :     } else {
     653           0 :         rc = -ENXIO;
     654             :     }
     655           0 :     free(xpath_string);
     656           0 :     free_xml(xml_search);
     657           0 :     g_free(host_lowercase);
     658             : 
     659           0 :     if (rc != pcmk_ok) {
     660           0 :         crm_debug("Could not map node name '%s' to a UUID: %s",
     661             :                   uname, pcmk_strerror(rc));
     662             :     } else {
     663           0 :         crm_info("Mapped node name '%s' to UUID %s", uname, (uuid? *uuid : ""));
     664             :     }
     665           0 :     return rc;
     666             : }
     667             : 
     668             : // Deprecated functions kept only for backward API compatibility
     669             : // LCOV_EXCL_START
     670             : 
     671             : #include <crm/cib/util_compat.h>
     672             : 
     673             : int
     674             : query_node_uname(cib_t * the_cib, const char *uuid, char **uname)
     675             : {
     676             :     int rc = pcmk_ok;
     677             :     xmlNode *a_child = NULL;
     678             :     xmlNode *xml_obj = NULL;
     679             :     xmlNode *fragment = NULL;
     680             :     const char *child_name = NULL;
     681             : 
     682             :     CRM_ASSERT(uname != NULL);
     683             :     CRM_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)
     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

Generated by: LCOV version 1.14