1 /*
2 * Copyright 2006-2026 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 General Public License version 2
7 * or later (GPLv2+) WITHOUT ANY WARRANTY.
8 */
9
10 #include <crm_internal.h>
11
12 #include <stdbool.h>
13
14 #include <crm/crm.h>
15 #include <crm/common/ipc.h>
16 #include <crm/common/xml.h>
17
18 #include <pacemaker-controld.h>
19
20 static pcmk_ipc_api_t *attrd_api = NULL;
21
22 void
23 controld_close_attrd_ipc(void)
24 {
|
(1) Event path: |
Condition "attrd_api == NULL", taking false branch. |
25 if (attrd_api == NULL) {
26 return;
27 }
28
|
(2) Event path: |
Switch case default. |
|
(3) Event path: |
Condition "trace_cs == NULL", taking true branch. |
|
(4) Event path: |
Condition "crm_is_callsite_active(trace_cs, _level, 0)", taking false branch. |
|
(5) Event path: |
Breaking from switch. |
29 pcmk__trace("Closing connection to " PCMK__SERVER_ATTRD);
30 pcmk_disconnect_ipc(attrd_api);
|
CID (unavailable; MK=365118909805af1f9bc248c73473cee4) (#1 of 1): Inconsistent C union access (INCONSISTENT_UNION_ACCESS): |
|
(6) Event assign_union_field: |
The union field "in" of "_pp" is written. |
|
(7) Event inconsistent_union_field_access: |
In "_pp.out", the union field used: "out" is inconsistent with the field most recently stored: "in". |
31 g_clear_pointer(&attrd_api, pcmk_free_ipc_api);
32 }
33
34 static inline const char *
35 node_type(bool is_remote)
36 {
37 return is_remote? "Pacemaker Remote" : "cluster";
38 }
39
40 static inline const char *
41 when(void)
42 {
43 return pcmk__is_set(controld_globals.fsa_input_register,
44 R_SHUTDOWN)? " at shutdown" : "";
45 }
46
47 static void
48 handle_attr_error(void)
49 {
50 if (AM_I_DC) {
51 /* We are unable to provide accurate information to the
52 * scheduler, so allow another node to take over DC.
53 * @TODO Should we do this unconditionally on any failure?
54 */
55 crmd_exit(CRM_EX_FATAL);
56
57 } else if (pcmk__is_set(controld_globals.fsa_input_register, R_SHUTDOWN)) {
58 // Fast-track shutdown since unable to request via attribute
59 controld_fsa_append(C_FSA_INTERNAL, I_FAIL, NULL);
60 }
61 }
62
63 void
64 update_attrd(const char *host, const char *name, const char *value,
65 bool is_remote_node)
66 {
67 int rc = pcmk_rc_ok;
68
69 if (attrd_api == NULL) {
70 rc = pcmk_new_ipc_api(&attrd_api, pcmk_ipc_attrd);
71 }
72 if (rc == pcmk_rc_ok) {
73 uint32_t attrd_opts = pcmk__node_attr_value;
74
75 if (is_remote_node) {
76 pcmk__set_node_attr_flags(attrd_opts, pcmk__node_attr_remote);
77 }
78 rc = pcmk__attrd_api_update(attrd_api, host, name, value, NULL, NULL,
79 NULL, attrd_opts);
80 }
81 if (rc != pcmk_rc_ok) {
82 do_crm_log(AM_I_DC? LOG_CRIT : LOG_ERR,
83 "Could not update attribute %s=%s for %s node %s%s: %s "
84 QB_XS " rc=%d", name, value, node_type(is_remote_node),
85 host, when(), pcmk_rc_str(rc), rc);
86 handle_attr_error();
87 }
88 }
89
90 void
91 update_attrd_list(GList *attrs, uint32_t opts)
92 {
93 int rc = pcmk_rc_ok;
94
95 if (attrd_api == NULL) {
96 rc = pcmk_new_ipc_api(&attrd_api, pcmk_ipc_attrd);
97 }
98 if (rc == pcmk_rc_ok) {
99 rc = pcmk__attrd_api_update_list(attrd_api, attrs, NULL, NULL, NULL,
100 opts | pcmk__node_attr_value);
101 }
102 if (rc != pcmk_rc_ok) {
103 do_crm_log(AM_I_DC? LOG_CRIT : LOG_ERR,
104 "Could not update multiple node attributes: %s "
105 QB_XS " rc=%d", pcmk_rc_str(rc), rc);
106 handle_attr_error();
107 }
108 }
109
110 /*!
111 * \internal
112 * \brief Ask attribute manager to purge a node and its transient attributes
113 *
114 * \param[in] node_name Node to purge
115 * \param[in] from_cache If true, purge from node caches as well
116 */
117 void
118 controld_purge_node_attrs(const char *node_name, bool from_cache)
119 {
120 int rc = pcmk_rc_ok;
121
122 if (attrd_api == NULL) {
123 rc = pcmk_new_ipc_api(&attrd_api, pcmk_ipc_attrd);
124 }
125 if (rc == pcmk_rc_ok) {
126 pcmk__debug("Asking %s to purge transient attributes%s for %s",
127 pcmk_ipc_name(attrd_api, true),
128 (from_cache? " and node cache" : ""), node_name);
129 rc = pcmk__attrd_api_purge(attrd_api, node_name, from_cache);
130 }
131 if (rc != pcmk_rc_ok) {
132 pcmk__err("Could not purge node %s from %s%s: %s "
133 QB_XS " rc=%d", node_name, pcmk_ipc_name(attrd_api, true),
134 when(), pcmk_rc_str(rc), rc);
135 }
136 }
137
138 void
139 update_attrd_clear_failures(const char *host, const char *rsc, const char *op,
140 const char *interval_spec, gboolean is_remote_node)
141 {
142 int rc = pcmk_rc_ok;
143
144 if (attrd_api == NULL) {
145 rc = pcmk_new_ipc_api(&attrd_api, pcmk_ipc_attrd);
146 }
147 if (rc == pcmk_rc_ok) {
148 uint32_t attrd_opts = pcmk__node_attr_none;
149
150 if (is_remote_node) {
151 pcmk__set_node_attr_flags(attrd_opts, pcmk__node_attr_remote);
152 }
153 rc = pcmk__attrd_api_clear_failures(attrd_api, host, rsc, op,
154 interval_spec, NULL, attrd_opts);
155 }
156 if (rc != pcmk_rc_ok) {
157 const char *interval_desc = "all";
158
159 if (op != NULL) {
160 interval_desc = pcmk__s(interval_spec, "nonrecurring");
161 }
162 pcmk__err("Could not clear failure of %s %s for %s on %s node %s%s: %s "
163 QB_XS " rc=%d",
164 interval_desc, pcmk__s(op, "operations"),
165 pcmk__s(rsc, "all resources"), node_type(is_remote_node),
166 host, when(), pcmk_rc_str(rc), rc);
167 }
168 }
169