This source file includes following definitions.
- stonith__list_rhcs_agents
- stonith_rhcs_parameter_not_required
- stonith__rhcs_get_metadata
- stonith__rhcs_metadata
- stonith__agent_is_rhcs
- stonith__rhcs_validate
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <sys/stat.h>
15 #include <glib.h>
16 #include <dirent.h>
17
18 #include <crm/crm.h>
19 #include <crm/stonith-ng.h>
20 #include <crm/fencing/internal.h>
21
22 #define RH_STONITH_PREFIX "fence_"
23
24
25
26
27
28
29
30
31
32 int
33 stonith__list_rhcs_agents(stonith_key_value_t **devices)
34 {
35
36
37 int count = 0, i;
38 struct dirent **namelist;
39 const int file_num = scandir(PCMK__FENCE_BINDIR, &namelist, 0, alphasort);
40
41 #if _POSIX_C_SOURCE < 200809L && !(defined(O_SEARCH) || defined(O_PATH))
42 char buffer[FILENAME_MAX + 1];
43 #elif defined(O_SEARCH)
44 const int dirfd = open(PCMK__FENCE_BINDIR, O_SEARCH);
45 #else
46 const int dirfd = open(PCMK__FENCE_BINDIR, O_PATH);
47 #endif
48
49 for (i = 0; i < file_num; i++) {
50 struct stat prop;
51
52 if (pcmk__starts_with(namelist[i]->d_name, RH_STONITH_PREFIX)) {
53 #if _POSIX_C_SOURCE < 200809L && !(defined(O_SEARCH) || defined(O_PATH))
54 snprintf(buffer, sizeof(buffer), "%s/%s", PCMK__FENCE_BINDIR,
55 namelist[i]->d_name);
56 if (stat(buffer, &prop) == 0 && S_ISREG(prop.st_mode)) {
57 #else
58 if (dirfd == -1) {
59 if (i == 0) {
60 crm_notice("Problem with listing %s directory"
61 CRM_XS "errno=%d", RH_STONITH_PREFIX, errno);
62 }
63 free(namelist[i]);
64 continue;
65 }
66
67
68
69 if (fstatat(dirfd, namelist[i]->d_name, &prop, 0) == 0
70 && S_ISREG(prop.st_mode)) {
71 #endif
72 *devices = stonith_key_value_add(*devices, NULL,
73 namelist[i]->d_name);
74 count++;
75 }
76 }
77 free(namelist[i]);
78 }
79 if (file_num > 0) {
80 free(namelist);
81 }
82 #if _POSIX_C_SOURCE >= 200809L || defined(O_SEARCH) || defined(O_PATH)
83 if (dirfd >= 0) {
84 close(dirfd);
85 }
86 #endif
87 return count;
88 }
89
90 static void
91 stonith_rhcs_parameter_not_required(xmlNode *metadata, const char *parameter)
92 {
93 char *xpath = NULL;
94 xmlXPathObject *xpathObj = NULL;
95
96 CRM_CHECK(metadata != NULL, return);
97 CRM_CHECK(parameter != NULL, return);
98
99 xpath = crm_strdup_printf("//parameter[@name='%s']", parameter);
100
101
102 xpathObj = xpath_search(metadata, xpath);
103 if (numXpathResults(xpathObj) > 0) {
104 xmlNode *tmp = getXpathResult(xpathObj, 0);
105
106 crm_xml_add(tmp, "required", "0");
107 }
108 freeXpathObject(xpathObj);
109 free(xpath);
110 }
111
112
113
114
115
116
117
118
119
120
121 static int
122 stonith__rhcs_get_metadata(const char *agent, int timeout, xmlNode **metadata)
123 {
124 char *buffer = NULL;
125 xmlNode *xml = NULL;
126 xmlNode *actions = NULL;
127 xmlXPathObject *xpathObj = NULL;
128 stonith_action_t *action = stonith_action_create(agent, "metadata", NULL, 0,
129 5, NULL, NULL, NULL);
130 int rc = stonith__execute(action);
131
132 if (rc < 0) {
133 crm_warn("Could not execute metadata action for %s: %s "
134 CRM_XS " rc=%d", agent, pcmk_strerror(rc), rc);
135 stonith__destroy_action(action);
136 return rc;
137 }
138
139 stonith__action_result(action, &rc, &buffer, NULL);
140 stonith__destroy_action(action);
141 if (rc < 0) {
142 crm_warn("Metadata action for %s failed: %s " CRM_XS "rc=%d",
143 agent, pcmk_strerror(rc), rc);
144 free(buffer);
145 return rc;
146 }
147
148 if (buffer == NULL) {
149 crm_warn("Metadata action for %s returned no data", agent);
150 return -ENODATA;
151 }
152
153 xml = string2xml(buffer);
154 free(buffer);
155 buffer = NULL;
156 if (xml == NULL) {
157 crm_warn("Metadata for %s is invalid", agent);
158 return -pcmk_err_schema_validation;
159 }
160
161 xpathObj = xpath_search(xml, "//actions");
162 if (numXpathResults(xpathObj) > 0) {
163 actions = getXpathResult(xpathObj, 0);
164 }
165 freeXpathObject(xpathObj);
166
167
168 xpathObj = xpath_search(xml, "//action[@name='stop']");
169 if (numXpathResults(xpathObj) <= 0) {
170 xmlNode *tmp = NULL;
171
172 tmp = create_xml_node(actions, "action");
173 crm_xml_add(tmp, "name", "stop");
174 crm_xml_add(tmp, "timeout", CRM_DEFAULT_OP_TIMEOUT_S);
175
176 tmp = create_xml_node(actions, "action");
177 crm_xml_add(tmp, "name", "start");
178 crm_xml_add(tmp, "timeout", CRM_DEFAULT_OP_TIMEOUT_S);
179 }
180 freeXpathObject(xpathObj);
181
182
183 stonith_rhcs_parameter_not_required(xml, "action");
184 stonith_rhcs_parameter_not_required(xml, "plug");
185 stonith_rhcs_parameter_not_required(xml, "port");
186
187 if (metadata) {
188 *metadata = xml;
189
190 } else {
191 free_xml(xml);
192 }
193
194 return pcmk_ok;
195 }
196
197
198
199
200
201
202
203
204
205
206 int
207 stonith__rhcs_metadata(const char *agent, int timeout, char **output)
208 {
209 char *buffer = NULL;
210 xmlNode *xml = NULL;
211
212 int rc = stonith__rhcs_get_metadata(agent, timeout, &xml);
213
214 if (rc != pcmk_ok) {
215 free_xml(xml);
216 return rc;
217 }
218
219 buffer = dump_xml_formatted_with_text(xml);
220 free_xml(xml);
221 if (buffer == NULL) {
222 return -pcmk_err_schema_validation;
223 }
224 if (output) {
225 *output = buffer;
226 } else {
227 free(buffer);
228 }
229 return pcmk_ok;
230 }
231
232 bool
233 stonith__agent_is_rhcs(const char *agent)
234 {
235 struct stat prop;
236 char *buffer = crm_strdup_printf(PCMK__FENCE_BINDIR "/%s", agent);
237 int rc = stat(buffer, &prop);
238
239 free(buffer);
240 return (rc >= 0) && S_ISREG(prop.st_mode);
241 }
242
243 int
244 stonith__rhcs_validate(stonith_t *st, int call_options, const char *target,
245 const char *agent, GHashTable *params,
246 const char * host_arg, int timeout,
247 char **output, char **error_output)
248 {
249 int rc = pcmk_ok;
250 int remaining_timeout = timeout;
251 xmlNode *metadata = NULL;
252 stonith_action_t *action = NULL;
253
254 if (host_arg == NULL) {
255 time_t start_time = time(NULL);
256
257 rc = stonith__rhcs_get_metadata(agent, remaining_timeout, &metadata);
258
259 if (rc == pcmk_ok) {
260 uint32_t device_flags = 0;
261
262 stonith__device_parameter_flags(&device_flags, agent, metadata);
263 if (pcmk_is_set(device_flags, st_device_supports_parameter_port)) {
264 host_arg = "port";
265
266 } else if (pcmk_is_set(device_flags,
267 st_device_supports_parameter_plug)) {
268 host_arg = "plug";
269 }
270 }
271
272 free_xml(metadata);
273
274 remaining_timeout -= time(NULL) - start_time;
275
276 if (rc == -ETIME || remaining_timeout <= 0 ) {
277 return -ETIME;
278 }
279
280 } else if (pcmk__str_eq(host_arg, "none", pcmk__str_casei)) {
281 host_arg = NULL;
282 }
283
284 action = stonith_action_create(agent, "validate-all",
285 target, 0, remaining_timeout, params,
286 NULL, host_arg);
287
288 rc = stonith__execute(action);
289 if (rc == pcmk_ok) {
290 stonith__action_result(action, &rc, output, error_output);
291 }
292 stonith__destroy_action(action);
293 return rc;
294 }