This source file includes following definitions.
- find_library_function
- stonith__agent_is_lha
- stonith__list_lha_agents
- strdup_null
- stonith_plugin
- stonith__lha_metadata
- i_hate_pils
- stonith__lha_validate
1
2
3
4
5
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
70
71
72
73
74
75
76
77
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
106 stonith__list_lha_agents(stonith_key_value_t **devices)
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,
119 LHA_STONITH_LIBRARY,
120 "stonith_types");
121 type_free_fn = find_library_function(&lha_agents_lib,
122 LHA_STONITH_LIBRARY,
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
260
261
262
263 #include <pils/plugin.h>
264
265 const char *i_hate_pils(int rc);
266
267 const char *
268 i_hate_pils(int rc)
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 }