pacemaker  2.0.5-ba59be712
Scalable High-Availability cluster resource manager
st_lha.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-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 #include <crm_internal.h>
9 
10 #include <stdio.h>
11 #include <stdarg.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <glib.h>
15 #include <dlfcn.h>
16 
17 #include <crm/crm.h>
18 #include <crm/stonith-ng.h>
19 #include <crm/fencing/internal.h>
20 #include <crm/msg_xml.h>
21 #include <crm/common/xml.h>
22 
23 #include <stonith/stonith.h>
24 
25 #define LHA_STONITH_LIBRARY "libstonith.so.1"
26 
27 static void *lha_agents_lib = NULL;
28 
29 static const char META_TEMPLATE[] =
30  "<?xml version=\"1.0\"?>\n"
31  "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n"
32  "<resource-agent name=\"%s\">\n"
33  " <version>1.0</version>\n"
34  " <longdesc lang=\"en\">\n"
35  "%s\n"
36  " </longdesc>\n"
37  " <shortdesc lang=\"en\">%s</shortdesc>\n"
38  "%s\n"
39  " <actions>\n"
40  " <action name=\"start\" timeout=\"20\" />\n"
41  " <action name=\"stop\" timeout=\"15\" />\n"
42  " <action name=\"status\" timeout=\"20\" />\n"
43  " <action name=\"monitor\" timeout=\"20\" interval=\"3600\"/>\n"
44  " <action name=\"meta-data\" timeout=\"15\" />\n"
45  " </actions>\n"
46  " <special tag=\"heartbeat\">\n"
47  " <version>2.0</version>\n" " </special>\n" "</resource-agent>\n";
48 
49 static void *
50 find_library_function(void **handle, const char *lib, const char *fn)
51 {
52  void *a_function;
53 
54  if (*handle == NULL) {
55  *handle = dlopen(lib, RTLD_LAZY);
56  if ((*handle) == NULL) {
57  crm_err("Could not open %s: %s", lib, dlerror());
58  return NULL;
59  }
60  }
61 
62  a_function = dlsym(*handle, fn);
63  if (a_function == NULL) {
64  crm_err("Could not find %s in %s: %s", fn, lib, dlerror());
65  }
66 
67  return a_function;
68 }
69 
78 bool
79 stonith__agent_is_lha(const char *agent)
80 {
81  Stonith *stonith_obj = NULL;
82 
83  static gboolean need_init = TRUE;
84  static Stonith *(*st_new_fn) (const char *) = NULL;
85  static void (*st_del_fn) (Stonith *) = NULL;
86 
87  if (need_init) {
88  need_init = FALSE;
89  st_new_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
90  "stonith_new");
91  st_del_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
92  "stonith_delete");
93  }
94 
95  if (lha_agents_lib && st_new_fn && st_del_fn) {
96  stonith_obj = (*st_new_fn) (agent);
97  if (stonith_obj) {
98  (*st_del_fn) (stonith_obj);
99  return TRUE;
100  }
101  }
102  return FALSE;
103 }
104 
105 int
107 {
108  static gboolean need_init = TRUE;
109 
110  int count = 0;
111  char **entry = NULL;
112  char **type_list = NULL;
113  static char **(*type_list_fn) (void) = NULL;
114  static void (*type_free_fn) (char **) = NULL;
115 
116  if (need_init) {
117  need_init = FALSE;
118  type_list_fn = find_library_function(&lha_agents_lib,
120  "stonith_types");
121  type_free_fn = find_library_function(&lha_agents_lib,
123  "stonith_free_hostlist");
124  }
125 
126  if (type_list_fn) {
127  type_list = (*type_list_fn) ();
128  }
129 
130  for (entry = type_list; entry != NULL && *entry; ++entry) {
131  crm_trace("Added: %s", *entry);
132  *devices = stonith_key_value_add(*devices, NULL, *entry);
133  count++;
134  }
135  if (type_list && type_free_fn) {
136  (*type_free_fn) (type_list);
137  }
138  return count;
139 }
140 
141 static inline char *
142 strdup_null(const char *val)
143 {
144  if (val) {
145  return strdup(val);
146  }
147  return NULL;
148 }
149 
150 static void
151 stonith_plugin(int priority, const char *fmt, ...) __attribute__((__format__ (__printf__, 2, 3)));
152 
153 static void
154 stonith_plugin(int priority, const char *format, ...)
155 {
156  int err = errno;
157 
158  va_list ap;
159  int len = 0;
160  char *string = NULL;
161 
162  va_start(ap, format);
163 
164  len = vasprintf (&string, format, ap);
165  va_end(ap);
166  CRM_ASSERT(len > 0);
167 
168  do_crm_log_alias(priority, __FILE__, __func__, __LINE__, "%s", string);
169 
170  free(string);
171  errno = err;
172 }
173 
174 int
175 stonith__lha_metadata(const char *agent, int timeout, char **output)
176 {
177  int rc = 0;
178  char *buffer = NULL;
179  static const char *no_parameter_info = "<!-- no value -->";
180 
181  Stonith *stonith_obj = NULL;
182 
183  static gboolean need_init = TRUE;
184  static Stonith *(*st_new_fn) (const char *) = NULL;
185  static const char *(*st_info_fn) (Stonith *, int) = NULL;
186  static void (*st_del_fn) (Stonith *) = NULL;
187  static void (*st_log_fn) (Stonith *, PILLogFun) = NULL;
188 
189  if (need_init) {
190  need_init = FALSE;
191  st_new_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
192  "stonith_new");
193  st_del_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
194  "stonith_delete");
195  st_log_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
196  "stonith_set_log");
197  st_info_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
198  "stonith_get_info");
199  }
200 
201  if (lha_agents_lib && st_new_fn && st_del_fn && st_info_fn && st_log_fn) {
202  char *xml_meta_longdesc = NULL;
203  char *xml_meta_shortdesc = NULL;
204 
205  char *meta_param = NULL;
206  char *meta_longdesc = NULL;
207  char *meta_shortdesc = NULL;
208 
209  stonith_obj = (*st_new_fn) (agent);
210  if (stonith_obj) {
211  (*st_log_fn) (stonith_obj, (PILLogFun) & stonith_plugin);
212  meta_longdesc = strdup_null((*st_info_fn) (stonith_obj, ST_DEVICEDESCR));
213  if (meta_longdesc == NULL) {
214  crm_warn("no long description in %s's metadata.", agent);
215  meta_longdesc = strdup(no_parameter_info);
216  }
217 
218  meta_shortdesc = strdup_null((*st_info_fn) (stonith_obj, ST_DEVICEID));
219  if (meta_shortdesc == NULL) {
220  crm_warn("no short description in %s's metadata.", agent);
221  meta_shortdesc = strdup(no_parameter_info);
222  }
223 
224  meta_param = strdup_null((*st_info_fn) (stonith_obj, ST_CONF_XML));
225  if (meta_param == NULL) {
226  crm_warn("no list of parameters in %s's metadata.", agent);
227  meta_param = strdup(no_parameter_info);
228  }
229  (*st_del_fn) (stonith_obj);
230  } else {
231  errno = EINVAL;
232  crm_perror(LOG_ERR, "Agent %s not found", agent);
233  return -EINVAL;
234  }
235 
236  xml_meta_longdesc =
237  (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_longdesc);
238  xml_meta_shortdesc =
239  (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_shortdesc);
240 
241  buffer = crm_strdup_printf(META_TEMPLATE, agent, xml_meta_longdesc,
242  xml_meta_shortdesc, meta_param);
243 
244  xmlFree(xml_meta_longdesc);
245  xmlFree(xml_meta_shortdesc);
246 
247  free(meta_shortdesc);
248  free(meta_longdesc);
249  free(meta_param);
250  }
251  if (output) {
252  *output = buffer;
253  } else {
254  free(buffer);
255  }
256  return rc;
257 }
258 
259 /* Implement a dummy function that uses -lpils so that linkers don't drop the
260  * reference.
261  */
262 
263 #include <pils/plugin.h>
264 
265 const char *i_hate_pils(int rc);
266 
267 const char *
269 {
270  return PIL_strerror(rc);
271 }
272 
273 int
274 stonith__lha_validate(stonith_t *st, int call_options, const char *target,
275  const char *agent, GHashTable *params, int timeout,
276  char **output, char **error_output)
277 {
278  errno = EOPNOTSUPP;
279  crm_perror(LOG_ERR, "Cannot validate Linux-HA fence agents");
280  return -EOPNOTSUPP;
281 }
A dumping ground.
int stonith__lha_validate(stonith_t *st, int call_options, const char *target, const char *agent, GHashTable *params, int timeout, char **output, char **error_output)
Definition: st_lha.c:274
int stonith__lha_metadata(const char *agent, int timeout, char **output)
Definition: st_lha.c:175
#define LHA_STONITH_LIBRARY
Definition: st_lha.c:25
#define do_crm_log_alias(level, file, function, line, fmt, args...)
Log a message as if it came from a different code location.
Definition: logging.h:270
const char * i_hate_pils(int rc)
Definition: st_lha.c:268
int stonith__list_lha_agents(stonith_key_value_t **devices)
Definition: st_lha.c:106
stonith_key_value_t * stonith_key_value_add(stonith_key_value_t *kvp, const char *key, const char *value)
Definition: st_client.c:2207
#define crm_warn(fmt, args...)
Definition: logging.h:348
stonith_t * st
Definition: pcmk_fence.c:28
int rc
Definition: pcmk_fence.c:35
#define crm_trace(fmt, args...)
Definition: logging.h:353
Wrappers for and extensions to libxml2.
const char * target
Definition: pcmk_fence.c:29
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
Definition: logging.h:298
#define crm_err(fmt, args...)
Definition: logging.h:347
#define CRM_ASSERT(expr)
Definition: results.h:42
Fencing aka. STONITH.
bool stonith__agent_is_lha(const char *agent)
Determine namespace of a fence agent.
Definition: st_lha.c:79
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
unsigned int timeout
Definition: pcmk_fence.c:32