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