diff options
author | Erik Andersen <andersen@codepoet.org> | 2000-02-09 04:16:43 +0000 |
---|---|---|
committer | Erik Andersen <andersen@codepoet.org> | 2000-02-09 04:16:43 +0000 |
commit | e132f4b09e5c9aedaef97f65279e8702633fd425 (patch) | |
tree | 50bfe1c027ff760e426ae31442da73e536dd4baa | |
parent | e49d5ecbbe51718fa925b6890a735e5937cc2aa2 (diff) | |
download | busybox-w32-e132f4b09e5c9aedaef97f65279e8702633fd425.tar.gz busybox-w32-e132f4b09e5c9aedaef97f65279e8702633fd425.tar.bz2 busybox-w32-e132f4b09e5c9aedaef97f65279e8702633fd425.zip |
Fixed the init problem where it wouldn't unmount filesystems
on reboot. Also fixed swapoff -a so it works.
-Erik
-rw-r--r-- | Changelog | 2 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | busybox.def.h | 1 | ||||
-rw-r--r-- | init.c | 126 | ||||
-rw-r--r-- | init/init.c | 126 | ||||
-rw-r--r-- | internal.h | 2 | ||||
-rw-r--r-- | mount.c | 54 | ||||
-rw-r--r-- | swaponoff.c | 23 | ||||
-rw-r--r-- | umount.c | 192 | ||||
-rw-r--r-- | util-linux/mount.c | 54 | ||||
-rw-r--r-- | util-linux/swaponoff.c | 23 | ||||
-rw-r--r-- | util-linux/umount.c | 192 | ||||
-rw-r--r-- | utility.c | 14 |
13 files changed, 457 insertions, 354 deletions
@@ -84,6 +84,8 @@ | |||
84 | - `fdflush', `length' and `printf' crashed when run without arguments | 84 | - `fdflush', `length' and `printf' crashed when run without arguments |
85 | - `fdflush' tried to flush itself using *argv | 85 | - `fdflush' tried to flush itself using *argv |
86 | - added "skip" and "seek" to dd. | 86 | - added "skip" and "seek" to dd. |
87 | * swapoff -a was not working. Now it is. | ||
88 | * init did not cleanly unmount filesystems on reboot. Now it does. | ||
87 | 89 | ||
88 | 90 | ||
89 | -Erik Andersen | 91 | -Erik Andersen |
@@ -62,7 +62,7 @@ endif | |||
62 | 62 | ||
63 | # -D_GNU_SOURCE is needed because environ is used in init.c | 63 | # -D_GNU_SOURCE is needed because environ is used in init.c |
64 | ifeq ($(DODEBUG),true) | 64 | ifeq ($(DODEBUG),true) |
65 | CFLAGS += -Wall -g -D_GNU_SOURCE -DDEBUG_INIT | 65 | CFLAGS += -Wall -g -D_GNU_SOURCE |
66 | STRIP = | 66 | STRIP = |
67 | LDFLAGS = | 67 | LDFLAGS = |
68 | else | 68 | else |
diff --git a/busybox.def.h b/busybox.def.h index f8c6e6e07..e2f5dd391 100644 --- a/busybox.def.h +++ b/busybox.def.h | |||
@@ -59,7 +59,6 @@ | |||
59 | #define BB_MOUNT | 59 | #define BB_MOUNT |
60 | #define BB_NFSMOUNT | 60 | #define BB_NFSMOUNT |
61 | //#define BB_MT | 61 | //#define BB_MT |
62 | //#define BB_MTAB | ||
63 | #define BB_NSLOOKUP | 62 | #define BB_NSLOOKUP |
64 | #define BB_PING | 63 | #define BB_PING |
65 | #define BB_POWEROFF | 64 | #define BB_POWEROFF |
@@ -22,6 +22,11 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | /* Turn this on to disable all the dangerous | ||
26 | rebooting stuff when debugging. | ||
27 | #define DEBUG_INIT | ||
28 | */ | ||
29 | |||
25 | #include "internal.h" | 30 | #include "internal.h" |
26 | #include <stdio.h> | 31 | #include <stdio.h> |
27 | #include <string.h> | 32 | #include <string.h> |
@@ -78,7 +83,8 @@ typedef enum { | |||
78 | RESPAWN, | 83 | RESPAWN, |
79 | ASKFIRST, | 84 | ASKFIRST, |
80 | WAIT, | 85 | WAIT, |
81 | ONCE | 86 | ONCE, |
87 | CTRLALTDEL | ||
82 | } initActionEnum; | 88 | } initActionEnum; |
83 | 89 | ||
84 | /* And now a list of the actions we support in the version of init */ | 90 | /* And now a list of the actions we support in the version of init */ |
@@ -93,6 +99,7 @@ static const struct initActionType actions[] = { | |||
93 | {"askfirst", ASKFIRST}, | 99 | {"askfirst", ASKFIRST}, |
94 | {"wait", WAIT}, | 100 | {"wait", WAIT}, |
95 | {"once", ONCE}, | 101 | {"once", ONCE}, |
102 | {"ctrlaltdel", CTRLALTDEL}, | ||
96 | {0} | 103 | {0} |
97 | }; | 104 | }; |
98 | 105 | ||
@@ -113,6 +120,7 @@ static char *log = VT_LOG; | |||
113 | static int kernelVersion = 0; | 120 | static int kernelVersion = 0; |
114 | static char termType[32] = "TERM=ansi"; | 121 | static char termType[32] = "TERM=ansi"; |
115 | static char console[32] = _PATH_CONSOLE; | 122 | static char console[32] = _PATH_CONSOLE; |
123 | static void delete_initAction(initAction * action); | ||
116 | 124 | ||
117 | 125 | ||
118 | /* print a message to the specified device: | 126 | /* print a message to the specified device: |
@@ -131,8 +139,8 @@ void message(int device, char *fmt, ...) | |||
131 | va_start(arguments, fmt); | 139 | va_start(arguments, fmt); |
132 | vsnprintf(msg, sizeof(msg), fmt, arguments); | 140 | vsnprintf(msg, sizeof(msg), fmt, arguments); |
133 | va_end(arguments); | 141 | va_end(arguments); |
134 | openlog("init", 0, LOG_DAEMON); | 142 | openlog("init", 0, LOG_USER); |
135 | syslog(LOG_DAEMON | LOG_NOTICE, msg); | 143 | syslog(LOG_USER|LOG_INFO, msg); |
136 | closelog(); | 144 | closelog(); |
137 | } | 145 | } |
138 | #else | 146 | #else |
@@ -146,11 +154,12 @@ void message(int device, char *fmt, ...) | |||
146 | log_fd = -2; | 154 | log_fd = -2; |
147 | /* log to main console instead */ | 155 | /* log to main console instead */ |
148 | device = CONSOLE; | 156 | device = CONSOLE; |
149 | } else if ((log_fd = device_open(log, O_RDWR | O_NDELAY)) < 0) { | 157 | } else if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) { |
150 | log_fd = -1; | 158 | log_fd = -2; |
151 | fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log); | 159 | fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log); |
152 | fflush(stderr); | 160 | fflush(stderr); |
153 | return; | 161 | log = NULL; |
162 | device = CONSOLE; | ||
154 | } | 163 | } |
155 | } | 164 | } |
156 | if ((device & LOG) && (log_fd >= 0)) { | 165 | if ((device & LOG) && (log_fd >= 0)) { |
@@ -303,10 +312,10 @@ static void console_init() | |||
303 | /* check for serial console and disable logging to tty3 & running a | 312 | /* check for serial console and disable logging to tty3 & running a |
304 | * shell to tty2 */ | 313 | * shell to tty2 */ |
305 | if (ioctl(0, TIOCGSERIAL, &sr) == 0) { | 314 | if (ioctl(0, TIOCGSERIAL, &sr) == 0) { |
306 | message(LOG | CONSOLE, | ||
307 | "serial console detected. Disabling virtual terminals.\r\n"); | ||
308 | log = NULL; | 315 | log = NULL; |
309 | secondConsole = NULL; | 316 | secondConsole = NULL; |
317 | message(LOG | CONSOLE, | ||
318 | "serial console detected. Disabling virtual terminals.\r\n"); | ||
310 | } | 319 | } |
311 | close(fd); | 320 | close(fd); |
312 | } | 321 | } |
@@ -319,6 +328,7 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
319 | pid_t pid; | 328 | pid_t pid; |
320 | char *tmpCmd; | 329 | char *tmpCmd; |
321 | char *cmd[255]; | 330 | char *cmd[255]; |
331 | char buf[255]; | ||
322 | static const char press_enter[] = | 332 | static const char press_enter[] = |
323 | 333 | ||
324 | "\nPlease press Enter to activate this console. "; | 334 | "\nPlease press Enter to activate this console. "; |
@@ -333,7 +343,9 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
333 | 343 | ||
334 | 344 | ||
335 | if ((pid = fork()) == 0) { | 345 | if ((pid = fork()) == 0) { |
346 | #ifdef DEBUG_INIT | ||
336 | pid_t shell_pgid = getpid(); | 347 | pid_t shell_pgid = getpid(); |
348 | #endif | ||
337 | 349 | ||
338 | /* Clean up */ | 350 | /* Clean up */ |
339 | close(0); | 351 | close(0); |
@@ -369,30 +381,40 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
369 | */ | 381 | */ |
370 | char c; | 382 | char c; |
371 | 383 | ||
384 | #ifdef DEBUG_INIT | ||
372 | message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n", | 385 | message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n", |
373 | command, shell_pgid, terminal); | 386 | command, shell_pgid, terminal); |
387 | #endif | ||
374 | write(fileno(stdout), press_enter, sizeof(press_enter) - 1); | 388 | write(fileno(stdout), press_enter, sizeof(press_enter) - 1); |
375 | read(fileno(stdin), &c, 1); | 389 | read(fileno(stdin), &c, 1); |
376 | } | 390 | } |
377 | 391 | ||
392 | #ifdef DEBUG_INIT | ||
378 | /* Log the process name and args */ | 393 | /* Log the process name and args */ |
379 | message(LOG, "Starting pid %d, console %s: '", | 394 | message(LOG, "Starting pid %d, console %s: '%s'\r\n", |
380 | shell_pgid, terminal, command); | 395 | shell_pgid, terminal, command); |
381 | |||
382 | /* Convert command (char*) into cmd (char**, one word per string) */ | ||
383 | for (tmpCmd = command, i = 0; | ||
384 | (tmpCmd = strsep(&command, " \t")) != NULL;) { | ||
385 | if (*tmpCmd != '\0') { | ||
386 | cmd[i] = tmpCmd; | ||
387 | #ifdef DEBUG_INIT | ||
388 | message(LOG, "%s ", tmpCmd); | ||
389 | #endif | 396 | #endif |
390 | tmpCmd++; | 397 | |
391 | i++; | 398 | /* See if any special /bin/sh requiring characters are present */ |
399 | if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { | ||
400 | cmd[0] = SHELL; | ||
401 | cmd[1] = "-c"; | ||
402 | strcpy(buf, "exec "); | ||
403 | strncat(buf, command, sizeof(buf) - strlen(buf) - 1); | ||
404 | cmd[2] = buf; | ||
405 | cmd[3] = NULL; | ||
406 | } else { | ||
407 | /* Convert command (char*) into cmd (char**, one word per string) */ | ||
408 | for (tmpCmd = command, i = 0; | ||
409 | (tmpCmd = strsep(&command, " \t")) != NULL;) { | ||
410 | if (*tmpCmd != '\0') { | ||
411 | cmd[i] = tmpCmd; | ||
412 | tmpCmd++; | ||
413 | i++; | ||
414 | } | ||
392 | } | 415 | } |
416 | cmd[i] = NULL; | ||
393 | } | 417 | } |
394 | cmd[i] = NULL; | ||
395 | message(LOG, "'\r\n"); | ||
396 | 418 | ||
397 | /* Now run it. The new program will take over this PID, | 419 | /* Now run it. The new program will take over this PID, |
398 | * so nothing further in init.c should be run. */ | 420 | * so nothing further in init.c should be run. */ |
@@ -413,9 +435,8 @@ static int waitfor(char *command, char *terminal, int get_enter) | |||
413 | 435 | ||
414 | while (1) { | 436 | while (1) { |
415 | wpid = wait(&status); | 437 | wpid = wait(&status); |
416 | if (wpid > 0) { | 438 | if (wpid > 0 && wpid != pid) { |
417 | message(LOG, "Process '%s' (pid %d) exited.\n", command, wpid); | 439 | continue; |
418 | break; | ||
419 | } | 440 | } |
420 | if (wpid == pid) | 441 | if (wpid == pid) |
421 | break; | 442 | break; |
@@ -424,7 +445,7 @@ static int waitfor(char *command, char *terminal, int get_enter) | |||
424 | } | 445 | } |
425 | 446 | ||
426 | /* Make sure there is enough memory to do something useful. * | 447 | /* Make sure there is enough memory to do something useful. * |
427 | * Calls swapon if needed so be sure /proc is mounted. */ | 448 | * Calls "swapon -a" if needed so be sure /etc/fstab is present... */ |
428 | static void check_memory() | 449 | static void check_memory() |
429 | { | 450 | { |
430 | struct stat statBuf; | 451 | struct stat statBuf; |
@@ -434,7 +455,7 @@ static void check_memory() | |||
434 | 455 | ||
435 | if (stat("/etc/fstab", &statBuf) == 0) { | 456 | if (stat("/etc/fstab", &statBuf) == 0) { |
436 | /* Try to turn on swap */ | 457 | /* Try to turn on swap */ |
437 | waitfor("/bin/swapon swapon -a", log, FALSE); | 458 | system("/sbin/swapon swapon -a"); |
438 | if (mem_total() < 3500) | 459 | if (mem_total() < 3500) |
439 | goto goodnight; | 460 | goto goodnight; |
440 | } else | 461 | } else |
@@ -448,31 +469,45 @@ static void check_memory() | |||
448 | sleep(1); | 469 | sleep(1); |
449 | } | 470 | } |
450 | 471 | ||
472 | /* Run all commands to be run right before halt/reboot */ | ||
473 | static void run_lastAction(void) | ||
474 | { | ||
475 | initAction *a; | ||
476 | for (a = initActionList; a; a = a->nextPtr) { | ||
477 | if (a->action == CTRLALTDEL) { | ||
478 | waitfor(a->process, a->console, FALSE); | ||
479 | delete_initAction(a); | ||
480 | } | ||
481 | } | ||
482 | } | ||
483 | |||
484 | |||
451 | #ifndef DEBUG_INIT | 485 | #ifndef DEBUG_INIT |
452 | static void shutdown_system(void) | 486 | static void shutdown_system(void) |
453 | { | 487 | { |
488 | |||
454 | /* first disable our SIGHUP signal */ | 489 | /* first disable our SIGHUP signal */ |
455 | signal(SIGHUP, SIG_DFL); | 490 | signal(SIGHUP, SIG_DFL); |
456 | 491 | ||
457 | /* Allow Ctrl-Alt-Del to reboot system. */ | 492 | /* Allow Ctrl-Alt-Del to reboot system. */ |
458 | reboot(RB_ENABLE_CAD); | 493 | reboot(RB_ENABLE_CAD); |
459 | message(CONSOLE, "\r\nThe system is going down NOW !!\r\n"); | 494 | |
495 | message(CONSOLE|LOG, "\r\nThe system is going down NOW !!\r\n"); | ||
460 | sync(); | 496 | sync(); |
461 | 497 | ||
462 | /* Send signals to every process _except_ pid 1 */ | 498 | /* Send signals to every process _except_ pid 1 */ |
463 | message(CONSOLE, "Sending SIGTERM to all processes.\r\n"); | 499 | message(CONSOLE|LOG, "Sending SIGTERM to all processes.\r\n"); |
464 | kill(-1, SIGTERM); | 500 | kill(-1, SIGTERM); |
465 | sleep(5); | 501 | sleep(1); |
466 | sync(); | 502 | sync(); |
467 | 503 | ||
468 | message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); | 504 | message(CONSOLE|LOG, "Sending SIGKILL to all processes.\r\n"); |
469 | kill(-1, SIGKILL); | 505 | kill(-1, SIGKILL); |
470 | sleep(5); | 506 | sleep(1); |
507 | |||
508 | /* run everything to be run at "ctrlaltdel" */ | ||
509 | run_lastAction(); | ||
471 | 510 | ||
472 | message(CONSOLE, "Disabling swap.\r\n"); | ||
473 | waitfor("swapoff -a", console, FALSE); | ||
474 | message(CONSOLE, "Unmounting filesystems.\r\n"); | ||
475 | waitfor("umount -a -r", console, FALSE); | ||
476 | sync(); | 511 | sync(); |
477 | if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) { | 512 | if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) { |
478 | /* bdflush, kupdate not needed for kernels >2.2.11 */ | 513 | /* bdflush, kupdate not needed for kernels >2.2.11 */ |
@@ -484,14 +519,14 @@ static void shutdown_system(void) | |||
484 | static void halt_signal(int sig) | 519 | static void halt_signal(int sig) |
485 | { | 520 | { |
486 | shutdown_system(); | 521 | shutdown_system(); |
487 | message(CONSOLE, | 522 | message(CONSOLE|LOG, |
488 | "The system is halted. Press %s or turn off power\r\n", | 523 | "The system is halted. Press %s or turn off power\r\n", |
489 | (secondConsole == NULL) /* serial console */ | 524 | (secondConsole == NULL) /* serial console */ |
490 | ? "Reset" : "CTRL-ALT-DEL"); | 525 | ? "Reset" : "CTRL-ALT-DEL"); |
491 | sync(); | 526 | sync(); |
492 | 527 | ||
493 | /* allow time for last message to reach serial console */ | 528 | /* allow time for last message to reach serial console */ |
494 | sleep(5); | 529 | sleep(2); |
495 | 530 | ||
496 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) | 531 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) |
497 | if (sig == SIGUSR2) | 532 | if (sig == SIGUSR2) |
@@ -505,7 +540,7 @@ static void halt_signal(int sig) | |||
505 | static void reboot_signal(int sig) | 540 | static void reboot_signal(int sig) |
506 | { | 541 | { |
507 | shutdown_system(); | 542 | shutdown_system(); |
508 | message(CONSOLE, "Please stand by while rebooting the system.\r\n"); | 543 | message(CONSOLE|LOG, "Please stand by while rebooting the system.\r\n"); |
509 | sync(); | 544 | sync(); |
510 | 545 | ||
511 | /* allow time for last message to reach serial console */ | 546 | /* allow time for last message to reach serial console */ |
@@ -631,7 +666,7 @@ void new_initAction(initActionEnum action, char *process, char *cons) | |||
631 | // newAction->process, newAction->action, newAction->console); | 666 | // newAction->process, newAction->action, newAction->console); |
632 | } | 667 | } |
633 | 668 | ||
634 | void delete_initAction(initAction * action) | 669 | static void delete_initAction(initAction * action) |
635 | { | 670 | { |
636 | initAction *a, *b = NULL; | 671 | initAction *a, *b = NULL; |
637 | 672 | ||
@@ -669,6 +704,10 @@ void parse_inittab(void) | |||
669 | if (file == NULL) { | 704 | if (file == NULL) { |
670 | /* No inittab file -- set up some default behavior */ | 705 | /* No inittab file -- set up some default behavior */ |
671 | #endif | 706 | #endif |
707 | /* Swapoff on halt/reboot */ | ||
708 | new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console); | ||
709 | /* Umount all filesystems on halt/reboot */ | ||
710 | new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console); | ||
672 | /* Askfirst shell on tty1 */ | 711 | /* Askfirst shell on tty1 */ |
673 | new_initAction(ASKFIRST, SHELL, console); | 712 | new_initAction(ASKFIRST, SHELL, console); |
674 | /* Askfirst shell on tty2 */ | 713 | /* Askfirst shell on tty2 */ |
@@ -756,6 +795,8 @@ void parse_inittab(void) | |||
756 | #endif | 795 | #endif |
757 | } | 796 | } |
758 | 797 | ||
798 | |||
799 | |||
759 | extern int init_main(int argc, char **argv) | 800 | extern int init_main(int argc, char **argv) |
760 | { | 801 | { |
761 | initAction *a; | 802 | initAction *a; |
@@ -768,9 +809,6 @@ extern int init_main(int argc, char **argv) | |||
768 | usage("init\n\nInit is the parent of all processes.\n\n" | 809 | usage("init\n\nInit is the parent of all processes.\n\n" |
769 | "This version of init is designed to be run only by the kernel\n"); | 810 | "This version of init is designed to be run only by the kernel\n"); |
770 | } | 811 | } |
771 | /* Fix up argv[0] to be certain we claim to be init */ | ||
772 | strncpy(argv[0], "init", strlen(argv[0])); | ||
773 | |||
774 | /* Set up sig handlers -- be sure to | 812 | /* Set up sig handlers -- be sure to |
775 | * clear all of these in run() */ | 813 | * clear all of these in run() */ |
776 | signal(SIGUSR1, halt_signal); | 814 | signal(SIGUSR1, halt_signal); |
@@ -838,6 +876,10 @@ extern int init_main(int argc, char **argv) | |||
838 | * of "askfirst" shells */ | 876 | * of "askfirst" shells */ |
839 | parse_inittab(); | 877 | parse_inittab(); |
840 | } | 878 | } |
879 | |||
880 | /* Fix up argv[0] to be certain we claim to be init */ | ||
881 | strncpy(argv[0], "init", strlen(argv[0])+1); | ||
882 | strncpy(argv[1], "\0", strlen(argv[1])+1); | ||
841 | 883 | ||
842 | /* Now run everything that needs to be run */ | 884 | /* Now run everything that needs to be run */ |
843 | 885 | ||
diff --git a/init/init.c b/init/init.c index 899dca48c..2f2203b38 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -22,6 +22,11 @@ | |||
22 | * | 22 | * |
23 | */ | 23 | */ |
24 | 24 | ||
25 | /* Turn this on to disable all the dangerous | ||
26 | rebooting stuff when debugging. | ||
27 | #define DEBUG_INIT | ||
28 | */ | ||
29 | |||
25 | #include "internal.h" | 30 | #include "internal.h" |
26 | #include <stdio.h> | 31 | #include <stdio.h> |
27 | #include <string.h> | 32 | #include <string.h> |
@@ -78,7 +83,8 @@ typedef enum { | |||
78 | RESPAWN, | 83 | RESPAWN, |
79 | ASKFIRST, | 84 | ASKFIRST, |
80 | WAIT, | 85 | WAIT, |
81 | ONCE | 86 | ONCE, |
87 | CTRLALTDEL | ||
82 | } initActionEnum; | 88 | } initActionEnum; |
83 | 89 | ||
84 | /* And now a list of the actions we support in the version of init */ | 90 | /* And now a list of the actions we support in the version of init */ |
@@ -93,6 +99,7 @@ static const struct initActionType actions[] = { | |||
93 | {"askfirst", ASKFIRST}, | 99 | {"askfirst", ASKFIRST}, |
94 | {"wait", WAIT}, | 100 | {"wait", WAIT}, |
95 | {"once", ONCE}, | 101 | {"once", ONCE}, |
102 | {"ctrlaltdel", CTRLALTDEL}, | ||
96 | {0} | 103 | {0} |
97 | }; | 104 | }; |
98 | 105 | ||
@@ -113,6 +120,7 @@ static char *log = VT_LOG; | |||
113 | static int kernelVersion = 0; | 120 | static int kernelVersion = 0; |
114 | static char termType[32] = "TERM=ansi"; | 121 | static char termType[32] = "TERM=ansi"; |
115 | static char console[32] = _PATH_CONSOLE; | 122 | static char console[32] = _PATH_CONSOLE; |
123 | static void delete_initAction(initAction * action); | ||
116 | 124 | ||
117 | 125 | ||
118 | /* print a message to the specified device: | 126 | /* print a message to the specified device: |
@@ -131,8 +139,8 @@ void message(int device, char *fmt, ...) | |||
131 | va_start(arguments, fmt); | 139 | va_start(arguments, fmt); |
132 | vsnprintf(msg, sizeof(msg), fmt, arguments); | 140 | vsnprintf(msg, sizeof(msg), fmt, arguments); |
133 | va_end(arguments); | 141 | va_end(arguments); |
134 | openlog("init", 0, LOG_DAEMON); | 142 | openlog("init", 0, LOG_USER); |
135 | syslog(LOG_DAEMON | LOG_NOTICE, msg); | 143 | syslog(LOG_USER|LOG_INFO, msg); |
136 | closelog(); | 144 | closelog(); |
137 | } | 145 | } |
138 | #else | 146 | #else |
@@ -146,11 +154,12 @@ void message(int device, char *fmt, ...) | |||
146 | log_fd = -2; | 154 | log_fd = -2; |
147 | /* log to main console instead */ | 155 | /* log to main console instead */ |
148 | device = CONSOLE; | 156 | device = CONSOLE; |
149 | } else if ((log_fd = device_open(log, O_RDWR | O_NDELAY)) < 0) { | 157 | } else if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) { |
150 | log_fd = -1; | 158 | log_fd = -2; |
151 | fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log); | 159 | fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log); |
152 | fflush(stderr); | 160 | fflush(stderr); |
153 | return; | 161 | log = NULL; |
162 | device = CONSOLE; | ||
154 | } | 163 | } |
155 | } | 164 | } |
156 | if ((device & LOG) && (log_fd >= 0)) { | 165 | if ((device & LOG) && (log_fd >= 0)) { |
@@ -303,10 +312,10 @@ static void console_init() | |||
303 | /* check for serial console and disable logging to tty3 & running a | 312 | /* check for serial console and disable logging to tty3 & running a |
304 | * shell to tty2 */ | 313 | * shell to tty2 */ |
305 | if (ioctl(0, TIOCGSERIAL, &sr) == 0) { | 314 | if (ioctl(0, TIOCGSERIAL, &sr) == 0) { |
306 | message(LOG | CONSOLE, | ||
307 | "serial console detected. Disabling virtual terminals.\r\n"); | ||
308 | log = NULL; | 315 | log = NULL; |
309 | secondConsole = NULL; | 316 | secondConsole = NULL; |
317 | message(LOG | CONSOLE, | ||
318 | "serial console detected. Disabling virtual terminals.\r\n"); | ||
310 | } | 319 | } |
311 | close(fd); | 320 | close(fd); |
312 | } | 321 | } |
@@ -319,6 +328,7 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
319 | pid_t pid; | 328 | pid_t pid; |
320 | char *tmpCmd; | 329 | char *tmpCmd; |
321 | char *cmd[255]; | 330 | char *cmd[255]; |
331 | char buf[255]; | ||
322 | static const char press_enter[] = | 332 | static const char press_enter[] = |
323 | 333 | ||
324 | "\nPlease press Enter to activate this console. "; | 334 | "\nPlease press Enter to activate this console. "; |
@@ -333,7 +343,9 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
333 | 343 | ||
334 | 344 | ||
335 | if ((pid = fork()) == 0) { | 345 | if ((pid = fork()) == 0) { |
346 | #ifdef DEBUG_INIT | ||
336 | pid_t shell_pgid = getpid(); | 347 | pid_t shell_pgid = getpid(); |
348 | #endif | ||
337 | 349 | ||
338 | /* Clean up */ | 350 | /* Clean up */ |
339 | close(0); | 351 | close(0); |
@@ -369,30 +381,40 @@ static pid_t run(char *command, char *terminal, int get_enter) | |||
369 | */ | 381 | */ |
370 | char c; | 382 | char c; |
371 | 383 | ||
384 | #ifdef DEBUG_INIT | ||
372 | message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n", | 385 | message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n", |
373 | command, shell_pgid, terminal); | 386 | command, shell_pgid, terminal); |
387 | #endif | ||
374 | write(fileno(stdout), press_enter, sizeof(press_enter) - 1); | 388 | write(fileno(stdout), press_enter, sizeof(press_enter) - 1); |
375 | read(fileno(stdin), &c, 1); | 389 | read(fileno(stdin), &c, 1); |
376 | } | 390 | } |
377 | 391 | ||
392 | #ifdef DEBUG_INIT | ||
378 | /* Log the process name and args */ | 393 | /* Log the process name and args */ |
379 | message(LOG, "Starting pid %d, console %s: '", | 394 | message(LOG, "Starting pid %d, console %s: '%s'\r\n", |
380 | shell_pgid, terminal, command); | 395 | shell_pgid, terminal, command); |
381 | |||
382 | /* Convert command (char*) into cmd (char**, one word per string) */ | ||
383 | for (tmpCmd = command, i = 0; | ||
384 | (tmpCmd = strsep(&command, " \t")) != NULL;) { | ||
385 | if (*tmpCmd != '\0') { | ||
386 | cmd[i] = tmpCmd; | ||
387 | #ifdef DEBUG_INIT | ||
388 | message(LOG, "%s ", tmpCmd); | ||
389 | #endif | 396 | #endif |
390 | tmpCmd++; | 397 | |
391 | i++; | 398 | /* See if any special /bin/sh requiring characters are present */ |
399 | if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { | ||
400 | cmd[0] = SHELL; | ||
401 | cmd[1] = "-c"; | ||
402 | strcpy(buf, "exec "); | ||
403 | strncat(buf, command, sizeof(buf) - strlen(buf) - 1); | ||
404 | cmd[2] = buf; | ||
405 | cmd[3] = NULL; | ||
406 | } else { | ||
407 | /* Convert command (char*) into cmd (char**, one word per string) */ | ||
408 | for (tmpCmd = command, i = 0; | ||
409 | (tmpCmd = strsep(&command, " \t")) != NULL;) { | ||
410 | if (*tmpCmd != '\0') { | ||
411 | cmd[i] = tmpCmd; | ||
412 | tmpCmd++; | ||
413 | i++; | ||
414 | } | ||
392 | } | 415 | } |
416 | cmd[i] = NULL; | ||
393 | } | 417 | } |
394 | cmd[i] = NULL; | ||
395 | message(LOG, "'\r\n"); | ||
396 | 418 | ||
397 | /* Now run it. The new program will take over this PID, | 419 | /* Now run it. The new program will take over this PID, |
398 | * so nothing further in init.c should be run. */ | 420 | * so nothing further in init.c should be run. */ |
@@ -413,9 +435,8 @@ static int waitfor(char *command, char *terminal, int get_enter) | |||
413 | 435 | ||
414 | while (1) { | 436 | while (1) { |
415 | wpid = wait(&status); | 437 | wpid = wait(&status); |
416 | if (wpid > 0) { | 438 | if (wpid > 0 && wpid != pid) { |
417 | message(LOG, "Process '%s' (pid %d) exited.\n", command, wpid); | 439 | continue; |
418 | break; | ||
419 | } | 440 | } |
420 | if (wpid == pid) | 441 | if (wpid == pid) |
421 | break; | 442 | break; |
@@ -424,7 +445,7 @@ static int waitfor(char *command, char *terminal, int get_enter) | |||
424 | } | 445 | } |
425 | 446 | ||
426 | /* Make sure there is enough memory to do something useful. * | 447 | /* Make sure there is enough memory to do something useful. * |
427 | * Calls swapon if needed so be sure /proc is mounted. */ | 448 | * Calls "swapon -a" if needed so be sure /etc/fstab is present... */ |
428 | static void check_memory() | 449 | static void check_memory() |
429 | { | 450 | { |
430 | struct stat statBuf; | 451 | struct stat statBuf; |
@@ -434,7 +455,7 @@ static void check_memory() | |||
434 | 455 | ||
435 | if (stat("/etc/fstab", &statBuf) == 0) { | 456 | if (stat("/etc/fstab", &statBuf) == 0) { |
436 | /* Try to turn on swap */ | 457 | /* Try to turn on swap */ |
437 | waitfor("/bin/swapon swapon -a", log, FALSE); | 458 | system("/sbin/swapon swapon -a"); |
438 | if (mem_total() < 3500) | 459 | if (mem_total() < 3500) |
439 | goto goodnight; | 460 | goto goodnight; |
440 | } else | 461 | } else |
@@ -448,31 +469,45 @@ static void check_memory() | |||
448 | sleep(1); | 469 | sleep(1); |
449 | } | 470 | } |
450 | 471 | ||
472 | /* Run all commands to be run right before halt/reboot */ | ||
473 | static void run_lastAction(void) | ||
474 | { | ||
475 | initAction *a; | ||
476 | for (a = initActionList; a; a = a->nextPtr) { | ||
477 | if (a->action == CTRLALTDEL) { | ||
478 | waitfor(a->process, a->console, FALSE); | ||
479 | delete_initAction(a); | ||
480 | } | ||
481 | } | ||
482 | } | ||
483 | |||
484 | |||
451 | #ifndef DEBUG_INIT | 485 | #ifndef DEBUG_INIT |
452 | static void shutdown_system(void) | 486 | static void shutdown_system(void) |
453 | { | 487 | { |
488 | |||
454 | /* first disable our SIGHUP signal */ | 489 | /* first disable our SIGHUP signal */ |
455 | signal(SIGHUP, SIG_DFL); | 490 | signal(SIGHUP, SIG_DFL); |
456 | 491 | ||
457 | /* Allow Ctrl-Alt-Del to reboot system. */ | 492 | /* Allow Ctrl-Alt-Del to reboot system. */ |
458 | reboot(RB_ENABLE_CAD); | 493 | reboot(RB_ENABLE_CAD); |
459 | message(CONSOLE, "\r\nThe system is going down NOW !!\r\n"); | 494 | |
495 | message(CONSOLE|LOG, "\r\nThe system is going down NOW !!\r\n"); | ||
460 | sync(); | 496 | sync(); |
461 | 497 | ||
462 | /* Send signals to every process _except_ pid 1 */ | 498 | /* Send signals to every process _except_ pid 1 */ |
463 | message(CONSOLE, "Sending SIGTERM to all processes.\r\n"); | 499 | message(CONSOLE|LOG, "Sending SIGTERM to all processes.\r\n"); |
464 | kill(-1, SIGTERM); | 500 | kill(-1, SIGTERM); |
465 | sleep(5); | 501 | sleep(1); |
466 | sync(); | 502 | sync(); |
467 | 503 | ||
468 | message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); | 504 | message(CONSOLE|LOG, "Sending SIGKILL to all processes.\r\n"); |
469 | kill(-1, SIGKILL); | 505 | kill(-1, SIGKILL); |
470 | sleep(5); | 506 | sleep(1); |
507 | |||
508 | /* run everything to be run at "ctrlaltdel" */ | ||
509 | run_lastAction(); | ||
471 | 510 | ||
472 | message(CONSOLE, "Disabling swap.\r\n"); | ||
473 | waitfor("swapoff -a", console, FALSE); | ||
474 | message(CONSOLE, "Unmounting filesystems.\r\n"); | ||
475 | waitfor("umount -a -r", console, FALSE); | ||
476 | sync(); | 511 | sync(); |
477 | if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) { | 512 | if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) { |
478 | /* bdflush, kupdate not needed for kernels >2.2.11 */ | 513 | /* bdflush, kupdate not needed for kernels >2.2.11 */ |
@@ -484,14 +519,14 @@ static void shutdown_system(void) | |||
484 | static void halt_signal(int sig) | 519 | static void halt_signal(int sig) |
485 | { | 520 | { |
486 | shutdown_system(); | 521 | shutdown_system(); |
487 | message(CONSOLE, | 522 | message(CONSOLE|LOG, |
488 | "The system is halted. Press %s or turn off power\r\n", | 523 | "The system is halted. Press %s or turn off power\r\n", |
489 | (secondConsole == NULL) /* serial console */ | 524 | (secondConsole == NULL) /* serial console */ |
490 | ? "Reset" : "CTRL-ALT-DEL"); | 525 | ? "Reset" : "CTRL-ALT-DEL"); |
491 | sync(); | 526 | sync(); |
492 | 527 | ||
493 | /* allow time for last message to reach serial console */ | 528 | /* allow time for last message to reach serial console */ |
494 | sleep(5); | 529 | sleep(2); |
495 | 530 | ||
496 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) | 531 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) |
497 | if (sig == SIGUSR2) | 532 | if (sig == SIGUSR2) |
@@ -505,7 +540,7 @@ static void halt_signal(int sig) | |||
505 | static void reboot_signal(int sig) | 540 | static void reboot_signal(int sig) |
506 | { | 541 | { |
507 | shutdown_system(); | 542 | shutdown_system(); |
508 | message(CONSOLE, "Please stand by while rebooting the system.\r\n"); | 543 | message(CONSOLE|LOG, "Please stand by while rebooting the system.\r\n"); |
509 | sync(); | 544 | sync(); |
510 | 545 | ||
511 | /* allow time for last message to reach serial console */ | 546 | /* allow time for last message to reach serial console */ |
@@ -631,7 +666,7 @@ void new_initAction(initActionEnum action, char *process, char *cons) | |||
631 | // newAction->process, newAction->action, newAction->console); | 666 | // newAction->process, newAction->action, newAction->console); |
632 | } | 667 | } |
633 | 668 | ||
634 | void delete_initAction(initAction * action) | 669 | static void delete_initAction(initAction * action) |
635 | { | 670 | { |
636 | initAction *a, *b = NULL; | 671 | initAction *a, *b = NULL; |
637 | 672 | ||
@@ -669,6 +704,10 @@ void parse_inittab(void) | |||
669 | if (file == NULL) { | 704 | if (file == NULL) { |
670 | /* No inittab file -- set up some default behavior */ | 705 | /* No inittab file -- set up some default behavior */ |
671 | #endif | 706 | #endif |
707 | /* Swapoff on halt/reboot */ | ||
708 | new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console); | ||
709 | /* Umount all filesystems on halt/reboot */ | ||
710 | new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console); | ||
672 | /* Askfirst shell on tty1 */ | 711 | /* Askfirst shell on tty1 */ |
673 | new_initAction(ASKFIRST, SHELL, console); | 712 | new_initAction(ASKFIRST, SHELL, console); |
674 | /* Askfirst shell on tty2 */ | 713 | /* Askfirst shell on tty2 */ |
@@ -756,6 +795,8 @@ void parse_inittab(void) | |||
756 | #endif | 795 | #endif |
757 | } | 796 | } |
758 | 797 | ||
798 | |||
799 | |||
759 | extern int init_main(int argc, char **argv) | 800 | extern int init_main(int argc, char **argv) |
760 | { | 801 | { |
761 | initAction *a; | 802 | initAction *a; |
@@ -768,9 +809,6 @@ extern int init_main(int argc, char **argv) | |||
768 | usage("init\n\nInit is the parent of all processes.\n\n" | 809 | usage("init\n\nInit is the parent of all processes.\n\n" |
769 | "This version of init is designed to be run only by the kernel\n"); | 810 | "This version of init is designed to be run only by the kernel\n"); |
770 | } | 811 | } |
771 | /* Fix up argv[0] to be certain we claim to be init */ | ||
772 | strncpy(argv[0], "init", strlen(argv[0])); | ||
773 | |||
774 | /* Set up sig handlers -- be sure to | 812 | /* Set up sig handlers -- be sure to |
775 | * clear all of these in run() */ | 813 | * clear all of these in run() */ |
776 | signal(SIGUSR1, halt_signal); | 814 | signal(SIGUSR1, halt_signal); |
@@ -838,6 +876,10 @@ extern int init_main(int argc, char **argv) | |||
838 | * of "askfirst" shells */ | 876 | * of "askfirst" shells */ |
839 | parse_inittab(); | 877 | parse_inittab(); |
840 | } | 878 | } |
879 | |||
880 | /* Fix up argv[0] to be certain we claim to be init */ | ||
881 | strncpy(argv[0], "init", strlen(argv[0])+1); | ||
882 | strncpy(argv[1], "\0", strlen(argv[1])+1); | ||
841 | 883 | ||
842 | /* Now run everything that needs to be run */ | 884 | /* Now run everything that needs to be run */ |
843 | 885 | ||
diff --git a/internal.h b/internal.h index 22f4f2fa1..090fcc8fb 100644 --- a/internal.h +++ b/internal.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <string.h> | 31 | #include <string.h> |
32 | #include <unistd.h> | 32 | #include <unistd.h> |
33 | #include <sys/stat.h> | 33 | #include <sys/stat.h> |
34 | //#include <sys/param.h> | ||
34 | #include <mntent.h> | 35 | #include <mntent.h> |
35 | 36 | ||
36 | 37 | ||
@@ -186,6 +187,7 @@ extern pid_t findInitPid(); | |||
186 | #if defined BB_INIT || defined BB_SYSLOGD | 187 | #if defined BB_INIT || defined BB_SYSLOGD |
187 | extern int device_open(char *device, int mode); | 188 | extern int device_open(char *device, int mode); |
188 | #endif | 189 | #endif |
190 | extern void whine_if_fstab_is_missing(); | ||
189 | 191 | ||
190 | #if defined BB_FEATURE_MOUNT_LOOP | 192 | #if defined BB_FEATURE_MOUNT_LOOP |
191 | extern int del_loop(const char *device); | 193 | extern int del_loop(const char *device); |
@@ -53,7 +53,7 @@ | |||
53 | #include <linux/loop.h> | 53 | #include <linux/loop.h> |
54 | 54 | ||
55 | 55 | ||
56 | static int use_loop = 0; | 56 | static int use_loop = FALSE; |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | extern const char mtab_file[]; /* Defined in utility.c */ | 59 | extern const char mtab_file[]; /* Defined in utility.c */ |
@@ -114,13 +114,14 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | |||
114 | char *mtab_opts) | 114 | char *mtab_opts) |
115 | { | 115 | { |
116 | int status = 0; | 116 | int status = 0; |
117 | char *lofile = NULL; | ||
117 | 118 | ||
118 | #if defined BB_MTAB | 119 | #if defined BB_MTAB |
119 | if (fakeIt == FALSE) | 120 | if (fakeIt == FALSE) |
120 | #endif | 121 | #endif |
121 | { | 122 | { |
122 | #if defined BB_FEATURE_MOUNT_LOOP | 123 | #if defined BB_FEATURE_MOUNT_LOOP |
123 | if (use_loop) { | 124 | if (use_loop==TRUE) { |
124 | int loro = flags & MS_RDONLY; | 125 | int loro = flags & MS_RDONLY; |
125 | char *lofile = specialfile; | 126 | char *lofile = specialfile; |
126 | 127 | ||
@@ -137,6 +138,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | |||
137 | fprintf(stderr, "WARNING: loop device is read-only\n"); | 138 | fprintf(stderr, "WARNING: loop device is read-only\n"); |
138 | flags &= ~MS_RDONLY; | 139 | flags &= ~MS_RDONLY; |
139 | } | 140 | } |
141 | use_loop = FALSE; | ||
140 | } | 142 | } |
141 | #endif | 143 | #endif |
142 | status = | 144 | status = |
@@ -157,7 +159,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | |||
157 | 159 | ||
158 | /* Bummer. mount failed. Clean up */ | 160 | /* Bummer. mount failed. Clean up */ |
159 | #if defined BB_FEATURE_MOUNT_LOOP | 161 | #if defined BB_FEATURE_MOUNT_LOOP |
160 | if (specialfile != NULL) { | 162 | if (lofile != NULL) { |
161 | del_loop(specialfile); | 163 | del_loop(specialfile); |
162 | } | 164 | } |
163 | #endif | 165 | #endif |
@@ -166,20 +168,6 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | |||
166 | 168 | ||
167 | 169 | ||
168 | 170 | ||
169 | #if defined BB_MTAB | ||
170 | #define whine_if_fstab_is_missing() {} | ||
171 | #else | ||
172 | extern void whine_if_fstab_is_missing() | ||
173 | { | ||
174 | struct stat statBuf; | ||
175 | |||
176 | if (stat("/etc/fstab", &statBuf) < 0) | ||
177 | fprintf(stderr, | ||
178 | "/etc/fstab file missing -- install one to name /dev/root.\n\n"); | ||
179 | } | ||
180 | #endif | ||
181 | |||
182 | |||
183 | /* Seperate standard mount options from the nonstandard string options */ | 171 | /* Seperate standard mount options from the nonstandard string options */ |
184 | static void | 172 | static void |
185 | parse_mount_options(char *options, unsigned long *flags, char *strflags) | 173 | parse_mount_options(char *options, unsigned long *flags, char *strflags) |
@@ -204,7 +192,7 @@ parse_mount_options(char *options, unsigned long *flags, char *strflags) | |||
204 | } | 192 | } |
205 | #if defined BB_FEATURE_MOUNT_LOOP | 193 | #if defined BB_FEATURE_MOUNT_LOOP |
206 | if (gotone == FALSE && !strcasecmp("loop", options)) { /* loop device support */ | 194 | if (gotone == FALSE && !strcasecmp("loop", options)) { /* loop device support */ |
207 | use_loop = 1; | 195 | use_loop = TRUE; |
208 | gotone = TRUE; | 196 | gotone = TRUE; |
209 | } | 197 | } |
210 | #endif | 198 | #endif |
@@ -229,7 +217,7 @@ parse_mount_options(char *options, unsigned long *flags, char *strflags) | |||
229 | int | 217 | int |
230 | mount_one(char *blockDevice, char *directory, char *filesystemType, | 218 | mount_one(char *blockDevice, char *directory, char *filesystemType, |
231 | unsigned long flags, char *string_flags, int useMtab, int fakeIt, | 219 | unsigned long flags, char *string_flags, int useMtab, int fakeIt, |
232 | char *mtab_opts) | 220 | char *mtab_opts, int whineOnErrors) |
233 | { | 221 | { |
234 | int status = 0; | 222 | int status = 0; |
235 | 223 | ||
@@ -270,9 +258,11 @@ mount_one(char *blockDevice, char *directory, char *filesystemType, | |||
270 | fakeIt, mtab_opts); | 258 | fakeIt, mtab_opts); |
271 | } | 259 | } |
272 | 260 | ||
273 | if (status == FALSE) { | 261 | if (status == FALSE && whineOnErrors == TRUE) { |
274 | fprintf(stderr, "Mounting %s on %s failed: %s\n", | 262 | if (whineOnErrors == TRUE) { |
275 | blockDevice, directory, strerror(errno)); | 263 | fprintf(stderr, "Mounting %s on %s failed: %s\n", |
264 | blockDevice, directory, strerror(errno)); | ||
265 | } | ||
276 | return (FALSE); | 266 | return (FALSE); |
277 | } | 267 | } |
278 | return (TRUE); | 268 | return (TRUE); |
@@ -387,18 +377,28 @@ extern int mount_main(int argc, char **argv) | |||
387 | exit(FALSE); | 377 | exit(FALSE); |
388 | } | 378 | } |
389 | while ((m = getmntent(f)) != NULL) { | 379 | while ((m = getmntent(f)) != NULL) { |
390 | // If the file system isn't noauto, and isn't mounted on /, | 380 | // If the file system isn't noauto, |
391 | // and isn't swap or nfs, then mount it | 381 | // and isn't swap or nfs, then mount it |
392 | if ((!strstr(m->mnt_opts, "noauto")) && | 382 | if ((!strstr(m->mnt_opts, "noauto")) && |
393 | (m->mnt_dir[1] != '\0') && | ||
394 | (!strstr(m->mnt_type, "swap")) && | 383 | (!strstr(m->mnt_type, "swap")) && |
395 | (!strstr(m->mnt_type, "nfs"))) { | 384 | (!strstr(m->mnt_type, "nfs"))) { |
396 | flags = 0; | 385 | flags = 0; |
397 | *string_flags = '\0'; | 386 | *string_flags = '\0'; |
398 | parse_mount_options(m->mnt_opts, &flags, string_flags); | 387 | parse_mount_options(m->mnt_opts, &flags, string_flags); |
399 | mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | 388 | /* If the directory is /, try to remount |
389 | * with the options specified in fstab */ | ||
390 | if (m->mnt_dir[0] == '/' && m->mnt_dir[1] == '\0') { | ||
391 | flags |= MS_REMOUNT; | ||
392 | } | ||
393 | if (mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | ||
400 | flags, string_flags, useMtab, fakeIt, | 394 | flags, string_flags, useMtab, fakeIt, |
401 | extra_opts); | 395 | extra_opts, FALSE)) |
396 | { | ||
397 | /* Try again, but this time try a remount */ | ||
398 | mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | ||
399 | flags|MS_REMOUNT, string_flags, useMtab, fakeIt, | ||
400 | extra_opts, TRUE); | ||
401 | } | ||
402 | } | 402 | } |
403 | } | 403 | } |
404 | endmntent(f); | 404 | endmntent(f); |
@@ -414,7 +414,7 @@ extern int mount_main(int argc, char **argv) | |||
414 | #endif | 414 | #endif |
415 | exit(mount_one(device, directory, filesystemType, | 415 | exit(mount_one(device, directory, filesystemType, |
416 | flags, string_flags, useMtab, fakeIt, | 416 | flags, string_flags, useMtab, fakeIt, |
417 | extra_opts)); | 417 | extra_opts, TRUE)); |
418 | } else { | 418 | } else { |
419 | goto goodbye; | 419 | goto goodbye; |
420 | } | 420 | } |
diff --git a/swaponoff.c b/swaponoff.c index 6bda22277..bc096ea95 100644 --- a/swaponoff.c +++ b/swaponoff.c | |||
@@ -36,13 +36,16 @@ static int whichApp; | |||
36 | static const char *appName; | 36 | static const char *appName; |
37 | 37 | ||
38 | static const char swapoff_usage[] = | 38 | static const char swapoff_usage[] = |
39 | "swapoff [OPTION] [device]\n\n" | ||
40 | "Stop swapping virtual memory pages on the given device.\n\n" | ||
41 | "Options:\n" | ||
42 | "\t-a\tStop swapping on all swap devices\n"; | ||
39 | 43 | ||
40 | "swapoff device\n" | ||
41 | "\nStop swapping virtual memory pages on the given device.\n"; | ||
42 | static const char swapon_usage[] = | 44 | static const char swapon_usage[] = |
43 | 45 | "swapon [OPTION] [device]\n\n" | |
44 | "swapon device\n" | 46 | "Start swapping virtual memory pages on the given device.\n\n" |
45 | "\nStart swapping virtual memory pages on the given device.\n"; | 47 | "Options:\n" |
48 | "\t-a\tStart swapping on all swap devices\n"; | ||
46 | 49 | ||
47 | 50 | ||
48 | #define SWAPON_APP 1 | 51 | #define SWAPON_APP 1 |
@@ -85,12 +88,6 @@ static void do_em_all() | |||
85 | 88 | ||
86 | extern int swap_on_off_main(int argc, char **argv) | 89 | extern int swap_on_off_main(int argc, char **argv) |
87 | { | 90 | { |
88 | struct stat statBuf; | ||
89 | |||
90 | if (stat("/etc/fstab", &statBuf) < 0) | ||
91 | fprintf(stderr, | ||
92 | "/etc/fstab file missing -- Please install one.\n\n"); | ||
93 | |||
94 | if (strcmp(*argv, "swapon") == 0) { | 91 | if (strcmp(*argv, "swapon") == 0) { |
95 | appName = *argv; | 92 | appName = *argv; |
96 | whichApp = SWAPON_APP; | 93 | whichApp = SWAPON_APP; |
@@ -100,8 +97,9 @@ extern int swap_on_off_main(int argc, char **argv) | |||
100 | whichApp = SWAPOFF_APP; | 97 | whichApp = SWAPOFF_APP; |
101 | } | 98 | } |
102 | 99 | ||
103 | if (argc < 2) | 100 | if (argc != 2) { |
104 | goto usage_and_exit; | 101 | goto usage_and_exit; |
102 | } | ||
105 | argc--; | 103 | argc--; |
106 | argv++; | 104 | argv++; |
107 | 105 | ||
@@ -110,6 +108,7 @@ extern int swap_on_off_main(int argc, char **argv) | |||
110 | while (*++(*argv)) | 108 | while (*++(*argv)) |
111 | switch (**argv) { | 109 | switch (**argv) { |
112 | case 'a': | 110 | case 'a': |
111 | whine_if_fstab_is_missing(); | ||
113 | do_em_all(); | 112 | do_em_all(); |
114 | break; | 113 | break; |
115 | default: | 114 | default: |
@@ -29,6 +29,7 @@ | |||
29 | #include <fstab.h> | 29 | #include <fstab.h> |
30 | #include <errno.h> | 30 | #include <errno.h> |
31 | 31 | ||
32 | |||
32 | static const char umount_usage[] = | 33 | static const char umount_usage[] = |
33 | "umount [flags] filesystem|directory\n\n" | 34 | "umount [flags] filesystem|directory\n\n" |
34 | "Flags:\n" "\t-a:\tUnmount all file systems" | 35 | "Flags:\n" "\t-a:\tUnmount all file systems" |
@@ -57,7 +58,99 @@ static int umountAll = FALSE; | |||
57 | static int doRemount = FALSE; | 58 | static int doRemount = FALSE; |
58 | extern const char mtab_file[]; /* Defined in utility.c */ | 59 | extern const char mtab_file[]; /* Defined in utility.c */ |
59 | 60 | ||
60 | #define MIN(x,y) (x > y ? x : y) | 61 | |
62 | /* These functions are here because the getmntent functions do not appear | ||
63 | * to be re-entrant, which leads to all sorts of problems when we try to | ||
64 | * use them recursively - randolph | ||
65 | */ | ||
66 | void mtab_read(void) | ||
67 | { | ||
68 | struct _mtab_entry_t *entry = NULL; | ||
69 | struct mntent *e; | ||
70 | FILE *fp; | ||
71 | |||
72 | if (mtab_cache != NULL) | ||
73 | return; | ||
74 | |||
75 | if ((fp = setmntent(mtab_file, "r")) == NULL) { | ||
76 | fprintf(stderr, "Cannot open %s\n", mtab_file); | ||
77 | return; | ||
78 | } | ||
79 | while ((e = getmntent(fp))) { | ||
80 | entry = malloc(sizeof(struct _mtab_entry_t)); | ||
81 | |||
82 | entry->device = strdup(e->mnt_fsname); | ||
83 | entry->mountpt = strdup(e->mnt_dir); | ||
84 | entry->next = mtab_cache; | ||
85 | mtab_cache = entry; | ||
86 | } | ||
87 | endmntent(fp); | ||
88 | } | ||
89 | |||
90 | char *mtab_getinfo(const char *match, const char which) | ||
91 | { | ||
92 | struct _mtab_entry_t *cur = mtab_cache; | ||
93 | |||
94 | while (cur) { | ||
95 | if (strcmp(cur->mountpt, match) == 0 || | ||
96 | strcmp(cur->device, match) == 0) { | ||
97 | if (which == MTAB_GETMOUNTPT) { | ||
98 | return cur->mountpt; | ||
99 | } else { | ||
100 | #if !defined BB_MTAB | ||
101 | if (strcmp(cur->device, "/dev/root") == 0) { | ||
102 | struct fstab *fstabItem; | ||
103 | |||
104 | fstabItem = getfsfile("/"); | ||
105 | if (fstabItem != NULL) | ||
106 | return fstabItem->fs_spec; | ||
107 | } | ||
108 | #endif | ||
109 | return cur->device; | ||
110 | } | ||
111 | } | ||
112 | cur = cur->next; | ||
113 | } | ||
114 | return NULL; | ||
115 | } | ||
116 | |||
117 | char *mtab_first(void **iter) | ||
118 | { | ||
119 | struct _mtab_entry_t *mtab_iter; | ||
120 | |||
121 | if (!iter) | ||
122 | return NULL; | ||
123 | mtab_iter = mtab_cache; | ||
124 | *iter = (void *) mtab_iter; | ||
125 | return mtab_next(iter); | ||
126 | } | ||
127 | |||
128 | char *mtab_next(void **iter) | ||
129 | { | ||
130 | char *mp; | ||
131 | |||
132 | if (iter == NULL || *iter == NULL) | ||
133 | return NULL; | ||
134 | mp = ((struct _mtab_entry_t *) (*iter))->mountpt; | ||
135 | *iter = (void *) ((struct _mtab_entry_t *) (*iter))->next; | ||
136 | return mp; | ||
137 | } | ||
138 | |||
139 | void mtab_free(void) | ||
140 | { | ||
141 | struct _mtab_entry_t *this, *next; | ||
142 | |||
143 | this = mtab_cache; | ||
144 | while (this) { | ||
145 | next = this->next; | ||
146 | if (this->device) | ||
147 | free(this->device); | ||
148 | if (this->mountpt) | ||
149 | free(this->mountpt); | ||
150 | free(this); | ||
151 | this = next; | ||
152 | } | ||
153 | } | ||
61 | 154 | ||
62 | static int do_umount(const char *name, int useMtab) | 155 | static int do_umount(const char *name, int useMtab) |
63 | { | 156 | { |
@@ -105,6 +198,9 @@ static int umount_all(int useMtab) | |||
105 | void *iter; | 198 | void *iter; |
106 | 199 | ||
107 | for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) { | 200 | for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) { |
201 | /* Never umount /proc on a umount -a */ | ||
202 | if (strstr(mountpt, "proc")!= NULL) | ||
203 | continue; | ||
108 | status = do_umount(mountpt, useMtab); | 204 | status = do_umount(mountpt, useMtab); |
109 | if (status != 0) { | 205 | if (status != 0) { |
110 | /* Don't bother retrying the umount on busy devices */ | 206 | /* Don't bother retrying the umount on busy devices */ |
@@ -163,97 +259,3 @@ extern int umount_main(int argc, char **argv) | |||
163 | } | 259 | } |
164 | } | 260 | } |
165 | 261 | ||
166 | |||
167 | |||
168 | /* These functions are here because the getmntent functions do not appear | ||
169 | * to be re-entrant, which leads to all sorts of problems when we try to | ||
170 | * use them recursively - randolph | ||
171 | */ | ||
172 | void mtab_read(void) | ||
173 | { | ||
174 | struct _mtab_entry_t *entry = NULL; | ||
175 | struct mntent *e; | ||
176 | FILE *fp; | ||
177 | |||
178 | if (mtab_cache != NULL) | ||
179 | return; | ||
180 | |||
181 | if ((fp = setmntent(mtab_file, "r")) == NULL) { | ||
182 | fprintf(stderr, "Cannot open %s\n", mtab_file); | ||
183 | return; | ||
184 | } | ||
185 | while ((e = getmntent(fp))) { | ||
186 | entry = malloc(sizeof(struct _mtab_entry_t)); | ||
187 | |||
188 | entry->device = strdup(e->mnt_fsname); | ||
189 | entry->mountpt = strdup(e->mnt_dir); | ||
190 | entry->next = mtab_cache; | ||
191 | mtab_cache = entry; | ||
192 | } | ||
193 | endmntent(fp); | ||
194 | } | ||
195 | |||
196 | char *mtab_getinfo(const char *match, const char which) | ||
197 | { | ||
198 | struct _mtab_entry_t *cur = mtab_cache; | ||
199 | |||
200 | while (cur) { | ||
201 | if (strcmp(cur->mountpt, match) == 0 || | ||
202 | strcmp(cur->device, match) == 0) { | ||
203 | if (which == MTAB_GETMOUNTPT) { | ||
204 | return cur->mountpt; | ||
205 | } else { | ||
206 | #if !defined BB_MTAB | ||
207 | if (strcmp(cur->device, "/dev/root") == 0) { | ||
208 | struct fstab *fstabItem; | ||
209 | |||
210 | fstabItem = getfsfile("/"); | ||
211 | if (fstabItem != NULL) | ||
212 | return fstabItem->fs_spec; | ||
213 | } | ||
214 | #endif | ||
215 | return cur->device; | ||
216 | } | ||
217 | } | ||
218 | cur = cur->next; | ||
219 | } | ||
220 | return NULL; | ||
221 | } | ||
222 | |||
223 | char *mtab_first(void **iter) | ||
224 | { | ||
225 | struct _mtab_entry_t *mtab_iter; | ||
226 | |||
227 | if (!iter) | ||
228 | return NULL; | ||
229 | mtab_iter = mtab_cache; | ||
230 | *iter = (void *) mtab_iter; | ||
231 | return mtab_next(iter); | ||
232 | } | ||
233 | |||
234 | char *mtab_next(void **iter) | ||
235 | { | ||
236 | char *mp; | ||
237 | |||
238 | if (iter == NULL || *iter == NULL) | ||
239 | return NULL; | ||
240 | mp = ((struct _mtab_entry_t *) (*iter))->mountpt; | ||
241 | *iter = (void *) ((struct _mtab_entry_t *) (*iter))->next; | ||
242 | return mp; | ||
243 | } | ||
244 | |||
245 | void mtab_free(void) | ||
246 | { | ||
247 | struct _mtab_entry_t *this, *next; | ||
248 | |||
249 | this = mtab_cache; | ||
250 | while (this) { | ||
251 | next = this->next; | ||
252 | if (this->device) | ||
253 | free(this->device); | ||
254 | if (this->mountpt) | ||
255 | free(this->mountpt); | ||
256 | free(this); | ||
257 | this = next; | ||
258 | } | ||
259 | } | ||
diff --git a/util-linux/mount.c b/util-linux/mount.c index c3e3bbd75..37f789d3c 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -53,7 +53,7 @@ | |||
53 | #include <linux/loop.h> | 53 | #include <linux/loop.h> |
54 | 54 | ||
55 | 55 | ||
56 | static int use_loop = 0; | 56 | static int use_loop = FALSE; |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | extern const char mtab_file[]; /* Defined in utility.c */ | 59 | extern const char mtab_file[]; /* Defined in utility.c */ |
@@ -114,13 +114,14 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | |||
114 | char *mtab_opts) | 114 | char *mtab_opts) |
115 | { | 115 | { |
116 | int status = 0; | 116 | int status = 0; |
117 | char *lofile = NULL; | ||
117 | 118 | ||
118 | #if defined BB_MTAB | 119 | #if defined BB_MTAB |
119 | if (fakeIt == FALSE) | 120 | if (fakeIt == FALSE) |
120 | #endif | 121 | #endif |
121 | { | 122 | { |
122 | #if defined BB_FEATURE_MOUNT_LOOP | 123 | #if defined BB_FEATURE_MOUNT_LOOP |
123 | if (use_loop) { | 124 | if (use_loop==TRUE) { |
124 | int loro = flags & MS_RDONLY; | 125 | int loro = flags & MS_RDONLY; |
125 | char *lofile = specialfile; | 126 | char *lofile = specialfile; |
126 | 127 | ||
@@ -137,6 +138,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | |||
137 | fprintf(stderr, "WARNING: loop device is read-only\n"); | 138 | fprintf(stderr, "WARNING: loop device is read-only\n"); |
138 | flags &= ~MS_RDONLY; | 139 | flags &= ~MS_RDONLY; |
139 | } | 140 | } |
141 | use_loop = FALSE; | ||
140 | } | 142 | } |
141 | #endif | 143 | #endif |
142 | status = | 144 | status = |
@@ -157,7 +159,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | |||
157 | 159 | ||
158 | /* Bummer. mount failed. Clean up */ | 160 | /* Bummer. mount failed. Clean up */ |
159 | #if defined BB_FEATURE_MOUNT_LOOP | 161 | #if defined BB_FEATURE_MOUNT_LOOP |
160 | if (specialfile != NULL) { | 162 | if (lofile != NULL) { |
161 | del_loop(specialfile); | 163 | del_loop(specialfile); |
162 | } | 164 | } |
163 | #endif | 165 | #endif |
@@ -166,20 +168,6 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | |||
166 | 168 | ||
167 | 169 | ||
168 | 170 | ||
169 | #if defined BB_MTAB | ||
170 | #define whine_if_fstab_is_missing() {} | ||
171 | #else | ||
172 | extern void whine_if_fstab_is_missing() | ||
173 | { | ||
174 | struct stat statBuf; | ||
175 | |||
176 | if (stat("/etc/fstab", &statBuf) < 0) | ||
177 | fprintf(stderr, | ||
178 | "/etc/fstab file missing -- install one to name /dev/root.\n\n"); | ||
179 | } | ||
180 | #endif | ||
181 | |||
182 | |||
183 | /* Seperate standard mount options from the nonstandard string options */ | 171 | /* Seperate standard mount options from the nonstandard string options */ |
184 | static void | 172 | static void |
185 | parse_mount_options(char *options, unsigned long *flags, char *strflags) | 173 | parse_mount_options(char *options, unsigned long *flags, char *strflags) |
@@ -204,7 +192,7 @@ parse_mount_options(char *options, unsigned long *flags, char *strflags) | |||
204 | } | 192 | } |
205 | #if defined BB_FEATURE_MOUNT_LOOP | 193 | #if defined BB_FEATURE_MOUNT_LOOP |
206 | if (gotone == FALSE && !strcasecmp("loop", options)) { /* loop device support */ | 194 | if (gotone == FALSE && !strcasecmp("loop", options)) { /* loop device support */ |
207 | use_loop = 1; | 195 | use_loop = TRUE; |
208 | gotone = TRUE; | 196 | gotone = TRUE; |
209 | } | 197 | } |
210 | #endif | 198 | #endif |
@@ -229,7 +217,7 @@ parse_mount_options(char *options, unsigned long *flags, char *strflags) | |||
229 | int | 217 | int |
230 | mount_one(char *blockDevice, char *directory, char *filesystemType, | 218 | mount_one(char *blockDevice, char *directory, char *filesystemType, |
231 | unsigned long flags, char *string_flags, int useMtab, int fakeIt, | 219 | unsigned long flags, char *string_flags, int useMtab, int fakeIt, |
232 | char *mtab_opts) | 220 | char *mtab_opts, int whineOnErrors) |
233 | { | 221 | { |
234 | int status = 0; | 222 | int status = 0; |
235 | 223 | ||
@@ -270,9 +258,11 @@ mount_one(char *blockDevice, char *directory, char *filesystemType, | |||
270 | fakeIt, mtab_opts); | 258 | fakeIt, mtab_opts); |
271 | } | 259 | } |
272 | 260 | ||
273 | if (status == FALSE) { | 261 | if (status == FALSE && whineOnErrors == TRUE) { |
274 | fprintf(stderr, "Mounting %s on %s failed: %s\n", | 262 | if (whineOnErrors == TRUE) { |
275 | blockDevice, directory, strerror(errno)); | 263 | fprintf(stderr, "Mounting %s on %s failed: %s\n", |
264 | blockDevice, directory, strerror(errno)); | ||
265 | } | ||
276 | return (FALSE); | 266 | return (FALSE); |
277 | } | 267 | } |
278 | return (TRUE); | 268 | return (TRUE); |
@@ -387,18 +377,28 @@ extern int mount_main(int argc, char **argv) | |||
387 | exit(FALSE); | 377 | exit(FALSE); |
388 | } | 378 | } |
389 | while ((m = getmntent(f)) != NULL) { | 379 | while ((m = getmntent(f)) != NULL) { |
390 | // If the file system isn't noauto, and isn't mounted on /, | 380 | // If the file system isn't noauto, |
391 | // and isn't swap or nfs, then mount it | 381 | // and isn't swap or nfs, then mount it |
392 | if ((!strstr(m->mnt_opts, "noauto")) && | 382 | if ((!strstr(m->mnt_opts, "noauto")) && |
393 | (m->mnt_dir[1] != '\0') && | ||
394 | (!strstr(m->mnt_type, "swap")) && | 383 | (!strstr(m->mnt_type, "swap")) && |
395 | (!strstr(m->mnt_type, "nfs"))) { | 384 | (!strstr(m->mnt_type, "nfs"))) { |
396 | flags = 0; | 385 | flags = 0; |
397 | *string_flags = '\0'; | 386 | *string_flags = '\0'; |
398 | parse_mount_options(m->mnt_opts, &flags, string_flags); | 387 | parse_mount_options(m->mnt_opts, &flags, string_flags); |
399 | mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | 388 | /* If the directory is /, try to remount |
389 | * with the options specified in fstab */ | ||
390 | if (m->mnt_dir[0] == '/' && m->mnt_dir[1] == '\0') { | ||
391 | flags |= MS_REMOUNT; | ||
392 | } | ||
393 | if (mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | ||
400 | flags, string_flags, useMtab, fakeIt, | 394 | flags, string_flags, useMtab, fakeIt, |
401 | extra_opts); | 395 | extra_opts, FALSE)) |
396 | { | ||
397 | /* Try again, but this time try a remount */ | ||
398 | mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | ||
399 | flags|MS_REMOUNT, string_flags, useMtab, fakeIt, | ||
400 | extra_opts, TRUE); | ||
401 | } | ||
402 | } | 402 | } |
403 | } | 403 | } |
404 | endmntent(f); | 404 | endmntent(f); |
@@ -414,7 +414,7 @@ extern int mount_main(int argc, char **argv) | |||
414 | #endif | 414 | #endif |
415 | exit(mount_one(device, directory, filesystemType, | 415 | exit(mount_one(device, directory, filesystemType, |
416 | flags, string_flags, useMtab, fakeIt, | 416 | flags, string_flags, useMtab, fakeIt, |
417 | extra_opts)); | 417 | extra_opts, TRUE)); |
418 | } else { | 418 | } else { |
419 | goto goodbye; | 419 | goto goodbye; |
420 | } | 420 | } |
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index 6bda22277..bc096ea95 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c | |||
@@ -36,13 +36,16 @@ static int whichApp; | |||
36 | static const char *appName; | 36 | static const char *appName; |
37 | 37 | ||
38 | static const char swapoff_usage[] = | 38 | static const char swapoff_usage[] = |
39 | "swapoff [OPTION] [device]\n\n" | ||
40 | "Stop swapping virtual memory pages on the given device.\n\n" | ||
41 | "Options:\n" | ||
42 | "\t-a\tStop swapping on all swap devices\n"; | ||
39 | 43 | ||
40 | "swapoff device\n" | ||
41 | "\nStop swapping virtual memory pages on the given device.\n"; | ||
42 | static const char swapon_usage[] = | 44 | static const char swapon_usage[] = |
43 | 45 | "swapon [OPTION] [device]\n\n" | |
44 | "swapon device\n" | 46 | "Start swapping virtual memory pages on the given device.\n\n" |
45 | "\nStart swapping virtual memory pages on the given device.\n"; | 47 | "Options:\n" |
48 | "\t-a\tStart swapping on all swap devices\n"; | ||
46 | 49 | ||
47 | 50 | ||
48 | #define SWAPON_APP 1 | 51 | #define SWAPON_APP 1 |
@@ -85,12 +88,6 @@ static void do_em_all() | |||
85 | 88 | ||
86 | extern int swap_on_off_main(int argc, char **argv) | 89 | extern int swap_on_off_main(int argc, char **argv) |
87 | { | 90 | { |
88 | struct stat statBuf; | ||
89 | |||
90 | if (stat("/etc/fstab", &statBuf) < 0) | ||
91 | fprintf(stderr, | ||
92 | "/etc/fstab file missing -- Please install one.\n\n"); | ||
93 | |||
94 | if (strcmp(*argv, "swapon") == 0) { | 91 | if (strcmp(*argv, "swapon") == 0) { |
95 | appName = *argv; | 92 | appName = *argv; |
96 | whichApp = SWAPON_APP; | 93 | whichApp = SWAPON_APP; |
@@ -100,8 +97,9 @@ extern int swap_on_off_main(int argc, char **argv) | |||
100 | whichApp = SWAPOFF_APP; | 97 | whichApp = SWAPOFF_APP; |
101 | } | 98 | } |
102 | 99 | ||
103 | if (argc < 2) | 100 | if (argc != 2) { |
104 | goto usage_and_exit; | 101 | goto usage_and_exit; |
102 | } | ||
105 | argc--; | 103 | argc--; |
106 | argv++; | 104 | argv++; |
107 | 105 | ||
@@ -110,6 +108,7 @@ extern int swap_on_off_main(int argc, char **argv) | |||
110 | while (*++(*argv)) | 108 | while (*++(*argv)) |
111 | switch (**argv) { | 109 | switch (**argv) { |
112 | case 'a': | 110 | case 'a': |
111 | whine_if_fstab_is_missing(); | ||
113 | do_em_all(); | 112 | do_em_all(); |
114 | break; | 113 | break; |
115 | default: | 114 | default: |
diff --git a/util-linux/umount.c b/util-linux/umount.c index a2ca8c74a..b58b1a08c 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <fstab.h> | 29 | #include <fstab.h> |
30 | #include <errno.h> | 30 | #include <errno.h> |
31 | 31 | ||
32 | |||
32 | static const char umount_usage[] = | 33 | static const char umount_usage[] = |
33 | "umount [flags] filesystem|directory\n\n" | 34 | "umount [flags] filesystem|directory\n\n" |
34 | "Flags:\n" "\t-a:\tUnmount all file systems" | 35 | "Flags:\n" "\t-a:\tUnmount all file systems" |
@@ -57,7 +58,99 @@ static int umountAll = FALSE; | |||
57 | static int doRemount = FALSE; | 58 | static int doRemount = FALSE; |
58 | extern const char mtab_file[]; /* Defined in utility.c */ | 59 | extern const char mtab_file[]; /* Defined in utility.c */ |
59 | 60 | ||
60 | #define MIN(x,y) (x > y ? x : y) | 61 | |
62 | /* These functions are here because the getmntent functions do not appear | ||
63 | * to be re-entrant, which leads to all sorts of problems when we try to | ||
64 | * use them recursively - randolph | ||
65 | */ | ||
66 | void mtab_read(void) | ||
67 | { | ||
68 | struct _mtab_entry_t *entry = NULL; | ||
69 | struct mntent *e; | ||
70 | FILE *fp; | ||
71 | |||
72 | if (mtab_cache != NULL) | ||
73 | return; | ||
74 | |||
75 | if ((fp = setmntent(mtab_file, "r")) == NULL) { | ||
76 | fprintf(stderr, "Cannot open %s\n", mtab_file); | ||
77 | return; | ||
78 | } | ||
79 | while ((e = getmntent(fp))) { | ||
80 | entry = malloc(sizeof(struct _mtab_entry_t)); | ||
81 | |||
82 | entry->device = strdup(e->mnt_fsname); | ||
83 | entry->mountpt = strdup(e->mnt_dir); | ||
84 | entry->next = mtab_cache; | ||
85 | mtab_cache = entry; | ||
86 | } | ||
87 | endmntent(fp); | ||
88 | } | ||
89 | |||
90 | char *mtab_getinfo(const char *match, const char which) | ||
91 | { | ||
92 | struct _mtab_entry_t *cur = mtab_cache; | ||
93 | |||
94 | while (cur) { | ||
95 | if (strcmp(cur->mountpt, match) == 0 || | ||
96 | strcmp(cur->device, match) == 0) { | ||
97 | if (which == MTAB_GETMOUNTPT) { | ||
98 | return cur->mountpt; | ||
99 | } else { | ||
100 | #if !defined BB_MTAB | ||
101 | if (strcmp(cur->device, "/dev/root") == 0) { | ||
102 | struct fstab *fstabItem; | ||
103 | |||
104 | fstabItem = getfsfile("/"); | ||
105 | if (fstabItem != NULL) | ||
106 | return fstabItem->fs_spec; | ||
107 | } | ||
108 | #endif | ||
109 | return cur->device; | ||
110 | } | ||
111 | } | ||
112 | cur = cur->next; | ||
113 | } | ||
114 | return NULL; | ||
115 | } | ||
116 | |||
117 | char *mtab_first(void **iter) | ||
118 | { | ||
119 | struct _mtab_entry_t *mtab_iter; | ||
120 | |||
121 | if (!iter) | ||
122 | return NULL; | ||
123 | mtab_iter = mtab_cache; | ||
124 | *iter = (void *) mtab_iter; | ||
125 | return mtab_next(iter); | ||
126 | } | ||
127 | |||
128 | char *mtab_next(void **iter) | ||
129 | { | ||
130 | char *mp; | ||
131 | |||
132 | if (iter == NULL || *iter == NULL) | ||
133 | return NULL; | ||
134 | mp = ((struct _mtab_entry_t *) (*iter))->mountpt; | ||
135 | *iter = (void *) ((struct _mtab_entry_t *) (*iter))->next; | ||
136 | return mp; | ||
137 | } | ||
138 | |||
139 | void mtab_free(void) | ||
140 | { | ||
141 | struct _mtab_entry_t *this, *next; | ||
142 | |||
143 | this = mtab_cache; | ||
144 | while (this) { | ||
145 | next = this->next; | ||
146 | if (this->device) | ||
147 | free(this->device); | ||
148 | if (this->mountpt) | ||
149 | free(this->mountpt); | ||
150 | free(this); | ||
151 | this = next; | ||
152 | } | ||
153 | } | ||
61 | 154 | ||
62 | static int do_umount(const char *name, int useMtab) | 155 | static int do_umount(const char *name, int useMtab) |
63 | { | 156 | { |
@@ -105,6 +198,9 @@ static int umount_all(int useMtab) | |||
105 | void *iter; | 198 | void *iter; |
106 | 199 | ||
107 | for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) { | 200 | for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) { |
201 | /* Never umount /proc on a umount -a */ | ||
202 | if (strstr(mountpt, "proc")!= NULL) | ||
203 | continue; | ||
108 | status = do_umount(mountpt, useMtab); | 204 | status = do_umount(mountpt, useMtab); |
109 | if (status != 0) { | 205 | if (status != 0) { |
110 | /* Don't bother retrying the umount on busy devices */ | 206 | /* Don't bother retrying the umount on busy devices */ |
@@ -163,97 +259,3 @@ extern int umount_main(int argc, char **argv) | |||
163 | } | 259 | } |
164 | } | 260 | } |
165 | 261 | ||
166 | |||
167 | |||
168 | /* These functions are here because the getmntent functions do not appear | ||
169 | * to be re-entrant, which leads to all sorts of problems when we try to | ||
170 | * use them recursively - randolph | ||
171 | */ | ||
172 | void mtab_read(void) | ||
173 | { | ||
174 | struct _mtab_entry_t *entry = NULL; | ||
175 | struct mntent *e; | ||
176 | FILE *fp; | ||
177 | |||
178 | if (mtab_cache != NULL) | ||
179 | return; | ||
180 | |||
181 | if ((fp = setmntent(mtab_file, "r")) == NULL) { | ||
182 | fprintf(stderr, "Cannot open %s\n", mtab_file); | ||
183 | return; | ||
184 | } | ||
185 | while ((e = getmntent(fp))) { | ||
186 | entry = malloc(sizeof(struct _mtab_entry_t)); | ||
187 | |||
188 | entry->device = strdup(e->mnt_fsname); | ||
189 | entry->mountpt = strdup(e->mnt_dir); | ||
190 | entry->next = mtab_cache; | ||
191 | mtab_cache = entry; | ||
192 | } | ||
193 | endmntent(fp); | ||
194 | } | ||
195 | |||
196 | char *mtab_getinfo(const char *match, const char which) | ||
197 | { | ||
198 | struct _mtab_entry_t *cur = mtab_cache; | ||
199 | |||
200 | while (cur) { | ||
201 | if (strcmp(cur->mountpt, match) == 0 || | ||
202 | strcmp(cur->device, match) == 0) { | ||
203 | if (which == MTAB_GETMOUNTPT) { | ||
204 | return cur->mountpt; | ||
205 | } else { | ||
206 | #if !defined BB_MTAB | ||
207 | if (strcmp(cur->device, "/dev/root") == 0) { | ||
208 | struct fstab *fstabItem; | ||
209 | |||
210 | fstabItem = getfsfile("/"); | ||
211 | if (fstabItem != NULL) | ||
212 | return fstabItem->fs_spec; | ||
213 | } | ||
214 | #endif | ||
215 | return cur->device; | ||
216 | } | ||
217 | } | ||
218 | cur = cur->next; | ||
219 | } | ||
220 | return NULL; | ||
221 | } | ||
222 | |||
223 | char *mtab_first(void **iter) | ||
224 | { | ||
225 | struct _mtab_entry_t *mtab_iter; | ||
226 | |||
227 | if (!iter) | ||
228 | return NULL; | ||
229 | mtab_iter = mtab_cache; | ||
230 | *iter = (void *) mtab_iter; | ||
231 | return mtab_next(iter); | ||
232 | } | ||
233 | |||
234 | char *mtab_next(void **iter) | ||
235 | { | ||
236 | char *mp; | ||
237 | |||
238 | if (iter == NULL || *iter == NULL) | ||
239 | return NULL; | ||
240 | mp = ((struct _mtab_entry_t *) (*iter))->mountpt; | ||
241 | *iter = (void *) ((struct _mtab_entry_t *) (*iter))->next; | ||
242 | return mp; | ||
243 | } | ||
244 | |||
245 | void mtab_free(void) | ||
246 | { | ||
247 | struct _mtab_entry_t *this, *next; | ||
248 | |||
249 | this = mtab_cache; | ||
250 | while (this) { | ||
251 | next = this->next; | ||
252 | if (this->device) | ||
253 | free(this->device); | ||
254 | if (this->mountpt) | ||
255 | free(this->mountpt); | ||
256 | free(this); | ||
257 | this = next; | ||
258 | } | ||
259 | } | ||
@@ -1298,5 +1298,19 @@ extern char *find_unused_loop_device(void) | |||
1298 | } | 1298 | } |
1299 | #endif /* BB_FEATURE_MOUNT_LOOP */ | 1299 | #endif /* BB_FEATURE_MOUNT_LOOP */ |
1300 | 1300 | ||
1301 | #if defined BB_MTAB | ||
1302 | #define whine_if_fstab_is_missing() {} | ||
1303 | #else | ||
1304 | extern void whine_if_fstab_is_missing() | ||
1305 | { | ||
1306 | struct stat statBuf; | ||
1307 | |||
1308 | if (stat("/etc/fstab", &statBuf) < 0) | ||
1309 | fprintf(stderr, | ||
1310 | "/etc/fstab file missing -- install one to name /dev/root.\n\n"); | ||
1311 | } | ||
1312 | #endif | ||
1313 | |||
1314 | |||
1301 | 1315 | ||
1302 | /* END CODE */ | 1316 | /* END CODE */ |