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

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