diff options
author | Eric Andersen | 1999-10-19 00:27:50 +0000 |
---|---|---|
committer | Eric Andersen | 1999-10-19 00:27:50 +0000 |
commit | abc7d597cb78a0ee3e92ecaeb73f6cbb2a3412bf (patch) | |
tree | beefd109c47f20772f26fe2aa9830fbd9be52ea2 /init.c | |
parent | b0e9a709ba1ae1724d413a77f5b67b1a3e6c6cb7 (diff) | |
download | busybox-abc7d597cb78a0ee3e92ecaeb73f6cbb2a3412bf.zip busybox-abc7d597cb78a0ee3e92ecaeb73f6cbb2a3412bf.tar.gz |
More stuff
Diffstat (limited to 'init.c')
-rw-r--r-- | init.c | 269 |
1 files changed, 151 insertions, 118 deletions
@@ -13,19 +13,21 @@ #include <sys/mount.h> #include <sys/reboot.h> #include <sys/kdaemon.h> -#include <sys/swap.h> #include <sys/sysmacros.h> - -const char init_usage[] = "Used internally by the system."; -char console[16] = ""; -const char * default_console = "/dev/tty1"; -char * first_terminal = NULL; -const char * second_terminal = "/dev/tty2"; -const char log[] = "/dev/tty3"; -char * term_ptr = NULL; +#include <linux/serial.h> /* for serial_struct */ +#include <sys/vt.h> /* for vt_stat */ +#include <sys/ioctl.h> + +static const char init_usage[] = "Used internally by the system."; +static char console[16] = ""; +static const char* default_console = "/dev/tty2"; +static char* first_terminal = NULL; +static const char* second_terminal = "/dev/tty2"; +static const char* log = "/dev/tty3"; +static char* term_ptr = NULL; static void -message(const char * terminal, const char * pattern, ...) +message(const char* terminal, const char * pattern, ...) { int fd; FILE * con = 0; @@ -36,7 +38,8 @@ message(const char * terminal, const char * pattern, ...) * has switched consoles, the open will get the new console. If we kept * the console open, we'd always print to the same one. */ - if ( ((fd = open(terminal, O_WRONLY|O_NOCTTY)) < 0) + if ( !terminal + || ((fd = open(terminal, O_WRONLY|O_NOCTTY)) < 0) || ((con = fdopen(fd, "w")) == NULL) ) return; @@ -158,44 +161,59 @@ run(const char* program, const char* const* arguments, static int mem_total() { - char s[80]; - char *p; - FILE *f; - const char pattern[]="MemTotal:"; - - f=fopen("/proc/meminfo","r"); - while (NULL != fgets(s,79,f)) { - p=strstr(s, pattern); - if (NULL != p) { - fclose(f); - return(atoi(p+strlen(pattern))); + char s[80]; + char *p; + FILE *f; + const char pattern[]="MemTotal:"; + + f=fopen("/proc/meminfo","r"); + while (NULL != fgets(s,79,f)) { + p=strstr(s, pattern); + if (NULL != p) { + fclose(f); + return(atoi(p+strlen(pattern))); + } } - } - return -1; + return -1; } static void set_free_pages() { - char s[80]; + char s[80]; + FILE *f; + + f=fopen("/proc/sys/vm/freepages","r"); + fgets(s,79,f); + if (atoi(s) < 32) { + fclose(f); + f=fopen("/proc/sys/vm/freepages","w"); + fprintf(f,"30\t40\t50\n"); + printf("\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); + } + fclose(f); +} + +static int +get_kernel_revision() +{ FILE *f; + int major=0, minor=0, patch=0; - f=fopen("/proc/sys/vm/freepages","r"); - fgets(s,79,f); - if (atoi(s) < 32) { - fclose(f); - f=fopen("/proc/sys/vm/freepages","w"); - fprintf(f,"30\t40\t50\n"); - printf("\nIncreased /proc/sys/vm/freepages values to 30/40/50\n"); - } + f = fopen("/proc/sys/kernel/osrelease","r"); + fscanf(f,"%d.%d.%d",&major,&minor,&patch); fclose(f); + return major*65536 + minor*256 + patch; } + static void -shutdown_system(int do_reboot) +shutdown_system(void) { static const char * const umount_args[] = {"/bin/umount", "-a", "-n", 0}; + static const char * const swapoff_args[] = {"/bin/swapoff", "-a", 0}; + message(console, "The system is going down NOW !!"); sync(); /* Allow Ctrl-Alt-Del to reboot system. */ reboot(RB_ENABLE_CAD); @@ -208,59 +226,72 @@ shutdown_system(int do_reboot) message(console, "Sending SIGKILL to all processes.\r\n"); kill(-1, SIGKILL); sleep(1); + waitfor(run("/bin/swapoff", swapoff_args, console, 0)); waitfor(run("/bin/umount", umount_args, console, 0)); sync(); - bdflush(1, 0); - sync(); - reboot(do_reboot ?RB_AUTOBOOT : RB_HALT_SYSTEM); - exit(0); + if (get_kernel_revision() <= 2*65536+2*256+11) { + /* Removed bdflush call, kupdate in kernels >2.2.11 */ + bdflush(1, 0); + sync(); + } } static void halt_signal(int sig) { - shutdown_system(0); + shutdown_system(); + message(console, "The system is halted. Press CTRL-ALT-DEL or turn off power\r\n"); + reboot( RB_HALT_SYSTEM); + exit(0); } static void reboot_signal(int sig) { - shutdown_system(1); + shutdown_system(); + message(console, "Please stand by while rebooting the system.\r\n"); + reboot( RB_AUTOBOOT); + exit(0); } static void -exit_signal(int sig) +configure_terminals( int serial_cons, int single_user_mode ) { - - /* initrd doesn't work anyway */ - - shutdown_system(1); - - /* This is used on the initial ramdisk */ - - /* message(log, "Init exiting."); - exit(0); - */ -} - -void -configure_terminals( int serial_cons ) -{ - //struct stat statbuf; char *tty; + struct serial_struct sr; + struct vt_stat vt; + switch (serial_cons) { + case -1: + /* 2.2 kernels: + * identify the real console backend and try to make use of it */ + if (ioctl(0,TIOCGSERIAL,&sr) == 0) { + sprintf( console, "/dev/ttyS%d", sr.line ); + serial_cons = sr.line+1; + } + else if (ioctl(0, VT_GETSTATE, &vt) == 0) { + sprintf( console, "/dev/tty%d", vt.v_active ); + serial_cons = 0; + } + else { + /* unknown backend: fallback to /dev/console */ + strcpy( console, "/dev/console" ); + serial_cons = 0; + } + break; + case 1: - strcpy( console, "/dev/ttyS0" ); + strcpy( console, "/dev/cua0" ); break; case 2: - strcpy( console, "/dev/ttyS1" ); + strcpy( console, "/dev/cua1" ); break; default: tty = ttyname(0); if (tty) { strcpy( console, tty ); - if (!strncmp( tty, "/dev/ttyS", 9 )) + if (!strncmp( tty, "/dev/cua", 8 )) serial_cons=1; } else @@ -269,24 +300,33 @@ configure_terminals( int serial_cons ) } if (!first_terminal) first_terminal = console; - if (serial_cons && !strncmp(term_ptr,"TERM=linux",10)) - term_ptr = "TERM=vt100"; +#if #cpu (sparc) + if (serial_cons > 0 && !strncmp(term_ptr,"TERM=linux",10)) + term_ptr = "TERM=vt100"; +#endif + if (serial_cons) { + /* disable other but the first terminal: + * VT is not initialized anymore on 2.2 kernel when booting from + * serial console, therefore modprobe is flooding the display with + * "can't locate module char-major-4" messages. */ + log = 0; + second_terminal = 0; + } } extern int init_main(int argc, char * * argv) { - static const char* const rc = "etc/rc"; + const char * rc_arguments[100]; const char * arguments[100]; - int run_rc = 1; + int run_rc = TRUE; int j; int pid1 = 0; int pid2 = 0; - int create_swap= -1; struct stat statbuf; - const char * tty_commands[2] = { "bin/sh", "bin/sh"}; - char swap[20]; + const char * tty_commands[3] = { "etc/init.d/rcS", "bin/sh"}; int serial_console = 0; + int retval; /* * If I am started as /linuxrc instead of /sbin/init, I don't have the @@ -299,7 +339,7 @@ init_main(int argc, char * * argv) signal(SIGUSR1, halt_signal); signal(SIGUSR2, reboot_signal); signal(SIGINT, reboot_signal); - signal(SIGTERM, exit_signal); + signal(SIGTERM, reboot_signal); reboot(RB_DISABLE_CAD); @@ -307,7 +347,7 @@ init_main(int argc, char * * argv) for ( j = 1; j < argc; j++ ) { if ( strcmp(argv[j], "single") == 0 ) { - run_rc = 0; + run_rc = FALSE; tty_commands[0] = "bin/sh"; tty_commands[1] = 0; } @@ -341,7 +381,6 @@ init_main(int argc, char * * argv) term_ptr=__environ[j]; } } - configure_terminals( serial_console ); printf("mounting /proc ...\n"); if (mount("/proc","/proc","proc",0,0)) { @@ -349,81 +388,75 @@ init_main(int argc, char * * argv) } printf("\tdone.\n"); + if (get_kernel_revision() >= 2*65536+1*256+71) { + /* if >= 2.1.71 kernel, /dev/console is not a symlink anymore: + * use it as primary console */ + serial_console=-1; + } + + /* Make sure /etc/init.d/rc exists */ + retval= stat(tty_commands[0],&statbuf); + if (retval) + run_rc = FALSE; + + configure_terminals( serial_console, run_rc); + set_free_pages(); /* not enough memory to do anything useful*/ if (mem_total() < 2000) { - int retval; - retval= stat("/etc/swappartition",&statbuf); - if (retval) { - printf("You do not have enough RAM, sorry.\n"); - while (1) { sleep(1);} - } else { /* everything OK */ - FILE *f; - - f=fopen("/etc/swappartition","r"); - fgets(swap,19,f); - fclose(f); - *(strstr(swap,"\n"))='\0'; - - if (swapon(swap,0)) { - perror("swapon failed\n"); - } else { - f=fopen("/etc/swaps","w"); - fprintf(f,"%s none swap rw 0 0",swap); - fclose(f); - create_swap = 0; + retval= stat("/etc/fstab",&statbuf); + if (retval) { + printf("You do not have enough RAM, sorry.\n"); + while (1) { sleep(1);} + } else { + /* Try to turn on swap */ + static const char * const swapon_args[] = {"/bin/swapon", "-a", 0}; + waitfor(run("/bin/swapon", swapon_args, console, 0)); + if (mem_total() < 2000) { + printf("You do not have enough RAM, sorry.\n"); + while (1) { sleep(1);} + } } - } } /* * Don't modify **argv directly, it would show up in the "ps" display. * I don't want "init" to look like "rc". */ - arguments[0] = rc; + rc_arguments[0] = tty_commands[0]; for ( j = 1; j < argc; j++ ) { - arguments[j] = argv[j]; - } - arguments[j] = 0; - - if ( run_rc ) { - run(rc, arguments, console, 0); - //waitfor(run(rc, arguments, console, 0)); - } - - if ( 0 == create_swap) { - if (unlink("/etc/swappartition")) { - perror("unlinking /etc/swappartition"); - } + rc_arguments[j] = argv[j]; } + rc_arguments[j] = 0; arguments[0] = "-sh"; arguments[1] = 0; + + /* Ok, now launch the rc script /etc/init.d/rcS and prepare to start up + * some VTs on tty1 and tty2 if somebody hits enter + */ for ( ; ; ) { int wpid; int status; - if ( pid1 == 0 && tty_commands[0] ) { - /* Ask before starting a shell */ - /* - arguments[0] = tty_commands[0]; - */ - pid1 = run(tty_commands[0], arguments, first_terminal, 1); + if ( pid1 == 0 && tty_commands[0] ) { + if ( run_rc == TRUE ) { + pid1 = run(tty_commands[0], rc_arguments, first_terminal, 0); + } else { + pid2 = run(tty_commands[1], arguments, first_terminal, 1); + } } - if ( pid2 == 0 && tty_commands[1] ) { + if ( pid2 == 0 && second_terminal && tty_commands[1] ) { pid2 = run(tty_commands[1], arguments, second_terminal, 1); } wpid = wait(&status); - if ( wpid > 0 ) { - /* DEBUGGING */ + if ( wpid > 0 && wpid != pid1) { message(log, "pid %d exited, status=%x.\n", wpid, status); } - if ( wpid == pid1 ) { - pid1 = 0; - } - if ( wpid == pid2 ) + if ( wpid == pid2 ) { pid2 = 0; + } } } |