diff options
| author | Erik Andersen <andersen@codepoet.org> | 2000-01-07 02:54:55 +0000 |
|---|---|---|
| committer | Erik Andersen <andersen@codepoet.org> | 2000-01-07 02:54:55 +0000 |
| commit | 0e3782f7c39c3caa2debae7a79495fc0732cc827 (patch) | |
| tree | 8abea7bdede9ca3f46e8a020499d21ba6d72371a /init | |
| parent | 9324b400abe4365e5e50d1d4e5e155d1f708dbc0 (diff) | |
| download | busybox-w32-0e3782f7c39c3caa2debae7a79495fc0732cc827.tar.gz busybox-w32-0e3782f7c39c3caa2debae7a79495fc0732cc827.tar.bz2 busybox-w32-0e3782f7c39c3caa2debae7a79495fc0732cc827.zip | |
Init is now _more_ perfect then before.
-Erik
Diffstat (limited to 'init')
| -rw-r--r-- | init/init.c | 97 |
1 files changed, 60 insertions, 37 deletions
diff --git a/init/init.c b/init/init.c index 95c2322f7..0472208c5 100644 --- a/init/init.c +++ b/init/init.c | |||
| @@ -319,22 +319,6 @@ static void console_init() | |||
| 319 | message(LOG, "console=%s\n", console ); | 319 | message(LOG, "console=%s\n", console ); |
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | static int waitfor(int pid) | ||
| 323 | { | ||
| 324 | int status, wpid; | ||
| 325 | |||
| 326 | while (1) { | ||
| 327 | wpid = wait(&status); | ||
| 328 | if (wpid > 0 ) { | ||
| 329 | message(LOG, "pid %d exited, status=0x%x.\n", wpid, status); | ||
| 330 | break; | ||
| 331 | } | ||
| 332 | if (wpid == pid ) | ||
| 333 | break; | ||
| 334 | } | ||
| 335 | return wpid; | ||
| 336 | } | ||
| 337 | |||
| 338 | static pid_t run(char* command, | 322 | static pid_t run(char* command, |
| 339 | char *terminal, int get_enter) | 323 | char *terminal, int get_enter) |
| 340 | { | 324 | { |
| @@ -415,18 +399,37 @@ static pid_t run(char* command, | |||
| 415 | return pid; | 399 | return pid; |
| 416 | } | 400 | } |
| 417 | 401 | ||
| 402 | static int waitfor(char* command, | ||
| 403 | char *terminal, int get_enter) | ||
| 404 | { | ||
| 405 | int status, wpid; | ||
| 406 | int pid = run( command, terminal, get_enter); | ||
| 407 | |||
| 408 | while (1) { | ||
| 409 | wpid = wait(&status); | ||
| 410 | if (wpid > 0 ) { | ||
| 411 | message(LOG, "Process '%s' (pid %d) exited.\n", | ||
| 412 | command, wpid); | ||
| 413 | break; | ||
| 414 | } | ||
| 415 | if (wpid == pid ) | ||
| 416 | break; | ||
| 417 | } | ||
| 418 | return wpid; | ||
| 419 | } | ||
| 420 | |||
| 418 | /* Make sure there is enough memory to do something useful. * | 421 | /* Make sure there is enough memory to do something useful. * |
| 419 | * Calls swapon if needed so be sure /proc is mounted. */ | 422 | * Calls swapon if needed so be sure /proc is mounted. */ |
| 420 | static void check_memory() | 423 | static void check_memory() |
| 421 | { | 424 | { |
| 422 | struct stat statbuf; | 425 | struct stat statBuf; |
| 423 | 426 | ||
| 424 | if (mem_total() > 3500) | 427 | if (mem_total() > 3500) |
| 425 | return; | 428 | return; |
| 426 | 429 | ||
| 427 | if (stat("/etc/fstab", &statbuf) == 0) { | 430 | if (stat("/etc/fstab", &statBuf) == 0) { |
| 428 | /* Try to turn on swap */ | 431 | /* Try to turn on swap */ |
| 429 | waitfor(run("/bin/swapon swapon -a", log, FALSE)); | 432 | waitfor("/bin/swapon swapon -a", log, FALSE); |
| 430 | if (mem_total() < 3500) | 433 | if (mem_total() < 3500) |
| 431 | goto goodnight; | 434 | goto goodnight; |
| 432 | } else | 435 | } else |
| @@ -457,13 +460,12 @@ static void shutdown_system(void) | |||
| 457 | sleep(1); | 460 | sleep(1); |
| 458 | 461 | ||
| 459 | message(CONSOLE, "Disabling swap.\r\n"); | 462 | message(CONSOLE, "Disabling swap.\r\n"); |
| 460 | waitfor(run( "swapoff -a", console, FALSE)); | 463 | waitfor( "swapoff -a", console, FALSE); |
| 461 | message(CONSOLE, "Unmounting filesystems.\r\n"); | 464 | message(CONSOLE, "Unmounting filesystems.\r\n"); |
| 462 | waitfor(run( "umount -a", console, FALSE)); | 465 | waitfor("umount -a", console, FALSE); |
| 463 | sync(); | 466 | sync(); |
| 464 | if (kernel_version > 0 && kernel_version <= 2 * 65536 + 2 * 256 + 11) { | 467 | if (kernel_version > 0 && kernel_version <= 2 * 65536 + 2 * 256 + 11) { |
| 465 | /* bdflush, kupdate not needed for kernels >2.2.11 */ | 468 | /* bdflush, kupdate not needed for kernels >2.2.11 */ |
| 466 | message(CONSOLE, "Flushing buffers.\r\n"); | ||
| 467 | bdflush(1, 0); | 469 | bdflush(1, 0); |
| 468 | sync(); | 470 | sync(); |
| 469 | } | 471 | } |
| @@ -503,23 +505,26 @@ void new_initAction (const struct initActionType *a, | |||
| 503 | /* If BusyBox detects that a serial console is in use, | 505 | /* If BusyBox detects that a serial console is in use, |
| 504 | * then entries containing non-empty id fields will _not_ be run. | 506 | * then entries containing non-empty id fields will _not_ be run. |
| 505 | */ | 507 | */ |
| 506 | if (second_console != NULL && *cons != '\0') | 508 | if (second_console == NULL && *cons != '\0') { |
| 507 | return; | 509 | return; |
| 510 | } | ||
| 508 | 511 | ||
| 509 | newAction = calloc ((size_t)(1), sizeof(initAction)); | 512 | newAction = calloc ((size_t)(1), sizeof(initAction)); |
| 510 | if (!newAction) { | 513 | if (!newAction) { |
| 511 | fprintf(stderr, "Memory allocation failure\n"); | 514 | message(LOG|CONSOLE,"Memory allocation failure\n"); |
| 512 | while (1) sleep(1); | 515 | while (1) sleep(1); |
| 513 | } | 516 | } |
| 514 | newAction->nextPtr = initActionList; | 517 | newAction->nextPtr = initActionList; |
| 515 | initActionList = newAction; | 518 | initActionList = newAction; |
| 516 | strncpy( newAction->process, process, 255); | 519 | strncpy( newAction->process, process, 255); |
| 517 | newAction->action = a->action; | 520 | newAction->action = a->action; |
| 518 | if (*cons != '\0') | 521 | if (*cons != '\0') { |
| 519 | strncpy(newAction->console, cons, 255); | 522 | strncpy(newAction->console, cons, 255); |
| 520 | else | 523 | } else |
| 521 | strncpy(newAction->console, console, 255); | 524 | strncpy(newAction->console, console, 255); |
| 522 | newAction->pid = 0; | 525 | newAction->pid = 0; |
| 526 | message(LOG|CONSOLE, "process='%s' action='%d' console='%s'\n", | ||
| 527 | newAction->process, newAction->action, newAction->console); | ||
| 523 | } | 528 | } |
| 524 | 529 | ||
| 525 | void delete_initAction (initAction *action) | 530 | void delete_initAction (initAction *action) |
| @@ -545,7 +550,7 @@ void parse_inittab(void) | |||
| 545 | { | 550 | { |
| 546 | #ifdef BB_FEATURE_USE_INITTAB | 551 | #ifdef BB_FEATURE_USE_INITTAB |
| 547 | FILE* file; | 552 | FILE* file; |
| 548 | char buf[256], buf1[256]; | 553 | char buf[256], lineAsRead[256], tmpConsole[256]; |
| 549 | char *p, *q, *r, *s; | 554 | char *p, *q, *r, *s; |
| 550 | const struct initActionType *a = actions; | 555 | const struct initActionType *a = actions; |
| 551 | int foundIt; | 556 | int foundIt; |
| @@ -578,7 +583,8 @@ void parse_inittab(void) | |||
| 578 | *q='\0'; | 583 | *q='\0'; |
| 579 | 584 | ||
| 580 | /* Keep a copy around for posterity's sake (and error msgs) */ | 585 | /* Keep a copy around for posterity's sake (and error msgs) */ |
| 581 | strcpy(buf1, buf); | 586 | strcpy(lineAsRead, buf); |
| 587 | message(LOG|CONSOLE, "read='%s'\n", lineAsRead); | ||
| 582 | 588 | ||
| 583 | /* Grab the ID field */ | 589 | /* Grab the ID field */ |
| 584 | s=p; | 590 | s=p; |
| @@ -592,7 +598,7 @@ void parse_inittab(void) | |||
| 592 | * of the string */ | 598 | * of the string */ |
| 593 | q = strrchr( p, ':'); | 599 | q = strrchr( p, ':'); |
| 594 | if ( q == NULL || *(q+1) == '\0' ) { | 600 | if ( q == NULL || *(q+1) == '\0' ) { |
| 595 | fprintf(stderr, "Bad inittab entry: %s\n", buf1); | 601 | message(LOG|CONSOLE,"Bad inittab entry: %s\n", lineAsRead); |
| 596 | continue; | 602 | continue; |
| 597 | } else { | 603 | } else { |
| 598 | *q='\0'; | 604 | *q='\0'; |
| @@ -602,7 +608,7 @@ void parse_inittab(void) | |||
| 602 | /* Now peal off the action field */ | 608 | /* Now peal off the action field */ |
| 603 | r = strrchr( p, ':'); | 609 | r = strrchr( p, ':'); |
| 604 | if ( r == NULL || *(r+1) == '\0') { | 610 | if ( r == NULL || *(r+1) == '\0') { |
| 605 | fprintf(stderr, "Bad inittab entry: %s\n", buf1); | 611 | message(LOG|CONSOLE,"Bad inittab entry: %s\n", lineAsRead); |
| 606 | continue; | 612 | continue; |
| 607 | } else { | 613 | } else { |
| 608 | ++r; | 614 | ++r; |
| @@ -612,6 +618,16 @@ void parse_inittab(void) | |||
| 612 | a = actions; | 618 | a = actions; |
| 613 | while (a->name != 0) { | 619 | while (a->name != 0) { |
| 614 | if (strcmp(a->name, r) == 0) { | 620 | if (strcmp(a->name, r) == 0) { |
| 621 | if (*s != '\0') { | ||
| 622 | struct stat statBuf; | ||
| 623 | strcpy(tmpConsole, "/dev/"); | ||
| 624 | strncat(tmpConsole, s, 200); | ||
| 625 | if (stat(tmpConsole, &statBuf) != 0) { | ||
| 626 | message(LOG|CONSOLE, "device '%s' does not exist. Did you read the directions?\n", tmpConsole); | ||
| 627 | break; | ||
| 628 | } | ||
| 629 | s = tmpConsole; | ||
| 630 | } | ||
| 615 | new_initAction( a, q, s); | 631 | new_initAction( a, q, s); |
| 616 | foundIt=TRUE; | 632 | foundIt=TRUE; |
| 617 | } | 633 | } |
| @@ -621,7 +637,7 @@ void parse_inittab(void) | |||
| 621 | continue; | 637 | continue; |
| 622 | else { | 638 | else { |
| 623 | /* Choke on an unknown action */ | 639 | /* Choke on an unknown action */ |
| 624 | fprintf(stderr, "Bad inittab entry: %s\n", buf1); | 640 | message(LOG|CONSOLE, "Bad inittab entry: %s\n", lineAsRead); |
| 625 | } | 641 | } |
| 626 | } | 642 | } |
| 627 | return; | 643 | return; |
| @@ -670,11 +686,11 @@ extern int init_main(int argc, char **argv) | |||
| 670 | 686 | ||
| 671 | /* Hello world */ | 687 | /* Hello world */ |
| 672 | #ifndef DEBUG_INIT | 688 | #ifndef DEBUG_INIT |
| 673 | message(CONSOLE|LOG, | 689 | message(LOG|CONSOLE, |
| 674 | "init started: BusyBox v%s (%s) multi-call binary\r\n", | 690 | "init started: BusyBox v%s (%s) multi-call binary\r\n", |
| 675 | BB_VER, BB_BT); | 691 | BB_VER, BB_BT); |
| 676 | #else | 692 | #else |
| 677 | message(CONSOLE|LOG, | 693 | message(LOG|CONSOLE, |
| 678 | "init(%d) started: BusyBox v%s (%s) multi-call binary\r\n", | 694 | "init(%d) started: BusyBox v%s (%s) multi-call binary\r\n", |
| 679 | getpid(), BB_VER, BB_BT); | 695 | getpid(), BB_VER, BB_BT); |
| 680 | #endif | 696 | #endif |
| @@ -682,10 +698,10 @@ extern int init_main(int argc, char **argv) | |||
| 682 | 698 | ||
| 683 | /* Mount /proc */ | 699 | /* Mount /proc */ |
| 684 | if (mount ("proc", "/proc", "proc", 0, 0) == 0) { | 700 | if (mount ("proc", "/proc", "proc", 0, 0) == 0) { |
| 685 | message(CONSOLE|LOG, "Mounting /proc: done.\n"); | 701 | message(LOG|CONSOLE, "Mounting /proc: done.\n"); |
| 686 | kernel_version = get_kernel_revision(); | 702 | kernel_version = get_kernel_revision(); |
| 687 | } else | 703 | } else |
| 688 | message(CONSOLE|LOG, "Mounting /proc: failed!\n"); | 704 | message(LOG|CONSOLE, "Mounting /proc: failed!\n"); |
| 689 | 705 | ||
| 690 | /* Make sure there is enough memory to do something useful. */ | 706 | /* Make sure there is enough memory to do something useful. */ |
| 691 | check_memory(); | 707 | check_memory(); |
| @@ -711,10 +727,11 @@ extern int init_main(int argc, char **argv) | |||
| 711 | 727 | ||
| 712 | /* Now run everything that needs to be run */ | 728 | /* Now run everything that needs to be run */ |
| 713 | 729 | ||
| 730 | message(LOG|CONSOLE, "Running SYSINIT\n"); | ||
| 714 | /* First run the sysinit command */ | 731 | /* First run the sysinit command */ |
| 715 | for( a=initActionList ; a; a=a->nextPtr) { | 732 | for( a=initActionList ; a; a=a->nextPtr) { |
| 716 | if (a->action == SYSINIT) { | 733 | if (a->action == SYSINIT) { |
| 717 | waitfor(run(a->process, console, FALSE)); | 734 | waitfor(a->process, console, FALSE); |
| 718 | /* Now remove the "sysinit" entry from the list */ | 735 | /* Now remove the "sysinit" entry from the list */ |
| 719 | delete_initAction( a); | 736 | delete_initAction( a); |
| 720 | } | 737 | } |
| @@ -722,7 +739,7 @@ extern int init_main(int argc, char **argv) | |||
| 722 | /* Next run anything that wants to block */ | 739 | /* Next run anything that wants to block */ |
| 723 | for( a=initActionList ; a; a=a->nextPtr) { | 740 | for( a=initActionList ; a; a=a->nextPtr) { |
| 724 | if (a->action == WAIT) { | 741 | if (a->action == WAIT) { |
| 725 | waitfor(run(a->process, console, FALSE)); | 742 | waitfor(a->process, console, FALSE); |
| 726 | /* Now remove the "wait" entry from the list */ | 743 | /* Now remove the "wait" entry from the list */ |
| 727 | delete_initAction( a); | 744 | delete_initAction( a); |
| 728 | } | 745 | } |
| @@ -735,9 +752,15 @@ extern int init_main(int argc, char **argv) | |||
| 735 | delete_initAction( a); | 752 | delete_initAction( a); |
| 736 | } | 753 | } |
| 737 | } | 754 | } |
| 755 | /* If there is nothing else to do, stop */ | ||
| 756 | if (initActionList == NULL) { | ||
| 757 | message(LOG|CONSOLE, "No more tasks for init -- sleeping forever.\n"); | ||
| 758 | while (1) sleep(1); | ||
| 759 | } | ||
| 738 | 760 | ||
| 739 | /* Now run the looping stuff for the rest of forever */ | 761 | /* Now run the looping stuff for the rest of forever */ |
| 740 | while (1) { | 762 | while (1) { |
| 763 | message(LOG|CONSOLE, "Looping\n"); | ||
| 741 | for( a=initActionList ; a; a=a->nextPtr) { | 764 | for( a=initActionList ; a; a=a->nextPtr) { |
| 742 | /* Only run stuff with pid==0. If they have | 765 | /* Only run stuff with pid==0. If they have |
| 743 | * a pid, that means they are still running */ | 766 | * a pid, that means they are still running */ |
