aboutsummaryrefslogtreecommitdiff
path: root/init
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-03-23 12:12:03 +0000
committerRon Yorston <rmy@pobox.com>2012-03-23 12:12:03 +0000
commitb0f54743e36af163ae2530c381c485bb29df13dc (patch)
treecda4cfeaae6e47fe4f14c1b566092be4da9affc4 /init
parent40514a0309939f2446f0d4ed9600cad5de396e7f (diff)
parentba88826c66411affc1da3614742b454654f7298a (diff)
downloadbusybox-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.c41
-rw-r--r--init/init.c68
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
211static void do_logging(unsigned sample_period_us) 211static 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
260static void finalize(char *tempdir, const char *prog) 257static 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
972static
973void 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
957int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 998int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
958int init_main(int argc UNUSED_PARAM, char **argv) 999int 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