pacemaker  2.1.8-3980678f03
Scalable High-Availability cluster resource manager
services_nagios.c
Go to the documentation of this file.
1 /*
2  * Copyright 2010-2024 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/common/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 
43 int
45 {
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, PCMK_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, PCMK_XA_CRM_FEATURE_SET, 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 
105 enum ocf_exitcode
106 services__nagios2ocf(int exit_status)
107 {
108  switch (exit_status) {
109  case NAGIOS_STATE_OK:
110  return PCMK_OCF_OK;
111 
114 
116  return PCMK_OCF_DEGRADED;
117 
120  default:
121  return PCMK_OCF_UNKNOWN_ERROR;
122  }
123 }
124 
125 static inline char *
126 nagios_metadata_name(const char *plugin)
127 {
128  return crm_strdup_printf(NAGIOS_METADATA_DIR "/%s.xml", plugin);
129 }
130 
131 GList *
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
156 {
157  char *buf = NULL;
158  gboolean rc = FALSE;
159  struct stat st;
160 
161  if (name == NULL) {
162  return rc;
163  }
164 
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)
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 = pcmk__assert_alloc(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 }
Services API.
A dumping ground.
ocf_exitcode
Exit status codes for resource agents.
Definition: results.h:177
guint interval_ms
Action interval for recurring resource actions, otherwise 0.
Definition: services.h:135
const char * name
Definition: cib.c:26
int services__nagios_prepare(svc_action_t *op)
#define PCMK_ACTION_MONITOR
Definition: actions.h:60
int services__get_nagios_metadata(const char *type, char **output)
GList * services_os_get_directory_list(const char *root, gboolean files, gboolean executable)
enum crm_ais_msg_types type
Definition: cpg.c:51
Wrappers for and extensions to glib mainloop.
stonith_t * st
Definition: pcmk_fence.c:28
svc_action_private_t * opaque
This field should be treated as internal to Pacemaker.
Definition: services.h:182
GHashTable * params
Definition: services.h:153
#define crm_trace(fmt, args...)
Definition: logging.h:404
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
Object for executing external actions.
Definition: services.h:122
Insufficient privileges.
Definition: results.h:185
char * agent
Resource agent name for resource actions, otherwise NULL.
Definition: services.h:144
gboolean services__nagios_agent_exists(const char *name)
Wrappers for and extensions to libxml2.
#define PCMK__NELEM(a)
Definition: internal.h:48
char * pcmk__full_path(const char *filename, const char *dirname)
Duplicate a file path, inserting a prefix if not absolute.
Definition: io.c:634
Unspecified error.
Definition: results.h:181
#define PCMK_XA_CRM_FEATURE_SET
Definition: xml_names.h:249
char * args[MAX_ARGC]
Service active but more likely to fail soon.
Definition: results.h:194
char * action
Name of action being executed for resource actions, otherwise NULL.
Definition: services.h:132
pcmk__action_result_t result
Definition: pcmk_fence.c:35
#define NAGIOS_PLUGIN_DIR
Definition: config.h:502
#define CRM_META
Definition: crm.h:81
#define crm_err(fmt, args...)
Definition: logging.h:391
#define CRM_ASSERT(expr)
Definition: results.h:42
Success.
Definition: results.h:178
GList * services__list_nagios_agents(void)
#define pcmk_ok
Definition: results.h:69
#define pcmk__assert_alloc(nmemb, size)
Definition: internal.h:297
#define crm_info(fmt, args...)
Definition: logging.h:399
#define NAGIOS_METADATA_DIR
Definition: config.h:499
enum ocf_exitcode services__nagios2ocf(int exit_status)