aboutsummaryrefslogtreecommitdiff
path: root/runit/runsv.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-08-20 17:27:40 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-08-20 17:27:40 +0000
commit45946f8b513d9c292613ac08c3ddf4a89b915752 (patch)
treed6ea51887431e4261a114b95989950d1973d3227 /runit/runsv.c
parent63db27f9f4c0ec8b9abe3c32c8d699be0781ffd6 (diff)
downloadbusybox-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.c151
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};
62static struct svdir svd[2];
63 62
63static struct svdir svd[2];
64static smallint sigterm; 64static smallint sigterm;
65static smallint haslog; 65static smallint haslog;
66static smallint pidchanged = 1; 66static smallint pidchanged = 1;
67static int logpipe[2]; 67static int logpipe[2];
68static char *dir; 68static char *dir;
69 69
70#define usage() bb_show_usage()
71
72static void fatal2_cannot(const char *m1, const char *m2) 70static 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}
91static void warnx_cannot(const char *m)
92{
93 bb_error_msg("%s: warning: cannot %s", dir, m);
94}
95 89
96static void s_child(int sig_no) 90static 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>
132static void gettimeofday_ns(struct timespec *ts)
133{
134 syscall(__NR_clock_gettime, CLOCK_REALTIME, ts);
135}
136
135static void update_status(struct svdir *s) 137static 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 }