pacemaker 2.1.4-dc6eb4362e
Scalable High-Availability cluster resource manager
attrd_client.c
Go to the documentation of this file.
1/*
2 * Copyright 2011-2021 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#ifndef _GNU_SOURCE
11# define _GNU_SOURCE
12#endif
13
14#include <crm_internal.h>
15
16#include <stdio.h>
17
18#include <crm/crm.h>
19#include <crm/msg_xml.h>
21
30static xmlNode *
31create_attrd_op(const char *user_name)
32{
33 xmlNode *attrd_op = create_xml_node(NULL, __func__);
34
35 crm_xml_add(attrd_op, F_TYPE, T_ATTRD);
36 crm_xml_add(attrd_op, F_ORIG, (crm_system_name? crm_system_name: "unknown"));
37 crm_xml_add(attrd_op, PCMK__XA_ATTR_USER, user_name);
38
39 return attrd_op;
40}
41
51static int
52send_attrd_op(crm_ipc_t *ipc, xmlNode *attrd_op)
53{
54 int rc = -ENOTCONN; // initially handled as legacy return code
55 int max = 5;
56
57 static gboolean connected = TRUE;
58 static crm_ipc_t *local_ipc = NULL;
60
61 if (ipc == NULL && local_ipc == NULL) {
62 local_ipc = crm_ipc_new(T_ATTRD, 0);
64 connected = FALSE;
65 }
66
67 if (ipc == NULL) {
68 ipc = local_ipc;
69 }
70
71 while (max > 0) {
72 if (connected == FALSE) {
73 crm_info("Connecting to cluster... %d retries remaining", max);
74 connected = crm_ipc_connect(ipc);
75 }
76
77 if (connected) {
78 rc = crm_ipc_send(ipc, attrd_op, flags, 0, NULL);
79 } else {
80 crm_perror(LOG_INFO, "Connection to cluster attribute manager failed");
81 }
82
83 if (ipc != local_ipc) {
84 break;
85
86 } else if (rc > 0) {
87 break;
88
89 } else if (rc == -EAGAIN || rc == -EALREADY) {
90 sleep(5 - max);
91 max--;
92
93 } else {
94 crm_ipc_close(ipc);
95 connected = FALSE;
96 sleep(5 - max);
97 max--;
98 }
99 }
100
101 if (rc > 0) {
102 rc = pcmk_ok;
103 }
104 return pcmk_legacy2rc(rc);
105}
106
132int
133pcmk__node_attr_request(crm_ipc_t *ipc, char command, const char *host,
134 const char *name, const char *value,
135 const char *section, const char *set,
136 const char *dampen, const char *user_name, int options)
137{
138 int rc = pcmk_rc_ok;
139 const char *task = NULL;
140 const char *name_as = NULL;
141 const char *display_host = (host ? host : "localhost");
142 const char *display_command = NULL; /* for commands without name/value */
143 xmlNode *update = create_attrd_op(user_name);
144
145 /* remap common aliases */
146 if (pcmk__str_eq(section, "reboot", pcmk__str_casei)) {
147 section = XML_CIB_TAG_STATUS;
148
149 } else if (pcmk__str_eq(section, "forever", pcmk__str_casei)) {
150 section = XML_CIB_TAG_NODES;
151 }
152
153 if (name == NULL && command == 'U') {
154 command = 'R';
155 }
156
157 switch (command) {
158 case 'u':
160 name_as = PCMK__XA_ATTR_PATTERN;
161 break;
162 case 'D':
163 case 'U':
164 case 'v':
166 name_as = PCMK__XA_ATTR_NAME;
167 break;
168 case 'R':
170 display_command = "refresh";
171 break;
172 case 'B':
174 name_as = PCMK__XA_ATTR_NAME;
175 break;
176 case 'Y':
178 name_as = PCMK__XA_ATTR_NAME;
179 break;
180 case 'Q':
182 name_as = PCMK__XA_ATTR_NAME;
183 break;
184 case 'C':
186 display_command = "purge";
187 break;
188 }
189
190 if (name_as != NULL) {
191 if (name == NULL) {
192 rc = EINVAL;
193 goto done;
194 }
195 crm_xml_add(update, name_as, name);
196 }
197
198 crm_xml_add(update, PCMK__XA_TASK, task);
199 crm_xml_add(update, PCMK__XA_ATTR_VALUE, value);
200 crm_xml_add(update, PCMK__XA_ATTR_DAMPENING, dampen);
201 crm_xml_add(update, PCMK__XA_ATTR_SECTION, section);
203 crm_xml_add(update, PCMK__XA_ATTR_SET, set);
208
209 rc = send_attrd_op(ipc, update);
210
211done:
212 free_xml(update);
213
214 if (display_command) {
215 crm_debug("Asked pacemaker-attrd to %s %s: %s (%d)",
216 display_command, display_host, pcmk_rc_str(rc), rc);
217 } else {
218 crm_debug("Asked pacemaker-attrd to update %s=%s for %s: %s (%d)",
219 name, value, display_host, pcmk_rc_str(rc), rc);
220 }
221 return rc;
222}
223
238int
240 const char *resource, const char *operation,
241 const char *interval_spec, const char *user_name,
242 int options)
243{
244 int rc = pcmk_rc_ok;
245 xmlNode *clear_op = create_attrd_op(user_name);
246 const char *interval_desc = NULL;
247 const char *op_desc = NULL;
248
251 crm_xml_add(clear_op, PCMK__XA_ATTR_RESOURCE, resource);
252 crm_xml_add(clear_op, PCMK__XA_ATTR_OPERATION, operation);
253 crm_xml_add(clear_op, PCMK__XA_ATTR_INTERVAL, interval_spec);
256
257 rc = send_attrd_op(ipc, clear_op);
258 free_xml(clear_op);
259
260 if (operation) {
261 interval_desc = interval_spec? interval_spec : "nonrecurring";
262 op_desc = operation;
263 } else {
264 interval_desc = "all";
265 op_desc = "operations";
266 }
267 crm_debug("Asked pacemaker-attrd to clear failure of %s %s for %s on %s: %s (%d)",
268 interval_desc, op_desc, (resource? resource : "all resources"),
269 (host? host : "all nodes"), pcmk_rc_str(rc), rc);
270 return rc;
271}
272
273#define LRM_TARGET_ENV "OCF_RESKEY_" CRM_META "_" XML_LRM_ATTR_TARGET
274
278const char *
280{
281 if (name == NULL || pcmk__strcase_any_of(name, "auto", "localhost", NULL)) {
282 char *target_var = crm_meta_name(XML_RSC_ATTR_TARGET);
283 char *phys_var = crm_meta_name(PCMK__ENV_PHYSICAL_HOST);
284 const char *target = getenv(target_var);
285 const char *host_physical = getenv(phys_var);
286
287 // It is important to use the name by which the scheduler knows us
288 if (host_physical && pcmk__str_eq(target, "host", pcmk__str_casei)) {
289 name = host_physical;
290
291 } else {
292 const char *host_pcmk = getenv(LRM_TARGET_ENV);
293
294 if (host_pcmk) {
295 name = host_pcmk;
296 }
297 }
298 free(target_var);
299 free(phys_var);
300
301 // TODO? Call get_local_node_name() if name == NULL
302 // (currently would require linkage against libcrmcluster)
303 return name;
304 } else {
305 return NULL;
306 }
307}
308
319char *
320pcmk_promotion_score_name(const char *rsc_id)
321{
322 if (rsc_id == NULL) {
323 rsc_id = getenv("OCF_RESOURCE_INSTANCE");
324 if (rsc_id == NULL) {
325 return NULL;
326 }
327 }
328 return crm_strdup_printf("master-%s", rsc_id);
329}
const char * pcmk__node_attr_target(const char *name)
Definition: attrd_client.c:279
int pcmk__node_attr_request(crm_ipc_t *ipc, char command, const char *host, const char *name, const char *value, const char *section, const char *set, const char *dampen, const char *user_name, int options)
Definition: attrd_client.c:133
#define LRM_TARGET_ENV
Definition: attrd_client.c:273
int pcmk__node_attr_request_clear(crm_ipc_t *ipc, const char *host, const char *resource, const char *operation, const char *interval_spec, const char *user_name, int options)
Definition: attrd_client.c:239
char * pcmk_promotion_score_name(const char *rsc_id)
Return the name of the node attribute used as a promotion score.
Definition: attrd_client.c:320
@ pcmk__node_attr_remote
@ pcmk__node_attr_private
const char * name
Definition: cib.c:24
uint64_t flags
Definition: remote.c:3
char * crm_meta_name(const char *field)
Definition: utils.c:439
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:122
pcmk__cpg_host_t host
Definition: cpg.c:4
A dumping ground.
char * crm_system_name
Definition: utils.c:54
#define PCMK__XA_ATTR_USER
Definition: crm_internal.h:74
#define PCMK__XA_ATTR_INTERVAL
Definition: crm_internal.h:63
#define PCMK__XA_ATTR_IS_PRIVATE
Definition: crm_internal.h:64
#define PCMK__XA_ATTR_SECTION
Definition: crm_internal.h:72
#define PCMK__XA_ATTR_SET
Definition: crm_internal.h:73
#define PCMK__XA_ATTR_NODE_NAME
Definition: crm_internal.h:68
#define PCMK__ATTRD_CMD_UPDATE_BOTH
Definition: crm_internal.h:97
#define PCMK__XA_ATTR_RESOURCE
Definition: crm_internal.h:71
#define PCMK__XA_ATTR_VALUE
Definition: crm_internal.h:76
#define PCMK__ATTRD_CMD_REFRESH
Definition: crm_internal.h:100
#define PCMK__ATTRD_CMD_CLEAR_FAILURE
Definition: crm_internal.h:104
#define PCMK__XA_ATTR_DAMPENING
Definition: crm_internal.h:61
#define PCMK__XA_ATTR_NAME
Definition: crm_internal.h:66
#define PCMK__XA_ATTR_PATTERN
Definition: crm_internal.h:70
#define PCMK__ATTRD_CMD_UPDATE_DELAY
Definition: crm_internal.h:98
#define PCMK__ATTRD_CMD_QUERY
Definition: crm_internal.h:99
#define PCMK__ATTRD_CMD_PEER_REMOVE
Definition: crm_internal.h:95
#define PCMK__XA_ATTR_IS_REMOTE
Definition: crm_internal.h:65
#define PCMK__XA_ATTR_OPERATION
Definition: crm_internal.h:69
#define PCMK__XA_TASK
Definition: crm_internal.h:80
#define PCMK__ATTRD_CMD_UPDATE
Definition: crm_internal.h:96
int crm_ipc_send(crm_ipc_t *client, xmlNode *message, enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply)
Send an IPC XML message.
Definition: ipc_client.c:1209
crm_ipc_flags
Definition: ipc.h:145
@ crm_ipc_flags_none
Definition: ipc.h:146
@ crm_ipc_client_response
Definition: ipc.h:151
bool crm_ipc_connect(crm_ipc_t *client)
Establish an IPC connection to a Pacemaker component.
Definition: ipc_client.c:847
void crm_ipc_close(crm_ipc_t *client)
Definition: ipc_client.c:917
struct crm_ipc_s crm_ipc_t
Definition: ipc.h:163
crm_ipc_t * crm_ipc_new(const char *name, size_t max_size)
Create a new (legacy) object for using Pacemaker daemon IPC.
Definition: ipc_client.c:800
#define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set)
Definition: ipc_internal.h:176
#define crm_info(fmt, args...)
Definition: logging.h:361
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
Definition: logging.h:309
#define crm_debug(fmt, args...)
Definition: logging.h:363
#define XML_RSC_ATTR_TARGET
Definition: msg_xml.h:227
#define T_ATTRD
Definition: msg_xml.h:85
#define F_ORIG
Definition: msg_xml.h:57
#define F_TYPE
Definition: msg_xml.h:69
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:187
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:185
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Create an XML attribute with specified name and integer value.
Definition: nvpair.c:431
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:323
#define PCMK__ENV_PHYSICAL_HOST
const char * target
Definition: pcmk_fence.c:28
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition: results.c:370
@ pcmk_rc_ok
Definition: results.h:146
#define pcmk_ok
Definition: results.h:68
int pcmk_legacy2rc(int legacy_rc)
Definition: results.c:428
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:931
@ pcmk__str_casei
void free_xml(xmlNode *child)
Definition: xml.c:824
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:696