root/lib/services/services_nagios.c

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

DEFINITIONS

This source file includes following definitions.
  1. services__nagios_prepare
  2. services__nagios2ocf
  3. nagios_metadata_name
  4. services__list_nagios_agents
  5. services__nagios_agent_exists
  6. services__get_nagios_metadata

   1 /*
   2  * Copyright 2010-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 #ifndef _GNU_SOURCE
  13 #  define _GNU_SOURCE
  14 #endif
  15 
  16 #include <sys/types.h>
  17 #include <sys/stat.h>
  18 #include <sys/wait.h>
  19 #include <errno.h>
  20 #include <unistd.h>
  21 #include <dirent.h>
  22 #include <grp.h>
  23 #include <string.h>
  24 #include <sys/time.h>
  25 #include <sys/resource.h>
  26 
  27 #include "crm/crm.h"
  28 #include <crm/msg_xml.h>
  29 #include "crm/common/mainloop.h"
  30 #include "crm/services.h"
  31 
  32 #include "services_private.h"
  33 #include "services_nagios.h"
  34 
  35 /*!
  36  * \internal
  37  * \brief Prepare a Nagios action
  38  *
  39  * \param[in] op  Action to prepare
  40  *
  41  * \return Standard Pacemaker return code
  42  */
  43 int
  44 services__nagios_prepare(svc_action_t *op)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46     op->opaque->exec = pcmk__full_path(op->agent, NAGIOS_PLUGIN_DIR);
  47     op->opaque->args[0] = strdup(op->opaque->exec);
  48     if (op->opaque->args[0] == NULL) {
  49         return ENOMEM;
  50     }
  51 
  52     if (pcmk__str_eq(op->action, "monitor", pcmk__str_casei)
  53         && (op->interval_ms == 0)) {
  54 
  55         // Invoke --version for a nagios probe
  56         op->opaque->args[1] = strdup("--version");
  57         if (op->opaque->args[1] == NULL) {
  58             return ENOMEM;
  59         }
  60 
  61     } else if (op->params != NULL) {
  62         GHashTableIter iter;
  63         char *key = NULL;
  64         char *value = NULL;
  65         int index = 1; // 0 is already set to executable name
  66 
  67         g_hash_table_iter_init(&iter, op->params);
  68 
  69         while (g_hash_table_iter_next(&iter, (gpointer *) & key,
  70                                       (gpointer *) & value)) {
  71 
  72             if (index > (PCMK__NELEM(op->opaque->args) - 2)) {
  73                 return E2BIG;
  74             }
  75 
  76             if (pcmk__str_eq(key, XML_ATTR_CRM_VERSION, pcmk__str_casei)
  77                 || strstr(key, CRM_META "_")) {
  78                 continue;
  79             }
  80 
  81             op->opaque->args[index++] = crm_strdup_printf("--%s", key);
  82             op->opaque->args[index++] = strdup(value);
  83             if (op->opaque->args[index - 1] == NULL) {
  84                 return ENOMEM;
  85             }
  86         }
  87     }
  88 
  89     // Nagios actions don't need to keep the parameters
  90     if (op->params != NULL) {
  91         g_hash_table_destroy(op->params);
  92         op->params = NULL;
  93     }
  94     return pcmk_rc_ok;
  95 }
  96 
  97 /*!
  98  * \internal
  99  * \brief Map a Nagios result to a standard OCF result
 100  *
 101  * \param[in] exit_status  Nagios exit status
 102  *
 103  * \return Standard OCF result
 104  */
 105 enum ocf_exitcode
 106 services__nagios2ocf(int exit_status)
     /* [previous][next][first][last][top][bottom][index][help] */
 107 {
 108     switch (exit_status) {
 109         case NAGIOS_STATE_OK:
 110             return PCMK_OCF_OK;
 111 
 112         case NAGIOS_INSUFFICIENT_PRIV:
 113             return PCMK_OCF_INSUFFICIENT_PRIV;
 114 
 115         case NAGIOS_STATE_WARNING:
 116             return PCMK_OCF_DEGRADED;
 117 
 118         case NAGIOS_STATE_CRITICAL:
 119         case NAGIOS_STATE_UNKNOWN:
 120         default:
 121             return PCMK_OCF_UNKNOWN_ERROR;
 122     }
 123 }
 124 
 125 static inline char *
 126 nagios_metadata_name(const char *plugin)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128     return crm_strdup_printf(NAGIOS_METADATA_DIR "/%s.xml", plugin);
 129 }
 130 
 131 GList *
 132 services__list_nagios_agents(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134     GList *plugin_list = NULL;
 135     GList *result = NULL;
 136 
 137     plugin_list = services_os_get_directory_list(NAGIOS_PLUGIN_DIR, TRUE, TRUE);
 138 
 139     // Return only the plugins that have metadata
 140     for (GList *gIter = plugin_list; gIter != NULL; gIter = gIter->next) {
 141         struct stat st;
 142         const char *plugin = gIter->data;
 143         char *metadata = nagios_metadata_name(plugin);
 144 
 145         if (stat(metadata, &st) == 0) {
 146             result = g_list_append(result, strdup(plugin));
 147         }
 148         free(metadata);
 149     }
 150     g_list_free_full(plugin_list, free);
 151     return result;
 152 }
 153 
 154 gboolean
 155 services__nagios_agent_exists(const char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157     char *buf = NULL;
 158     gboolean rc = FALSE;
 159     struct stat st;
 160 
 161     if (name == NULL) {
 162         return rc;
 163     }
 164 
 165     buf = crm_strdup_printf(NAGIOS_PLUGIN_DIR "/%s", name);
 166     if (stat(buf, &st) == 0) {
 167         rc = TRUE;
 168     }
 169 
 170     free(buf);
 171     return rc;
 172 }
 173 
 174 int
 175 services__get_nagios_metadata(const char *type, char **output)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177     int rc = pcmk_ok;
 178     FILE *file_strm = NULL;
 179     int start = 0, length = 0, read_len = 0;
 180     char *metadata_file = nagios_metadata_name(type);
 181 
 182     file_strm = fopen(metadata_file, "r");
 183     if (file_strm == NULL) {
 184         crm_err("Metadata file %s does not exist", metadata_file);
 185         free(metadata_file);
 186         return -EIO;
 187     }
 188 
 189     /* see how big the file is */
 190     start = ftell(file_strm);
 191     fseek(file_strm, 0L, SEEK_END);
 192     length = ftell(file_strm);
 193     fseek(file_strm, 0L, start);
 194 
 195     CRM_ASSERT(length >= 0);
 196     CRM_ASSERT(start == ftell(file_strm));
 197 
 198     if (length <= 0) {
 199         crm_info("%s was not valid", metadata_file);
 200         free(*output);
 201         *output = NULL;
 202         rc = -EIO;
 203 
 204     } else {
 205         crm_trace("Reading %d bytes from file", length);
 206         *output = calloc(1, (length + 1));
 207         read_len = fread(*output, 1, length, file_strm);
 208         if (read_len != length) {
 209             crm_err("Calculated and read bytes differ: %d vs. %d",
 210                     length, read_len);
 211             free(*output);
 212             *output = NULL;
 213             rc = -EIO;
 214         }
 215     }
 216 
 217     fclose(file_strm);
 218     free(metadata_file);
 219     return rc;
 220 }

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