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. stonith_plugin
  5. stonith__lha_metadata
  6. i_hate_pils
  7. stonith__lha_validate

   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>
  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 void
 146 stonith_plugin(int priority, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
     /* [previous][next][first][last][top][bottom][index][help] */
 147 
 148 static void
 149 stonith_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 
 169 int
 170 stonith__lha_metadata(const char *agent, int timeout, char **output)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 263 const char *i_hate_pils(int rc);
 264 
 265 const char *
 266 i_hate_pils(int rc)
     /* [previous][next][first][last][top][bottom][index][help] */
 267 {
 268     return PIL_strerror(rc);
 269 }
 270 
 271 int
 272 stonith__lha_validate(stonith_t *st, int call_options, const char *target,
     /* [previous][next][first][last][top][bottom][index][help] */
 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 }

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