Fixed the init problem where it wouldn't unmount filesystems
on reboot. Also fixed swapoff -a so it works. -Erik
This commit is contained in:
		| @@ -84,6 +84,8 @@ | ||||
| 	    - `fdflush', `length' and `printf' crashed when run without arguments | ||||
| 	    - `fdflush' tried to flush itself using *argv | ||||
| 	    - added "skip" and "seek" to dd. | ||||
| 	* swapoff -a was not working.  Now it is. | ||||
| 	* init did not cleanly unmount filesystems on reboot.  Now it does. | ||||
|  | ||||
|  | ||||
| 	-Erik Andersen | ||||
|   | ||||
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -62,7 +62,7 @@ endif | ||||
|  | ||||
| # -D_GNU_SOURCE is needed because environ is used in init.c | ||||
| ifeq ($(DODEBUG),true) | ||||
|     CFLAGS += -Wall -g -D_GNU_SOURCE -DDEBUG_INIT | ||||
|     CFLAGS += -Wall -g -D_GNU_SOURCE | ||||
|     STRIP   = | ||||
|     LDFLAGS = | ||||
| else | ||||
|   | ||||
| @@ -59,7 +59,6 @@ | ||||
| #define BB_MOUNT | ||||
| #define BB_NFSMOUNT | ||||
| //#define BB_MT | ||||
| //#define BB_MTAB | ||||
| #define BB_NSLOOKUP | ||||
| #define BB_PING | ||||
| #define BB_POWEROFF | ||||
|   | ||||
							
								
								
									
										128
									
								
								init.c
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								init.c
									
									
									
									
									
								
							| @@ -22,6 +22,11 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /* Turn this on to disable all the dangerous  | ||||
|    rebooting stuff when debugging. | ||||
| #define DEBUG_INIT | ||||
| */ | ||||
|  | ||||
| #include "internal.h" | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| @@ -78,7 +83,8 @@ typedef enum { | ||||
| 	RESPAWN, | ||||
| 	ASKFIRST, | ||||
| 	WAIT, | ||||
| 	ONCE | ||||
| 	ONCE, | ||||
| 	CTRLALTDEL | ||||
| } initActionEnum; | ||||
|  | ||||
| /* And now a list of the actions we support in the version of init */ | ||||
| @@ -93,6 +99,7 @@ static const struct initActionType actions[] = { | ||||
| 	{"askfirst", ASKFIRST}, | ||||
| 	{"wait", WAIT}, | ||||
| 	{"once", ONCE}, | ||||
| 	{"ctrlaltdel", CTRLALTDEL}, | ||||
| 	{0} | ||||
| }; | ||||
|  | ||||
| @@ -113,6 +120,7 @@ static char *log = VT_LOG; | ||||
| static int kernelVersion = 0; | ||||
| static char termType[32] = "TERM=ansi"; | ||||
| static char console[32] = _PATH_CONSOLE; | ||||
| static void delete_initAction(initAction * action); | ||||
|  | ||||
|  | ||||
| /* print a message to the specified device: | ||||
| @@ -131,8 +139,8 @@ void message(int device, char *fmt, ...) | ||||
| 		va_start(arguments, fmt); | ||||
| 		vsnprintf(msg, sizeof(msg), fmt, arguments); | ||||
| 		va_end(arguments); | ||||
| 		openlog("init", 0, LOG_DAEMON); | ||||
| 		syslog(LOG_DAEMON | LOG_NOTICE, msg); | ||||
| 		openlog("init", 0, LOG_USER); | ||||
| 		syslog(LOG_USER|LOG_INFO, msg); | ||||
| 		closelog(); | ||||
| 	} | ||||
| #else | ||||
| @@ -146,11 +154,12 @@ void message(int device, char *fmt, ...) | ||||
| 			log_fd = -2; | ||||
| 			/* log to main console instead */ | ||||
| 			device = CONSOLE; | ||||
| 		} else if ((log_fd = device_open(log, O_RDWR | O_NDELAY)) < 0) { | ||||
| 			log_fd = -1; | ||||
| 		} else if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) { | ||||
| 			log_fd = -2; | ||||
| 			fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log); | ||||
| 			fflush(stderr); | ||||
| 			return; | ||||
| 			log = NULL; | ||||
| 			device = CONSOLE; | ||||
| 		} | ||||
| 	} | ||||
| 	if ((device & LOG) && (log_fd >= 0)) { | ||||
| @@ -303,10 +312,10 @@ static void console_init() | ||||
| 		/* check for serial console and disable logging to tty3 & running a | ||||
| 		   * shell to tty2 */ | ||||
| 		if (ioctl(0, TIOCGSERIAL, &sr) == 0) { | ||||
| 			message(LOG | CONSOLE, | ||||
| 					"serial console detected.  Disabling virtual terminals.\r\n"); | ||||
| 			log = NULL; | ||||
| 			secondConsole = NULL; | ||||
| 			message(LOG | CONSOLE, | ||||
| 					"serial console detected.  Disabling virtual terminals.\r\n"); | ||||
| 		} | ||||
| 		close(fd); | ||||
| 	} | ||||
| @@ -319,6 +328,7 @@ static pid_t run(char *command, char *terminal, int get_enter) | ||||
| 	pid_t pid; | ||||
| 	char *tmpCmd; | ||||
| 	char *cmd[255]; | ||||
| 	char buf[255]; | ||||
| 	static const char press_enter[] = | ||||
|  | ||||
| 		"\nPlease press Enter to activate this console. "; | ||||
| @@ -333,7 +343,9 @@ static pid_t run(char *command, char *terminal, int get_enter) | ||||
|  | ||||
|  | ||||
| 	if ((pid = fork()) == 0) { | ||||
| #ifdef DEBUG_INIT | ||||
| 		pid_t shell_pgid = getpid(); | ||||
| #endif | ||||
|  | ||||
| 		/* Clean up */ | ||||
| 		close(0); | ||||
| @@ -369,30 +381,40 @@ static pid_t run(char *command, char *terminal, int get_enter) | ||||
| 			 */ | ||||
| 			char c; | ||||
|  | ||||
| #ifdef DEBUG_INIT | ||||
| 			message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n", | ||||
| 					command, shell_pgid, terminal); | ||||
| #endif | ||||
| 			write(fileno(stdout), press_enter, sizeof(press_enter) - 1); | ||||
| 			read(fileno(stdin), &c, 1); | ||||
| 		} | ||||
|  | ||||
| 		/* Log the process name and args */ | ||||
| 		message(LOG, "Starting pid %d, console %s: '", | ||||
| 				shell_pgid, terminal, command); | ||||
|  | ||||
| 		/* Convert command (char*) into cmd (char**, one word per string) */ | ||||
| 		for (tmpCmd = command, i = 0; | ||||
| 			 (tmpCmd = strsep(&command, " \t")) != NULL;) { | ||||
| 			if (*tmpCmd != '\0') { | ||||
| 				cmd[i] = tmpCmd; | ||||
| #ifdef DEBUG_INIT | ||||
| 				message(LOG, "%s ", tmpCmd); | ||||
| 		/* Log the process name and args */ | ||||
| 		message(LOG, "Starting pid %d, console %s: '%s'\r\n", | ||||
| 				shell_pgid, terminal, command); | ||||
| #endif | ||||
| 				tmpCmd++; | ||||
| 				i++; | ||||
|  | ||||
| 		/* See if any special /bin/sh requiring characters are present */ | ||||
| 		if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { | ||||
| 			cmd[0] = SHELL; | ||||
| 			cmd[1] = "-c"; | ||||
| 			strcpy(buf, "exec "); | ||||
| 			strncat(buf, command, sizeof(buf) - strlen(buf) - 1); | ||||
| 			cmd[2] = buf; | ||||
| 			cmd[3] = NULL; | ||||
| 		} else { | ||||
| 			/* Convert command (char*) into cmd (char**, one word per string) */ | ||||
| 			for (tmpCmd = command, i = 0; | ||||
| 				 (tmpCmd = strsep(&command, " \t")) != NULL;) { | ||||
| 				if (*tmpCmd != '\0') { | ||||
| 					cmd[i] = tmpCmd; | ||||
| 					tmpCmd++; | ||||
| 					i++; | ||||
| 				} | ||||
| 			} | ||||
| 			cmd[i] = NULL; | ||||
| 		} | ||||
| 		cmd[i] = NULL; | ||||
| 		message(LOG, "'\r\n"); | ||||
|  | ||||
| 		/* Now run it.  The new program will take over this PID,  | ||||
| 		 * so nothing further in init.c should be run. */ | ||||
| @@ -413,9 +435,8 @@ static int waitfor(char *command, char *terminal, int get_enter) | ||||
|  | ||||
| 	while (1) { | ||||
| 		wpid = wait(&status); | ||||
| 		if (wpid > 0) { | ||||
| 			message(LOG, "Process '%s' (pid %d) exited.\n", command, wpid); | ||||
| 			break; | ||||
| 		if (wpid > 0 && wpid != pid) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (wpid == pid) | ||||
| 			break; | ||||
| @@ -424,7 +445,7 @@ static int waitfor(char *command, char *terminal, int get_enter) | ||||
| } | ||||
|  | ||||
| /* Make sure there is enough memory to do something useful. * | ||||
|  * Calls swapon if needed so be sure /proc is mounted. */ | ||||
|  * Calls "swapon -a" if needed so be sure /etc/fstab is present... */ | ||||
| static void check_memory() | ||||
| { | ||||
| 	struct stat statBuf; | ||||
| @@ -434,7 +455,7 @@ static void check_memory() | ||||
|  | ||||
| 	if (stat("/etc/fstab", &statBuf) == 0) { | ||||
| 		/* Try to turn on swap */ | ||||
| 		waitfor("/bin/swapon swapon -a", log, FALSE); | ||||
| 		system("/sbin/swapon swapon -a"); | ||||
| 		if (mem_total() < 3500) | ||||
| 			goto goodnight; | ||||
| 	} else | ||||
| @@ -448,31 +469,45 @@ static void check_memory() | ||||
| 		sleep(1); | ||||
| } | ||||
|  | ||||
| /* Run all commands to be run right before halt/reboot */ | ||||
| static void run_lastAction(void) | ||||
| { | ||||
| 	initAction *a; | ||||
| 	for (a = initActionList; a; a = a->nextPtr) { | ||||
| 		if (a->action == CTRLALTDEL) { | ||||
| 			waitfor(a->process, a->console, FALSE); | ||||
| 			delete_initAction(a); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifndef DEBUG_INIT | ||||
| static void shutdown_system(void) | ||||
| { | ||||
|  | ||||
| 	/* first disable our SIGHUP signal */ | ||||
| 	signal(SIGHUP, SIG_DFL); | ||||
|  | ||||
| 	/* Allow Ctrl-Alt-Del to reboot system. */ | ||||
| 	reboot(RB_ENABLE_CAD); | ||||
| 	message(CONSOLE, "\r\nThe system is going down NOW !!\r\n"); | ||||
|  | ||||
| 	message(CONSOLE|LOG, "\r\nThe system is going down NOW !!\r\n"); | ||||
| 	sync(); | ||||
|  | ||||
| 	/* Send signals to every process _except_ pid 1 */ | ||||
| 	message(CONSOLE, "Sending SIGTERM to all processes.\r\n"); | ||||
| 	message(CONSOLE|LOG, "Sending SIGTERM to all processes.\r\n"); | ||||
| 	kill(-1, SIGTERM); | ||||
| 	sleep(5); | ||||
| 	sleep(1); | ||||
| 	sync(); | ||||
|  | ||||
| 	message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); | ||||
| 	message(CONSOLE|LOG, "Sending SIGKILL to all processes.\r\n"); | ||||
| 	kill(-1, SIGKILL); | ||||
| 	sleep(5); | ||||
| 	sleep(1); | ||||
|  | ||||
| 	/* run everything to be run at "ctrlaltdel" */ | ||||
| 	run_lastAction(); | ||||
|  | ||||
| 	message(CONSOLE, "Disabling swap.\r\n"); | ||||
| 	waitfor("swapoff -a", console, FALSE); | ||||
| 	message(CONSOLE, "Unmounting filesystems.\r\n"); | ||||
| 	waitfor("umount -a -r", console, FALSE); | ||||
| 	sync(); | ||||
| 	if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) { | ||||
| 		/* bdflush, kupdate not needed for kernels >2.2.11 */ | ||||
| @@ -484,14 +519,14 @@ static void shutdown_system(void) | ||||
| static void halt_signal(int sig) | ||||
| { | ||||
| 	shutdown_system(); | ||||
| 	message(CONSOLE, | ||||
| 	message(CONSOLE|LOG, | ||||
| 			"The system is halted. Press %s or turn off power\r\n", | ||||
| 			(secondConsole == NULL)	/* serial console */ | ||||
| 			? "Reset" : "CTRL-ALT-DEL"); | ||||
| 	sync(); | ||||
|  | ||||
| 	/* allow time for last message to reach serial console */ | ||||
| 	sleep(5); | ||||
| 	sleep(2); | ||||
|  | ||||
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) | ||||
| 	if (sig == SIGUSR2) | ||||
| @@ -505,7 +540,7 @@ static void halt_signal(int sig) | ||||
| static void reboot_signal(int sig) | ||||
| { | ||||
| 	shutdown_system(); | ||||
| 	message(CONSOLE, "Please stand by while rebooting the system.\r\n"); | ||||
| 	message(CONSOLE|LOG, "Please stand by while rebooting the system.\r\n"); | ||||
| 	sync(); | ||||
|  | ||||
| 	/* allow time for last message to reach serial console */ | ||||
| @@ -631,7 +666,7 @@ void new_initAction(initActionEnum action, char *process, char *cons) | ||||
| //      newAction->process, newAction->action, newAction->console); | ||||
| } | ||||
|  | ||||
| void delete_initAction(initAction * action) | ||||
| static void delete_initAction(initAction * action) | ||||
| { | ||||
| 	initAction *a, *b = NULL; | ||||
|  | ||||
| @@ -669,6 +704,10 @@ void parse_inittab(void) | ||||
| 	if (file == NULL) { | ||||
| 		/* No inittab file -- set up some default behavior */ | ||||
| #endif | ||||
| 		/* Swapoff on halt/reboot */ | ||||
| 		new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console); | ||||
| 		/* Umount all filesystems on halt/reboot */ | ||||
| 		new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console); | ||||
| 		/* Askfirst shell on tty1 */ | ||||
| 		new_initAction(ASKFIRST, SHELL, console); | ||||
| 		/* Askfirst shell on tty2 */ | ||||
| @@ -756,6 +795,8 @@ void parse_inittab(void) | ||||
| #endif | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| extern int init_main(int argc, char **argv) | ||||
| { | ||||
| 	initAction *a; | ||||
| @@ -768,9 +809,6 @@ extern int init_main(int argc, char **argv) | ||||
| 		usage("init\n\nInit is the parent of all processes.\n\n" | ||||
| 			  "This version of init is designed to be run only by the kernel\n"); | ||||
| 	} | ||||
| 	/* Fix up argv[0] to be certain we claim to be init */ | ||||
| 	strncpy(argv[0], "init", strlen(argv[0])); | ||||
|  | ||||
| 	/* Set up sig handlers  -- be sure to | ||||
| 	 * clear all of these in run() */ | ||||
| 	signal(SIGUSR1, halt_signal); | ||||
| @@ -838,6 +876,10 @@ extern int init_main(int argc, char **argv) | ||||
| 		 * of "askfirst" shells */ | ||||
| 		parse_inittab(); | ||||
| 	} | ||||
| 	 | ||||
| 	/* Fix up argv[0] to be certain we claim to be init */ | ||||
| 	strncpy(argv[0], "init", strlen(argv[0])+1); | ||||
| 	strncpy(argv[1], "\0", strlen(argv[1])+1); | ||||
|  | ||||
| 	/* Now run everything that needs to be run */ | ||||
|  | ||||
|   | ||||
							
								
								
									
										128
									
								
								init/init.c
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								init/init.c
									
									
									
									
									
								
							| @@ -22,6 +22,11 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /* Turn this on to disable all the dangerous  | ||||
|    rebooting stuff when debugging. | ||||
| #define DEBUG_INIT | ||||
| */ | ||||
|  | ||||
| #include "internal.h" | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| @@ -78,7 +83,8 @@ typedef enum { | ||||
| 	RESPAWN, | ||||
| 	ASKFIRST, | ||||
| 	WAIT, | ||||
| 	ONCE | ||||
| 	ONCE, | ||||
| 	CTRLALTDEL | ||||
| } initActionEnum; | ||||
|  | ||||
| /* And now a list of the actions we support in the version of init */ | ||||
| @@ -93,6 +99,7 @@ static const struct initActionType actions[] = { | ||||
| 	{"askfirst", ASKFIRST}, | ||||
| 	{"wait", WAIT}, | ||||
| 	{"once", ONCE}, | ||||
| 	{"ctrlaltdel", CTRLALTDEL}, | ||||
| 	{0} | ||||
| }; | ||||
|  | ||||
| @@ -113,6 +120,7 @@ static char *log = VT_LOG; | ||||
| static int kernelVersion = 0; | ||||
| static char termType[32] = "TERM=ansi"; | ||||
| static char console[32] = _PATH_CONSOLE; | ||||
| static void delete_initAction(initAction * action); | ||||
|  | ||||
|  | ||||
| /* print a message to the specified device: | ||||
| @@ -131,8 +139,8 @@ void message(int device, char *fmt, ...) | ||||
| 		va_start(arguments, fmt); | ||||
| 		vsnprintf(msg, sizeof(msg), fmt, arguments); | ||||
| 		va_end(arguments); | ||||
| 		openlog("init", 0, LOG_DAEMON); | ||||
| 		syslog(LOG_DAEMON | LOG_NOTICE, msg); | ||||
| 		openlog("init", 0, LOG_USER); | ||||
| 		syslog(LOG_USER|LOG_INFO, msg); | ||||
| 		closelog(); | ||||
| 	} | ||||
| #else | ||||
| @@ -146,11 +154,12 @@ void message(int device, char *fmt, ...) | ||||
| 			log_fd = -2; | ||||
| 			/* log to main console instead */ | ||||
| 			device = CONSOLE; | ||||
| 		} else if ((log_fd = device_open(log, O_RDWR | O_NDELAY)) < 0) { | ||||
| 			log_fd = -1; | ||||
| 		} else if ((log_fd = device_open(log, O_RDWR|O_NDELAY)) < 0) { | ||||
| 			log_fd = -2; | ||||
| 			fprintf(stderr, "Bummer, can't write to log on %s!\r\n", log); | ||||
| 			fflush(stderr); | ||||
| 			return; | ||||
| 			log = NULL; | ||||
| 			device = CONSOLE; | ||||
| 		} | ||||
| 	} | ||||
| 	if ((device & LOG) && (log_fd >= 0)) { | ||||
| @@ -303,10 +312,10 @@ static void console_init() | ||||
| 		/* check for serial console and disable logging to tty3 & running a | ||||
| 		   * shell to tty2 */ | ||||
| 		if (ioctl(0, TIOCGSERIAL, &sr) == 0) { | ||||
| 			message(LOG | CONSOLE, | ||||
| 					"serial console detected.  Disabling virtual terminals.\r\n"); | ||||
| 			log = NULL; | ||||
| 			secondConsole = NULL; | ||||
| 			message(LOG | CONSOLE, | ||||
| 					"serial console detected.  Disabling virtual terminals.\r\n"); | ||||
| 		} | ||||
| 		close(fd); | ||||
| 	} | ||||
| @@ -319,6 +328,7 @@ static pid_t run(char *command, char *terminal, int get_enter) | ||||
| 	pid_t pid; | ||||
| 	char *tmpCmd; | ||||
| 	char *cmd[255]; | ||||
| 	char buf[255]; | ||||
| 	static const char press_enter[] = | ||||
|  | ||||
| 		"\nPlease press Enter to activate this console. "; | ||||
| @@ -333,7 +343,9 @@ static pid_t run(char *command, char *terminal, int get_enter) | ||||
|  | ||||
|  | ||||
| 	if ((pid = fork()) == 0) { | ||||
| #ifdef DEBUG_INIT | ||||
| 		pid_t shell_pgid = getpid(); | ||||
| #endif | ||||
|  | ||||
| 		/* Clean up */ | ||||
| 		close(0); | ||||
| @@ -369,30 +381,40 @@ static pid_t run(char *command, char *terminal, int get_enter) | ||||
| 			 */ | ||||
| 			char c; | ||||
|  | ||||
| #ifdef DEBUG_INIT | ||||
| 			message(LOG, "Waiting for enter to start '%s' (pid %d, console %s)\r\n", | ||||
| 					command, shell_pgid, terminal); | ||||
| #endif | ||||
| 			write(fileno(stdout), press_enter, sizeof(press_enter) - 1); | ||||
| 			read(fileno(stdin), &c, 1); | ||||
| 		} | ||||
|  | ||||
| 		/* Log the process name and args */ | ||||
| 		message(LOG, "Starting pid %d, console %s: '", | ||||
| 				shell_pgid, terminal, command); | ||||
|  | ||||
| 		/* Convert command (char*) into cmd (char**, one word per string) */ | ||||
| 		for (tmpCmd = command, i = 0; | ||||
| 			 (tmpCmd = strsep(&command, " \t")) != NULL;) { | ||||
| 			if (*tmpCmd != '\0') { | ||||
| 				cmd[i] = tmpCmd; | ||||
| #ifdef DEBUG_INIT | ||||
| 				message(LOG, "%s ", tmpCmd); | ||||
| 		/* Log the process name and args */ | ||||
| 		message(LOG, "Starting pid %d, console %s: '%s'\r\n", | ||||
| 				shell_pgid, terminal, command); | ||||
| #endif | ||||
| 				tmpCmd++; | ||||
| 				i++; | ||||
|  | ||||
| 		/* See if any special /bin/sh requiring characters are present */ | ||||
| 		if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) { | ||||
| 			cmd[0] = SHELL; | ||||
| 			cmd[1] = "-c"; | ||||
| 			strcpy(buf, "exec "); | ||||
| 			strncat(buf, command, sizeof(buf) - strlen(buf) - 1); | ||||
| 			cmd[2] = buf; | ||||
| 			cmd[3] = NULL; | ||||
| 		} else { | ||||
| 			/* Convert command (char*) into cmd (char**, one word per string) */ | ||||
| 			for (tmpCmd = command, i = 0; | ||||
| 				 (tmpCmd = strsep(&command, " \t")) != NULL;) { | ||||
| 				if (*tmpCmd != '\0') { | ||||
| 					cmd[i] = tmpCmd; | ||||
| 					tmpCmd++; | ||||
| 					i++; | ||||
| 				} | ||||
| 			} | ||||
| 			cmd[i] = NULL; | ||||
| 		} | ||||
| 		cmd[i] = NULL; | ||||
| 		message(LOG, "'\r\n"); | ||||
|  | ||||
| 		/* Now run it.  The new program will take over this PID,  | ||||
| 		 * so nothing further in init.c should be run. */ | ||||
| @@ -413,9 +435,8 @@ static int waitfor(char *command, char *terminal, int get_enter) | ||||
|  | ||||
| 	while (1) { | ||||
| 		wpid = wait(&status); | ||||
| 		if (wpid > 0) { | ||||
| 			message(LOG, "Process '%s' (pid %d) exited.\n", command, wpid); | ||||
| 			break; | ||||
| 		if (wpid > 0 && wpid != pid) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (wpid == pid) | ||||
| 			break; | ||||
| @@ -424,7 +445,7 @@ static int waitfor(char *command, char *terminal, int get_enter) | ||||
| } | ||||
|  | ||||
| /* Make sure there is enough memory to do something useful. * | ||||
|  * Calls swapon if needed so be sure /proc is mounted. */ | ||||
|  * Calls "swapon -a" if needed so be sure /etc/fstab is present... */ | ||||
| static void check_memory() | ||||
| { | ||||
| 	struct stat statBuf; | ||||
| @@ -434,7 +455,7 @@ static void check_memory() | ||||
|  | ||||
| 	if (stat("/etc/fstab", &statBuf) == 0) { | ||||
| 		/* Try to turn on swap */ | ||||
| 		waitfor("/bin/swapon swapon -a", log, FALSE); | ||||
| 		system("/sbin/swapon swapon -a"); | ||||
| 		if (mem_total() < 3500) | ||||
| 			goto goodnight; | ||||
| 	} else | ||||
| @@ -448,31 +469,45 @@ static void check_memory() | ||||
| 		sleep(1); | ||||
| } | ||||
|  | ||||
| /* Run all commands to be run right before halt/reboot */ | ||||
| static void run_lastAction(void) | ||||
| { | ||||
| 	initAction *a; | ||||
| 	for (a = initActionList; a; a = a->nextPtr) { | ||||
| 		if (a->action == CTRLALTDEL) { | ||||
| 			waitfor(a->process, a->console, FALSE); | ||||
| 			delete_initAction(a); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifndef DEBUG_INIT | ||||
| static void shutdown_system(void) | ||||
| { | ||||
|  | ||||
| 	/* first disable our SIGHUP signal */ | ||||
| 	signal(SIGHUP, SIG_DFL); | ||||
|  | ||||
| 	/* Allow Ctrl-Alt-Del to reboot system. */ | ||||
| 	reboot(RB_ENABLE_CAD); | ||||
| 	message(CONSOLE, "\r\nThe system is going down NOW !!\r\n"); | ||||
|  | ||||
| 	message(CONSOLE|LOG, "\r\nThe system is going down NOW !!\r\n"); | ||||
| 	sync(); | ||||
|  | ||||
| 	/* Send signals to every process _except_ pid 1 */ | ||||
| 	message(CONSOLE, "Sending SIGTERM to all processes.\r\n"); | ||||
| 	message(CONSOLE|LOG, "Sending SIGTERM to all processes.\r\n"); | ||||
| 	kill(-1, SIGTERM); | ||||
| 	sleep(5); | ||||
| 	sleep(1); | ||||
| 	sync(); | ||||
|  | ||||
| 	message(CONSOLE, "Sending SIGKILL to all processes.\r\n"); | ||||
| 	message(CONSOLE|LOG, "Sending SIGKILL to all processes.\r\n"); | ||||
| 	kill(-1, SIGKILL); | ||||
| 	sleep(5); | ||||
| 	sleep(1); | ||||
|  | ||||
| 	/* run everything to be run at "ctrlaltdel" */ | ||||
| 	run_lastAction(); | ||||
|  | ||||
| 	message(CONSOLE, "Disabling swap.\r\n"); | ||||
| 	waitfor("swapoff -a", console, FALSE); | ||||
| 	message(CONSOLE, "Unmounting filesystems.\r\n"); | ||||
| 	waitfor("umount -a -r", console, FALSE); | ||||
| 	sync(); | ||||
| 	if (kernelVersion > 0 && kernelVersion <= 2 * 65536 + 2 * 256 + 11) { | ||||
| 		/* bdflush, kupdate not needed for kernels >2.2.11 */ | ||||
| @@ -484,14 +519,14 @@ static void shutdown_system(void) | ||||
| static void halt_signal(int sig) | ||||
| { | ||||
| 	shutdown_system(); | ||||
| 	message(CONSOLE, | ||||
| 	message(CONSOLE|LOG, | ||||
| 			"The system is halted. Press %s or turn off power\r\n", | ||||
| 			(secondConsole == NULL)	/* serial console */ | ||||
| 			? "Reset" : "CTRL-ALT-DEL"); | ||||
| 	sync(); | ||||
|  | ||||
| 	/* allow time for last message to reach serial console */ | ||||
| 	sleep(5); | ||||
| 	sleep(2); | ||||
|  | ||||
| #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) | ||||
| 	if (sig == SIGUSR2) | ||||
| @@ -505,7 +540,7 @@ static void halt_signal(int sig) | ||||
| static void reboot_signal(int sig) | ||||
| { | ||||
| 	shutdown_system(); | ||||
| 	message(CONSOLE, "Please stand by while rebooting the system.\r\n"); | ||||
| 	message(CONSOLE|LOG, "Please stand by while rebooting the system.\r\n"); | ||||
| 	sync(); | ||||
|  | ||||
| 	/* allow time for last message to reach serial console */ | ||||
| @@ -631,7 +666,7 @@ void new_initAction(initActionEnum action, char *process, char *cons) | ||||
| //      newAction->process, newAction->action, newAction->console); | ||||
| } | ||||
|  | ||||
| void delete_initAction(initAction * action) | ||||
| static void delete_initAction(initAction * action) | ||||
| { | ||||
| 	initAction *a, *b = NULL; | ||||
|  | ||||
| @@ -669,6 +704,10 @@ void parse_inittab(void) | ||||
| 	if (file == NULL) { | ||||
| 		/* No inittab file -- set up some default behavior */ | ||||
| #endif | ||||
| 		/* Swapoff on halt/reboot */ | ||||
| 		new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console); | ||||
| 		/* Umount all filesystems on halt/reboot */ | ||||
| 		new_initAction(CTRLALTDEL, "/bin/umount -a -r > /dev/null 2>&1", console); | ||||
| 		/* Askfirst shell on tty1 */ | ||||
| 		new_initAction(ASKFIRST, SHELL, console); | ||||
| 		/* Askfirst shell on tty2 */ | ||||
| @@ -756,6 +795,8 @@ void parse_inittab(void) | ||||
| #endif | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| extern int init_main(int argc, char **argv) | ||||
| { | ||||
| 	initAction *a; | ||||
| @@ -768,9 +809,6 @@ extern int init_main(int argc, char **argv) | ||||
| 		usage("init\n\nInit is the parent of all processes.\n\n" | ||||
| 			  "This version of init is designed to be run only by the kernel\n"); | ||||
| 	} | ||||
| 	/* Fix up argv[0] to be certain we claim to be init */ | ||||
| 	strncpy(argv[0], "init", strlen(argv[0])); | ||||
|  | ||||
| 	/* Set up sig handlers  -- be sure to | ||||
| 	 * clear all of these in run() */ | ||||
| 	signal(SIGUSR1, halt_signal); | ||||
| @@ -838,6 +876,10 @@ extern int init_main(int argc, char **argv) | ||||
| 		 * of "askfirst" shells */ | ||||
| 		parse_inittab(); | ||||
| 	} | ||||
| 	 | ||||
| 	/* Fix up argv[0] to be certain we claim to be init */ | ||||
| 	strncpy(argv[0], "init", strlen(argv[0])+1); | ||||
| 	strncpy(argv[1], "\0", strlen(argv[1])+1); | ||||
|  | ||||
| 	/* Now run everything that needs to be run */ | ||||
|  | ||||
|   | ||||
| @@ -31,6 +31,7 @@ | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/stat.h> | ||||
| //#include <sys/param.h> | ||||
| #include <mntent.h> | ||||
|  | ||||
|  | ||||
| @@ -186,6 +187,7 @@ extern pid_t findInitPid(); | ||||
| #if defined BB_INIT || defined BB_SYSLOGD | ||||
| extern int device_open(char *device, int mode); | ||||
| #endif | ||||
| extern void whine_if_fstab_is_missing(); | ||||
|  | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| extern int del_loop(const char *device); | ||||
|   | ||||
							
								
								
									
										54
									
								
								mount.c
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								mount.c
									
									
									
									
									
								
							| @@ -53,7 +53,7 @@ | ||||
| #include <linux/loop.h> | ||||
|  | ||||
|  | ||||
| static int use_loop = 0; | ||||
| static int use_loop = FALSE; | ||||
| #endif | ||||
|  | ||||
| extern const char mtab_file[];	/* Defined in utility.c */ | ||||
| @@ -114,13 +114,14 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | ||||
| 		 char *mtab_opts) | ||||
| { | ||||
| 	int status = 0; | ||||
| 	char *lofile = NULL; | ||||
|  | ||||
| #if defined BB_MTAB | ||||
| 	if (fakeIt == FALSE) | ||||
| #endif | ||||
| 	{ | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| 		if (use_loop) { | ||||
| 		if (use_loop==TRUE) { | ||||
| 			int loro = flags & MS_RDONLY; | ||||
| 			char *lofile = specialfile; | ||||
|  | ||||
| @@ -137,6 +138,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | ||||
| 				fprintf(stderr, "WARNING: loop device is read-only\n"); | ||||
| 				flags &= ~MS_RDONLY; | ||||
| 			} | ||||
| 			use_loop = FALSE; | ||||
| 		} | ||||
| #endif | ||||
| 		status = | ||||
| @@ -157,7 +159,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | ||||
|  | ||||
| 	/* Bummer.  mount failed.  Clean up */ | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| 	if (specialfile != NULL) { | ||||
| 	if (lofile != NULL) { | ||||
| 		del_loop(specialfile); | ||||
| 	} | ||||
| #endif | ||||
| @@ -166,20 +168,6 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | ||||
|  | ||||
|  | ||||
|  | ||||
| #if defined BB_MTAB | ||||
| #define whine_if_fstab_is_missing() {} | ||||
| #else | ||||
| extern void whine_if_fstab_is_missing() | ||||
| { | ||||
| 	struct stat statBuf; | ||||
|  | ||||
| 	if (stat("/etc/fstab", &statBuf) < 0) | ||||
| 		fprintf(stderr, | ||||
| 				"/etc/fstab file missing -- install one to name /dev/root.\n\n"); | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* Seperate standard mount options from the nonstandard string options */ | ||||
| static void | ||||
| parse_mount_options(char *options, unsigned long *flags, char *strflags) | ||||
| @@ -204,7 +192,7 @@ parse_mount_options(char *options, unsigned long *flags, char *strflags) | ||||
| 		} | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| 		if (gotone == FALSE && !strcasecmp("loop", options)) {	/* loop device support */ | ||||
| 			use_loop = 1; | ||||
| 			use_loop = TRUE; | ||||
| 			gotone = TRUE; | ||||
| 		} | ||||
| #endif | ||||
| @@ -229,7 +217,7 @@ parse_mount_options(char *options, unsigned long *flags, char *strflags) | ||||
| int | ||||
| mount_one(char *blockDevice, char *directory, char *filesystemType, | ||||
| 		  unsigned long flags, char *string_flags, int useMtab, int fakeIt, | ||||
| 		  char *mtab_opts) | ||||
| 		  char *mtab_opts, int whineOnErrors) | ||||
| { | ||||
| 	int status = 0; | ||||
|  | ||||
| @@ -270,9 +258,11 @@ mount_one(char *blockDevice, char *directory, char *filesystemType, | ||||
| 						  fakeIt, mtab_opts); | ||||
| 	} | ||||
|  | ||||
| 	if (status == FALSE) { | ||||
| 		fprintf(stderr, "Mounting %s on %s failed: %s\n", | ||||
| 				blockDevice, directory, strerror(errno)); | ||||
| 	if (status == FALSE && whineOnErrors == TRUE) { | ||||
| 		if (whineOnErrors == TRUE) { | ||||
| 			fprintf(stderr, "Mounting %s on %s failed: %s\n", | ||||
| 					blockDevice, directory, strerror(errno)); | ||||
| 		} | ||||
| 		return (FALSE); | ||||
| 	} | ||||
| 	return (TRUE); | ||||
| @@ -387,18 +377,28 @@ extern int mount_main(int argc, char **argv) | ||||
| 			exit(FALSE); | ||||
| 		} | ||||
| 		while ((m = getmntent(f)) != NULL) { | ||||
| 			// If the file system isn't noauto, and isn't mounted on /,  | ||||
| 			// If the file system isn't noauto,  | ||||
| 			// and isn't swap or nfs, then mount it | ||||
| 			if ((!strstr(m->mnt_opts, "noauto")) && | ||||
| 				(m->mnt_dir[1] != '\0') && | ||||
| 				(!strstr(m->mnt_type, "swap")) && | ||||
| 				(!strstr(m->mnt_type, "nfs"))) { | ||||
| 				flags = 0; | ||||
| 				*string_flags = '\0'; | ||||
| 				parse_mount_options(m->mnt_opts, &flags, string_flags); | ||||
| 				mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | ||||
| 				/* If the directory is /, try to remount | ||||
| 				 * with the options specified in fstab */ | ||||
| 				if (m->mnt_dir[0] == '/' && m->mnt_dir[1] == '\0') { | ||||
| 					flags |= MS_REMOUNT; | ||||
| 				} | ||||
| 				if (mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | ||||
| 						  flags, string_flags, useMtab, fakeIt, | ||||
| 						  extra_opts); | ||||
| 						  extra_opts, FALSE))  | ||||
| 				{ | ||||
| 					/* Try again, but this time try a remount */ | ||||
| 					mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | ||||
| 							  flags|MS_REMOUNT, string_flags, useMtab, fakeIt, | ||||
| 							  extra_opts, TRUE); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		endmntent(f); | ||||
| @@ -414,7 +414,7 @@ extern int mount_main(int argc, char **argv) | ||||
| #endif | ||||
| 			exit(mount_one(device, directory, filesystemType, | ||||
| 						   flags, string_flags, useMtab, fakeIt, | ||||
| 						   extra_opts)); | ||||
| 						   extra_opts, TRUE)); | ||||
| 		} else { | ||||
| 			goto goodbye; | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										23
									
								
								swaponoff.c
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								swaponoff.c
									
									
									
									
									
								
							| @@ -36,13 +36,16 @@ static int whichApp; | ||||
| static const char *appName; | ||||
|  | ||||
| static const char swapoff_usage[] = | ||||
| 	"swapoff [OPTION] [device]\n\n" | ||||
| 	"Stop swapping virtual memory pages on the given device.\n\n" | ||||
| 	"Options:\n" | ||||
| 	"\t-a\tStop swapping on all swap devices\n"; | ||||
|  | ||||
| 	"swapoff device\n" | ||||
| 	"\nStop swapping virtual memory pages on the given device.\n"; | ||||
| static const char swapon_usage[] = | ||||
|  | ||||
| 	"swapon device\n" | ||||
| 	"\nStart swapping virtual memory pages on the given device.\n"; | ||||
| 	"swapon [OPTION] [device]\n\n" | ||||
| 	"Start swapping virtual memory pages on the given device.\n\n" | ||||
| 	"Options:\n" | ||||
| 	"\t-a\tStart swapping on all swap devices\n"; | ||||
|  | ||||
|  | ||||
| #define SWAPON_APP   1 | ||||
| @@ -85,12 +88,6 @@ static void do_em_all() | ||||
|  | ||||
| extern int swap_on_off_main(int argc, char **argv) | ||||
| { | ||||
| 	struct stat statBuf; | ||||
|  | ||||
| 	if (stat("/etc/fstab", &statBuf) < 0) | ||||
| 		fprintf(stderr, | ||||
| 				"/etc/fstab file missing -- Please install one.\n\n"); | ||||
|  | ||||
| 	if (strcmp(*argv, "swapon") == 0) { | ||||
| 		appName = *argv; | ||||
| 		whichApp = SWAPON_APP; | ||||
| @@ -100,8 +97,9 @@ extern int swap_on_off_main(int argc, char **argv) | ||||
| 		whichApp = SWAPOFF_APP; | ||||
| 	} | ||||
|  | ||||
| 	if (argc < 2) | ||||
| 	if (argc != 2) { | ||||
| 		goto usage_and_exit; | ||||
| 	} | ||||
| 	argc--; | ||||
| 	argv++; | ||||
|  | ||||
| @@ -110,6 +108,7 @@ extern int swap_on_off_main(int argc, char **argv) | ||||
| 		while (*++(*argv)) | ||||
| 			switch (**argv) { | ||||
| 			case 'a': | ||||
| 				whine_if_fstab_is_missing(); | ||||
| 				do_em_all(); | ||||
| 				break; | ||||
| 			default: | ||||
|   | ||||
							
								
								
									
										216
									
								
								umount.c
									
									
									
									
									
								
							
							
						
						
									
										216
									
								
								umount.c
									
									
									
									
									
								
							| @@ -29,6 +29,7 @@ | ||||
| #include <fstab.h> | ||||
| #include <errno.h> | ||||
|  | ||||
|  | ||||
| static const char umount_usage[] = | ||||
| 	"umount [flags] filesystem|directory\n\n" | ||||
| 	"Flags:\n" "\t-a:\tUnmount all file systems" | ||||
| @@ -57,113 +58,6 @@ static int umountAll = FALSE; | ||||
| static int doRemount = FALSE; | ||||
| extern const char mtab_file[];	/* Defined in utility.c */ | ||||
|  | ||||
| #define MIN(x,y) (x > y ? x : y) | ||||
|  | ||||
| static int do_umount(const char *name, int useMtab) | ||||
| { | ||||
| 	int status; | ||||
| 	char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE); | ||||
|  | ||||
| 	if (blockDevice && strcmp(blockDevice, name) == 0) | ||||
| 		name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT); | ||||
|  | ||||
| 	status = umount(name); | ||||
|  | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| 	if (blockDevice != NULL && !strncmp("/dev/loop", blockDevice, 9)) | ||||
| 		/* this was a loop device, delete it */ | ||||
| 		del_loop(blockDevice); | ||||
| #endif | ||||
| #if defined BB_FEATURE_REMOUNT | ||||
| 	if (status != 0 && doRemount == TRUE && errno == EBUSY) { | ||||
| 		status = mount(blockDevice, name, NULL, | ||||
| 					   MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL); | ||||
| 		if (status == 0) { | ||||
| 			fprintf(stderr, "umount: %s busy - remounted read-only\n", | ||||
| 					blockDevice); | ||||
| 			/* TODO: update mtab if BB_MTAB is defined */ | ||||
| 		} else { | ||||
| 			fprintf(stderr, "umount: Cannot remount %s read-only\n", | ||||
| 					blockDevice); | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 	if (status == 0) { | ||||
| #if defined BB_MTAB | ||||
| 		if (useMtab == TRUE) | ||||
| 			erase_mtab(name); | ||||
| #endif | ||||
| 		return (TRUE); | ||||
| 	} | ||||
| 	return (FALSE); | ||||
| } | ||||
|  | ||||
| static int umount_all(int useMtab) | ||||
| { | ||||
| 	int status = TRUE; | ||||
| 	char *mountpt; | ||||
| 	void *iter; | ||||
|  | ||||
| 	for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) { | ||||
| 		status = do_umount(mountpt, useMtab); | ||||
| 		if (status != 0) { | ||||
| 			/* Don't bother retrying the umount on busy devices */ | ||||
| 			if (errno == EBUSY) { | ||||
| 				perror(mountpt); | ||||
| 				continue; | ||||
| 			} | ||||
| 			status = do_umount(mountpt, useMtab); | ||||
| 			if (status != 0) { | ||||
| 				printf("Couldn't umount %s on %s: %s\n", | ||||
| 					   mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), | ||||
| 					   strerror(errno)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return (status); | ||||
| } | ||||
|  | ||||
| extern int umount_main(int argc, char **argv) | ||||
| { | ||||
| 	if (argc < 2) { | ||||
| 		usage(umount_usage); | ||||
| 	} | ||||
|  | ||||
| 	/* Parse any options */ | ||||
| 	while (--argc > 0 && **(++argv) == '-') { | ||||
| 		while (*++(*argv)) | ||||
| 			switch (**argv) { | ||||
| 			case 'a': | ||||
| 				umountAll = TRUE; | ||||
| 				break; | ||||
| #ifdef BB_MTAB | ||||
| 			case 'n': | ||||
| 				useMtab = FALSE; | ||||
| 				break; | ||||
| #endif | ||||
| #ifdef BB_FEATURE_REMOUNT | ||||
| 			case 'r': | ||||
| 				doRemount = TRUE; | ||||
| 				break; | ||||
| #endif | ||||
| 			default: | ||||
| 				usage(umount_usage); | ||||
| 			} | ||||
| 	} | ||||
|  | ||||
| 	mtab_read(); | ||||
| 	if (umountAll == TRUE) { | ||||
| 		exit(umount_all(useMtab)); | ||||
| 	} | ||||
| 	if (do_umount(*argv, useMtab) == 0) | ||||
| 		exit(TRUE); | ||||
| 	else { | ||||
| 		perror("umount"); | ||||
| 		exit(FALSE); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* These functions are here because the getmntent functions do not appear | ||||
|  * to be re-entrant, which leads to all sorts of problems when we try to | ||||
| @@ -257,3 +151,111 @@ void mtab_free(void) | ||||
| 		this = next; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int do_umount(const char *name, int useMtab) | ||||
| { | ||||
| 	int status; | ||||
| 	char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE); | ||||
|  | ||||
| 	if (blockDevice && strcmp(blockDevice, name) == 0) | ||||
| 		name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT); | ||||
|  | ||||
| 	status = umount(name); | ||||
|  | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| 	if (blockDevice != NULL && !strncmp("/dev/loop", blockDevice, 9)) | ||||
| 		/* this was a loop device, delete it */ | ||||
| 		del_loop(blockDevice); | ||||
| #endif | ||||
| #if defined BB_FEATURE_REMOUNT | ||||
| 	if (status != 0 && doRemount == TRUE && errno == EBUSY) { | ||||
| 		status = mount(blockDevice, name, NULL, | ||||
| 					   MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL); | ||||
| 		if (status == 0) { | ||||
| 			fprintf(stderr, "umount: %s busy - remounted read-only\n", | ||||
| 					blockDevice); | ||||
| 			/* TODO: update mtab if BB_MTAB is defined */ | ||||
| 		} else { | ||||
| 			fprintf(stderr, "umount: Cannot remount %s read-only\n", | ||||
| 					blockDevice); | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 	if (status == 0) { | ||||
| #if defined BB_MTAB | ||||
| 		if (useMtab == TRUE) | ||||
| 			erase_mtab(name); | ||||
| #endif | ||||
| 		return (TRUE); | ||||
| 	} | ||||
| 	return (FALSE); | ||||
| } | ||||
|  | ||||
| static int umount_all(int useMtab) | ||||
| { | ||||
| 	int status = TRUE; | ||||
| 	char *mountpt; | ||||
| 	void *iter; | ||||
|  | ||||
| 	for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) { | ||||
| 		/* Never umount /proc on a umount -a */ | ||||
| 		if (strstr(mountpt, "proc")!= NULL) | ||||
| 			continue; | ||||
| 		status = do_umount(mountpt, useMtab); | ||||
| 		if (status != 0) { | ||||
| 			/* Don't bother retrying the umount on busy devices */ | ||||
| 			if (errno == EBUSY) { | ||||
| 				perror(mountpt); | ||||
| 				continue; | ||||
| 			} | ||||
| 			status = do_umount(mountpt, useMtab); | ||||
| 			if (status != 0) { | ||||
| 				printf("Couldn't umount %s on %s: %s\n", | ||||
| 					   mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), | ||||
| 					   strerror(errno)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return (status); | ||||
| } | ||||
|  | ||||
| extern int umount_main(int argc, char **argv) | ||||
| { | ||||
| 	if (argc < 2) { | ||||
| 		usage(umount_usage); | ||||
| 	} | ||||
|  | ||||
| 	/* Parse any options */ | ||||
| 	while (--argc > 0 && **(++argv) == '-') { | ||||
| 		while (*++(*argv)) | ||||
| 			switch (**argv) { | ||||
| 			case 'a': | ||||
| 				umountAll = TRUE; | ||||
| 				break; | ||||
| #ifdef BB_MTAB | ||||
| 			case 'n': | ||||
| 				useMtab = FALSE; | ||||
| 				break; | ||||
| #endif | ||||
| #ifdef BB_FEATURE_REMOUNT | ||||
| 			case 'r': | ||||
| 				doRemount = TRUE; | ||||
| 				break; | ||||
| #endif | ||||
| 			default: | ||||
| 				usage(umount_usage); | ||||
| 			} | ||||
| 	} | ||||
|  | ||||
| 	mtab_read(); | ||||
| 	if (umountAll == TRUE) { | ||||
| 		exit(umount_all(useMtab)); | ||||
| 	} | ||||
| 	if (do_umount(*argv, useMtab) == 0) | ||||
| 		exit(TRUE); | ||||
| 	else { | ||||
| 		perror("umount"); | ||||
| 		exit(FALSE); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -53,7 +53,7 @@ | ||||
| #include <linux/loop.h> | ||||
|  | ||||
|  | ||||
| static int use_loop = 0; | ||||
| static int use_loop = FALSE; | ||||
| #endif | ||||
|  | ||||
| extern const char mtab_file[];	/* Defined in utility.c */ | ||||
| @@ -114,13 +114,14 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | ||||
| 		 char *mtab_opts) | ||||
| { | ||||
| 	int status = 0; | ||||
| 	char *lofile = NULL; | ||||
|  | ||||
| #if defined BB_MTAB | ||||
| 	if (fakeIt == FALSE) | ||||
| #endif | ||||
| 	{ | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| 		if (use_loop) { | ||||
| 		if (use_loop==TRUE) { | ||||
| 			int loro = flags & MS_RDONLY; | ||||
| 			char *lofile = specialfile; | ||||
|  | ||||
| @@ -137,6 +138,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | ||||
| 				fprintf(stderr, "WARNING: loop device is read-only\n"); | ||||
| 				flags &= ~MS_RDONLY; | ||||
| 			} | ||||
| 			use_loop = FALSE; | ||||
| 		} | ||||
| #endif | ||||
| 		status = | ||||
| @@ -157,7 +159,7 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | ||||
|  | ||||
| 	/* Bummer.  mount failed.  Clean up */ | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| 	if (specialfile != NULL) { | ||||
| 	if (lofile != NULL) { | ||||
| 		del_loop(specialfile); | ||||
| 	} | ||||
| #endif | ||||
| @@ -166,20 +168,6 @@ do_mount(char *specialfile, char *dir, char *filesystemtype, | ||||
|  | ||||
|  | ||||
|  | ||||
| #if defined BB_MTAB | ||||
| #define whine_if_fstab_is_missing() {} | ||||
| #else | ||||
| extern void whine_if_fstab_is_missing() | ||||
| { | ||||
| 	struct stat statBuf; | ||||
|  | ||||
| 	if (stat("/etc/fstab", &statBuf) < 0) | ||||
| 		fprintf(stderr, | ||||
| 				"/etc/fstab file missing -- install one to name /dev/root.\n\n"); | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* Seperate standard mount options from the nonstandard string options */ | ||||
| static void | ||||
| parse_mount_options(char *options, unsigned long *flags, char *strflags) | ||||
| @@ -204,7 +192,7 @@ parse_mount_options(char *options, unsigned long *flags, char *strflags) | ||||
| 		} | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| 		if (gotone == FALSE && !strcasecmp("loop", options)) {	/* loop device support */ | ||||
| 			use_loop = 1; | ||||
| 			use_loop = TRUE; | ||||
| 			gotone = TRUE; | ||||
| 		} | ||||
| #endif | ||||
| @@ -229,7 +217,7 @@ parse_mount_options(char *options, unsigned long *flags, char *strflags) | ||||
| int | ||||
| mount_one(char *blockDevice, char *directory, char *filesystemType, | ||||
| 		  unsigned long flags, char *string_flags, int useMtab, int fakeIt, | ||||
| 		  char *mtab_opts) | ||||
| 		  char *mtab_opts, int whineOnErrors) | ||||
| { | ||||
| 	int status = 0; | ||||
|  | ||||
| @@ -270,9 +258,11 @@ mount_one(char *blockDevice, char *directory, char *filesystemType, | ||||
| 						  fakeIt, mtab_opts); | ||||
| 	} | ||||
|  | ||||
| 	if (status == FALSE) { | ||||
| 		fprintf(stderr, "Mounting %s on %s failed: %s\n", | ||||
| 				blockDevice, directory, strerror(errno)); | ||||
| 	if (status == FALSE && whineOnErrors == TRUE) { | ||||
| 		if (whineOnErrors == TRUE) { | ||||
| 			fprintf(stderr, "Mounting %s on %s failed: %s\n", | ||||
| 					blockDevice, directory, strerror(errno)); | ||||
| 		} | ||||
| 		return (FALSE); | ||||
| 	} | ||||
| 	return (TRUE); | ||||
| @@ -387,18 +377,28 @@ extern int mount_main(int argc, char **argv) | ||||
| 			exit(FALSE); | ||||
| 		} | ||||
| 		while ((m = getmntent(f)) != NULL) { | ||||
| 			// If the file system isn't noauto, and isn't mounted on /,  | ||||
| 			// If the file system isn't noauto,  | ||||
| 			// and isn't swap or nfs, then mount it | ||||
| 			if ((!strstr(m->mnt_opts, "noauto")) && | ||||
| 				(m->mnt_dir[1] != '\0') && | ||||
| 				(!strstr(m->mnt_type, "swap")) && | ||||
| 				(!strstr(m->mnt_type, "nfs"))) { | ||||
| 				flags = 0; | ||||
| 				*string_flags = '\0'; | ||||
| 				parse_mount_options(m->mnt_opts, &flags, string_flags); | ||||
| 				mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | ||||
| 				/* If the directory is /, try to remount | ||||
| 				 * with the options specified in fstab */ | ||||
| 				if (m->mnt_dir[0] == '/' && m->mnt_dir[1] == '\0') { | ||||
| 					flags |= MS_REMOUNT; | ||||
| 				} | ||||
| 				if (mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | ||||
| 						  flags, string_flags, useMtab, fakeIt, | ||||
| 						  extra_opts); | ||||
| 						  extra_opts, FALSE))  | ||||
| 				{ | ||||
| 					/* Try again, but this time try a remount */ | ||||
| 					mount_one(m->mnt_fsname, m->mnt_dir, m->mnt_type, | ||||
| 							  flags|MS_REMOUNT, string_flags, useMtab, fakeIt, | ||||
| 							  extra_opts, TRUE); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		endmntent(f); | ||||
| @@ -414,7 +414,7 @@ extern int mount_main(int argc, char **argv) | ||||
| #endif | ||||
| 			exit(mount_one(device, directory, filesystemType, | ||||
| 						   flags, string_flags, useMtab, fakeIt, | ||||
| 						   extra_opts)); | ||||
| 						   extra_opts, TRUE)); | ||||
| 		} else { | ||||
| 			goto goodbye; | ||||
| 		} | ||||
|   | ||||
| @@ -36,13 +36,16 @@ static int whichApp; | ||||
| static const char *appName; | ||||
|  | ||||
| static const char swapoff_usage[] = | ||||
| 	"swapoff [OPTION] [device]\n\n" | ||||
| 	"Stop swapping virtual memory pages on the given device.\n\n" | ||||
| 	"Options:\n" | ||||
| 	"\t-a\tStop swapping on all swap devices\n"; | ||||
|  | ||||
| 	"swapoff device\n" | ||||
| 	"\nStop swapping virtual memory pages on the given device.\n"; | ||||
| static const char swapon_usage[] = | ||||
|  | ||||
| 	"swapon device\n" | ||||
| 	"\nStart swapping virtual memory pages on the given device.\n"; | ||||
| 	"swapon [OPTION] [device]\n\n" | ||||
| 	"Start swapping virtual memory pages on the given device.\n\n" | ||||
| 	"Options:\n" | ||||
| 	"\t-a\tStart swapping on all swap devices\n"; | ||||
|  | ||||
|  | ||||
| #define SWAPON_APP   1 | ||||
| @@ -85,12 +88,6 @@ static void do_em_all() | ||||
|  | ||||
| extern int swap_on_off_main(int argc, char **argv) | ||||
| { | ||||
| 	struct stat statBuf; | ||||
|  | ||||
| 	if (stat("/etc/fstab", &statBuf) < 0) | ||||
| 		fprintf(stderr, | ||||
| 				"/etc/fstab file missing -- Please install one.\n\n"); | ||||
|  | ||||
| 	if (strcmp(*argv, "swapon") == 0) { | ||||
| 		appName = *argv; | ||||
| 		whichApp = SWAPON_APP; | ||||
| @@ -100,8 +97,9 @@ extern int swap_on_off_main(int argc, char **argv) | ||||
| 		whichApp = SWAPOFF_APP; | ||||
| 	} | ||||
|  | ||||
| 	if (argc < 2) | ||||
| 	if (argc != 2) { | ||||
| 		goto usage_and_exit; | ||||
| 	} | ||||
| 	argc--; | ||||
| 	argv++; | ||||
|  | ||||
| @@ -110,6 +108,7 @@ extern int swap_on_off_main(int argc, char **argv) | ||||
| 		while (*++(*argv)) | ||||
| 			switch (**argv) { | ||||
| 			case 'a': | ||||
| 				whine_if_fstab_is_missing(); | ||||
| 				do_em_all(); | ||||
| 				break; | ||||
| 			default: | ||||
|   | ||||
| @@ -29,6 +29,7 @@ | ||||
| #include <fstab.h> | ||||
| #include <errno.h> | ||||
|  | ||||
|  | ||||
| static const char umount_usage[] = | ||||
| 	"umount [flags] filesystem|directory\n\n" | ||||
| 	"Flags:\n" "\t-a:\tUnmount all file systems" | ||||
| @@ -57,113 +58,6 @@ static int umountAll = FALSE; | ||||
| static int doRemount = FALSE; | ||||
| extern const char mtab_file[];	/* Defined in utility.c */ | ||||
|  | ||||
| #define MIN(x,y) (x > y ? x : y) | ||||
|  | ||||
| static int do_umount(const char *name, int useMtab) | ||||
| { | ||||
| 	int status; | ||||
| 	char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE); | ||||
|  | ||||
| 	if (blockDevice && strcmp(blockDevice, name) == 0) | ||||
| 		name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT); | ||||
|  | ||||
| 	status = umount(name); | ||||
|  | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| 	if (blockDevice != NULL && !strncmp("/dev/loop", blockDevice, 9)) | ||||
| 		/* this was a loop device, delete it */ | ||||
| 		del_loop(blockDevice); | ||||
| #endif | ||||
| #if defined BB_FEATURE_REMOUNT | ||||
| 	if (status != 0 && doRemount == TRUE && errno == EBUSY) { | ||||
| 		status = mount(blockDevice, name, NULL, | ||||
| 					   MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL); | ||||
| 		if (status == 0) { | ||||
| 			fprintf(stderr, "umount: %s busy - remounted read-only\n", | ||||
| 					blockDevice); | ||||
| 			/* TODO: update mtab if BB_MTAB is defined */ | ||||
| 		} else { | ||||
| 			fprintf(stderr, "umount: Cannot remount %s read-only\n", | ||||
| 					blockDevice); | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 	if (status == 0) { | ||||
| #if defined BB_MTAB | ||||
| 		if (useMtab == TRUE) | ||||
| 			erase_mtab(name); | ||||
| #endif | ||||
| 		return (TRUE); | ||||
| 	} | ||||
| 	return (FALSE); | ||||
| } | ||||
|  | ||||
| static int umount_all(int useMtab) | ||||
| { | ||||
| 	int status = TRUE; | ||||
| 	char *mountpt; | ||||
| 	void *iter; | ||||
|  | ||||
| 	for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) { | ||||
| 		status = do_umount(mountpt, useMtab); | ||||
| 		if (status != 0) { | ||||
| 			/* Don't bother retrying the umount on busy devices */ | ||||
| 			if (errno == EBUSY) { | ||||
| 				perror(mountpt); | ||||
| 				continue; | ||||
| 			} | ||||
| 			status = do_umount(mountpt, useMtab); | ||||
| 			if (status != 0) { | ||||
| 				printf("Couldn't umount %s on %s: %s\n", | ||||
| 					   mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), | ||||
| 					   strerror(errno)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return (status); | ||||
| } | ||||
|  | ||||
| extern int umount_main(int argc, char **argv) | ||||
| { | ||||
| 	if (argc < 2) { | ||||
| 		usage(umount_usage); | ||||
| 	} | ||||
|  | ||||
| 	/* Parse any options */ | ||||
| 	while (--argc > 0 && **(++argv) == '-') { | ||||
| 		while (*++(*argv)) | ||||
| 			switch (**argv) { | ||||
| 			case 'a': | ||||
| 				umountAll = TRUE; | ||||
| 				break; | ||||
| #ifdef BB_MTAB | ||||
| 			case 'n': | ||||
| 				useMtab = FALSE; | ||||
| 				break; | ||||
| #endif | ||||
| #ifdef BB_FEATURE_REMOUNT | ||||
| 			case 'r': | ||||
| 				doRemount = TRUE; | ||||
| 				break; | ||||
| #endif | ||||
| 			default: | ||||
| 				usage(umount_usage); | ||||
| 			} | ||||
| 	} | ||||
|  | ||||
| 	mtab_read(); | ||||
| 	if (umountAll == TRUE) { | ||||
| 		exit(umount_all(useMtab)); | ||||
| 	} | ||||
| 	if (do_umount(*argv, useMtab) == 0) | ||||
| 		exit(TRUE); | ||||
| 	else { | ||||
| 		perror("umount"); | ||||
| 		exit(FALSE); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* These functions are here because the getmntent functions do not appear | ||||
|  * to be re-entrant, which leads to all sorts of problems when we try to | ||||
| @@ -257,3 +151,111 @@ void mtab_free(void) | ||||
| 		this = next; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int do_umount(const char *name, int useMtab) | ||||
| { | ||||
| 	int status; | ||||
| 	char *blockDevice = mtab_getinfo(name, MTAB_GETDEVICE); | ||||
|  | ||||
| 	if (blockDevice && strcmp(blockDevice, name) == 0) | ||||
| 		name = mtab_getinfo(blockDevice, MTAB_GETMOUNTPT); | ||||
|  | ||||
| 	status = umount(name); | ||||
|  | ||||
| #if defined BB_FEATURE_MOUNT_LOOP | ||||
| 	if (blockDevice != NULL && !strncmp("/dev/loop", blockDevice, 9)) | ||||
| 		/* this was a loop device, delete it */ | ||||
| 		del_loop(blockDevice); | ||||
| #endif | ||||
| #if defined BB_FEATURE_REMOUNT | ||||
| 	if (status != 0 && doRemount == TRUE && errno == EBUSY) { | ||||
| 		status = mount(blockDevice, name, NULL, | ||||
| 					   MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL); | ||||
| 		if (status == 0) { | ||||
| 			fprintf(stderr, "umount: %s busy - remounted read-only\n", | ||||
| 					blockDevice); | ||||
| 			/* TODO: update mtab if BB_MTAB is defined */ | ||||
| 		} else { | ||||
| 			fprintf(stderr, "umount: Cannot remount %s read-only\n", | ||||
| 					blockDevice); | ||||
| 		} | ||||
| 	} | ||||
| #endif | ||||
| 	if (status == 0) { | ||||
| #if defined BB_MTAB | ||||
| 		if (useMtab == TRUE) | ||||
| 			erase_mtab(name); | ||||
| #endif | ||||
| 		return (TRUE); | ||||
| 	} | ||||
| 	return (FALSE); | ||||
| } | ||||
|  | ||||
| static int umount_all(int useMtab) | ||||
| { | ||||
| 	int status = TRUE; | ||||
| 	char *mountpt; | ||||
| 	void *iter; | ||||
|  | ||||
| 	for (mountpt = mtab_first(&iter); mountpt; mountpt = mtab_next(&iter)) { | ||||
| 		/* Never umount /proc on a umount -a */ | ||||
| 		if (strstr(mountpt, "proc")!= NULL) | ||||
| 			continue; | ||||
| 		status = do_umount(mountpt, useMtab); | ||||
| 		if (status != 0) { | ||||
| 			/* Don't bother retrying the umount on busy devices */ | ||||
| 			if (errno == EBUSY) { | ||||
| 				perror(mountpt); | ||||
| 				continue; | ||||
| 			} | ||||
| 			status = do_umount(mountpt, useMtab); | ||||
| 			if (status != 0) { | ||||
| 				printf("Couldn't umount %s on %s: %s\n", | ||||
| 					   mountpt, mtab_getinfo(mountpt, MTAB_GETDEVICE), | ||||
| 					   strerror(errno)); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return (status); | ||||
| } | ||||
|  | ||||
| extern int umount_main(int argc, char **argv) | ||||
| { | ||||
| 	if (argc < 2) { | ||||
| 		usage(umount_usage); | ||||
| 	} | ||||
|  | ||||
| 	/* Parse any options */ | ||||
| 	while (--argc > 0 && **(++argv) == '-') { | ||||
| 		while (*++(*argv)) | ||||
| 			switch (**argv) { | ||||
| 			case 'a': | ||||
| 				umountAll = TRUE; | ||||
| 				break; | ||||
| #ifdef BB_MTAB | ||||
| 			case 'n': | ||||
| 				useMtab = FALSE; | ||||
| 				break; | ||||
| #endif | ||||
| #ifdef BB_FEATURE_REMOUNT | ||||
| 			case 'r': | ||||
| 				doRemount = TRUE; | ||||
| 				break; | ||||
| #endif | ||||
| 			default: | ||||
| 				usage(umount_usage); | ||||
| 			} | ||||
| 	} | ||||
|  | ||||
| 	mtab_read(); | ||||
| 	if (umountAll == TRUE) { | ||||
| 		exit(umount_all(useMtab)); | ||||
| 	} | ||||
| 	if (do_umount(*argv, useMtab) == 0) | ||||
| 		exit(TRUE); | ||||
| 	else { | ||||
| 		perror("umount"); | ||||
| 		exit(FALSE); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										14
									
								
								utility.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								utility.c
									
									
									
									
									
								
							| @@ -1298,5 +1298,19 @@ extern char *find_unused_loop_device(void) | ||||
| } | ||||
| #endif							/* BB_FEATURE_MOUNT_LOOP */ | ||||
|  | ||||
| #if defined BB_MTAB | ||||
| #define whine_if_fstab_is_missing() {} | ||||
| #else | ||||
| extern void whine_if_fstab_is_missing() | ||||
| { | ||||
| 	struct stat statBuf; | ||||
|  | ||||
| 	if (stat("/etc/fstab", &statBuf) < 0) | ||||
| 		fprintf(stderr, | ||||
| 				"/etc/fstab file missing -- install one to name /dev/root.\n\n"); | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| /* END CODE */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user