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 #include "fencing_private.h"
  28 
  29 #define LHA_STONITH_LIBRARY "libstonith.so.1"
  30 
  31 static void *lha_agents_lib = NULL;
  32 
  33 static 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 
  53 static void *
  54 find_library_function(void **handle, const char *lib, const char *fn)
     /* [previous][next][first][last][top][bottom][index][help] */
  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 
  74 /*!
  75  * \brief Determine namespace of a fence agent
  76  *
  77  * \param[in] agent        Fence agent type
  78  * \param[in] namespace_s  Name of agent namespace as string, if known
  79  *
  80  * \return Namespace of specified agent, as enum value
  81  */
  82 bool
  83 stonith__agent_is_lha(const char *agent)
     /* [previous][next][first][last][top][bottom][index][help] */
  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 
 109 int
 110 stonith__list_lha_agents(stonith_key_value_t **devices)
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
 123                                              LHA_STONITH_LIBRARY,
 124                                              "stonith_types");
 125         type_free_fn = find_library_function(&lha_agents_lib,
 126                                              LHA_STONITH_LIBRARY,
 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 
 145 static inline char *
 146 strdup_null(const char *val)
     /* [previous][next][first][last][top][bottom][index][help] */
 147 {
 148     if (val) {
 149         return strdup(val);
 150     }
 151     return NULL;
 152 }
 153 
 154 static void
 155 stonith_plugin(int priority, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
     /* [previous][next][first][last][top][bottom][index][help] */
 156 
 157 static void
 158 stonith_plugin(int priority, const char *format, ...)
 159 {
 160     int err = errno;
 161 
 162     va_list ap;
 163     int len = 0;
 164     char *string = NULL;
 165 
 166     va_start(ap, format);
 167 
 168     len = vasprintf (&string, format, ap);
 169     va_end(ap);
 170     CRM_ASSERT(len > 0);
 171 
 172     do_crm_log_alias(priority, __FILE__, __func__, __LINE__, "%s", string);
 173 
 174     free(string);
 175     errno = err;
 176 }
 177 
 178 int
 179 stonith__lha_metadata(const char *agent, int timeout, char **output)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181     int rc = 0;
 182     char *buffer = NULL;
 183     static const char *no_parameter_info = "<!-- no value -->";
 184 
 185     Stonith *stonith_obj = NULL;
 186 
 187     static gboolean need_init = TRUE;
 188     static Stonith *(*st_new_fn) (const char *) = NULL;
 189     static const char *(*st_info_fn) (Stonith *, int) = NULL;
 190     static void (*st_del_fn) (Stonith *) = NULL;
 191     static void (*st_log_fn) (Stonith *, PILLogFun) = NULL;
 192 
 193     if (need_init) {
 194         need_init = FALSE;
 195         st_new_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
 196                                           "stonith_new");
 197         st_del_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
 198                                           "stonith_delete");
 199         st_log_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
 200                                           "stonith_set_log");
 201         st_info_fn = find_library_function(&lha_agents_lib, LHA_STONITH_LIBRARY,
 202                                            "stonith_get_info");
 203     }
 204 
 205     if (lha_agents_lib && st_new_fn && st_del_fn && st_info_fn && st_log_fn) {
 206         char *xml_meta_longdesc = NULL;
 207         char *xml_meta_shortdesc = NULL;
 208 
 209         char *meta_param = NULL;
 210         char *meta_longdesc = NULL;
 211         char *meta_shortdesc = NULL;
 212 
 213         stonith_obj = (*st_new_fn) (agent);
 214         if (stonith_obj) {
 215             (*st_log_fn) (stonith_obj, (PILLogFun) & stonith_plugin);
 216             meta_longdesc = strdup_null((*st_info_fn) (stonith_obj, ST_DEVICEDESCR));
 217             if (meta_longdesc == NULL) {
 218                 crm_warn("no long description in %s's metadata.", agent);
 219                 meta_longdesc = strdup(no_parameter_info);
 220             }
 221 
 222             meta_shortdesc = strdup_null((*st_info_fn) (stonith_obj, ST_DEVICEID));
 223             if (meta_shortdesc == NULL) {
 224                 crm_warn("no short description in %s's metadata.", agent);
 225                 meta_shortdesc = strdup(no_parameter_info);
 226             }
 227 
 228             meta_param = strdup_null((*st_info_fn) (stonith_obj, ST_CONF_XML));
 229             if (meta_param == NULL) {
 230                 crm_warn("no list of parameters in %s's metadata.", agent);
 231                 meta_param = strdup(no_parameter_info);
 232             }
 233             (*st_del_fn) (stonith_obj);
 234         } else {
 235             errno = EINVAL;
 236             crm_perror(LOG_ERR, "Agent %s not found", agent);
 237             return -EINVAL;
 238         }
 239 
 240         xml_meta_longdesc =
 241             (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_longdesc);
 242         xml_meta_shortdesc =
 243             (char *)xmlEncodeEntitiesReentrant(NULL, (const unsigned char *)meta_shortdesc);
 244 
 245         buffer = crm_strdup_printf(META_TEMPLATE, agent, xml_meta_longdesc,
 246                                    xml_meta_shortdesc, meta_param);
 247 
 248         xmlFree(xml_meta_longdesc);
 249         xmlFree(xml_meta_shortdesc);
 250 
 251         free(meta_shortdesc);
 252         free(meta_longdesc);
 253         free(meta_param);
 254     }
 255     if (output) {
 256         *output = buffer;
 257     } else {
 258         free(buffer);
 259     }
 260     return rc;
 261 }
 262 
 263 /* Implement a dummy function that uses -lpils so that linkers don't drop the
 264  * reference.
 265  */
 266 
 267 #include <pils/plugin.h>
 268 
 269 const char *i_hate_pils(int rc);
 270 
 271 const char *
 272 i_hate_pils(int rc)
     /* [previous][next][first][last][top][bottom][index][help] */
 273 {
 274     return PIL_strerror(rc);
 275 }
 276 
 277 int
 278 stonith__lha_validate(stonith_t *st, int call_options, const char *target,
     /* [previous][next][first][last][top][bottom][index][help] */
 279                       const char *agent, GHashTable *params, int timeout,
 280                       char **output, char **error_output)
 281 {
 282     errno = EOPNOTSUPP;
 283     crm_perror(LOG_ERR, "Cannot validate Linux-HA fence agents");
 284     return -EOPNOTSUPP;
 285 }

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