Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/runit/runsvdir.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/runit/runsvdir.c
r3232 r3621 27 27 28 28 /* Busyboxed by Denys Vlasenko <vda.linux@googlemail.com> */ 29 /* TODO: depends on runit_lib.c - review and reduce/eliminate */ 29 30 //config:config RUNSVDIR 31 //config: bool "runsvdir" 32 //config: default y 33 //config: help 34 //config: runsvdir starts a runsv process for each subdirectory, or symlink to 35 //config: a directory, in the services directory dir, up to a limit of 1000 36 //config: subdirectories, and restarts a runsv process if it terminates. 37 //config: 38 //config:config FEATURE_RUNSVDIR_LOG 39 //config: bool "Enable scrolling argument log" 40 //config: depends on RUNSVDIR 41 //config: default n 42 //config: help 43 //config: Enable feature where second parameter of runsvdir holds last error 44 //config: message (viewable via top/ps). Otherwise (feature is off 45 //config: or no parameter), error messages go to stderr only. 46 47 //applet:IF_RUNSVDIR(APPLET(runsvdir, BB_DIR_USR_BIN, BB_SUID_DROP)) 48 49 //kbuild:lib-$(CONFIG_RUNSVDIR) += runsvdir.o 30 50 31 51 //usage:#define runsvdir_trivial_usage … … 36 56 //usage: "\n -s SCRIPT Run SCRIPT <signo> after signal is processed" 37 57 38 #include <sys/poll.h>39 58 #include <sys/file.h> 40 59 #include "libbb.h" 60 #include "common_bufsiz.h" 41 61 #include "runit_lib.h" 42 62 … … 61 81 #if ENABLE_FEATURE_RUNSVDIR_LOG 62 82 char *rplog; 63 int rploglen;64 83 struct fd_pair logpipe; 65 84 struct pollfd pfd[1]; … … 67 86 #endif 68 87 } FIX_ALIASING; 69 #define G (*(struct globals*) &bb_common_bufsiz1)88 #define G (*(struct globals*)bb_common_bufsiz1) 70 89 #define sv (G.sv ) 71 90 #define svdir (G.svdir ) 72 91 #define svnum (G.svnum ) 73 92 #define rplog (G.rplog ) 74 #define rploglen (G.rploglen )75 93 #define logpipe (G.logpipe ) 76 94 #define pfd (G.pfd ) 77 95 #define stamplog (G.stamplog ) 78 #define INIT_G() do { } while (0)96 #define INIT_G() do { setup_common_bufsiz(); } while (0) 79 97 80 98 static void fatal2_cannot(const char *m1, const char *m2) … … 221 239 dev_t last_dev = last_dev; /* for gcc */ 222 240 ino_t last_ino = last_ino; /* for gcc */ 223 time_t last_mtime = 0; 224 int wstat; 241 time_t last_mtime; 225 242 int curdir; 226 pid_t pid;227 unsigned deadline;228 unsigned now;229 243 unsigned stampcheck; 230 244 int i; 231 int need_rescan = 1; 245 int need_rescan; 246 bool i_am_init; 232 247 char *opt_s_argv[3]; 233 248 … … 240 255 argv += optind; 241 256 257 i_am_init = (getpid() == 1); 242 258 bb_signals(0 243 259 | (1 << SIGTERM) 244 260 | (1 << SIGHUP) 245 261 /* For busybox's init, SIGTERM == reboot, 246 * SIGUSR1 == halt 247 * SIGUSR2 == poweroff 248 * so we need to intercept SIGUSRn too. 262 * SIGUSR1 == halt, 263 * SIGUSR2 == poweroff, 264 * Ctlr-ALt-Del sends SIGINT to init, 265 * so we need to intercept SIGUSRn and SIGINT too. 249 266 * Note that we do not implement actual reboot 250 267 * (killall(TERM) + umount, etc), we just pause 251 268 * respawing and avoid exiting (-> making kernel oops). 252 * The user is responsible for the rest. */ 253 | (getpid() == 1 ? ((1 << SIGUSR1) | (1 << SIGUSR2)) : 0) 269 * The user is responsible for the rest. 270 */ 271 | (i_am_init ? ((1 << SIGUSR1) | (1 << SIGUSR2) | (1 << SIGINT)) : 0) 254 272 , record_signo); 255 273 svdir = *argv++; … … 259 277 if (*argv) { 260 278 rplog = *argv; 261 rploglen = strlen(rplog); 262 if (rploglen < 7) { 279 if (strlen(rplog) < 7) { 263 280 warnx("log must have at least seven characters"); 264 281 } else if (piped_pair(logpipe)) { … … 289 306 290 307 stampcheck = monotonic_sec(); 308 need_rescan = 1; 309 last_mtime = 0; 291 310 292 311 for (;;) { 312 unsigned now; 313 unsigned sig; 314 293 315 /* collect children */ 294 316 for (;;) { 295 pid = wait_any_nohang(&wstat);317 pid_t pid = wait_any_nohang(NULL); 296 318 if (pid <= 0) 297 319 break; … … 347 369 pfd[0].revents = 0; 348 370 #endif 349 deadline = (need_rescan ? 1 : 5);350 sig_block(SIGCHLD);351 #if ENABLE_FEATURE_RUNSVDIR_LOG 352 if (rplog)353 poll(pfd, 1, deadline*1000);354 else355 #endif 356 sleep(deadline);357 sig_unblock(SIGCHLD);371 { 372 unsigned deadline = (need_rescan ? 1 : 5); 373 #if ENABLE_FEATURE_RUNSVDIR_LOG 374 if (rplog) 375 poll(pfd, 1, deadline*1000); 376 else 377 #endif 378 sleep(deadline); 379 } 358 380 359 381 #if ENABLE_FEATURE_RUNSVDIR_LOG … … 363 385 if (ch < ' ') 364 386 ch = ' '; 365 for (i = 6; i < rploglen; i++)387 for (i = 6; rplog[i] != '\0'; i++) 366 388 rplog[i-1] = rplog[i]; 367 rplog[rploglen-1] = ch; 368 } 369 } 370 #endif 371 if (!bb_got_signal) 389 rplog[i-1] = ch; 390 } 391 } 392 #endif 393 sig = bb_got_signal; 394 if (!sig) 372 395 continue; 396 bb_got_signal = 0; 373 397 374 398 /* -s SCRIPT: useful if we are init. … … 376 400 * it halts/powers off/reboots the system. */ 377 401 if (opt_s_argv[0]) { 402 pid_t pid; 403 378 404 /* Single parameter: signal# */ 379 opt_s_argv[1] = utoa( bb_got_signal);405 opt_s_argv[1] = utoa(sig); 380 406 pid = spawn(opt_s_argv); 381 407 if (pid > 0) { … … 387 413 } 388 414 389 if ( bb_got_signal== SIGHUP) {415 if (sig == SIGHUP) { 390 416 for (i = 0; i < svnum; i++) 391 417 if (sv[i].pid) … … 394 420 /* SIGHUP or SIGTERM (or SIGUSRn if we are init) */ 395 421 /* Exit unless we are init */ 396 if ( getpid() != 1)397 return (SIGHUP == bb_got_signal) ? 111 : EXIT_SUCCESS;422 if (!i_am_init) 423 return (SIGHUP == sig) ? 111 : EXIT_SUCCESS; 398 424 399 425 /* init continues to monitor services forever */ 400 bb_got_signal = 0;401 426 } /* for (;;) */ 402 427 }
Note:
See TracChangeset
for help on using the changeset viewer.