pacemaker  1.1.18-7fdfbbe
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 (C) 2011-2017 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 attrd to %s %s: %s (%d)",
216  display_command, display_host, pcmk_strerror(rc), rc);
217  } else {
218  crm_debug("Asked attrd to update %s=%s for %s: %s (%d)",
219  name, value, display_host, pcmk_strerror(rc), rc);
220  }
221  return rc;
222 }
223 
235 int
236 attrd_clear_delegate(crm_ipc_t *ipc, const char *host, const char *resource,
237  const char *operation, const char *interval,
238  const char *user_name, int options)
239 {
240  int rc = pcmk_ok;
241  xmlNode *clear_op = create_attrd_op(user_name);
242 
244  crm_xml_add(clear_op, F_ATTRD_HOST, host);
245  crm_xml_add(clear_op, F_ATTRD_RESOURCE, resource);
246  crm_xml_add(clear_op, F_ATTRD_OPERATION, operation);
247  crm_xml_add(clear_op, F_ATTRD_INTERVAL, interval);
248  crm_xml_add_int(clear_op, F_ATTRD_IS_REMOTE, is_set(options, attrd_opt_remote));
249 
250  rc = send_attrd_op(ipc, clear_op);
251  free_xml(clear_op);
252 
253  crm_debug("Asked attrd to clear failure of %s (interval %s) for %s on %s: %s (%d)",
254  (operation? operation : "all operations"),
255  (interval? interval : "0"),
256  (resource? resource : "all resources"),
257  (host? host : "all nodes"), pcmk_strerror(rc), rc);
258  return rc;
259 }
260 
261 #define LRM_TARGET_ENV "OCF_RESKEY_" CRM_META "_" XML_LRM_ATTR_TARGET
262 
263 const char *
264 attrd_get_target(const char *name)
265 {
266  if(safe_str_eq(name, "auto") || safe_str_eq(name, "localhost")) {
267  name = NULL;
268  }
269 
270  if(name != NULL) {
271  return name;
272 
273  } else {
274  char *target_var = crm_meta_name(XML_RSC_ATTR_TARGET);
275  char *phys_var = crm_meta_name(PCMK_ENV_PHYSICAL_HOST);
276  const char *target = getenv(target_var);
277  const char *host_physical = getenv(phys_var);
278 
279  /* It is important we use the names by which the PE knows us */
280  if (host_physical && safe_str_eq(target, "host")) {
281  name = host_physical;
282 
283  } else {
284  const char *host_pcmk = getenv(LRM_TARGET_ENV);
285 
286  if (host_pcmk) {
287  name = host_pcmk;
288  }
289  }
290  free(target_var);
291  free(phys_var);
292  }
293 
294  // TODO? Call get_local_node_name() if name == NULL
295  // (currently would require linkage against libcrmcluster)
296  return name;
297 }
#define T_ATTRD
Definition: msg_xml.h:50
#define F_ATTRD_VALUE
Definition: crm_internal.h:264
bool crm_ipc_connect(crm_ipc_t *client)
Establish an IPC connection to a Pacemaker component.
Definition: ipc.c:873
A dumping ground.
#define F_TYPE
Definition: msg_xml.h:34
const char * pcmk_strerror(int rc)
Definition: logging.c:1135
#define F_ATTRD_HOST
Definition: crm_internal.h:271
#define LRM_TARGET_ENV
Definition: attrd_client.c:261
#define F_ATTRD_REGEX
Definition: crm_internal.h:262
#define pcmk_ok
Definition: error.h:42
#define F_ATTRD_USER
Definition: crm_internal.h:273
#define ATTRD_OP_UPDATE
Definition: crm_internal.h:282
AIS_Host host
Definition: internal.h:52
char * crm_system_name
Definition: utils.c:70
#define F_ATTRD_SECTION
Definition: crm_internal.h:268
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:160
#define XML_RSC_ATTR_TARGET
Definition: msg_xml.h:203
#define attrd_opt_private
Definition: attrd.h:25
#define F_ATTRD_SET
Definition: crm_internal.h:265
#define ATTRD_OP_REFRESH
Definition: crm_internal.h:286
char * crm_meta_name(const char *field)
Definition: utils.c:927
#define ATTRD_OP_PEER_REMOVE
Definition: crm_internal.h:281
int attrd_clear_delegate(crm_ipc_t *ipc, const char *host, const char *resource, const char *operation, const char *interval, const char *user_name, int options)
Send a request to attrd to clear resource failure.
Definition: attrd_client.c:236
#define F_ATTRD_OPERATION
Definition: crm_internal.h:277
#define PCMK_ENV_PHYSICAL_HOST
Definition: crm_internal.h:292
const char * attrd_get_target(const char *name)
Definition: attrd_client.c:264
#define F_ATTRD_RESOURCE
Definition: crm_internal.h:276
#define F_ATTRD_ATTRIBUTE
Definition: crm_internal.h:261
#define ATTRD_OP_UPDATE_BOTH
Definition: crm_internal.h:283
#define crm_debug(fmt, args...)
Definition: logging.h:253
struct crm_ipc_s crm_ipc_t
Definition: ipc.h:61
#define F_ATTRD_IS_PRIVATE
Definition: crm_internal.h:267
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:2588
#define F_ATTRD_TASK
Definition: crm_internal.h:263
#define F_ATTRD_IS_REMOTE
Definition: crm_internal.h:266
#define F_ORIG
Definition: msg_xml.h:22
void free_xml(xmlNode *child)
Definition: xml.c:2706
#define attrd_opt_remote
Definition: attrd.h:24
#define ATTRD_OP_CLEAR_FAILURE
Definition: crm_internal.h:290
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 attrd.
Definition: attrd_client.c:135
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Definition: xml.c:2490
const char * crm_xml_add_int(xmlNode *node, const char *name, int value)
Definition: xml.c:2578
#define ATTRD_OP_QUERY
Definition: crm_internal.h:285
#define F_ATTRD_INTERVAL
Definition: crm_internal.h:278
#define crm_perror(level, fmt, args...)
Log a system error message.
Definition: logging.h:226
int crm_ipc_send(crm_ipc_t *client, xmlNode *message, enum crm_ipc_flags flags, int32_t ms_timeout, xmlNode **reply)
Definition: ipc.c:1199
crm_ipc_t * crm_ipc_new(const char *name, size_t max_size)
Definition: ipc.c:845
#define F_ATTRD_DAMPEN
Definition: crm_internal.h:269
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:158
#define safe_str_eq(a, b)
Definition: util.h:72
crm_ipc_flags
Definition: ipc.h:41
void crm_ipc_close(crm_ipc_t *client)
Definition: ipc.c:904
#define ATTRD_OP_UPDATE_DELAY
Definition: crm_internal.h:284
#define crm_info(fmt, args...)
Definition: logging.h:251
uint64_t flags
Definition: remote.c:156