pacemaker 2.1.1-77db578727
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
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)
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)
#define LRM_TARGET_ENV
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)
char * pcmk_promotion_score_name(const char *rsc_id)
Return the name of the node attribute used as a promotion score.
@ pcmk__node_attr_remote
@ pcmk__node_attr_private
uint64_t flags
Definition remote.c:3
char * crm_meta_name(const char *field)
Definition utils.c:511
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:114
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
#define PCMK__XA_ATTR_INTERVAL
#define PCMK__XA_ATTR_IS_PRIVATE
#define PCMK__XA_ATTR_SECTION
#define PCMK__XA_ATTR_SET
#define PCMK__XA_ATTR_NODE_NAME
#define PCMK__ATTRD_CMD_UPDATE_BOTH
#define PCMK__XA_ATTR_RESOURCE
#define PCMK__XA_ATTR_VALUE
#define PCMK__ATTRD_CMD_REFRESH
#define PCMK__ATTRD_CMD_CLEAR_FAILURE
#define PCMK__XA_ATTR_DAMPENING
#define PCMK__XA_ATTR_NAME
#define PCMK__XA_ATTR_PATTERN
#define PCMK__ATTRD_CMD_UPDATE_DELAY
#define PCMK__ATTRD_CMD_QUERY
#define PCMK__ATTRD_CMD_PEER_REMOVE
#define PCMK__ENV_PHYSICAL_HOST
#define PCMK__XA_ATTR_IS_REMOTE
#define PCMK__XA_ATTR_OPERATION
#define PCMK__XA_TASK
#define PCMK__ATTRD_CMD_UPDATE
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.
crm_ipc_flags
Definition ipc.h:144
@ crm_ipc_flags_none
Definition ipc.h:145
@ crm_ipc_client_response
Definition ipc.h:150
bool crm_ipc_connect(crm_ipc_t *client)
Establish an IPC connection to a Pacemaker component.
Definition ipc_client.c:792
void crm_ipc_close(crm_ipc_t *client)
Definition ipc_client.c:862
struct crm_ipc_s crm_ipc_t
Definition ipc.h:162
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:745
#define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set)
#define crm_info(fmt, args...)
Definition logging.h:353
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
Definition logging.h:301
#define crm_debug(fmt, args...)
Definition logging.h:355
#define XML_RSC_ATTR_TARGET
Definition msg_xml.h:221
#define T_ATTRD
Definition msg_xml.h:79
#define F_ORIG
Definition msg_xml.h:51
#define F_TYPE
Definition msg_xml.h:63
#define XML_CIB_TAG_NODES
Definition msg_xml.h:181
#define XML_CIB_TAG_STATUS
Definition msg_xml.h:179
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:432
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:324
char * name
Definition pcmk_fence.c:31
int rc
Definition pcmk_fence.c:35
const char * target
Definition pcmk_fence.c:29
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition results.c:420
@ pcmk_rc_ok
Definition results.h:142
#define pcmk_ok
Definition results.h:67
int pcmk_legacy2rc(int legacy_rc)
Definition results.c:450
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition strings.c:955
@ pcmk__str_casei
void free_xml(xmlNode *child)
Definition xml.c:823
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition xml.c:696