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
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
72
73
74
75
76
77
78
79
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
108 stonith__list_lha_agents(stonith_key_value_t **devices)
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,
121 LHA_STONITH_LIBRARY,
122 "stonith_types");
123 type_free_fn = find_library_function(&lha_agents_lib,
124 LHA_STONITH_LIBRARY,
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
262
263
264
265 #include <pils/plugin.h>
266
267 const char *i_hate_pils(int rc);
268
269 const char *
270 i_hate_pils(int rc)
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 }