root/lib/fencing/st_lha.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_library_function
  2. stonith__agent_is_lha
  3. stonith__list_lha_agents
  4. strdup_null
  5. stonith_plugin
  6. stonith__lha_metadata
  7. i_hate_pils
  8. stonith__lha_validate

   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 #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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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  * \brief Determine namespace of a fence agent
  72  *
  73  * \param[in] agent        Fence agent type
  74  * \param[in] namespace_s  Name of agent namespace as string, if known
  75  *
  76  * \return Namespace of specified agent, as enum value
  77  */
  78 bool
  79 stonith__agent_is_lha(const char *agent)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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, ...)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 /* Implement a dummy function that uses -lpils so that linkers don't drop the
 260  * reference.
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 269 {
 270     return PIL_strerror(rc);
 271 }
 272 
 273 int
 274 stonith__lha_validate(stonith_t *st, int call_options, const char *target,
     /* [previous][next][first][last][top][bottom][index][help] */
 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 }

/* [previous][next][first][last][top][bottom][index][help] */