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