pacemaker  2.1.8-3980678f03
Scalable High-Availability cluster resource manager
services_ocf.c
Go to the documentation of this file.
1 /*
2  * Copyright 2012-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 <string.h>
14 #include <sys/stat.h>
15 
16 #include <crm/crm.h>
17 #include <crm/services.h>
18 #include <crm/services_internal.h>
19 
20 #include "services_private.h"
21 #include "services_ocf.h"
22 
23 GList *
25 {
26  return get_directory_list(OCF_RA_PATH, FALSE, TRUE);
27 }
28 
29 static GList *
30 services_os_get_directory_list_provider(const char *root, const char *provider,
31  gboolean files, gboolean executable)
32 {
33  GList *result = NULL;
34  char *dirs = strdup(root);
35  char *dir = NULL;
36  char buffer[PATH_MAX];
37 
38  if (pcmk__str_empty(dirs)) {
39  free(dirs);
40  return result;
41  }
42 
43  for (dir = strtok(dirs, ":"); dir != NULL; dir = strtok(NULL, ":")) {
44  GList *tmp = NULL;
45 
46  sprintf(buffer, "%s/%s", dir, provider);
47  tmp = services_os_get_single_directory_list(buffer, files, executable);
48 
49  if (tmp) {
50  result = g_list_concat(result, tmp);
51  }
52  }
53 
54  free(dirs);
55 
56  return result;
57 }
58 
59 GList *
60 resources_os_list_ocf_agents(const char *provider)
61 {
62  GList *gIter = NULL;
63  GList *result = NULL;
64  GList *providers = NULL;
65 
66  if (provider) {
67  return services_os_get_directory_list_provider(OCF_RA_PATH, provider,
68  TRUE, TRUE);
69  }
70 
71  providers = resources_os_list_ocf_providers();
72  for (gIter = providers; gIter != NULL; gIter = gIter->next) {
73  GList *tmp1 = result;
74  GList *tmp2 = resources_os_list_ocf_agents(gIter->data);
75 
76  if (tmp2) {
77  result = g_list_concat(tmp1, tmp2);
78  }
79  }
80  g_list_free_full(providers, free);
81  return result;
82 }
83 
84 gboolean
85 services__ocf_agent_exists(const char *provider, const char *agent)
86 {
87  gboolean rc = FALSE;
88  struct stat st;
89  char *dirs = strdup(OCF_RA_PATH);
90  char *dir = NULL;
91  char *buf = NULL;
92 
93  if (provider == NULL || agent == NULL || pcmk__str_empty(dirs)) {
94  free(dirs);
95  return rc;
96  }
97 
98  for (dir = strtok(dirs, ":"); dir != NULL; dir = strtok(NULL, ":")) {
99  buf = crm_strdup_printf("%s/%s/%s", dir, provider, agent);
100  if (stat(buf, &st) == 0) {
101  free(buf);
102  rc = TRUE;
103  break;
104  }
105 
106  free(buf);
107  }
108 
109  free(dirs);
110 
111  return rc;
112 }
113 
122 int
124 {
125  char *dirs = strdup(OCF_RA_PATH);
126  struct stat st;
127 
128  if (dirs == NULL) {
129  return ENOMEM;
130  }
131 
132  // Look for agent on path
133  for (char *dir = strtok(dirs, ":"); dir != NULL; dir = strtok(NULL, ":")) {
134  char *buf = crm_strdup_printf("%s/%s/%s", dir, op->provider, op->agent);
135 
136  if (stat(buf, &st) == 0) {
137  op->opaque->exec = buf;
138  break;
139  }
140  free(buf);
141  }
142  free(dirs);
143 
144  if (op->opaque->exec == NULL) {
145  return ENOENT;
146  }
147 
148  op->opaque->args[0] = strdup(op->opaque->exec);
149  op->opaque->args[1] = strdup(op->action);
150  if ((op->opaque->args[0] == NULL) || (op->opaque->args[1] == NULL)) {
151  return ENOMEM;
152  }
153 
154  return pcmk_rc_ok;
155 }
156 
165 enum ocf_exitcode
166 services__ocf2ocf(int exit_status)
167 {
168  switch (exit_status) {
169  case PCMK_OCF_DEGRADED:
171  break;
172  default:
173  if ((exit_status < 0) || (exit_status > PCMK_OCF_FAILED_PROMOTED)) {
174  exit_status = PCMK_OCF_UNKNOWN_ERROR;
175  }
176  break;
177  }
178  return (enum ocf_exitcode) exit_status;
179 }
Services API.
A dumping ground.
ocf_exitcode
Exit status codes for resource agents.
Definition: results.h:177
Service failed and possibly in promoted role.
Definition: results.h:193
Service promoted but more likely to fail soon.
Definition: results.h:195
stonith_t * st
Definition: pcmk_fence.c:28
GList * resources_os_list_ocf_providers(void)
Definition: services_ocf.c:24
svc_action_private_t * opaque
This field should be treated as internal to Pacemaker.
Definition: services.h:182
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
GList * services_os_get_single_directory_list(const char *root, gboolean files, gboolean executable)
int services__ocf_prepare(svc_action_t *op)
Definition: services_ocf.c:123
Object for executing external actions.
Definition: services.h:122
char * agent
Resource agent name for resource actions, otherwise NULL.
Definition: services.h:144
Unspecified error.
Definition: results.h:181
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
GList * get_directory_list(const char *root, gboolean files, gboolean executable)
Get a list of files or directories in a given path.
Definition: services.c:1053
enum ocf_exitcode services__ocf2ocf(int exit_status)
Definition: services_ocf.c:166
GList * resources_os_list_ocf_agents(const char *provider)
Definition: services_ocf.c:60
gboolean services__ocf_agent_exists(const char *provider, const char *agent)
Definition: services_ocf.c:85
char * provider
Resource provider for resource actions that require it, otherwise NULL.
Definition: services.h:141
#define OCF_RA_PATH
Definition: config.h:508