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