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