This source file includes following definitions.
- lsb_meta_helper_get_value
- services__get_lsb_metadata
- services__list_lsb_agents
- services__lsb_agent_exists
- services__lsb_prepare
- services__lsb2ocf
- services_action_create
- services_list
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <crm_internal.h>
  11 
  12 #ifndef _GNU_SOURCE
  13 #  define _GNU_SOURCE
  14 #endif
  15 
  16 #include <stdio.h>
  17 #include <errno.h>
  18 #include <sys/stat.h>
  19 
  20 #include <crm/crm.h>
  21 #include <crm/common/xml.h>
  22 #include <crm/services.h>
  23 #include "services_private.h"
  24 #include "services_lsb.h"
  25 
  26 
  27 #define lsb_metadata_template  \
  28     "<?xml " PCMK_XA_VERSION "='1.0'?>\n"                                     \
  29     "<" PCMK_XE_RESOURCE_AGENT " "                                            \
  30         PCMK_XA_NAME "='%s' "                                                 \
  31         PCMK_XA_VERSION "='" PCMK_DEFAULT_AGENT_VERSION "'>\n"                \
  32     "  <" PCMK_XE_VERSION ">1.1</" PCMK_XE_VERSION ">\n"                      \
  33     "  <" PCMK_XE_LONGDESC " " PCMK_XA_LANG "='" PCMK__VALUE_EN "'>\n"        \
  34         "%s"                                                                  \
  35     "  </" PCMK_XE_LONGDESC ">\n"                                             \
  36     "  <" PCMK_XE_SHORTDESC " " PCMK_XA_LANG "='" PCMK__VALUE_EN "'>"         \
  37         "%s"                                                                  \
  38       "</" PCMK_XE_SHORTDESC ">\n"                                            \
  39     "  <" PCMK_XE_PARAMETERS "/>\n"                                           \
  40     "  <" PCMK_XE_ACTIONS ">\n"                                               \
  41     "    <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_META_DATA "'"    \
  42                            " " PCMK_META_TIMEOUT "='5s' />\n"                 \
  43     "    <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_START "'"        \
  44                            " " PCMK_META_TIMEOUT "='15s' />\n"                \
  45     "    <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_STOP "'"         \
  46                            " " PCMK_META_TIMEOUT "='15s' />\n"                \
  47     "    <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_STATUS "'"       \
  48                            " " PCMK_META_TIMEOUT "='15s' />\n"                \
  49     "    <" PCMK_XE_ACTION " " PCMK_XA_NAME "='restart'"                      \
  50                            " " PCMK_META_TIMEOUT "='15s' />\n"                \
  51     "    <" PCMK_XE_ACTION " " PCMK_XA_NAME "='force-reload'"                 \
  52                            " " PCMK_META_TIMEOUT "='15s' />\n"                \
  53     "    <" PCMK_XE_ACTION " " PCMK_XA_NAME "='" PCMK_ACTION_MONITOR "'"      \
  54                            " " PCMK_META_TIMEOUT "='15s'"                     \
  55                            " " PCMK_META_INTERVAL "='15s' />\n"               \
  56     "  </" PCMK_XE_ACTIONS ">\n"                                              \
  57     "  <" PCMK_XE_SPECIAL " " PCMK_XA_TAG "='LSB'>\n"                         \
  58     "    <Provides>%s</Provides>\n"                                           \
  59     "    <Required-Start>%s</Required-Start>\n"                               \
  60     "    <Required-Stop>%s</Required-Stop>\n"                                 \
  61     "    <Should-Start>%s</Should-Start>\n"                                   \
  62     "    <Should-Stop>%s</Should-Stop>\n"                                     \
  63     "    <Default-Start>%s</Default-Start>\n"                                 \
  64     "    <Default-Stop>%s</Default-Stop>\n"                                   \
  65     "  </" PCMK_XE_SPECIAL ">\n"                                              \
  66     "</" PCMK_XE_RESOURCE_AGENT ">\n"
  67 
  68 
  69 
  70 
  71 #define LSB_INITSCRIPT_INFOBEGIN_TAG    "### BEGIN INIT INFO"
  72 #define LSB_INITSCRIPT_INFOEND_TAG      "### END INIT INFO"
  73 #define PROVIDES                        "# Provides:"
  74 #define REQUIRED_START                  "# Required-Start:"
  75 #define REQUIRED_STOP                   "# Required-Stop:"
  76 #define SHOULD_START                    "# Should-Start:"
  77 #define SHOULD_STOP                     "# Should-Stop:"
  78 #define DEFAULT_START                   "# Default-Start:"
  79 #define DEFAULT_STOP                    "# Default-Stop:"
  80 #define SHORT_DESC                      "# Short-Description:"
  81 #define DESCRIPTION                     "# Description:"
  82 
  83 
  84 
  85 
  86 
  87 
  88 
  89 
  90 
  91 
  92 
  93 static inline gboolean
  94 lsb_meta_helper_get_value(const char *line, gchar **value, const char *prefix)
     
  95 {
  96     
  97 
  98 
  99     if ((*value == NULL) && pcmk__starts_with(line, prefix)) {
 100         *value = pcmk__xml_escape(line + strlen(prefix), pcmk__xml_escape_text);
 101         return TRUE;
 102     }
 103     return FALSE;
 104 }
 105 
 106 int
 107 services__get_lsb_metadata(const char *type, char **output)
     
 108 {
 109     char ra_pathname[PATH_MAX] = { 0, };
 110     FILE *fp = NULL;
 111     char buffer[1024] = { 0, };
 112     gchar *provides = NULL;
 113     gchar *required_start = NULL;
 114     gchar *required_stop = NULL;
 115     gchar *should_start = NULL;
 116     gchar *should_stop = NULL;
 117     gchar *default_start = NULL;
 118     gchar *default_stop = NULL;
 119     gchar *short_desc = NULL;
 120     gchar *long_desc = NULL;
 121     bool in_header = FALSE;
 122 
 123     if (type[0] == '/') {
 124         snprintf(ra_pathname, sizeof(ra_pathname), "%s", type);
 125     } else {
 126         snprintf(ra_pathname, sizeof(ra_pathname), "%s/%s",
 127                  PCMK__LSB_INIT_DIR, type);
 128     }
 129 
 130     crm_trace("Looking into %s", ra_pathname);
 131     fp = fopen(ra_pathname, "r");
 132     if (fp == NULL) {
 133         return -errno;
 134     }
 135 
 136     
 137     while (fgets(buffer, sizeof(buffer), fp)) {
 138 
 139         
 140         if (pcmk__starts_with(buffer, LSB_INITSCRIPT_INFOBEGIN_TAG)) {
 141             in_header = TRUE;
 142             continue;
 143         }
 144         if (!in_header) {
 145             continue;
 146         }
 147 
 148         
 149         if (lsb_meta_helper_get_value(buffer, &provides, PROVIDES)) {
 150             continue;
 151         }
 152         if (lsb_meta_helper_get_value(buffer, &required_start,
 153                                       REQUIRED_START)) {
 154             continue;
 155         }
 156         if (lsb_meta_helper_get_value(buffer, &required_stop, REQUIRED_STOP)) {
 157             continue;
 158         }
 159         if (lsb_meta_helper_get_value(buffer, &should_start, SHOULD_START)) {
 160             continue;
 161         }
 162         if (lsb_meta_helper_get_value(buffer, &should_stop, SHOULD_STOP)) {
 163             continue;
 164         }
 165         if (lsb_meta_helper_get_value(buffer, &default_start, DEFAULT_START)) {
 166             continue;
 167         }
 168         if (lsb_meta_helper_get_value(buffer, &default_stop, DEFAULT_STOP)) {
 169             continue;
 170         }
 171         if (lsb_meta_helper_get_value(buffer, &short_desc, SHORT_DESC)) {
 172             continue;
 173         }
 174 
 175         
 176         if ((long_desc == NULL)  
 177             && pcmk__starts_with(buffer, DESCRIPTION)) {
 178             bool processed_line = TRUE;
 179             GString *desc = g_string_sized_new(2048);
 180 
 181             
 182             g_string_append(desc, buffer + sizeof(DESCRIPTION) - 1);
 183 
 184             
 185             buffer[0] = '\0';
 186             while (fgets(buffer, sizeof(buffer), fp)) {
 187                 if (pcmk__starts_with(buffer, "#  ")
 188                     || pcmk__starts_with(buffer, "#\t")) {
 189                     
 190 
 191 
 192                     g_string_append(desc, buffer + 1);
 193                 } else {
 194                     
 195 
 196 
 197                     processed_line = FALSE;
 198                     break;
 199                 }
 200             }
 201 
 202             
 203             long_desc = pcmk__xml_escape(desc->str, pcmk__xml_escape_text);
 204             g_string_free(desc, TRUE);
 205 
 206             if (processed_line) {
 207                 
 208                 continue;
 209             }
 210         }
 211 
 212         
 213         if (pcmk__starts_with(buffer, LSB_INITSCRIPT_INFOEND_TAG)) {
 214             break;
 215         }
 216         if (buffer[0] != '#') {
 217             break;
 218         }
 219     }
 220     fclose(fp);
 221 
 222     *output = crm_strdup_printf(lsb_metadata_template, type,
 223                                 pcmk__s(long_desc, type),
 224                                 pcmk__s(short_desc, type),
 225                                 pcmk__s(provides, ""),
 226                                 pcmk__s(required_start, ""),
 227                                 pcmk__s(required_stop, ""),
 228                                 pcmk__s(should_start, ""),
 229                                 pcmk__s(should_stop, ""),
 230                                 pcmk__s(default_start, ""),
 231                                 pcmk__s(default_stop, ""));
 232 
 233     g_free(long_desc);
 234     g_free(short_desc);
 235     g_free(provides);
 236     g_free(required_start);
 237     g_free(required_stop);
 238     g_free(should_start);
 239     g_free(should_stop);
 240     g_free(default_start);
 241     g_free(default_stop);
 242     return pcmk_ok;
 243 }
 244 
 245 GList *
 246 services__list_lsb_agents(void)
     
 247 {
 248     return services_os_get_directory_list(PCMK__LSB_INIT_DIR, TRUE, TRUE);
 249 }
 250 
 251 bool
 252 services__lsb_agent_exists(const char *agent)
     
 253 {
 254     bool rc = FALSE;
 255     struct stat st;
 256     char *path = pcmk__full_path(agent, PCMK__LSB_INIT_DIR);
 257 
 258     rc = (stat(path, &st) == 0);
 259     free(path);
 260     return rc;
 261 }
 262 
 263 
 264 
 265 
 266 
 267 
 268 
 269 
 270 
 271 int
 272 services__lsb_prepare(svc_action_t *op)
     
 273 {
 274     op->opaque->exec = pcmk__full_path(op->agent, PCMK__LSB_INIT_DIR);
 275     op->opaque->args[0] = strdup(op->opaque->exec);
 276     op->opaque->args[1] = strdup(op->action);
 277     if ((op->opaque->args[0] == NULL) || (op->opaque->args[1] == NULL)) {
 278         return ENOMEM;
 279     }
 280     return pcmk_rc_ok;
 281 }
 282 
 283 
 284 
 285 
 286 
 287 
 288 
 289 
 290 
 291 
 292 enum ocf_exitcode
 293 services__lsb2ocf(const char *action, int exit_status)
     
 294 {
 295     
 296     if (!pcmk__str_any_of(action, PCMK_ACTION_STATUS, PCMK_ACTION_MONITOR,
 297                           NULL)) {
 298         if ((exit_status < 0) || (exit_status > PCMK_LSB_NOT_RUNNING)) {
 299             return PCMK_OCF_UNKNOWN_ERROR;
 300         }
 301         return (enum ocf_exitcode) exit_status;
 302     }
 303 
 304     
 305     switch (exit_status) {
 306         case PCMK_LSB_STATUS_OK:
 307             return PCMK_OCF_OK;
 308 
 309         case PCMK_LSB_STATUS_NOT_INSTALLED:
 310             return PCMK_OCF_NOT_INSTALLED;
 311 
 312         case PCMK_LSB_STATUS_INSUFFICIENT_PRIV:
 313             return PCMK_OCF_INSUFFICIENT_PRIV;
 314 
 315         case PCMK_LSB_STATUS_VAR_PID:
 316         case PCMK_LSB_STATUS_VAR_LOCK:
 317         case PCMK_LSB_STATUS_NOT_RUNNING:
 318             return PCMK_OCF_NOT_RUNNING;
 319 
 320         default:
 321             return PCMK_OCF_UNKNOWN_ERROR;
 322     }
 323 }
 324 
 325 
 326 
 327 
 328 #include <crm/services_compat.h>
 329 
 330 svc_action_t *
 331 services_action_create(const char *name, const char *action,
     
 332                        guint interval_ms, int timeout)
 333 {
 334     return resources_action_create(name, PCMK_RESOURCE_CLASS_LSB, NULL, name,
 335                                    action, interval_ms, timeout, NULL, 0);
 336 }
 337 
 338 GList *
 339 services_list(void)
     
 340 {
 341     return resources_list_agents(PCMK_RESOURCE_CLASS_LSB, NULL);
 342 }
 343 
 344 
 345