This source file includes following definitions.
- sigdone
- sigreap
- find_env_var_name
- load_env_vars
- remoted_spawn_pidone
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdio.h>
13 #include <ctype.h>
14 #include <stdlib.h>
15 #include <signal.h>
16 #include <unistd.h>
17 #include <sys/types.h>
18 #include <sys/wait.h>
19
20 #include <crm/crm.h>
21 #include "pacemaker-execd.h"
22
23 static pid_t main_pid = 0;
24
25 static void
26 sigdone(void)
27 {
28 exit(CRM_EX_OK);
29 }
30
31 static void
32 sigreap(void)
33 {
34 pid_t pid = 0;
35 int status;
36
37 do {
38
39
40
41
42
43 pid = waitpid(-1, &status, WNOHANG);
44 if (pid == main_pid) {
45
46 if (WIFEXITED(status)) {
47 exit(WEXITSTATUS(status));
48 }
49 exit(CRM_EX_ERROR);
50 }
51 } while (pid > 0);
52 }
53
54 static struct {
55 int sig;
56 void (*handler)(void);
57 } sigmap[] = {
58 { SIGCHLD, sigreap },
59 { SIGINT, sigdone },
60 };
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 static bool
76 find_env_var_name(char *line, char **first, char **last)
77 {
78
79 *first = line;
80 while (isspace(**first)) {
81 ++*first;
82 }
83
84 if (isalpha(**first) || (**first == '_')) {
85 *last = *first;
86 while (isalnum(*(*last + 1)) || (*(*last + 1) == '_')) {
87 ++*last;
88 }
89 return TRUE;
90 }
91
92 *first = *last = NULL;
93 return FALSE;
94 }
95
96 static void
97 load_env_vars(const char *filename)
98 {
99
100
101
102 FILE *fp = fopen(filename, "r");
103
104 if (fp != NULL) {
105 char line[LINE_MAX] = { '\0', };
106
107 while (fgets(line, LINE_MAX, fp) != NULL) {
108 char *name = NULL;
109 char *end = NULL;
110 char *value = NULL;
111 char *quote = NULL;
112
113
114 if (find_env_var_name(line, &name, &end) && (*++end == '=')) {
115
116
117 *end++ = '\0';
118
119
120 if ((*end == '\'') || (*end == '"')) {
121 quote = end++;
122 }
123 value = end;
124
125 if (quote) {
126
127
128
129 while (((*end != *quote) || (*(end - 1) == '\\'))
130 && (*end != '\0')) {
131 end++;
132 }
133 if (*end == *quote) {
134
135 *end++ = '\0';
136 } else {
137
138 value = NULL;
139 }
140
141 } else {
142
143
144
145 while ((!isspace(*end) || (*(end - 1) == '\\'))
146 && (*end != '\0')) {
147 ++end;
148 }
149
150 if (end == (line + LINE_MAX - 1)) {
151
152 value = NULL;
153 }
154
155 }
156
157
158
159
160
161
162 if (value) {
163 char *value_end = end;
164
165 while (isspace(*end) && (*end != '\n')) {
166 ++end;
167 }
168 if ((*end == '\n') || (*end == '#')) {
169 if (quote == NULL) {
170
171 *value_end = '\0';
172 }
173
174
175 setenv(name, value, 0);
176
177 } else {
178 value = NULL;
179 }
180 }
181 }
182
183 if ((value == NULL) && (strchr(line, '\n') == NULL)) {
184
185 if (fscanf(fp, "%*[^\n]\n") == EOF) {
186 value = NULL;
187 }
188 }
189 }
190 fclose(fp);
191 }
192 }
193
194 void
195 remoted_spawn_pidone(int argc, char **argv, char **envp)
196 {
197 sigset_t set;
198
199
200
201
202
203
204
205
206 const char *pid1 = "default";
207
208 if (getpid() != 1) {
209 pid1 = pcmk__env_option(PCMK__ENV_REMOTE_PID1);
210 if (!pcmk__str_any_of(pid1, "full", "vars", NULL)) {
211
212 return;
213 }
214 }
215
216
217
218
219
220
221
222 load_env_vars("/etc/pacemaker/pcmk-init.env");
223
224 if (strcmp(pid1, "vars") == 0) {
225 return;
226 }
227
228
229
230
231
232 if (pcmk__env_option(PCMK__ENV_LOGFILE) == NULL) {
233 pcmk__set_env_option(PCMK__ENV_LOGFILE, "/var/log/pcmk-init.log", true);
234 }
235
236 sigfillset(&set);
237 sigprocmask(SIG_BLOCK, &set, 0);
238
239 main_pid = fork();
240 switch (main_pid) {
241 case 0:
242 sigprocmask(SIG_UNBLOCK, &set, NULL);
243 setsid();
244 setpgid(0, 0);
245
246
247 return;
248 case -1:
249 crm_err("fork failed: %s", pcmk_rc_str(errno));
250 }
251
252
253
254
255 # ifdef HAVE_PROGNAME
256
257 {
258 char *p;
259 int i, maxlen;
260 char *LastArgv = NULL;
261 const char *name = "pcmk-init";
262
263 for (i = 0; i < argc; i++) {
264 if (!i || (LastArgv + 1 == argv[i]))
265 LastArgv = argv[i] + strlen(argv[i]);
266 }
267
268 for (i = 0; envp[i] != NULL; i++) {
269 if ((LastArgv + 1) == envp[i]) {
270 LastArgv = envp[i] + strlen(envp[i]);
271 }
272 }
273
274 maxlen = (LastArgv - argv[0]) - 2;
275
276 i = strlen(name);
277
278
279 snprintf(argv[0], maxlen, "%s", name);
280
281
282 p = &argv[0][i];
283 while (p < LastArgv) {
284 *p++ = '\0';
285 }
286 argv[1] = NULL;
287 }
288 # endif
289
290 while (1) {
291 int sig;
292 size_t i;
293
294 sigwait(&set, &sig);
295 for (i = 0; i < PCMK__NELEM(sigmap); i++) {
296 if (sigmap[i].sig == sig) {
297 sigmap[i].handler();
298 break;
299 }
300 }
301 }
302 }