root/lib/cib/cib_attrs.c

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

DEFINITIONS

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

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

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