diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-05-15 19:44:48 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-05-15 19:44:48 +0200 |
commit | bcb5764822b07f2f1f6a5db355566ac1da70ac5b (patch) | |
tree | 51d3fab40d6d4306e6373fea0c67eb5fc57402f9 | |
parent | 79c0d7332ab9707bcbdaaa71b034d939ad36c8d7 (diff) | |
download | busybox-w32-bcb5764822b07f2f1f6a5db355566ac1da70ac5b.tar.gz busybox-w32-bcb5764822b07f2f1f6a5db355566ac1da70ac5b.tar.bz2 busybox-w32-bcb5764822b07f2f1f6a5db355566ac1da70ac5b.zip |
runsv: update to match version 2.1.2 of runit
Backport from upstream versions:
2.1.0
Thu, 24 Sep 2009 22:49:33 +0000
* runsv.c: exit with error if [log/]supervise/control exists, but is
not a fifo.
[Code abstracted into a separate function to make it more compact
for BusyBox.]
1.9.0
Mon, 05 May 2008 22:00:13 +0000
* runsv.c: create temporary new status files for log/supervise/
actually in log/supervise/.
1.7.2
Tue, 21 Nov 2006 15:13:47 +0000
* runsv.c: really don't act on commands in state finish; minor.
function old new delta
open_control - 135 +135
update_status 553 612 +59
custom 223 242 +19
ctrl 426 422 -4
warn_cannot 21 10 -11
runsv_main 1786 1662 -124
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/3 up/down: 213/-139) Total: 74 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | runit/runsv.c | 95 |
1 files changed, 58 insertions, 37 deletions
diff --git a/runit/runsv.c b/runit/runsv.c index e0e31508a..939653d12 100644 --- a/runit/runsv.c +++ b/runit/runsv.c | |||
@@ -134,9 +134,13 @@ static void fatal2x_cannot(const char *m1, const char *m2) | |||
134 | bb_error_msg_and_die("%s: fatal: can't %s%s", dir, m1, m2); | 134 | bb_error_msg_and_die("%s: fatal: can't %s%s", dir, m1, m2); |
135 | /* was exiting 111 */ | 135 | /* was exiting 111 */ |
136 | } | 136 | } |
137 | static void warn2_cannot(const char *m1, const char *m2) | ||
138 | { | ||
139 | bb_perror_msg("%s: warning: can't %s%s", dir, m1, m2); | ||
140 | } | ||
137 | static void warn_cannot(const char *m) | 141 | static void warn_cannot(const char *m) |
138 | { | 142 | { |
139 | bb_perror_msg("%s: warning: cannot %s", dir, m); | 143 | warn2_cannot(m, ""); |
140 | } | 144 | } |
141 | 145 | ||
142 | static void s_child(int sig_no UNUSED_PARAM) | 146 | static void s_child(int sig_no UNUSED_PARAM) |
@@ -165,10 +169,25 @@ static void update_status(struct svdir *s) | |||
165 | ssize_t sz; | 169 | ssize_t sz; |
166 | int fd; | 170 | int fd; |
167 | svstatus_t status; | 171 | svstatus_t status; |
172 | const char *fstatus ="log/supervise/status"; | ||
173 | const char *fstatusnew ="log/supervise/status.new"; | ||
174 | const char *f_stat ="log/supervise/stat"; | ||
175 | const char *fstatnew ="log/supervise/stat.new"; | ||
176 | const char *fpid ="log/supervise/pid"; | ||
177 | const char *fpidnew ="log/supervise/pid.new"; | ||
178 | |||
179 | if (!s->islog) { | ||
180 | fstatus += 4; | ||
181 | fstatusnew += 4; | ||
182 | f_stat += 4; | ||
183 | fstatnew += 4; | ||
184 | fpid += 4; | ||
185 | fpidnew += 4; | ||
186 | } | ||
168 | 187 | ||
169 | /* pid */ | 188 | /* pid */ |
170 | if (pidchanged) { | 189 | if (pidchanged) { |
171 | fd = open_trunc_or_warn("supervise/pid.new"); | 190 | fd = open_trunc_or_warn(fpidnew); |
172 | if (fd < 0) | 191 | if (fd < 0) |
173 | return; | 192 | return; |
174 | if (s->pid) { | 193 | if (s->pid) { |
@@ -177,14 +196,13 @@ static void update_status(struct svdir *s) | |||
177 | write(fd, spid, size); | 196 | write(fd, spid, size); |
178 | } | 197 | } |
179 | close(fd); | 198 | close(fd); |
180 | if (rename_or_warn("supervise/pid.new", | 199 | if (rename_or_warn(fpidnew, fpid)) |
181 | s->islog ? "log/supervise/pid" : "log/supervise/pid"+4)) | ||
182 | return; | 200 | return; |
183 | pidchanged = 0; | 201 | pidchanged = 0; |
184 | } | 202 | } |
185 | 203 | ||
186 | /* stat */ | 204 | /* stat */ |
187 | fd = open_trunc_or_warn("supervise/stat.new"); | 205 | fd = open_trunc_or_warn(fstatnew); |
188 | if (fd < -1) | 206 | if (fd < -1) |
189 | return; | 207 | return; |
190 | 208 | ||
@@ -220,8 +238,7 @@ static void update_status(struct svdir *s) | |||
220 | close(fd); | 238 | close(fd); |
221 | } | 239 | } |
222 | 240 | ||
223 | rename_or_warn("supervise/stat.new", | 241 | rename_or_warn(fstatnew, f_stat); |
224 | s->islog ? "log/supervise/stat" : "log/supervise/stat"+4); | ||
225 | 242 | ||
226 | /* supervise compatibility */ | 243 | /* supervise compatibility */ |
227 | memset(&status, 0, sizeof(status)); | 244 | memset(&status, 0, sizeof(status)); |
@@ -237,18 +254,17 @@ static void update_status(struct svdir *s) | |||
237 | if (s->ctrl & C_TERM) | 254 | if (s->ctrl & C_TERM) |
238 | status.got_term = 1; | 255 | status.got_term = 1; |
239 | status.run_or_finish = s->state; | 256 | status.run_or_finish = s->state; |
240 | fd = open_trunc_or_warn("supervise/status.new"); | 257 | fd = open_trunc_or_warn(fstatusnew); |
241 | if (fd < 0) | 258 | if (fd < 0) |
242 | return; | 259 | return; |
243 | sz = write(fd, &status, sizeof(status)); | 260 | sz = write(fd, &status, sizeof(status)); |
244 | close(fd); | 261 | close(fd); |
245 | if (sz != sizeof(status)) { | 262 | if (sz != sizeof(status)) { |
246 | warn_cannot("write supervise/status.new"); | 263 | warn2_cannot("write ", fstatusnew); |
247 | unlink("supervise/status.new"); | 264 | unlink(fstatusnew); |
248 | return; | 265 | return; |
249 | } | 266 | } |
250 | rename_or_warn("supervise/status.new", | 267 | rename_or_warn(fstatusnew, fstatus); |
251 | s->islog ? "log/supervise/status" : "log/supervise/status"+4); | ||
252 | } | 268 | } |
253 | 269 | ||
254 | static unsigned custom(struct svdir *s, char c) | 270 | static unsigned custom(struct svdir *s, char c) |
@@ -266,26 +282,26 @@ static unsigned custom(struct svdir *s, char c) | |||
266 | if (st.st_mode & S_IXUSR) { | 282 | if (st.st_mode & S_IXUSR) { |
267 | pid = vfork(); | 283 | pid = vfork(); |
268 | if (pid == -1) { | 284 | if (pid == -1) { |
269 | warn_cannot("vfork for control/?"); | 285 | warn2_cannot("vfork for ", a); |
270 | return 0; | 286 | return 0; |
271 | } | 287 | } |
272 | if (pid == 0) { | 288 | if (pid == 0) { |
273 | /* child */ | 289 | /* child */ |
274 | if (haslog && dup2(logpipe.wr, 1) == -1) | 290 | if (haslog && dup2(logpipe.wr, 1) == -1) |
275 | warn_cannot("setup stdout for control/?"); | 291 | warn2_cannot("setup stdout for ", a); |
276 | execl(a, a, (char *) NULL); | 292 | execl(a, a, (char *) NULL); |
277 | fatal_cannot("run control/?"); | 293 | fatal2_cannot("run ", a); |
278 | } | 294 | } |
279 | /* parent */ | 295 | /* parent */ |
280 | if (safe_waitpid(pid, &w, 0) == -1) { | 296 | if (safe_waitpid(pid, &w, 0) == -1) { |
281 | warn_cannot("wait for child control/?"); | 297 | warn2_cannot("wait for child ", a); |
282 | return 0; | 298 | return 0; |
283 | } | 299 | } |
284 | return WEXITSTATUS(w) == 0; | 300 | return WEXITSTATUS(w) == 0; |
285 | } | 301 | } |
286 | } else { | 302 | } else { |
287 | if (errno != ENOENT) | 303 | if (errno != ENOENT) |
288 | warn_cannot("stat control/?"); | 304 | warn2_cannot("stat ", a); |
289 | } | 305 | } |
290 | return 0; | 306 | return 0; |
291 | } | 307 | } |
@@ -387,13 +403,13 @@ static int ctrl(struct svdir *s, char c) | |||
387 | case 'd': /* down */ | 403 | case 'd': /* down */ |
388 | s->sd_want = W_DOWN; | 404 | s->sd_want = W_DOWN; |
389 | update_status(s); | 405 | update_status(s); |
390 | if (s->pid && s->state != S_FINISH) | 406 | if (s->state == S_RUN) |
391 | stopservice(s); | 407 | stopservice(s); |
392 | break; | 408 | break; |
393 | case 'u': /* up */ | 409 | case 'u': /* up */ |
394 | s->sd_want = W_UP; | 410 | s->sd_want = W_UP; |
395 | update_status(s); | 411 | update_status(s); |
396 | if (s->pid == 0) | 412 | if (s->state == S_DOWN) |
397 | startservice(s); | 413 | startservice(s); |
398 | break; | 414 | break; |
399 | case 'x': /* exit */ | 415 | case 'x': /* exit */ |
@@ -403,22 +419,22 @@ static int ctrl(struct svdir *s, char c) | |||
403 | update_status(s); | 419 | update_status(s); |
404 | /* FALLTHROUGH */ | 420 | /* FALLTHROUGH */ |
405 | case 't': /* sig term */ | 421 | case 't': /* sig term */ |
406 | if (s->pid && s->state != S_FINISH) | 422 | if (s->state == S_RUN) |
407 | stopservice(s); | 423 | stopservice(s); |
408 | break; | 424 | break; |
409 | case 'k': /* sig kill */ | 425 | case 'k': /* sig kill */ |
410 | if (s->pid && !custom(s, c)) | 426 | if ((s->state == S_RUN) && !custom(s, c)) |
411 | kill(s->pid, SIGKILL); | 427 | kill(s->pid, SIGKILL); |
412 | s->state = S_DOWN; | 428 | s->state = S_DOWN; |
413 | break; | 429 | break; |
414 | case 'p': /* sig pause */ | 430 | case 'p': /* sig pause */ |
415 | if (s->pid && !custom(s, c)) | 431 | if ((s->state == S_RUN) && !custom(s, c)) |
416 | kill(s->pid, SIGSTOP); | 432 | kill(s->pid, SIGSTOP); |
417 | s->ctrl |= C_PAUSE; | 433 | s->ctrl |= C_PAUSE; |
418 | update_status(s); | 434 | update_status(s); |
419 | break; | 435 | break; |
420 | case 'c': /* sig cont */ | 436 | case 'c': /* sig cont */ |
421 | if (s->pid && !custom(s, c)) | 437 | if ((s->state == S_RUN) && !custom(s, c)) |
422 | kill(s->pid, SIGCONT); | 438 | kill(s->pid, SIGCONT); |
423 | s->ctrl &= ~C_PAUSE; | 439 | s->ctrl &= ~C_PAUSE; |
424 | update_status(s); | 440 | update_status(s); |
@@ -426,7 +442,7 @@ static int ctrl(struct svdir *s, char c) | |||
426 | case 'o': /* once */ | 442 | case 'o': /* once */ |
427 | s->sd_want = W_DOWN; | 443 | s->sd_want = W_DOWN; |
428 | update_status(s); | 444 | update_status(s); |
429 | if (!s->pid) | 445 | if (s->state == S_DOWN) |
430 | startservice(s); | 446 | startservice(s); |
431 | break; | 447 | break; |
432 | case 'a': /* sig alarm */ | 448 | case 'a': /* sig alarm */ |
@@ -450,11 +466,26 @@ static int ctrl(struct svdir *s, char c) | |||
450 | } | 466 | } |
451 | return 1; | 467 | return 1; |
452 | sendsig: | 468 | sendsig: |
453 | if (s->pid && !custom(s, c)) | 469 | if ((s->state == S_RUN) && !custom(s, c)) |
454 | kill(s->pid, sig); | 470 | kill(s->pid, sig); |
455 | return 1; | 471 | return 1; |
456 | } | 472 | } |
457 | 473 | ||
474 | static void open_control(const char *f, struct svdir *s) | ||
475 | { | ||
476 | struct stat st; | ||
477 | mkfifo(f, 0600); | ||
478 | if (stat(f, &st) == -1) | ||
479 | fatal2_cannot("stat ", f); | ||
480 | if (!S_ISFIFO(st.st_mode)) | ||
481 | bb_error_msg_and_die("%s: fatal: %s exists but is not a fifo", dir, f); | ||
482 | s->fdcontrol = xopen(f, O_RDONLY|O_NDELAY); | ||
483 | close_on_exec_on(s->fdcontrol); | ||
484 | s->fdcontrolwrite = xopen(f, O_WRONLY|O_NDELAY); | ||
485 | close_on_exec_on(s->fdcontrolwrite); | ||
486 | update_status(s); | ||
487 | } | ||
488 | |||
458 | int runsv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 489 | int runsv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
459 | int runsv_main(int argc UNUSED_PARAM, char **argv) | 490 | int runsv_main(int argc UNUSED_PARAM, char **argv) |
460 | { | 491 | { |
@@ -554,19 +585,9 @@ int runsv_main(int argc UNUSED_PARAM, char **argv) | |||
554 | close_on_exec_on(svd[1].fdlock); | 585 | close_on_exec_on(svd[1].fdlock); |
555 | } | 586 | } |
556 | 587 | ||
557 | mkfifo("log/supervise/control"+4, 0600); | 588 | open_control("log/supervise/control"+4, &svd[0]); |
558 | svd[0].fdcontrol = xopen("log/supervise/control"+4, O_RDONLY|O_NDELAY); | ||
559 | close_on_exec_on(svd[0].fdcontrol); | ||
560 | svd[0].fdcontrolwrite = xopen("log/supervise/control"+4, O_WRONLY|O_NDELAY); | ||
561 | close_on_exec_on(svd[0].fdcontrolwrite); | ||
562 | update_status(&svd[0]); | ||
563 | if (haslog) { | 589 | if (haslog) { |
564 | mkfifo("log/supervise/control", 0600); | 590 | open_control("log/supervise/control", &svd[1]); |
565 | svd[1].fdcontrol = xopen("log/supervise/control", O_RDONLY|O_NDELAY); | ||
566 | close_on_exec_on(svd[1].fdcontrol); | ||
567 | svd[1].fdcontrolwrite = xopen("log/supervise/control", O_WRONLY|O_NDELAY); | ||
568 | close_on_exec_on(svd[1].fdcontrolwrite); | ||
569 | update_status(&svd[1]); | ||
570 | } | 591 | } |
571 | mkfifo("log/supervise/ok"+4, 0600); | 592 | mkfifo("log/supervise/ok"+4, 0600); |
572 | fd = xopen("log/supervise/ok"+4, O_RDONLY|O_NDELAY); | 593 | fd = xopen("log/supervise/ok"+4, O_RDONLY|O_NDELAY); |