aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Byrne <james.byrne at origamienergy.com>2017-05-15 21:39:51 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-05-15 21:40:18 +0200
commit0c63299b84513ff995413f820cb5f3d546c0c5d7 (patch)
tree97da88d8a741ce485ecf0e767c030296135e817f
parentbcb5764822b07f2f1f6a5db355566ac1da70ac5b (diff)
downloadbusybox-w32-0c63299b84513ff995413f820cb5f3d546c0c5d7.tar.gz
busybox-w32-0c63299b84513ff995413f820cb5f3d546c0c5d7.tar.bz2
busybox-w32-0c63299b84513ff995413f820cb5f3d546c0c5d7.zip
sv: update to match version 2.1.2 of runit
Backport from upstream versions: 2.1.2 Sun, 10 Aug 2014 18:01:54 +0000 * sv.c: properly format status command's output on failure cases. * sv.c: support optional LSB init script actions reload and try-restart. * sv.c: fix typo that may lead to wrong output from sv when reporting status of multiple service directories. 2.1.1 Sun, 04 Oct 2009 20:28:38 +0000 * sv.c: on 'down', send runsv the 'down' command properly if not yet done (e.g. when taken up with 'once'). [Remove previous workaround added to BusyBox version]. 1.9.0 Mon, 05 May 2008 22:00:13 +0000 * sv.c: service name is also relative to the current directory if it ends with a slash. 1.8.0 Fri, 21 Sep 2007 00:33:56 +0000 * sv.c: fix race on check for down if pid is 0 and state is run or finish. 1.7.1 Sat, 04 Nov 2006 19:23:29 +0000 * sv.c: properly wait for a service to be restarted on 'restart'; support checks through -v for pause, cont, kill. function old new delta sv 1184 1280 +96 control 132 180 +48 status 118 139 +21 out 64 85 +21 svstatus_print 334 344 +10 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/0 up/down: 196/0) Total: 196 bytes Signed-off-by: James Byrne <james.byrne at origamienergy.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--runit/sv.c163
1 files changed, 98 insertions, 65 deletions
diff --git a/runit/sv.c b/runit/sv.c
index 64f1ae395..faa31d4fa 100644
--- a/runit/sv.c
+++ b/runit/sv.c
@@ -25,7 +25,7 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/ 26*/
27 27
28/* Taken from http://smarden.sunsite.dk/runit/sv.8.html: 28/* Taken from http://smarden.org/runit/sv.8.html:
29 29
30sv - control and manage services monitored by runsv 30sv - control and manage services monitored by runsv
31 31
@@ -36,17 +36,13 @@ The sv program reports the current status and controls the state of services
36monitored by the runsv(8) supervisor. 36monitored by the runsv(8) supervisor.
37 37
38services consists of one or more arguments, each argument naming a directory 38services consists of one or more arguments, each argument naming a directory
39service used by runsv(8). If service doesn't start with a dot or slash, 39service used by runsv(8). If service doesn't start with a dot or slash and
40it is searched in the default services directory /var/service/, otherwise 40doesn't end with a slash, it is searched in the default services directory
41relative to the current directory. 41/var/service/, otherwise relative to the current directory.
42 42
43command is one of up, down, status, once, pause, cont, hup, alarm, interrupt, 43command is one of up, down, status, once, pause, cont, hup, alarm, interrupt,
441, 2, term, kill, or exit, or start, stop, restart, shutdown, force-stop, 441, 2, term, kill, or exit, or start, stop, reload, restart, shutdown,
45force-reload, force-restart, force-shutdown. 45force-stop, force-reload, force-restart, force-shutdown, try-restart.
46
47The sv program can be sym-linked to /etc/init.d/ to provide an LSB init
48script interface. The service to be controlled then is specified by the
49base name of the "init script".
50 46
51status 47status
52 Report the current status of the service, and the appendant log service 48 Report the current status of the service, and the appendant log service
@@ -66,9 +62,9 @@ exit
66 If the service is running, send it the TERM signal, and the CONT signal. 62 If the service is running, send it the TERM signal, and the CONT signal.
67 Do not restart the service. If the service is down, and no log service 63 Do not restart the service. If the service is down, and no log service
68 exists, runsv(8) exits. If the service is down and a log service exists, 64 exists, runsv(8) exits. If the service is down and a log service exists,
69 send the TERM signal to the log service. If the log service is down, 65 runsv(8) closes the standard input of the log service and waits for it to
70 runsv(8) exits. This command is ignored if it is given to an appendant 66 terminate. If the log service is down, runsv(8) exits. This command is
71 log service. 67 ignored if it is given to an appendant log service.
72 68
73sv actually looks only at the first character of above commands. 69sv actually looks only at the first character of above commands.
74 70
@@ -85,6 +81,8 @@ start
85stop 81stop
86 Same as down, but wait up to 7 seconds for the service to become down. 82 Same as down, but wait up to 7 seconds for the service to become down.
87 Then report the status or timeout. 83 Then report the status or timeout.
84reload
85 Same as hup, and additionally report the status afterwards.
88restart 86restart
89 Send the commands term, cont, and up to the service, and wait up to 87 Send the commands term, cont, and up to the service, and wait up to
90 7 seconds for the service to restart. Then report the status or timeout. 88 7 seconds for the service to restart. Then report the status or timeout.
@@ -112,6 +110,9 @@ force-shutdown
112 Same as exit, but wait up to 7 seconds for the runsv(8) process to 110 Same as exit, but wait up to 7 seconds for the runsv(8) process to
113 terminate. Then report the status, and on timeout send the service 111 terminate. Then report the status, and on timeout send the service
114 the kill command. 112 the kill command.
113try-restart
114 if the service is running, send it the term and cont commands, and wait up to
115 7 seconds for the service to restart. Then report the status or timeout.
115 116
116Additional Commands 117Additional Commands
117 118
@@ -126,8 +127,8 @@ check
126Options 127Options
127 128
128-v 129-v
129 wait up to 7 seconds for the command to take effect. 130 If the command is up, down, term, once, cont, or exit, then wait up to 7
130 Then report the status or timeout. 131 seconds for the command to take effect. Then report the status or timeout.
131-w sec 132-w sec
132 Override the default timeout of 7 seconds with sec seconds. Implies -v. 133 Override the default timeout of 7 seconds with sec seconds. Implies -v.
133 134
@@ -192,6 +193,7 @@ struct globals {
192/* "Bernstein" time format: unix + 0x400000000000000aULL */ 193/* "Bernstein" time format: unix + 0x400000000000000aULL */
193 uint64_t tstart, tnow; 194 uint64_t tstart, tnow;
194 svstatus_t svstatus; 195 svstatus_t svstatus;
196 unsigned islog;
195} FIX_ALIASING; 197} FIX_ALIASING;
196#define G (*(struct globals*)bb_common_bufsiz1) 198#define G (*(struct globals*)bb_common_bufsiz1)
197#define acts (G.acts ) 199#define acts (G.acts )
@@ -200,6 +202,7 @@ struct globals {
200#define tstart (G.tstart ) 202#define tstart (G.tstart )
201#define tnow (G.tnow ) 203#define tnow (G.tnow )
202#define svstatus (G.svstatus ) 204#define svstatus (G.svstatus )
205#define islog (G.islog )
203#define INIT_G() do { setup_common_bufsiz(); } while (0) 206#define INIT_G() do { setup_common_bufsiz(); } while (0)
204 207
205 208
@@ -215,7 +218,7 @@ static void fatal_cannot(const char *m1)
215 218
216static void out(const char *p, const char *m1) 219static void out(const char *p, const char *m1)
217{ 220{
218 printf("%s%s: %s", p, *service, m1); 221 printf("%s%s%s: %s", p, *service, islog ? "/log" : "", m1);
219 if (errno) { 222 if (errno) {
220 printf(": %s", strerror(errno)); 223 printf(": %s", strerror(errno));
221 } 224 }
@@ -300,15 +303,14 @@ static unsigned svstatus_print(const char *m)
300 } 303 }
301 pid = SWAP_LE32(svstatus.pid_le32); 304 pid = SWAP_LE32(svstatus.pid_le32);
302 timestamp = SWAP_BE64(svstatus.time_be64); 305 timestamp = SWAP_BE64(svstatus.time_be64);
303 if (pid) { 306 switch (svstatus.run_or_finish) {
304 switch (svstatus.run_or_finish) { 307 case 0: printf("down: "); break;
305 case 1: printf("run: "); break; 308 case 1: printf("run: "); break;
306 case 2: printf("finish: "); break; 309 case 2: printf("finish: "); break;
307 }
308 printf("%s: (pid %d) ", m, pid);
309 } else {
310 printf("down: %s: ", m);
311 } 310 }
311 printf("%s: ", m);
312 if (svstatus.run_or_finish)
313 printf("(pid %d) ", pid);
312 diff = tnow - timestamp; 314 diff = tnow - timestamp;
313 printf("%us", (diff < 0 ? 0 : diff)); 315 printf("%us", (diff < 0 ? 0 : diff));
314 if (pid) { 316 if (pid) {
@@ -331,16 +333,21 @@ static int status(const char *unused UNUSED_PARAM)
331 return 0; 333 return 0;
332 334
333 r = svstatus_print(*service); 335 r = svstatus_print(*service);
336 islog = 1;
334 if (chdir("log") == -1) { 337 if (chdir("log") == -1) {
335 if (errno != ENOENT) { 338 if (errno != ENOENT) {
336 printf("; log: "WARN"can't change to log service directory: %s", 339 printf("; ");
337 strerror(errno)); 340 warn("can't change directory");
338 } 341 } else
339 } else if (svstatus_get()) { 342 bb_putchar('\n');
343 } else {
340 printf("; "); 344 printf("; ");
341 svstatus_print("log"); 345 if (svstatus_get()) {
346 r = svstatus_print("log");
347 bb_putchar('\n');
348 }
342 } 349 }
343 bb_putchar('\n'); /* will also flush the output */ 350 islog = 0;
344 return r; 351 return r;
345} 352}
346 353
@@ -379,35 +386,53 @@ static int check(const char *a)
379 r = svstatus_get(); 386 r = svstatus_get();
380 if (r == -1) 387 if (r == -1)
381 return -1; 388 return -1;
382 if (r == 0) { 389 while (*a) {
383 if (*a == 'x') 390 if (r == 0) {
384 return 1; 391 if (*a == 'x')
385 return -1; 392 return 1;
386 } 393 return -1;
387 pid_le32 = svstatus.pid_le32; 394 }
388 switch (*a) { 395 pid_le32 = svstatus.pid_le32;
389 case 'x': 396 switch (*a) {
390 return 0; 397 case 'x':
391 case 'u':
392 if (!pid_le32 || svstatus.run_or_finish != 1) return 0;
393 if (!checkscript()) return 0;
394 break;
395 case 'd':
396 if (pid_le32) return 0;
397 break;
398 case 'c':
399 if (pid_le32 && !checkscript()) return 0;
400 break;
401 case 't':
402 if (!pid_le32 && svstatus.want == 'd') break;
403 timestamp = SWAP_BE64(svstatus.time_be64);
404 if ((tstart > timestamp) || !pid_le32 || svstatus.got_term || !checkscript())
405 return 0;
406 break;
407 case 'o':
408 timestamp = SWAP_BE64(svstatus.time_be64);
409 if ((!pid_le32 && tstart > timestamp) || (pid_le32 && svstatus.want != 'd'))
410 return 0; 398 return 0;
399 case 'u':
400 if (!pid_le32 || svstatus.run_or_finish != 1)
401 return 0;
402 if (!checkscript())
403 return 0;
404 break;
405 case 'd':
406 if (pid_le32 || svstatus.run_or_finish != 0)
407 return 0;
408 break;
409 case 'C':
410 if (pid_le32 && !checkscript())
411 return 0;
412 break;
413 case 't':
414 case 'k':
415 if (!pid_le32 && svstatus.want == 'd')
416 break;
417 timestamp = SWAP_BE64(svstatus.time_be64);
418 if ((tstart > timestamp) || !pid_le32 || svstatus.got_term || !checkscript())
419 return 0;
420 break;
421 case 'o':
422 timestamp = SWAP_BE64(svstatus.time_be64);
423 if ((!pid_le32 && tstart > timestamp) || (pid_le32 && svstatus.want != 'd'))
424 return 0;
425 break;
426 case 'p':
427 if (pid_le32 && !svstatus.paused)
428 return 0;
429 break;
430 case 'c':
431 if (pid_le32 && svstatus.paused)
432 return 0;
433 break;
434 }
435 ++a;
411 } 436 }
412 printf(OK); 437 printf(OK);
413 svstatus_print(*service); 438 svstatus_print(*service);
@@ -419,14 +444,10 @@ static int control(const char *a)
419{ 444{
420 int fd, r, l; 445 int fd, r, l;
421 446
422/* Is it an optimization?
423 It causes problems with "sv o SRV; ...; sv d SRV"
424 ('d' is not passed to SRV because its .want == 'd'):
425 if (svstatus_get() <= 0) 447 if (svstatus_get() <= 0)
426 return -1; 448 return -1;
427 if (svstatus.want == *a) 449 if (svstatus.want == *a && (*a != 'd' || svstatus.got_term == 1))
428 return 0; 450 return 0;
429*/
430 fd = open("supervise/control", O_WRONLY|O_NDELAY); 451 fd = open("supervise/control", O_WRONLY|O_NDELAY);
431 if (fd == -1) { 452 if (fd == -1) {
432 if (errno != ENODEV) 453 if (errno != ENODEV)
@@ -516,17 +537,23 @@ static int sv(char **argv)
516 acts = "tc"; 537 acts = "tc";
517 kll = 1; 538 kll = 1;
518 break; 539 break;
540 case 't':
541 if (str_equal(action, "try-restart")) {
542 acts = "tc";
543 break;
544 }
519 case 'c': 545 case 'c':
520 if (str_equal(action, "check")) { 546 if (str_equal(action, "check")) {
521 act = NULL; 547 act = NULL;
522 acts = "c"; 548 acts = "C";
523 break; 549 break;
524 } 550 }
525 case 'u': case 'd': case 'o': case 't': case 'p': case 'h': 551 case 'u': case 'd': case 'o': case 'p': case 'h':
526 case 'a': case 'i': case 'k': case 'q': case '1': case '2': 552 case 'a': case 'i': case 'k': case 'q': case '1': case '2':
527 action[1] = '\0'; 553 action[1] = '\0';
528 acts = action; 554 acts = action;
529 if (!verbose) cbk = NULL; 555 if (!verbose)
556 cbk = NULL;
530 break; 557 break;
531 case 's': 558 case 's':
532 if (str_equal(action, "shutdown")) { 559 if (str_equal(action, "shutdown")) {
@@ -550,6 +577,10 @@ static int sv(char **argv)
550 acts = "tcu"; 577 acts = "tcu";
551 break; 578 break;
552 } 579 }
580 if (str_equal(action, "reload")) {
581 acts = "h";
582 break;
583 }
553 bb_show_usage(); 584 bb_show_usage();
554 case 'f': 585 case 'f':
555 if (str_equal(action, "force-reload")) { 586 if (str_equal(action, "force-reload")) {
@@ -578,7 +609,9 @@ static int sv(char **argv)
578 609
579 service = argv; 610 service = argv;
580 while ((x = *service) != NULL) { 611 while ((x = *service) != NULL) {
581 if (x[0] != '/' && x[0] != '.') { 612 if (x[0] != '/' && x[0] != '.'
613 && x[0] != '\0' && x[strlen(x) - 1] != '/'
614 ) {
582 if (chdir(varservice) == -1) 615 if (chdir(varservice) == -1)
583 goto chdir_failed_0; 616 goto chdir_failed_0;
584 } 617 }