diff options
author | Ron Yorston <rmy@pobox.com> | 2012-03-23 12:12:03 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-03-23 12:12:03 +0000 |
commit | b0f54743e36af163ae2530c381c485bb29df13dc (patch) | |
tree | cda4cfeaae6e47fe4f14c1b566092be4da9affc4 /init | |
parent | 40514a0309939f2446f0d4ed9600cad5de396e7f (diff) | |
parent | ba88826c66411affc1da3614742b454654f7298a (diff) | |
download | busybox-w32-b0f54743e36af163ae2530c381c485bb29df13dc.tar.gz busybox-w32-b0f54743e36af163ae2530c381c485bb29df13dc.tar.bz2 busybox-w32-b0f54743e36af163ae2530c381c485bb29df13dc.zip |
Merge branch 'busybox' into merge
Conflicts:
Makefile.flags
Diffstat (limited to 'init')
-rw-r--r-- | init/bootchartd.c | 41 | ||||
-rw-r--r-- | init/init.c | 68 |
2 files changed, 87 insertions, 22 deletions
diff --git a/init/bootchartd.c b/init/bootchartd.c index 5f6121fa4..9fd623357 100644 --- a/init/bootchartd.c +++ b/init/bootchartd.c | |||
@@ -208,14 +208,8 @@ static char *make_tempdir(void) | |||
208 | return tempdir; | 208 | return tempdir; |
209 | } | 209 | } |
210 | 210 | ||
211 | static void do_logging(unsigned sample_period_us) | 211 | static void do_logging(unsigned sample_period_us, int process_accounting) |
212 | { | 212 | { |
213 | //# Enable process accounting if configured | ||
214 | //if [ "$PROCESS_ACCOUNTING" = "yes" ]; then | ||
215 | // [ -e kernel_pacct ] || : > kernel_pacct | ||
216 | // accton kernel_pacct | ||
217 | //fi | ||
218 | |||
219 | FILE *proc_stat = xfopen("proc_stat.log", "w"); | 213 | FILE *proc_stat = xfopen("proc_stat.log", "w"); |
220 | FILE *proc_diskstats = xfopen("proc_diskstats.log", "w"); | 214 | FILE *proc_diskstats = xfopen("proc_diskstats.log", "w"); |
221 | //FILE *proc_netdev = xfopen("proc_netdev.log", "w"); | 215 | //FILE *proc_netdev = xfopen("proc_netdev.log", "w"); |
@@ -223,6 +217,11 @@ static void do_logging(unsigned sample_period_us) | |||
223 | int look_for_login_process = (getppid() == 1); | 217 | int look_for_login_process = (getppid() == 1); |
224 | unsigned count = 60*1000*1000 / sample_period_us; /* ~1 minute */ | 218 | unsigned count = 60*1000*1000 / sample_period_us; /* ~1 minute */ |
225 | 219 | ||
220 | if (process_accounting) { | ||
221 | close(xopen("kernel_pacct", O_WRONLY | O_CREAT | O_TRUNC)); | ||
222 | acct("kernel_pacct"); | ||
223 | } | ||
224 | |||
226 | while (--count && !bb_got_signal) { | 225 | while (--count && !bb_got_signal) { |
227 | char *p; | 226 | char *p; |
228 | int len = open_read_close("/proc/uptime", G.jiffy_line, sizeof(G.jiffy_line)-2); | 227 | int len = open_read_close("/proc/uptime", G.jiffy_line, sizeof(G.jiffy_line)-2); |
@@ -253,11 +252,9 @@ static void do_logging(unsigned sample_period_us) | |||
253 | wait_more: | 252 | wait_more: |
254 | usleep(sample_period_us); | 253 | usleep(sample_period_us); |
255 | } | 254 | } |
256 | |||
257 | // [ -e kernel_pacct ] && accton off | ||
258 | } | 255 | } |
259 | 256 | ||
260 | static void finalize(char *tempdir, const char *prog) | 257 | static void finalize(char *tempdir, const char *prog, int process_accounting) |
261 | { | 258 | { |
262 | //# Stop process accounting if configured | 259 | //# Stop process accounting if configured |
263 | //local pacct= | 260 | //local pacct= |
@@ -265,6 +262,9 @@ static void finalize(char *tempdir, const char *prog) | |||
265 | 262 | ||
266 | FILE *header_fp = xfopen("header", "w"); | 263 | FILE *header_fp = xfopen("header", "w"); |
267 | 264 | ||
265 | if (process_accounting) | ||
266 | acct(NULL); | ||
267 | |||
268 | if (prog) | 268 | if (prog) |
269 | fprintf(header_fp, "profile.process = %s\n", prog); | 269 | fprintf(header_fp, "profile.process = %s\n", prog); |
270 | 270 | ||
@@ -307,7 +307,7 @@ static void finalize(char *tempdir, const char *prog) | |||
307 | fclose(header_fp); | 307 | fclose(header_fp); |
308 | 308 | ||
309 | /* Package log files */ | 309 | /* Package log files */ |
310 | system("tar -zcf /var/log/bootchart.tgz header *.log"); // + $pacct | 310 | system(xasprintf("tar -zcf /var/log/bootlog.tgz header %s *.log", process_accounting ? "kernel_pacct" : "")); |
311 | /* Clean up (if we are not in detached tmpfs) */ | 311 | /* Clean up (if we are not in detached tmpfs) */ |
312 | if (tempdir) { | 312 | if (tempdir) { |
313 | unlink("header"); | 313 | unlink("header"); |
@@ -315,6 +315,8 @@ static void finalize(char *tempdir, const char *prog) | |||
315 | unlink("proc_diskstats.log"); | 315 | unlink("proc_diskstats.log"); |
316 | //unlink("proc_netdev.log"); | 316 | //unlink("proc_netdev.log"); |
317 | unlink("proc_ps.log"); | 317 | unlink("proc_ps.log"); |
318 | if (process_accounting) | ||
319 | unlink("kernel_pacct"); | ||
318 | rmdir(tempdir); | 320 | rmdir(tempdir); |
319 | } | 321 | } |
320 | 322 | ||
@@ -338,6 +340,7 @@ int bootchartd_main(int argc UNUSED_PARAM, char **argv) | |||
338 | unsigned sample_period_us; | 340 | unsigned sample_period_us; |
339 | pid_t parent_pid, logger_pid; | 341 | pid_t parent_pid, logger_pid; |
340 | smallint cmd; | 342 | smallint cmd; |
343 | int process_accounting; | ||
341 | enum { | 344 | enum { |
342 | CMD_STOP = 0, | 345 | CMD_STOP = 0, |
343 | CMD_START, | 346 | CMD_START, |
@@ -371,6 +374,7 @@ int bootchartd_main(int argc UNUSED_PARAM, char **argv) | |||
371 | 374 | ||
372 | /* Read config file: */ | 375 | /* Read config file: */ |
373 | sample_period_us = 200 * 1000; | 376 | sample_period_us = 200 * 1000; |
377 | process_accounting = 0; | ||
374 | if (ENABLE_FEATURE_BOOTCHARTD_CONFIG_FILE) { | 378 | if (ENABLE_FEATURE_BOOTCHARTD_CONFIG_FILE) { |
375 | char* token[2]; | 379 | char* token[2]; |
376 | parser_t *parser = config_open2("/etc/bootchartd.conf" + 5, fopen_for_read); | 380 | parser_t *parser = config_open2("/etc/bootchartd.conf" + 5, fopen_for_read); |
@@ -379,11 +383,16 @@ int bootchartd_main(int argc UNUSED_PARAM, char **argv) | |||
379 | while (config_read(parser, token, 2, 0, "#=", PARSE_NORMAL & ~PARSE_COLLAPSE)) { | 383 | while (config_read(parser, token, 2, 0, "#=", PARSE_NORMAL & ~PARSE_COLLAPSE)) { |
380 | if (strcmp(token[0], "SAMPLE_PERIOD") == 0 && token[1]) | 384 | if (strcmp(token[0], "SAMPLE_PERIOD") == 0 && token[1]) |
381 | sample_period_us = atof(token[1]) * 1000000; | 385 | sample_period_us = atof(token[1]) * 1000000; |
386 | if (strcmp(token[0], "PROCESS_ACCOUNTING") == 0 && token[1] | ||
387 | && (strcmp(token[1], "on") == 0 || strcmp(token[1], "yes") == 0) | ||
388 | ) { | ||
389 | process_accounting = 1; | ||
390 | } | ||
382 | } | 391 | } |
383 | config_close(parser); | 392 | config_close(parser); |
393 | if ((int)sample_period_us <= 0) | ||
394 | sample_period_us = 1; /* prevent division by 0 */ | ||
384 | } | 395 | } |
385 | if ((int)sample_period_us <= 0) | ||
386 | sample_period_us = 1; /* prevent division by 0 */ | ||
387 | 396 | ||
388 | /* Create logger child: */ | 397 | /* Create logger child: */ |
389 | logger_pid = fork_or_rexec(argv); | 398 | logger_pid = fork_or_rexec(argv); |
@@ -411,13 +420,15 @@ int bootchartd_main(int argc UNUSED_PARAM, char **argv) | |||
411 | putenv((char*)bb_PATH_root_path); | 420 | putenv((char*)bb_PATH_root_path); |
412 | 421 | ||
413 | tempdir = make_tempdir(); | 422 | tempdir = make_tempdir(); |
414 | do_logging(sample_period_us); | 423 | do_logging(sample_period_us, process_accounting); |
415 | finalize(tempdir, cmd == CMD_START ? argv[2] : NULL); | 424 | finalize(tempdir, cmd == CMD_START ? argv[2] : NULL, process_accounting); |
416 | return EXIT_SUCCESS; | 425 | return EXIT_SUCCESS; |
417 | } | 426 | } |
418 | 427 | ||
419 | /* parent */ | 428 | /* parent */ |
420 | 429 | ||
430 | USE_FOR_NOMMU(argv[0][0] &= 0x7f); /* undo fork_or_rexec() damage */ | ||
431 | |||
421 | if (DO_SIGNAL_SYNC) { | 432 | if (DO_SIGNAL_SYNC) { |
422 | /* Wait for logger child to set handlers, then unpause it. | 433 | /* Wait for logger child to set handlers, then unpause it. |
423 | * Otherwise with short-lived PROG (e.g. "bootchartd start true") | 434 | * Otherwise with short-lived PROG (e.g. "bootchartd start true") |
diff --git a/init/init.c b/init/init.c index 645f694c0..724894698 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -108,6 +108,8 @@ | |||
108 | //config: Note that on Linux, init attempts to detect serial terminal and | 108 | //config: Note that on Linux, init attempts to detect serial terminal and |
109 | //config: sets TERM to "vt102" if one is found. | 109 | //config: sets TERM to "vt102" if one is found. |
110 | 110 | ||
111 | #define DEBUG_SEGV_HANDLER 0 | ||
112 | |||
111 | #include "libbb.h" | 113 | #include "libbb.h" |
112 | #include <syslog.h> | 114 | #include <syslog.h> |
113 | #include <paths.h> | 115 | #include <paths.h> |
@@ -118,6 +120,15 @@ | |||
118 | #endif | 120 | #endif |
119 | #include "reboot.h" /* reboot() constants */ | 121 | #include "reboot.h" /* reboot() constants */ |
120 | 122 | ||
123 | #if DEBUG_SEGV_HANDLER | ||
124 | # undef _GNU_SOURCE | ||
125 | # define _GNU_SOURCE 1 | ||
126 | # undef __USE_GNU | ||
127 | # define __USE_GNU 1 | ||
128 | # include <execinfo.h> | ||
129 | # include <sys/ucontext.h> | ||
130 | #endif | ||
131 | |||
121 | /* Used only for sanitizing purposes in set_sane_term() below. On systems where | 132 | /* Used only for sanitizing purposes in set_sane_term() below. On systems where |
122 | * the baud rate is stored in a separate field, we can safely disable them. */ | 133 | * the baud rate is stored in a separate field, we can safely disable them. */ |
123 | #ifndef CBAUD | 134 | #ifndef CBAUD |
@@ -523,15 +534,17 @@ static struct init_action *mark_terminated(pid_t pid) | |||
523 | struct init_action *a; | 534 | struct init_action *a; |
524 | 535 | ||
525 | if (pid > 0) { | 536 | if (pid > 0) { |
537 | update_utmp(pid, DEAD_PROCESS, | ||
538 | /*tty_name:*/ NULL, | ||
539 | /*username:*/ NULL, | ||
540 | /*hostname:*/ NULL | ||
541 | ); | ||
526 | for (a = init_action_list; a; a = a->next) { | 542 | for (a = init_action_list; a; a = a->next) { |
527 | if (a->pid == pid) { | 543 | if (a->pid == pid) { |
528 | a->pid = 0; | 544 | a->pid = 0; |
529 | return a; | 545 | return a; |
530 | } | 546 | } |
531 | } | 547 | } |
532 | update_utmp(pid, DEAD_PROCESS, /*tty_name:*/ NULL, | ||
533 | /*username:*/ NULL, | ||
534 | /*hostname:*/ NULL); | ||
535 | } | 548 | } |
536 | return NULL; | 549 | return NULL; |
537 | } | 550 | } |
@@ -596,7 +609,7 @@ static void new_init_action(uint8_t action_type, const char *command, const char | |||
596 | */ | 609 | */ |
597 | nextp = &init_action_list; | 610 | nextp = &init_action_list; |
598 | while ((a = *nextp) != NULL) { | 611 | while ((a = *nextp) != NULL) { |
599 | /* Don't enter action if it's already in the list, | 612 | /* Don't enter action if it's already in the list. |
600 | * This prevents losing running RESPAWNs. | 613 | * This prevents losing running RESPAWNs. |
601 | */ | 614 | */ |
602 | if (strcmp(a->command, command) == 0 | 615 | if (strcmp(a->command, command) == 0 |
@@ -608,14 +621,15 @@ static void new_init_action(uint8_t action_type, const char *command, const char | |||
608 | while (*nextp != NULL) | 621 | while (*nextp != NULL) |
609 | nextp = &(*nextp)->next; | 622 | nextp = &(*nextp)->next; |
610 | a->next = NULL; | 623 | a->next = NULL; |
611 | break; | 624 | goto append; |
612 | } | 625 | } |
613 | nextp = &a->next; | 626 | nextp = &a->next; |
614 | } | 627 | } |
615 | 628 | ||
616 | if (!a) | 629 | a = xzalloc(sizeof(*a)); |
617 | a = xzalloc(sizeof(*a)); | 630 | |
618 | /* Append to the end of the list */ | 631 | /* Append to the end of the list */ |
632 | append: | ||
619 | *nextp = a; | 633 | *nextp = a; |
620 | a->action_type = action_type; | 634 | a->action_type = action_type; |
621 | safe_strncpy(a->command, command, sizeof(a->command)); | 635 | safe_strncpy(a->command, command, sizeof(a->command)); |
@@ -954,6 +968,33 @@ static int check_delayed_sigs(void) | |||
954 | } | 968 | } |
955 | } | 969 | } |
956 | 970 | ||
971 | #if DEBUG_SEGV_HANDLER | ||
972 | static | ||
973 | void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) | ||
974 | { | ||
975 | long ip; | ||
976 | ucontext_t *uc; | ||
977 | |||
978 | uc = ucontext; | ||
979 | ip = uc->uc_mcontext.gregs[REG_EIP]; | ||
980 | fdprintf(2, "signal:%d address:0x%lx ip:0x%lx\n", | ||
981 | sig, | ||
982 | /* this is void*, but using %p would print "(null)" | ||
983 | * even for ptrs which are not exactly 0, but, say, 0x123: | ||
984 | */ | ||
985 | (long)info->si_addr, | ||
986 | ip); | ||
987 | { | ||
988 | /* glibc extension */ | ||
989 | void *array[50]; | ||
990 | int size; | ||
991 | size = backtrace(array, 50); | ||
992 | backtrace_symbols_fd(array, size, 2); | ||
993 | } | ||
994 | for (;;) sleep(9999); | ||
995 | } | ||
996 | #endif | ||
997 | |||
957 | int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 998 | int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
958 | int init_main(int argc UNUSED_PARAM, char **argv) | 999 | int init_main(int argc UNUSED_PARAM, char **argv) |
959 | { | 1000 | { |
@@ -961,6 +1002,19 @@ int init_main(int argc UNUSED_PARAM, char **argv) | |||
961 | return kill(1, SIGHUP); | 1002 | return kill(1, SIGHUP); |
962 | } | 1003 | } |
963 | 1004 | ||
1005 | #if DEBUG_SEGV_HANDLER | ||
1006 | { | ||
1007 | struct sigaction sa; | ||
1008 | memset(&sa, 0, sizeof(sa)); | ||
1009 | sa.sa_sigaction = handle_sigsegv; | ||
1010 | sa.sa_flags = SA_SIGINFO; | ||
1011 | sigaction(SIGSEGV, &sa, NULL); | ||
1012 | sigaction(SIGILL, &sa, NULL); | ||
1013 | sigaction(SIGFPE, &sa, NULL); | ||
1014 | sigaction(SIGBUS, &sa, NULL); | ||
1015 | } | ||
1016 | #endif | ||
1017 | |||
964 | if (!DEBUG_INIT) { | 1018 | if (!DEBUG_INIT) { |
965 | /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ | 1019 | /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ |
966 | if (getpid() != 1 | 1020 | if (getpid() != 1 |