diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-20 17:27:40 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-20 17:27:40 +0000 |
commit | 45946f8b513d9c292613ac08c3ddf4a89b915752 (patch) | |
tree | d6ea51887431e4261a114b95989950d1973d3227 /runit/runsv.c | |
parent | 63db27f9f4c0ec8b9abe3c32c8d699be0781ffd6 (diff) | |
download | busybox-w32-45946f8b513d9c292613ac08c3ddf4a89b915752.tar.gz busybox-w32-45946f8b513d9c292613ac08c3ddf4a89b915752.tar.bz2 busybox-w32-45946f8b513d9c292613ac08c3ddf4a89b915752.zip |
runit/*: get rid of tai[a] time abstraction, it's too bloaty.
text data bss dec hex filename
772537 1058 11092 784687 bf92f busybox.t0/busybox
772459 1058 11060 784577 bf8c1 busybox.t1/busybox
772326 1058 11028 784412 bf81c busybox.t2/busybox
772158 1058 10980 784196 bf744 busybox.t3/busybox
771490 1055 10988 783533 bf4ad busybox.t4/busybox
Diffstat (limited to 'runit/runsv.c')
-rw-r--r-- | runit/runsv.c | 151 |
1 files changed, 73 insertions, 78 deletions
diff --git a/runit/runsv.c b/runit/runsv.c index f70b51390..baef6e13f 100644 --- a/runit/runsv.c +++ b/runit/runsv.c | |||
@@ -54,21 +54,19 @@ struct svdir { | |||
54 | smallint ctrl; | 54 | smallint ctrl; |
55 | smallint want; | 55 | smallint want; |
56 | smallint islog; | 56 | smallint islog; |
57 | struct taia start; | 57 | struct timespec start; |
58 | int fdlock; | 58 | int fdlock; |
59 | int fdcontrol; | 59 | int fdcontrol; |
60 | int fdcontrolwrite; | 60 | int fdcontrolwrite; |
61 | }; | 61 | }; |
62 | static struct svdir svd[2]; | ||
63 | 62 | ||
63 | static struct svdir svd[2]; | ||
64 | static smallint sigterm; | 64 | static smallint sigterm; |
65 | static smallint haslog; | 65 | static smallint haslog; |
66 | static smallint pidchanged = 1; | 66 | static smallint pidchanged = 1; |
67 | static int logpipe[2]; | 67 | static int logpipe[2]; |
68 | static char *dir; | 68 | static char *dir; |
69 | 69 | ||
70 | #define usage() bb_show_usage() | ||
71 | |||
72 | static void fatal2_cannot(const char *m1, const char *m2) | 70 | static void fatal2_cannot(const char *m1, const char *m2) |
73 | { | 71 | { |
74 | bb_perror_msg_and_die("%s: fatal: cannot %s%s", dir, m1, m2); | 72 | bb_perror_msg_and_die("%s: fatal: cannot %s%s", dir, m1, m2); |
@@ -88,10 +86,6 @@ static void warn_cannot(const char *m) | |||
88 | { | 86 | { |
89 | bb_perror_msg("%s: warning: cannot %s", dir, m); | 87 | bb_perror_msg("%s: warning: cannot %s", dir, m); |
90 | } | 88 | } |
91 | static void warnx_cannot(const char *m) | ||
92 | { | ||
93 | bb_error_msg("%s: warning: cannot %s", dir, m); | ||
94 | } | ||
95 | 89 | ||
96 | static void s_child(int sig_no) | 90 | static void s_child(int sig_no) |
97 | { | 91 | { |
@@ -132,11 +126,19 @@ static int rename_or_warn(const char *old, const char *new) | |||
132 | return 0; | 126 | return 0; |
133 | } | 127 | } |
134 | 128 | ||
129 | #define LESS(a,b) ((int)((unsigned)(b) - (unsigned)(a)) > 0) | ||
130 | |||
131 | #include <sys/syscall.h> | ||
132 | static void gettimeofday_ns(struct timespec *ts) | ||
133 | { | ||
134 | syscall(__NR_clock_gettime, CLOCK_REALTIME, ts); | ||
135 | } | ||
136 | |||
135 | static void update_status(struct svdir *s) | 137 | static void update_status(struct svdir *s) |
136 | { | 138 | { |
137 | unsigned long l; | 139 | ssize_t sz; |
138 | int fd; | 140 | int fd; |
139 | char status[20]; | 141 | svstatus_t status; |
140 | 142 | ||
141 | /* pid */ | 143 | /* pid */ |
142 | if (pidchanged) { | 144 | if (pidchanged) { |
@@ -194,40 +196,29 @@ static void update_status(struct svdir *s) | |||
194 | s->islog ? "log/supervise/stat" : "log/supervise/stat"+4); | 196 | s->islog ? "log/supervise/stat" : "log/supervise/stat"+4); |
195 | 197 | ||
196 | /* supervise compatibility */ | 198 | /* supervise compatibility */ |
197 | taia_pack(status, &s->start); | 199 | memset(&status, 0, sizeof(status)); |
198 | l = (unsigned long)s->pid; | 200 | status.time_be64 = SWAP_BE64(s->start.tv_sec + 0x400000000000000aULL); |
199 | status[12] = l; l >>=8; | 201 | status.time_nsec_be32 = SWAP_BE32(s->start.tv_nsec); |
200 | status[13] = l; l >>=8; | 202 | status.pid_le32 = SWAP_LE32(s->pid); |
201 | status[14] = l; l >>=8; | ||
202 | status[15] = l; | ||
203 | if (s->ctrl & C_PAUSE) | 203 | if (s->ctrl & C_PAUSE) |
204 | status[16] = 1; | 204 | status.paused = 1; |
205 | else | ||
206 | status[16] = 0; | ||
207 | if (s->want == W_UP) | 205 | if (s->want == W_UP) |
208 | status[17] = 'u'; | 206 | status.want = 'u'; |
209 | else | 207 | else |
210 | status[17] = 'd'; | 208 | status.want = 'd'; |
211 | if (s->ctrl & C_TERM) | 209 | if (s->ctrl & C_TERM) |
212 | status[18] = 1; | 210 | status.got_term = 1; |
213 | else | 211 | status.run_or_finish = s->state; |
214 | status[18] = 0; | ||
215 | status[19] = s->state; | ||
216 | fd = open_trunc_or_warn("supervise/status.new"); | 212 | fd = open_trunc_or_warn("supervise/status.new"); |
217 | if (fd < 0) | 213 | if (fd < 0) |
218 | return; | 214 | return; |
219 | l = write(fd, status, sizeof(status)); | 215 | sz = write(fd, &status, sizeof(status)); |
220 | if (l < 0) { | 216 | close(fd); |
217 | if (sz != sizeof(status)) { | ||
221 | warn_cannot("write supervise/status.new"); | 218 | warn_cannot("write supervise/status.new"); |
222 | close(fd); | ||
223 | unlink("supervise/status.new"); | 219 | unlink("supervise/status.new"); |
224 | return; | 220 | return; |
225 | } | 221 | } |
226 | close(fd); | ||
227 | if (l < sizeof(status)) { | ||
228 | warnx_cannot("write supervise/status.new: partial write"); | ||
229 | return; | ||
230 | } | ||
231 | rename_or_warn("supervise/status.new", | 222 | rename_or_warn("supervise/status.new", |
232 | s->islog ? "log/supervise/status" : "log/supervise/status"+4); | 223 | s->islog ? "log/supervise/status" : "log/supervise/status"+4); |
233 | } | 224 | } |
@@ -329,7 +320,7 @@ static void startservice(struct svdir *s) | |||
329 | fatal2_cannot(s->islog ? "start log/" : "start ", *run); | 320 | fatal2_cannot(s->islog ? "start log/" : "start ", *run); |
330 | } | 321 | } |
331 | if (s->state != S_FINISH) { | 322 | if (s->state != S_FINISH) { |
332 | taia_now(&s->start); | 323 | gettimeofday_ns(&s->start); |
333 | s->state = S_RUN; | 324 | s->state = S_RUN; |
334 | } | 325 | } |
335 | s->pid = p; | 326 | s->pid = p; |
@@ -346,39 +337,48 @@ static int ctrl(struct svdir *s, char c) | |||
346 | case 'd': /* down */ | 337 | case 'd': /* down */ |
347 | s->want = W_DOWN; | 338 | s->want = W_DOWN; |
348 | update_status(s); | 339 | update_status(s); |
349 | if (s->pid && s->state != S_FINISH) stopservice(s); | 340 | if (s->pid && s->state != S_FINISH) |
341 | stopservice(s); | ||
350 | break; | 342 | break; |
351 | case 'u': /* up */ | 343 | case 'u': /* up */ |
352 | s->want = W_UP; | 344 | s->want = W_UP; |
353 | update_status(s); | 345 | update_status(s); |
354 | if (s->pid == 0) startservice(s); | 346 | if (s->pid == 0) |
347 | startservice(s); | ||
355 | break; | 348 | break; |
356 | case 'x': /* exit */ | 349 | case 'x': /* exit */ |
357 | if (s->islog) break; | 350 | if (s->islog) |
351 | break; | ||
358 | s->want = W_EXIT; | 352 | s->want = W_EXIT; |
359 | update_status(s); | 353 | update_status(s); |
360 | /* FALLTHROUGH */ | 354 | /* FALLTHROUGH */ |
361 | case 't': /* sig term */ | 355 | case 't': /* sig term */ |
362 | if (s->pid && s->state != S_FINISH) stopservice(s); | 356 | if (s->pid && s->state != S_FINISH) |
357 | stopservice(s); | ||
363 | break; | 358 | break; |
364 | case 'k': /* sig kill */ | 359 | case 'k': /* sig kill */ |
365 | if (s->pid && !custom(s, c)) kill(s->pid, SIGKILL); | 360 | if (s->pid && !custom(s, c)) |
361 | kill(s->pid, SIGKILL); | ||
366 | s->state = S_DOWN; | 362 | s->state = S_DOWN; |
367 | break; | 363 | break; |
368 | case 'p': /* sig pause */ | 364 | case 'p': /* sig pause */ |
369 | if (s->pid && !custom(s, c)) kill(s->pid, SIGSTOP); | 365 | if (s->pid && !custom(s, c)) |
366 | kill(s->pid, SIGSTOP); | ||
370 | s->ctrl |= C_PAUSE; | 367 | s->ctrl |= C_PAUSE; |
371 | update_status(s); | 368 | update_status(s); |
372 | break; | 369 | break; |
373 | case 'c': /* sig cont */ | 370 | case 'c': /* sig cont */ |
374 | if (s->pid && !custom(s, c)) kill(s->pid, SIGCONT); | 371 | if (s->pid && !custom(s, c)) |
375 | if (s->ctrl & C_PAUSE) s->ctrl &= ~C_PAUSE; | 372 | kill(s->pid, SIGCONT); |
373 | if (s->ctrl & C_PAUSE) | ||
374 | s->ctrl &= ~C_PAUSE; | ||
376 | update_status(s); | 375 | update_status(s); |
377 | break; | 376 | break; |
378 | case 'o': /* once */ | 377 | case 'o': /* once */ |
379 | s->want = W_DOWN; | 378 | s->want = W_DOWN; |
380 | update_status(s); | 379 | update_status(s); |
381 | if (!s->pid) startservice(s); | 380 | if (!s->pid) |
381 | startservice(s); | ||
382 | break; | 382 | break; |
383 | case 'a': /* sig alarm */ | 383 | case 'a': /* sig alarm */ |
384 | sig = SIGALRM; | 384 | sig = SIGALRM; |
@@ -414,7 +414,8 @@ int runsv_main(int argc, char **argv) | |||
414 | int r; | 414 | int r; |
415 | char buf[256]; | 415 | char buf[256]; |
416 | 416 | ||
417 | if (!argv[1] || argv[2]) usage(); | 417 | if (!argv[1] || argv[2]) |
418 | bb_show_usage(); | ||
418 | dir = argv[1]; | 419 | dir = argv[1]; |
419 | 420 | ||
420 | xpipe(selfpipe); | 421 | xpipe(selfpipe); |
@@ -435,22 +436,23 @@ int runsv_main(int argc, char **argv) | |||
435 | if (W_UP) svd[0].want = W_UP; | 436 | if (W_UP) svd[0].want = W_UP; |
436 | /* bss: svd[0].islog = 0; */ | 437 | /* bss: svd[0].islog = 0; */ |
437 | /* bss: svd[1].pid = 0; */ | 438 | /* bss: svd[1].pid = 0; */ |
438 | taia_now(&svd[0].start); | 439 | gettimeofday_ns(&svd[0].start); |
439 | if (stat("down", &s) != -1) svd[0].want = W_DOWN; | 440 | if (stat("down", &s) != -1) svd[0].want = W_DOWN; |
440 | 441 | ||
441 | if (stat("log", &s) == -1) { | 442 | if (stat("log", &s) == -1) { |
442 | if (errno != ENOENT) | 443 | if (errno != ENOENT) |
443 | warn_cannot("stat ./log"); | 444 | warn_cannot("stat ./log"); |
444 | } else { | 445 | } else { |
445 | if (!S_ISDIR(s.st_mode)) | 446 | if (!S_ISDIR(s.st_mode)) { |
446 | warnx_cannot("stat log/down: log is not a directory"); | 447 | errno = 0; |
447 | else { | 448 | warn_cannot("stat log/down: log is not a directory"); |
449 | } else { | ||
448 | haslog = 1; | 450 | haslog = 1; |
449 | svd[1].state = S_DOWN; | 451 | svd[1].state = S_DOWN; |
450 | svd[1].ctrl = C_NOOP; | 452 | svd[1].ctrl = C_NOOP; |
451 | svd[1].want = W_UP; | 453 | svd[1].want = W_UP; |
452 | svd[1].islog = 1; | 454 | svd[1].islog = 1; |
453 | taia_now(&svd[1].start); | 455 | gettimeofday_ns(&svd[1].start); |
454 | if (stat("log/down", &s) != -1) | 456 | if (stat("log/down", &s) != -1) |
455 | svd[1].want = W_DOWN; | 457 | svd[1].want = W_DOWN; |
456 | xpipe(logpipe); | 458 | xpipe(logpipe); |
@@ -525,9 +527,8 @@ int runsv_main(int argc, char **argv) | |||
525 | coe(fd); | 527 | coe(fd); |
526 | } | 528 | } |
527 | for (;;) { | 529 | for (;;) { |
528 | iopause_fd x[3]; | 530 | struct pollfd x[3]; |
529 | struct taia deadline; | 531 | unsigned deadline; |
530 | struct taia now; | ||
531 | char ch; | 532 | char ch; |
532 | 533 | ||
533 | if (haslog) | 534 | if (haslog) |
@@ -538,32 +539,30 @@ int runsv_main(int argc, char **argv) | |||
538 | startservice(&svd[0]); | 539 | startservice(&svd[0]); |
539 | 540 | ||
540 | x[0].fd = selfpipe[0]; | 541 | x[0].fd = selfpipe[0]; |
541 | x[0].events = IOPAUSE_READ; | 542 | x[0].events = POLLIN; |
542 | x[1].fd = svd[0].fdcontrol; | 543 | x[1].fd = svd[0].fdcontrol; |
543 | x[1].events = IOPAUSE_READ; | 544 | x[1].events = POLLIN; |
544 | if (haslog) { | 545 | /* x[2] is used only if haslog == 1 */ |
545 | x[2].fd = svd[1].fdcontrol; | 546 | x[2].fd = svd[1].fdcontrol; |
546 | x[2].events = IOPAUSE_READ; | 547 | x[2].events = POLLIN; |
547 | } | ||
548 | taia_now(&now); | ||
549 | taia_uint(&deadline, 3600); | ||
550 | taia_add(&deadline, &now, &deadline); | ||
551 | |||
552 | sig_unblock(SIGTERM); | 548 | sig_unblock(SIGTERM); |
553 | sig_unblock(SIGCHLD); | 549 | sig_unblock(SIGCHLD); |
554 | iopause(x, 2+haslog, &deadline, &now); | 550 | poll(x, 2 + haslog, 3600*1000); |
555 | sig_block(SIGTERM); | 551 | sig_block(SIGTERM); |
556 | sig_block(SIGCHLD); | 552 | sig_block(SIGCHLD); |
557 | 553 | ||
558 | while (read(selfpipe[0], &ch, 1) == 1) | 554 | while (read(selfpipe[0], &ch, 1) == 1) |
559 | ; | 555 | continue; |
556 | |||
560 | for (;;) { | 557 | for (;;) { |
561 | int child; | 558 | int child; |
562 | int wstat; | 559 | int wstat; |
563 | 560 | ||
564 | child = wait_nohang(&wstat); | 561 | child = wait_nohang(&wstat); |
565 | if (!child) break; | 562 | if (!child) |
566 | if ((child == -1) && (errno != EINTR)) break; | 563 | break; |
564 | if ((child == -1) && (errno != EINTR)) | ||
565 | break; | ||
567 | if (child == svd[0].pid) { | 566 | if (child == svd[0].pid) { |
568 | svd[0].pid = 0; | 567 | svd[0].pid = 0; |
569 | pidchanged = 1; | 568 | pidchanged = 1; |
@@ -578,11 +577,11 @@ int runsv_main(int argc, char **argv) | |||
578 | } | 577 | } |
579 | } | 578 | } |
580 | svd[0].state = S_DOWN; | 579 | svd[0].state = S_DOWN; |
581 | taia_uint(&deadline, 1); | 580 | deadline = svd[0].start.tv_sec + 1; |
582 | taia_add(&deadline, &svd[0].start, &deadline); | 581 | gettimeofday_ns(&svd[0].start); |
583 | taia_now(&svd[0].start); | ||
584 | update_status(&svd[0]); | 582 | update_status(&svd[0]); |
585 | if (taia_less(&svd[0].start, &deadline)) sleep(1); | 583 | if (LESS(svd[0].start.tv_sec, deadline)) |
584 | sleep(1); | ||
586 | } | 585 | } |
587 | if (haslog) { | 586 | if (haslog) { |
588 | if (child == svd[1].pid) { | 587 | if (child == svd[1].pid) { |
@@ -590,11 +589,11 @@ int runsv_main(int argc, char **argv) | |||
590 | pidchanged = 1; | 589 | pidchanged = 1; |
591 | svd[1].state = S_DOWN; | 590 | svd[1].state = S_DOWN; |
592 | svd[1].ctrl &= ~C_TERM; | 591 | svd[1].ctrl &= ~C_TERM; |
593 | taia_uint(&deadline, 1); | 592 | deadline = svd[1].start.tv_sec + 1; |
594 | taia_add(&deadline, &svd[1].start, &deadline); | 593 | gettimeofday_ns(&svd[1].start); |
595 | taia_now(&svd[1].start); | ||
596 | update_status(&svd[1]); | 594 | update_status(&svd[1]); |
597 | if (taia_less(&svd[1].start, &deadline)) sleep(1); | 595 | if (LESS(svd[1].start.tv_sec, deadline)) |
596 | sleep(1); | ||
598 | } | 597 | } |
599 | } | 598 | } |
600 | } | 599 | } |
@@ -618,10 +617,6 @@ int runsv_main(int argc, char **argv) | |||
618 | update_status(&svd[1]); | 617 | update_status(&svd[1]); |
619 | close(logpipe[1]); | 618 | close(logpipe[1]); |
620 | close(logpipe[0]); | 619 | close(logpipe[0]); |
621 | //if (close(logpipe[1]) == -1) | ||
622 | // warn_cannot("close logpipe[1]"); | ||
623 | //if (close(logpipe[0]) == -1) | ||
624 | // warn_cannot("close logpipe[0]"); | ||
625 | } | 620 | } |
626 | } | 621 | } |
627 | } | 622 | } |