pacemaker  2.0.5-ba59be712
Scalable High-Availability cluster resource manager
attrd_client.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2020 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 
30 static xmlNode *
31 create_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 #if ENABLE_ACL
38  crm_xml_add(attrd_op, PCMK__XA_ATTR_USER, user_name);
39 #endif
40 
41  return attrd_op;
42 }
43 
53 static int
54 send_attrd_op(crm_ipc_t *ipc, xmlNode *attrd_op)
55 {
56  int rc = -ENOTCONN; // initially handled as legacy return code
57  int max = 5;
58 
59  static gboolean connected = TRUE;
60  static crm_ipc_t *local_ipc = NULL;
62 
63  if (ipc == NULL && local_ipc == NULL) {
64  local_ipc = crm_ipc_new(T_ATTRD, 0);
66  connected = FALSE;
67  }
68 
69  if (ipc == NULL) {
70  ipc = local_ipc;
71  }
72 
73  while (max > 0) {
74  if (connected == FALSE) {
75  crm_info("Connecting to cluster... %d retries remaining", max);
76  connected = crm_ipc_connect(ipc);
77  }
78 
79  if (connected) {
80  rc = crm_ipc_send(ipc, attrd_op, flags, 0, NULL);
81  } else {
82  crm_perror(LOG_INFO, "Connection to cluster attribute manager failed");
83  }
84 
85  if (ipc != local_ipc) {
86  break;
87 
88  } else if (rc > 0) {
89  break;
90 
91  } else if (rc == -EAGAIN || rc == -EALREADY) {
92  sleep(5 - max);
93  max--;
94 
95  } else {
96  crm_ipc_close(ipc);
97  connected = FALSE;
98  sleep(5 - max);
99  max--;
100  }
101  }
102 
103  if (rc > 0) {
104  rc = pcmk_ok;
105  }
106  return pcmk_legacy2rc(rc);
107 }
108 
134 int
135 pcmk__node_attr_request(crm_ipc_t *ipc, char command, const char *host,
136  const char *name, const char *value,
137  const char *section, const char *set,
138  const char *dampen, const char *user_name, int options)
139 {
140  int rc = pcmk_rc_ok;
141  const char *task = NULL;
142  const char *name_as = NULL;
143  const char *display_host = (host ? host : "localhost");
144  const char *display_command = NULL; /* for commands without name/value */
145  xmlNode *update = create_attrd_op(user_name);
146 
147  /* remap common aliases */
148  if (pcmk__str_eq(section, "reboot", pcmk__str_casei)) {
149  section = XML_CIB_TAG_STATUS;
150 
151  } else if (pcmk__str_eq(section, "forever", pcmk__str_casei)) {
152  section = XML_CIB_TAG_NODES;
153  }
154 
155  if (name == NULL && command == 'U') {
156  command = 'R';
157  }
158 
159  switch (command) {
160  case 'u':
161  task = PCMK__ATTRD_CMD_UPDATE;
162  name_as = PCMK__XA_ATTR_PATTERN;
163  break;
164  case 'D':
165  case 'U':
166  case 'v':
167  task = PCMK__ATTRD_CMD_UPDATE;
168  name_as = PCMK__XA_ATTR_NAME;
169  break;
170  case 'R':
172  display_command = "refresh";
173  break;
174  case 'B':
176  name_as = PCMK__XA_ATTR_NAME;
177  break;
178  case 'Y':
180  name_as = PCMK__XA_ATTR_NAME;
181  break;
182  case 'Q':
183  task = PCMK__ATTRD_CMD_QUERY;
184  name_as = PCMK__XA_ATTR_NAME;
185  break;
186  case 'C':
188  display_command = "purge";
189  break;
190  }
191 
192  if (name_as != NULL) {
193  if (name == NULL) {
194  rc = EINVAL;
195  goto done;
196  }
197  crm_xml_add(update, name_as, name);
198  }
199 
200  crm_xml_add(update, PCMK__XA_TASK, task);
201  crm_xml_add(update, PCMK__XA_ATTR_VALUE, value);
202  crm_xml_add(update, PCMK__XA_ATTR_DAMPENING, dampen);
203  crm_xml_add(update, PCMK__XA_ATTR_SECTION, section);
205  crm_xml_add(update, PCMK__XA_ATTR_SET, set);
210 
211  rc = send_attrd_op(ipc, update);
212 
213 done:
214  free_xml(update);
215 
216  if (display_command) {
217  crm_debug("Asked pacemaker-attrd to %s %s: %s (%d)",
218  display_command, display_host, pcmk_rc_str(rc), rc);
219  } else {
220  crm_debug("Asked pacemaker-attrd to update %s=%s for %s: %s (%d)",
221  name, value, display_host, pcmk_rc_str(rc), rc);
222  }
223  return rc;
224 }
225 
240 int
242  const char *resource, const char *operation,
243  const char *interval_spec, const char *user_name,
244  int options)
245 {
246  int rc = pcmk_rc_ok;
247  xmlNode *clear_op = create_attrd_op(user_name);
248  const char *interval_desc = NULL;
249  const char *op_desc = NULL;
250 
253  crm_xml_add(clear_op, PCMK__XA_ATTR_RESOURCE, resource);
254  crm_xml_add(clear_op, PCMK__XA_ATTR_OPERATION, operation);
255  crm_xml_add(clear_op, PCMK__XA_ATTR_INTERVAL, interval_spec);
258 
259  rc = send_attrd_op(ipc, clear_op);
260  free_xml(clear_op);
261 
262  if (operation) {
263  interval_desc = interval_spec? interval_spec : "nonrecurring";
264  op_desc = operation;
265  } else {
266  interval_desc = "all";
267  op_desc = "operations";
268  }
269  crm_debug("Asked pacemaker-attrd to clear failure of %s %s for %s on %s: %s (%d)",
270  interval_desc, op_desc, (resource? resource : "all resources"),
271  (host? host : "all nodes"), pcmk_rc_str(rc), rc);
272  return rc;
273 }
274 
275 #define LRM_TARGET_ENV "OCF_RESKEY_" CRM_META "_" XML_LRM_ATTR_TARGET
276 
280 const char *
282 {
283  if (pcmk__strcase_any_of(name, "auto", "localhost", NULL)) {
284  name = NULL;
285  }
286 
287  if(name != NULL) {
288  return name;
289 
290  } else {
291  char *target_var = crm_meta_name(XML_RSC_ATTR_TARGET);
292  char *phys_var = crm_meta_name(PCMK__ENV_PHYSICAL_HOST);
293  const char *target = getenv(target_var);
294  const char *host_physical = getenv(phys_var);
295 
296  // It is important to use the name by which the scheduler knows us
297  if (host_physical && pcmk__str_eq(target, "host", pcmk__str_casei)) {
298  name = host_physical;
299 
300  } else {
301  const char *host_pcmk = getenv(LRM_TARGET_ENV);
302 
303  if (host_pcmk) {
304  name = host_pcmk;
305  }
306  }
307  free(target_var);
308  free(phys_var);
309  }
310 
311  // TODO? Call get_local_node_name() if name == NULL
312  // (currently would require linkage against libcrmcluster)
313  return name;
314 }
#define T_ATTRD
Definition: msg_xml.h:46
#define PCMK__XA_ATTR_DAMPENING
Definition: crm_internal.h:42
#define PCMK__ATTRD_CMD_UPDATE_DELAY
Definition: crm_internal.h:79
#define PCMK__XA_ATTR_NAME
Definition: crm_internal.h:47
bool crm_ipc_connect(crm_ipc_t *client)
Establish an IPC connection to a Pacemaker component.
Definition: ipc_client.c:790
A dumping ground.
#define F_TYPE
Definition: msg_xml.h:30
#define PCMK__ATTRD_CMD_UPDATE_BOTH
Definition: crm_internal.h:78
#define PCMK__ATTRD_CMD_PEER_REMOVE
Definition: crm_internal.h:76
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:842
#define PCMK__XA_TASK
Definition: crm_internal.h:61
#define LRM_TARGET_ENV
Definition: attrd_client.c:275
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:425
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:317
#define PCMK__XA_ATTR_VALUE
Definition: crm_internal.h:57
AIS_Host host
Definition: internal.h:84
char * crm_system_name
Definition: utils.c:54
#define PCMK__XA_ATTR_RESOURCE
Definition: crm_internal.h:52
#define PCMK__ATTRD_CMD_CLEAR_FAILURE
Definition: crm_internal.h:85
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition: results.c:420
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:148
#define XML_RSC_ATTR_TARGET
Definition: msg_xml.h:189
char * crm_meta_name(const char *field)
Definition: utils.c:457
#define PCMK__XA_ATTR_SECTION
Definition: crm_internal.h:53
int rc
Definition: pcmk_fence.c:35
#define crm_debug(fmt, args...)
Definition: logging.h:352
struct crm_ipc_s crm_ipc_t
Definition: ipc.h:162
#define PCMK__XA_ATTR_OPERATION
Definition: crm_internal.h:50
#define PCMK__ATTRD_CMD_REFRESH
Definition: crm_internal.h:81
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:241
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:196
#define PCMK__XA_ATTR_INTERVAL
Definition: crm_internal.h:44
#define PCMK__XA_ATTR_IS_PRIVATE
Definition: crm_internal.h:45
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:663
#define PCMK__XA_ATTR_USER
Definition: crm_internal.h:55
#define PCMK__ATTRD_CMD_QUERY
Definition: crm_internal.h:80
int pcmk_legacy2rc(int legacy_rc)
Definition: results.c:450
#define PCMK__ATTRD_CMD_UPDATE
Definition: crm_internal.h:77
#define F_ORIG
Definition: msg_xml.h:18
void free_xml(xmlNode *child)
Definition: xml.c:790
#define PCMK__ENV_PHYSICAL_HOST
Definition: crm_internal.h:93
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:135
const char * target
Definition: pcmk_fence.c:29
#define PCMK__XA_ATTR_NODE_NAME
Definition: crm_internal.h:49
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
Definition: logging.h:298
#define pcmk__set_ipc_flags(ipc_flags, ipc_name, flags_to_set)
Definition: ipc_internal.h:176
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:1139
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__XA_ATTR_IS_REMOTE
Definition: crm_internal.h:46
#define pcmk_ok
Definition: results.h:67
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:146
#define PCMK__XA_ATTR_PATTERN
Definition: crm_internal.h:51
const char * pcmk__node_attr_target(const char *name)
Definition: attrd_client.c:281
#define PCMK__XA_ATTR_SET
Definition: crm_internal.h:54
char * name
Definition: pcmk_fence.c:31
crm_ipc_flags
Definition: ipc.h:143
void crm_ipc_close(crm_ipc_t *client)
Definition: ipc_client.c:857
#define crm_info(fmt, args...)
Definition: logging.h:350
uint64_t flags
Definition: remote.c:149