pacemaker  2.0.2-debe490
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
attrd_client.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2018 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This source code is licensed under the GNU Lesser General Public License
5  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
6  */
7 
8 
9 #ifndef _GNU_SOURCE
10 # define _GNU_SOURCE
11 #endif
12 
13 #include <crm_internal.h>
14 
15 #include <stdio.h>
16 
17 #include <crm/crm.h>
18 #include <crm/msg_xml.h>
19 #include <crm/attrd.h>
20 
29 static xmlNode *
30 create_attrd_op(const char *user_name)
31 {
32  xmlNode *attrd_op = create_xml_node(NULL, __FUNCTION__);
33 
34  crm_xml_add(attrd_op, F_TYPE, T_ATTRD);
35  crm_xml_add(attrd_op, F_ORIG, (crm_system_name? crm_system_name: "unknown"));
36 #if ENABLE_ACL
37  crm_xml_add(attrd_op, F_ATTRD_USER, user_name);
38 #endif
39 
40  return attrd_op;
41 }
42 
52 static int
53 send_attrd_op(crm_ipc_t *ipc, xmlNode *attrd_op)
54 {
55  int rc = -ENOTCONN;
56  int max = 5;
57 
58  static gboolean connected = TRUE;
59  static crm_ipc_t *local_ipc = NULL;
61 
62  if (ipc == NULL && local_ipc == NULL) {
63  local_ipc = crm_ipc_new(T_ATTRD, 0);
64  flags |= crm_ipc_client_response;
65  connected = FALSE;
66  }
67 
68  if (ipc == NULL) {
69  ipc = local_ipc;
70  }
71 
72  while (max > 0) {
73  if (connected == FALSE) {
74  crm_info("Connecting to cluster... %d retries remaining", max);
75  connected = crm_ipc_connect(ipc);
76  }
77 
78  if (connected) {
79  rc = crm_ipc_send(ipc, attrd_op, flags, 0, NULL);
80  } else {
81  crm_perror(LOG_INFO, "Connection to cluster attribute manager failed");
82  }
83 
84  if (ipc != local_ipc) {
85  break;
86 
87  } else if (rc > 0) {
88  break;
89 
90  } else if (rc == -EAGAIN || rc == -EALREADY) {
91  sleep(5 - max);
92  max--;
93 
94  } else {
95  crm_ipc_close(ipc);
96  connected = FALSE;
97  sleep(5 - max);
98  max--;
99  }
100  }
101 
102  if (rc > 0) {
103  rc = pcmk_ok;
104  }
105  return rc;
106 }
107 
134 int
135 attrd_update_delegate(crm_ipc_t *ipc, char command, const char *host,
136  const char *name, const char *value, const char *section,
137  const char *set, const char *dampen,
138  const char *user_name, int options)
139 {
140  int rc = pcmk_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 (safe_str_eq(section, "reboot")) {
149  section = XML_CIB_TAG_STATUS;
150 
151  } else if (safe_str_eq(section, "forever")) {
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 = ATTRD_OP_UPDATE;
162  name_as = F_ATTRD_REGEX;
163  break;
164  case 'D':
165  case 'U':
166  case 'v':
167  task = ATTRD_OP_UPDATE;
168  name_as = F_ATTRD_ATTRIBUTE;
169  break;
170  case 'R':
171  task = ATTRD_OP_REFRESH;
172  display_command = "refresh";
173  break;
174  case 'B':
175  task = ATTRD_OP_UPDATE_BOTH;
176  name_as = F_ATTRD_ATTRIBUTE;
177  break;
178  case 'Y':
179  task = ATTRD_OP_UPDATE_DELAY;
180  name_as = F_ATTRD_ATTRIBUTE;
181  break;
182  case 'Q':
183  task = ATTRD_OP_QUERY;
184  name_as = F_ATTRD_ATTRIBUTE;
185  break;
186  case 'C':
187  task = ATTRD_OP_PEER_REMOVE;
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, F_ATTRD_TASK, task);
201  crm_xml_add(update, F_ATTRD_VALUE, value);
202  crm_xml_add(update, F_ATTRD_DAMPEN, dampen);
203  crm_xml_add(update, F_ATTRD_SECTION, section);
204  crm_xml_add(update, F_ATTRD_HOST, host);
205  crm_xml_add(update, F_ATTRD_SET, set);
206  crm_xml_add_int(update, F_ATTRD_IS_REMOTE, is_set(options, attrd_opt_remote));
207  crm_xml_add_int(update, F_ATTRD_IS_PRIVATE, is_set(options, attrd_opt_private));
208 
209  rc = send_attrd_op(ipc, update);
210 
211 done:
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_strerror(rc), rc);
217  } else {
218  crm_debug("Asked pacemaker-attrd to update %s=%s for %s: %s (%d)",
219  name, value, display_host, pcmk_strerror(rc), rc);
220  }
221  return rc;
222 }
223 
237 int
238 attrd_clear_delegate(crm_ipc_t *ipc, const char *host, const char *resource,
239  const char *operation, const char *interval_spec,
240  const char *user_name, int options)
241 {
242  int rc = pcmk_ok;
243  xmlNode *clear_op = create_attrd_op(user_name);
244  const char *interval_desc = NULL;
245  const char *op_desc = NULL;
246 
248  crm_xml_add(clear_op, F_ATTRD_HOST, host);
249  crm_xml_add(clear_op, F_ATTRD_RESOURCE, resource);
250  crm_xml_add(clear_op, F_ATTRD_OPERATION, operation);
251  crm_xml_add(clear_op, F_ATTRD_INTERVAL, interval_spec);
252  crm_xml_add_int(clear_op, F_ATTRD_IS_REMOTE, is_set(options, attrd_opt_remote));
253 
254  rc = send_attrd_op(ipc, clear_op);
255  free_xml(clear_op);
256 
257  if (operation) {
258  interval_desc = interval_spec? interval_spec : "nonrecurring";
259  op_desc = operation;
260  } else {
261  interval_desc = "all";
262  op_desc = "operations";
263  }
264  crm_debug("Asked pacemaker-attrd to clear failure of %s %s for %s on %s: %s (%d)",
265  interval_desc, op_desc, (resource? resource : "all resources"),
266  (host? host : "all nodes"), pcmk_strerror(rc), rc);
267  return rc;
268 }
269 
270 #define LRM_TARGET_ENV "OCF_RESKEY_" CRM_META "_" XML_LRM_ATTR_TARGET
271 
272 const char *
273 attrd_get_target(const char *name)
274 {
275  if(safe_str_eq(name, "auto") || safe_str_eq(name, "localhost")) {
276  name = NULL;
277  }
278 
279  if(name != NULL) {
280  return name;
281 
282  } else {
283  char *target_var = crm_meta_name(XML_RSC_ATTR_TARGET);
284  char *phys_var = crm_meta_name(PCMK_ENV_PHYSICAL_HOST);
285  const char *target = getenv(target_var);
286  const char *host_physical = getenv(phys_var);
287 
288  // It is important to use the name by which the scheduler knows us
289  if (host_physical && safe_str_eq(target, "host")) {
290  name = host_physical;
291 
292  } else {
293  const char *host_pcmk = getenv(LRM_TARGET_ENV);
294 
295  if (host_pcmk) {
296  name = host_pcmk;
297  }
298  }
299  free(target_var);
300  free(phys_var);
301  }
302 
303  // TODO? Call get_local_node_name() if name == NULL
304  // (currently would require linkage against libcrmcluster)
305  return name;
306 }
#define T_ATTRD
Definition: msg_xml.h:46
#define F_ATTRD_VALUE
Definition: crm_internal.h:186
bool crm_ipc_connect(crm_ipc_t *client)
Establish an IPC connection to a Pacemaker component.
Definition: ipc.c:955
A dumping ground.
#define F_TYPE
Definition: msg_xml.h:30
const char * pcmk_strerror(int rc)
Definition: results.c:188
#define F_ATTRD_HOST
Definition: crm_internal.h:192
#define LRM_TARGET_ENV
Definition: attrd_client.c:270
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:383
#define F_ATTRD_REGEX
Definition: crm_internal.h:184
#define F_ATTRD_USER
Definition: crm_internal.h:194
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:275
#define ATTRD_OP_UPDATE
Definition: crm_internal.h:204
AIS_Host host
Definition: internal.h:86
char * crm_system_name
Definition: utils.c:61
#define F_ATTRD_SECTION
Definition: crm_internal.h:190
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:141
#define XML_RSC_ATTR_TARGET
Definition: msg_xml.h:182
#define attrd_opt_private
Definition: attrd.h:32
#define F_ATTRD_SET
Definition: crm_internal.h:187
#define ATTRD_OP_REFRESH
Definition: crm_internal.h:208
char * crm_meta_name(const char *field)
Definition: utils.c:734
#define ATTRD_OP_PEER_REMOVE
Definition: crm_internal.h:203
#define F_ATTRD_OPERATION
Definition: crm_internal.h:198
#define PCMK_ENV_PHYSICAL_HOST
Definition: crm_internal.h:214
const char * attrd_get_target(const char *name)
Definition: attrd_client.c:273
#define F_ATTRD_RESOURCE
Definition: crm_internal.h:197
#define F_ATTRD_ATTRIBUTE
Definition: crm_internal.h:183
#define ATTRD_OP_UPDATE_BOTH
Definition: crm_internal.h:205
#define crm_debug(fmt, args...)
Definition: logging.h:245
struct crm_ipc_s crm_ipc_t
Definition: ipc.h:58
#define F_ATTRD_IS_PRIVATE
Definition: crm_internal.h:189
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1890
#define F_ATTRD_TASK
Definition: crm_internal.h:185
#define F_ATTRD_IS_REMOTE
Definition: crm_internal.h:188
#define F_ORIG
Definition: msg_xml.h:18
void free_xml(xmlNode *child)
Definition: xml.c:2014
#define attrd_opt_remote
Definition: attrd.h:31
#define ATTRD_OP_CLEAR_FAILURE
Definition: crm_internal.h:212
int attrd_update_delegate(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)
Send a request to pacemaker-attrd.
Definition: attrd_client.c:135
#define ATTRD_OP_QUERY
Definition: crm_internal.h:207
#define F_ATTRD_INTERVAL
Definition: crm_internal.h:199
int attrd_clear_delegate(crm_ipc_t *ipc, const char *host, const char *resource, const char *operation, const char *interval_spec, const char *user_name, int options)
Send a request to pacemaker-attrd to clear resource failure.
Definition: attrd_client.c:238
#define crm_perror(level, fmt, args...)
Log a system error message.
Definition: logging.h:218
int crm_ipc_send(crm_ipc_t *client, xmlNode *message, enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply)
Definition: ipc.c:1320
crm_ipc_t * crm_ipc_new(const char *name, size_t max_size)
Definition: ipc.c:925
#define F_ATTRD_DAMPEN
Definition: crm_internal.h:191
#define pcmk_ok
Definition: results.h:57
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:139
#define safe_str_eq(a, b)
Definition: util.h:59
crm_ipc_flags
Definition: ipc.h:39
void crm_ipc_close(crm_ipc_t *client)
Definition: ipc.c:1023
#define ATTRD_OP_UPDATE_DELAY
Definition: crm_internal.h:206
#define crm_info(fmt, args...)
Definition: logging.h:243
uint64_t flags
Definition: remote.c:148