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/services.h>
22 #include "services_private.h"
23 #include "services_lsb.h"
24
25 #define lsb_metadata_template \
26 "<?xml version='1.0'?>\n" \
27 "<!DOCTYPE resource-agent SYSTEM 'ra-api-1.dtd'>\n" \
28 "<resource-agent name='%s' version='" PCMK_DEFAULT_AGENT_VERSION "'>\n" \
29 " <version>1.0</version>\n" \
30 " <longdesc lang='en'>\n" \
31 "%s" \
32 " </longdesc>\n" \
33 " <shortdesc lang='en'>%s</shortdesc>\n" \
34 " <parameters>\n" \
35 " </parameters>\n" \
36 " <actions>\n" \
37 " <action name='meta-data' timeout='5' />\n" \
38 " <action name='start' timeout='15' />\n" \
39 " <action name='stop' timeout='15' />\n" \
40 " <action name='status' timeout='15' />\n" \
41 " <action name='restart' timeout='15' />\n" \
42 " <action name='force-reload' timeout='15' />\n" \
43 " <action name='monitor' timeout='15' interval='15' />\n" \
44 " </actions>\n" \
45 " <special tag='LSB'>\n" \
46 " <Provides>%s</Provides>\n" \
47 " <Required-Start>%s</Required-Start>\n" \
48 " <Required-Stop>%s</Required-Stop>\n" \
49 " <Should-Start>%s</Should-Start>\n" \
50 " <Should-Stop>%s</Should-Stop>\n" \
51 " <Default-Start>%s</Default-Start>\n" \
52 " <Default-Stop>%s</Default-Stop>\n" \
53 " </special>\n" \
54 "</resource-agent>\n"
55
56
57
58
59 #define LSB_INITSCRIPT_INFOBEGIN_TAG "### BEGIN INIT INFO"
60 #define LSB_INITSCRIPT_INFOEND_TAG "### END INIT INFO"
61 #define PROVIDES "# Provides:"
62 #define REQ_START "# Required-Start:"
63 #define REQ_STOP "# Required-Stop:"
64 #define SHLD_START "# Should-Start:"
65 #define SHLD_STOP "# Should-Stop:"
66 #define DFLT_START "# Default-Start:"
67 #define DFLT_STOP "# Default-Stop:"
68 #define SHORT_DSCR "# Short-Description:"
69 #define DESCRIPTION "# Description:"
70
71 #define lsb_meta_helper_free_value(m) \
72 do { \
73 if ((m) != NULL) { \
74 xmlFree(m); \
75 (m) = NULL; \
76 } \
77 } while(0)
78
79
80
81
82
83
84
85
86
87
88
89 static inline gboolean
90 lsb_meta_helper_get_value(const char *line, char **value, const char *prefix)
91 {
92 if (!*value && pcmk__starts_with(line, prefix)) {
93 *value = (char *)xmlEncodeEntitiesReentrant(NULL, BAD_CAST line+strlen(prefix));
94 return TRUE;
95 }
96 return FALSE;
97 }
98
99 int
100 services__get_lsb_metadata(const char *type, char **output)
101 {
102 char ra_pathname[PATH_MAX] = { 0, };
103 FILE *fp = NULL;
104 char buffer[1024] = { 0, };
105 char *provides = NULL;
106 char *req_start = NULL;
107 char *req_stop = NULL;
108 char *shld_start = NULL;
109 char *shld_stop = NULL;
110 char *dflt_start = NULL;
111 char *dflt_stop = NULL;
112 char *s_dscrpt = NULL;
113 char *xml_l_dscrpt = NULL;
114 bool in_header = FALSE;
115
116 if (type[0] == '/') {
117 snprintf(ra_pathname, sizeof(ra_pathname), "%s", type);
118 } else {
119 snprintf(ra_pathname, sizeof(ra_pathname), "%s/%s",
120 PCMK__LSB_INIT_DIR, type);
121 }
122
123 crm_trace("Looking into %s", ra_pathname);
124 fp = fopen(ra_pathname, "r");
125 if (fp == NULL) {
126 return -errno;
127 }
128
129
130 while (fgets(buffer, sizeof(buffer), fp)) {
131
132
133 if (pcmk__starts_with(buffer, LSB_INITSCRIPT_INFOBEGIN_TAG)) {
134 in_header = TRUE;
135 continue;
136 }
137 if (!in_header) {
138 continue;
139 }
140
141
142 if (lsb_meta_helper_get_value(buffer, &provides, PROVIDES)) {
143 continue;
144 }
145 if (lsb_meta_helper_get_value(buffer, &req_start, REQ_START)) {
146 continue;
147 }
148 if (lsb_meta_helper_get_value(buffer, &req_stop, REQ_STOP)) {
149 continue;
150 }
151 if (lsb_meta_helper_get_value(buffer, &shld_start, SHLD_START)) {
152 continue;
153 }
154 if (lsb_meta_helper_get_value(buffer, &shld_stop, SHLD_STOP)) {
155 continue;
156 }
157 if (lsb_meta_helper_get_value(buffer, &dflt_start, DFLT_START)) {
158 continue;
159 }
160 if (lsb_meta_helper_get_value(buffer, &dflt_stop, DFLT_STOP)) {
161 continue;
162 }
163 if (lsb_meta_helper_get_value(buffer, &s_dscrpt, SHORT_DSCR)) {
164 continue;
165 }
166
167
168 if ((xml_l_dscrpt == NULL)
169 && pcmk__starts_with(buffer, DESCRIPTION)) {
170 bool processed_line = TRUE;
171 GString *desc = g_string_sized_new(2048);
172
173
174 g_string_append(desc, buffer + sizeof(DESCRIPTION) - 1);
175
176
177 buffer[0] = '\0';
178 while (fgets(buffer, sizeof(buffer), fp)) {
179 if (pcmk__starts_with(buffer, "# ")
180 || pcmk__starts_with(buffer, "#\t")) {
181
182
183
184 g_string_append(desc, buffer + 1);
185 } else {
186
187
188
189 processed_line = FALSE;
190 break;
191 }
192 }
193
194
195 xml_l_dscrpt =
196 (char *) xmlEncodeEntitiesReentrant(NULL,
197 (pcmkXmlStr) desc->str);
198 g_string_free(desc, TRUE);
199
200 if (processed_line) {
201
202 continue;
203 }
204 }
205
206
207 if (pcmk__starts_with(buffer, LSB_INITSCRIPT_INFOEND_TAG)) {
208 break;
209 }
210 if (buffer[0] != '#') {
211 break;
212 }
213 }
214 fclose(fp);
215
216 *output = crm_strdup_printf(lsb_metadata_template, type,
217 (xml_l_dscrpt? xml_l_dscrpt : type),
218 (s_dscrpt? s_dscrpt : type),
219 (provides? provides : ""),
220 (req_start? req_start : ""),
221 (req_stop? req_stop : ""),
222 (shld_start? shld_start : ""),
223 (shld_stop? shld_stop : ""),
224 (dflt_start? dflt_start : ""),
225 (dflt_stop? dflt_stop : ""));
226
227 lsb_meta_helper_free_value(xml_l_dscrpt);
228 lsb_meta_helper_free_value(s_dscrpt);
229 lsb_meta_helper_free_value(provides);
230 lsb_meta_helper_free_value(req_start);
231 lsb_meta_helper_free_value(req_stop);
232 lsb_meta_helper_free_value(shld_start);
233 lsb_meta_helper_free_value(shld_stop);
234 lsb_meta_helper_free_value(dflt_start);
235 lsb_meta_helper_free_value(dflt_stop);
236
237 crm_trace("Created fake metadata: %llu",
238 (unsigned long long) strlen(*output));
239 return pcmk_ok;
240 }
241
242 GList *
243 services__list_lsb_agents(void)
244 {
245 return services_os_get_directory_list(PCMK__LSB_INIT_DIR, TRUE, TRUE);
246 }
247
248 bool
249 services__lsb_agent_exists(const char *agent)
250 {
251 bool rc = FALSE;
252 struct stat st;
253 char *path = pcmk__full_path(agent, PCMK__LSB_INIT_DIR);
254
255 rc = (stat(path, &st) == 0);
256 free(path);
257 return rc;
258 }
259
260
261
262
263
264
265
266
267
268 int
269 services__lsb_prepare(svc_action_t *op)
270 {
271 op->opaque->exec = pcmk__full_path(op->agent, PCMK__LSB_INIT_DIR);
272 op->opaque->args[0] = strdup(op->opaque->exec);
273 op->opaque->args[1] = strdup(op->action);
274 if ((op->opaque->args[0] == NULL) || (op->opaque->args[1] == NULL)) {
275 return ENOMEM;
276 }
277 return pcmk_rc_ok;
278 }
279
280
281
282
283
284
285
286
287
288
289 enum ocf_exitcode
290 services__lsb2ocf(const char *action, int exit_status)
291 {
292
293 if (!pcmk__str_any_of(action, "status", "monitor", NULL)) {
294 if ((exit_status < 0) || (exit_status > PCMK_LSB_NOT_RUNNING)) {
295 return PCMK_OCF_UNKNOWN_ERROR;
296 }
297 return (enum ocf_exitcode) exit_status;
298 }
299
300
301 switch (exit_status) {
302 case PCMK_LSB_STATUS_OK:
303 return PCMK_OCF_OK;
304
305 case PCMK_LSB_STATUS_NOT_INSTALLED:
306 return PCMK_OCF_NOT_INSTALLED;
307
308 case PCMK_LSB_STATUS_INSUFFICIENT_PRIV:
309 return PCMK_OCF_INSUFFICIENT_PRIV;
310
311 case PCMK_LSB_STATUS_VAR_PID:
312 case PCMK_LSB_STATUS_VAR_LOCK:
313 case PCMK_LSB_STATUS_NOT_RUNNING:
314 return PCMK_OCF_NOT_RUNNING;
315
316 default:
317 return PCMK_OCF_UNKNOWN_ERROR;
318 }
319 }
320
321
322
323
324 #include <crm/services_compat.h>
325
326 svc_action_t *
327 services_action_create(const char *name, const char *action,
328 guint interval_ms, int timeout)
329 {
330 return resources_action_create(name, PCMK_RESOURCE_CLASS_LSB, NULL, name,
331 action, interval_ms, timeout, NULL, 0);
332 }
333
334 GList *
335 services_list(void)
336 {
337 return resources_list_agents(PCMK_RESOURCE_CLASS_LSB, NULL);
338 }
339
340
341