Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/runit/sv.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 228  static int svstatus_get(void) Line 228  static int svstatus_get(void)
228               : failx("runsv not running");               : failx("runsv not running");
229   return 0;   return 0;
230   }   }
231   warn("cannot open supervise/ok");   warn("can't open supervise/ok");
232   return -1;   return -1;
233   }   }
234   close(fd);   close(fd);
235   fd = open_read("supervise/status");   fd = open_read("supervise/status");
236   if (fd == -1) {   if (fd == -1) {
237   warn("cannot open supervise/status");   warn("can't open supervise/status");
238   return -1;   return -1;
239   }   }
240   r = read(fd, &svstatus, 20);   r = read(fd, &svstatus, 20);
# Line 243  static int svstatus_get(void) Line 243  static int svstatus_get(void)
243   case 20:   case 20:
244   break;   break;
245   case -1:   case -1:
246   warn("cannot read supervise/status");   warn("can't read supervise/status");
247   return -1;   return -1;
248   default:   default:
249   errno = 0;   errno = 0;
250   warn("cannot read supervise/status: bad format");   warn("can't read supervise/status: bad format");
251   return -1;   return -1;
252   }   }
253   return 1;   return 1;
# Line 263  static unsigned svstatus_print(const cha Line 263  static unsigned svstatus_print(const cha
263    
264   if (stat("down", &s) == -1) {   if (stat("down", &s) == -1) {
265   if (errno != ENOENT) {   if (errno != ENOENT) {
266   bb_perror_msg(WARN"cannot stat %s/down", *service);   bb_perror_msg(WARN"can't stat %s/down", *service);
267   return 0;   return 0;
268   }   }
269   normallyup = 1;   normallyup = 1;
# Line 297  static int status(const char *unused UNU Line 297  static int status(const char *unused UNU
297  {  {
298   int r;   int r;
299    
300   r = svstatus_get();   if (svstatus_get() <= 0)
301   switch (r) { case -1: case 0: return 0; }   return 0;
302    
303   r = svstatus_print(*service);   r = svstatus_print(*service);
304   if (chdir("log") == -1) {   if (chdir("log") == -1) {
305   if (errno != ENOENT) {   if (errno != ENOENT) {
306   printf("; log: "WARN"cannot change to log service directory: %s",   printf("; log: "WARN"can't change to log service directory: %s",
307   strerror(errno));   strerror(errno));
308   }   }
309   } else if (svstatus_get()) {   } else if (svstatus_get()) {
# Line 322  static int checkscript(void) Line 322  static int checkscript(void)
322    
323   if (stat("check", &s) == -1) {   if (stat("check", &s) == -1) {
324   if (errno == ENOENT) return 1;   if (errno == ENOENT) return 1;
325   bb_perror_msg(WARN"cannot stat %s/check", *service);   bb_perror_msg(WARN"can't stat %s/check", *service);
326   return 0;   return 0;
327   }   }
328   /* if (!(s.st_mode & S_IXUSR)) return 1; */   /* if (!(s.st_mode & S_IXUSR)) return 1; */
# Line 330  static int checkscript(void) Line 330  static int checkscript(void)
330   prog[1] = NULL;   prog[1] = NULL;
331   pid = spawn(prog);   pid = spawn(prog);
332   if (pid <= 0) {   if (pid <= 0) {
333   bb_perror_msg(WARN"cannot %s child %s/check", "run", *service);   bb_perror_msg(WARN"can't %s child %s/check", "run", *service);
334   return 0;   return 0;
335   }   }
336   while (safe_waitpid(pid, &w, 0) == -1) {   while (safe_waitpid(pid, &w, 0) == -1) {
337   bb_perror_msg(WARN"cannot %s child %s/check", "wait for", *service);   bb_perror_msg(WARN"can't %s child %s/check", "wait for", *service);
338   return 0;   return 0;
339   }   }
340   return !wait_exitcode(w);   return WEXITSTATUS(w) == 0;
341  }  }
342    
343  static int check(const char *a)  static int check(const char *a)
344  {  {
345   int r;   int r;
346   unsigned pid;   unsigned pid_le32;
347   uint64_t timestamp;   uint64_t timestamp;
348    
349   r = svstatus_get();   r = svstatus_get();
# Line 354  static int check(const char *a) Line 354  static int check(const char *a)
354   return 1;   return 1;
355   return -1;   return -1;
356   }   }
357   pid = SWAP_LE32(svstatus.pid_le32);   pid_le32 = svstatus.pid_le32;
358   switch (*a) {   switch (*a) {
359   case 'x':   case 'x':
360   return 0;   return 0;
361   case 'u':   case 'u':
362   if (!pid || svstatus.run_or_finish != 1) return 0;   if (!pid_le32 || svstatus.run_or_finish != 1) return 0;
363   if (!checkscript()) return 0;   if (!checkscript()) return 0;
364   break;   break;
365   case 'd':   case 'd':
366   if (pid) return 0;   if (pid_le32) return 0;
367   break;   break;
368   case 'c':   case 'c':
369   if (pid && !checkscript()) return 0;   if (pid_le32 && !checkscript()) return 0;
370   break;   break;
371   case 't':   case 't':
372   if (!pid && svstatus.want == 'd') break;   if (!pid_le32 && svstatus.want == 'd') break;
373   timestamp = SWAP_BE64(svstatus.time_be64);   timestamp = SWAP_BE64(svstatus.time_be64);
374   if ((tstart > timestamp) || !pid || svstatus.got_term || !checkscript())   if ((tstart > timestamp) || !pid_le32 || svstatus.got_term || !checkscript())
375   return 0;   return 0;
376   break;   break;
377   case 'o':   case 'o':
378   timestamp = SWAP_BE64(svstatus.time_be64);   timestamp = SWAP_BE64(svstatus.time_be64);
379   if ((!pid && tstart > timestamp) || (pid && svstatus.want != 'd'))   if ((!pid_le32 && tstart > timestamp) || (pid_le32 && svstatus.want != 'd'))
380   return 0;   return 0;
381   }   }
382   printf(OK);   printf(OK);
# Line 387  static int check(const char *a) Line 387  static int check(const char *a)
387    
388  static int control(const char *a)  static int control(const char *a)
389  {  {
390   int fd, r;   int fd, r, l;
391    
392    /* Is it an optimization?
393       It causes problems with "sv o SRV; ...; sv d SRV"
394       ('d' is not passed to SRV because its .want == 'd'):
395   if (svstatus_get() <= 0)   if (svstatus_get() <= 0)
396   return -1;   return -1;
397   if (svstatus.want == *a)   if (svstatus.want == *a)
398   return 0;   return 0;
399    */
400   fd = open_write("supervise/control");   fd = open_write("supervise/control");
401   if (fd == -1) {   if (fd == -1) {
402   if (errno != ENODEV)   if (errno != ENODEV)
403   warn("cannot open supervise/control");   warn("can't open supervise/control");
404   else   else
405   *a == 'x' ? ok("runsv not running") : failx("runsv not running");   *a == 'x' ? ok("runsv not running") : failx("runsv not running");
406   return -1;   return -1;
407   }   }
408   r = write(fd, a, strlen(a));   l = strlen(a);
409     r = write(fd, a, l);
410   close(fd);   close(fd);
411   if (r != strlen(a)) {   if (r != l) {
412   warn("cannot write to supervise/control");   warn("can't write to supervise/control");
413   return -1;   return -1;
414   }   }
415   return 1;   return 1;
416  }  }
417    
418  int sv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;  int sv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
419  int sv_main(int argc, char **argv)  int sv_main(int argc UNUSED_PARAM, char **argv)
420  {  {
421   unsigned opt;   unsigned opt;
  unsigned i, want_exit;  
422   char *x;   char *x;
423   char *action;   char *action;
424   const char *varservice = CONFIG_SV_DEFAULT_SERVICE_DIR;   const char *varservice = CONFIG_SV_DEFAULT_SERVICE_DIR;
  unsigned services;  
  char **servicex;  
425   unsigned waitsec = 7;   unsigned waitsec = 7;
426   smallint kll = 0;   smallint kll = 0;
427   int verbose = 0;   int verbose = 0;
# Line 438  int sv_main(int argc, char **argv) Line 440  int sv_main(int argc, char **argv)
440    
441   opt_complementary = "w+:vv"; /* -w N, -v is a counter */   opt_complementary = "w+:vv"; /* -w N, -v is a counter */
442   opt = getopt32(argv, "w:v", &waitsec, &verbose);   opt = getopt32(argv, "w:v", &waitsec, &verbose);
  argc -= optind;  
443   argv += optind;   argv += optind;
444   action = *argv++;   action = *argv++;
445   if (!action || !*argv) bb_show_usage();   if (!action || !*argv) bb_show_usage();
  service = argv;  
  services = argc - 1;  
446    
447   tnow = time(0) + 0x400000000000000aULL;   tnow = time(NULL) + 0x400000000000000aULL;
448   tstart = tnow;   tstart = tnow;
449   curdir = open_read(".");   curdir = open_read(".");
450   if (curdir == -1)   if (curdir == -1)
# Line 534  int sv_main(int argc, char **argv) Line 533  int sv_main(int argc, char **argv)
533   bb_show_usage();   bb_show_usage();
534   }   }
535    
536   servicex = service;   service = argv;
537   for (i = 0; i < services; ++i) {   while ((x = *service) != NULL) {
538   if ((**service != '/') && (**service != '.')) {   if (x[0] != '/' && x[0] != '.') {
539   if (chdir(varservice) == -1)   if (chdir(varservice) == -1)
540   goto chdir_failed_0;   goto chdir_failed_0;
541   }   }
542   if (chdir(*service) == -1) {   if (chdir(x) == -1) {
543   chdir_failed_0:   chdir_failed_0:
544   fail("cannot change to service directory");   fail("can't change to service directory");
545   goto nullify_service_0;   goto nullify_service_0;
546   }   }
547   if (act && (act(acts) == -1)) {   if (act && (act(acts) == -1)) {
548   nullify_service_0:   nullify_service_0:
549   *service = NULL;   *service = (char*) -1L; /* "dead" */
550   }   }
551   if (fchdir(curdir) == -1)   if (fchdir(curdir) == -1)
552   fatal_cannot("change to original directory");   fatal_cannot("change to original directory");
# Line 555  int sv_main(int argc, char **argv) Line 554  int sv_main(int argc, char **argv)
554   }   }
555    
556   if (cbk) while (1) {   if (cbk) while (1) {
557     int want_exit;
558   int diff;   int diff;
559    
560   diff = tnow - tstart;   diff = tnow - tstart;
561   service = servicex;   service = argv;
562   want_exit = 1;   want_exit = 1;
563   for (i = 0; i < services; ++i, ++service) {   while ((x = *service) != NULL) {
564   if (!*service)   if (x == (char*) -1L) /* "dead" */
565   continue;   goto next;
566   if ((**service != '/') && (**service != '.')) {   if (x[0] != '/' && x[0] != '.') {
567   if (chdir(varservice) == -1)   if (chdir(varservice) == -1)
568   goto chdir_failed;   goto chdir_failed;
569   }   }
570   if (chdir(*service) == -1) {   if (chdir(x) == -1) {
571   chdir_failed:   chdir_failed:
572   fail("cannot change to service directory");   fail("can't change to service directory");
573   goto nullify_service;   goto nullify_service;
574   }   }
575   if (cbk(acts) != 0)   if (cbk(acts) != 0)
# Line 578  int sv_main(int argc, char **argv) Line 578  int sv_main(int argc, char **argv)
578   if (diff >= waitsec) {   if (diff >= waitsec) {
579   printf(kll ? "kill: " : "timeout: ");   printf(kll ? "kill: " : "timeout: ");
580   if (svstatus_get() > 0) {   if (svstatus_get() > 0) {
581   svstatus_print(*service);   svstatus_print(x);
582   ++rc;   ++rc;
583   }   }
584   bb_putchar('\n'); /* will also flush the output */   bb_putchar('\n'); /* will also flush the output */
585   if (kll)   if (kll)
586   control("k");   control("k");
587   nullify_service:   nullify_service:
588   *service = NULL;   *service = (char*) -1L; /* "dead" */
589   }   }
590   if (fchdir(curdir) == -1)   if (fchdir(curdir) == -1)
591   fatal_cannot("change to original directory");   fatal_cannot("change to original directory");
592     next:
593     service++;
594   }   }
595   if (want_exit) break;   if (want_exit) break;
596   usleep(420000);   usleep(420000);
597   tnow = time(0) + 0x400000000000000aULL;   tnow = time(NULL) + 0x400000000000000aULL;
598   }   }
599   return rc > 99 ? 99 : rc;   return rc > 99 ? 99 : rc;
600  }  }

Legend:
Removed from v.983  
changed lines
  Added in v.984