aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-21 20:40:51 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-21 20:40:51 +0000
commitf9d4fc3cf8ca91dbebfa305c5c08f8781caa1a0f (patch)
treeb341f97661b629cc112ebe09933c044ebb31a6f7
parent950bd729665cecf1fbee65bc6e57e087c93aaab6 (diff)
downloadbusybox-w32-f9d4fc3cf8ca91dbebfa305c5c08f8781caa1a0f.tar.gz
busybox-w32-f9d4fc3cf8ca91dbebfa305c5c08f8781caa1a0f.tar.bz2
busybox-w32-f9d4fc3cf8ca91dbebfa305c5c08f8781caa1a0f.zip
switch_root: improve behavior on error; improve help text
*: make "can't execute '%s'" message uniform
-rw-r--r--archival/libunarchive/open_transformer.c2
-rw-r--r--archival/tar.c2
-rw-r--r--coreutils/chroot.c2
-rw-r--r--debianutils/run_parts.c2
-rw-r--r--include/usage.h11
-rw-r--r--loginutils/adduser.c2
-rw-r--r--selinux/runcon.c4
-rw-r--r--shell/cttyhack.c2
-rw-r--r--shell/hush.c2
-rw-r--r--util-linux/switch_root.c62
10 files changed, 49 insertions, 42 deletions
diff --git a/archival/libunarchive/open_transformer.c b/archival/libunarchive/open_transformer.c
index fae589ee0..47c13e6f4 100644
--- a/archival/libunarchive/open_transformer.c
+++ b/archival/libunarchive/open_transformer.c
@@ -52,7 +52,7 @@ void FAST_FUNC open_transformer(int fd,
52 argv[2] = (char*)"-"; 52 argv[2] = (char*)"-";
53 argv[3] = NULL; 53 argv[3] = NULL;
54 BB_EXECVP(transform_prog, argv); 54 BB_EXECVP(transform_prog, argv);
55 bb_perror_msg_and_die("can't exec %s", transform_prog); 55 bb_perror_msg_and_die("can't execute '%s'", transform_prog);
56 } 56 }
57#endif 57#endif
58 /* notreached */ 58 /* notreached */
diff --git a/archival/tar.c b/archival/tar.c
index 379028bd9..9b7a42a18 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -577,7 +577,7 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip)
577#endif 577#endif
578 if (vfork_exec_errno) { 578 if (vfork_exec_errno) {
579 errno = vfork_exec_errno; 579 errno = vfork_exec_errno;
580 bb_perror_msg_and_die("cannot exec %s", zip_exec); 580 bb_perror_msg_and_die("can't execute '%s'", zip_exec);
581 } 581 }
582} 582}
583#endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 */ 583#endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 */
diff --git a/coreutils/chroot.c b/coreutils/chroot.c
index 1198a415a..9b3d70044 100644
--- a/coreutils/chroot.c
+++ b/coreutils/chroot.c
@@ -33,5 +33,5 @@ int chroot_main(int argc, char **argv)
33 } 33 }
34 34
35 BB_EXECVP(*argv, argv); 35 BB_EXECVP(*argv, argv);
36 bb_perror_msg_and_die("cannot execute %s", *argv); 36 bb_perror_msg_and_die("can't execute '%s'", *argv);
37} 37}
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c
index 77fdcccb0..ea019c27c 100644
--- a/debianutils/run_parts.c
+++ b/debianutils/run_parts.c
@@ -164,7 +164,7 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv)
164 continue; 164 continue;
165 n = 1; 165 n = 1;
166 if (ret < 0) 166 if (ret < 0)
167 bb_perror_msg("can't exec %s", name); 167 bb_perror_msg("can't execute '%s'", name);
168 else /* ret > 0 */ 168 else /* ret > 0 */
169 bb_error_msg("%s exited with code %d", name, ret); 169 bb_error_msg("%s exited with code %d", name, ret);
170 } 170 }
diff --git a/include/usage.h b/include/usage.h
index bfb07a4cf..84da445f2 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -4125,12 +4125,13 @@
4125 ) \ 4125 ) \
4126 4126
4127#define switch_root_trivial_usage \ 4127#define switch_root_trivial_usage \
4128 "[-c /dev/console] NEW_ROOT NEW_INIT [ARGUMENTS_TO_INIT]" 4128 "[-c /dev/console] NEW_ROOT NEW_INIT [ARG...]"
4129#define switch_root_full_usage "\n\n" \ 4129#define switch_root_full_usage "\n\n" \
4130 "Use from PID 1 under initramfs to free initramfs, chroot to NEW_ROOT,\n" \ 4130 "Free initramfs and switch to another root fs:\n" \
4131 "and exec NEW_INIT\n" \ 4131 "chroot to NEW_ROOT, delete all in /, move NEW_ROOT to /,\n" \
4132 "execute NEW_INIT. PID must be 1. NEW_ROOT must be a mountpoint.\n" \
4132 "\nOptions:" \ 4133 "\nOptions:" \
4133 "\n -c Redirect console to device on new root" \ 4134 "\n -c DEV Reopen stdio to DEV after switch" \
4134 4135
4135#define sync_trivial_usage \ 4136#define sync_trivial_usage \
4136 "" 4137 ""
@@ -4142,7 +4143,7 @@
4142#define sysctl_full_usage "\n\n" \ 4143#define sysctl_full_usage "\n\n" \
4143 "Configure kernel parameters at runtime\n" \ 4144 "Configure kernel parameters at runtime\n" \
4144 "\nOptions:" \ 4145 "\nOptions:" \
4145 "\n -n Disable printing of key names" \ 4146 "\n -n Don't print key names" \
4146 "\n -e Don't warn about unknown keys" \ 4147 "\n -e Don't warn about unknown keys" \
4147 "\n -w Change sysctl setting" \ 4148 "\n -w Change sysctl setting" \
4148 "\n -p FILE Load sysctl settings from FILE (default /etc/sysctl.conf)" \ 4149 "\n -p FILE Load sysctl settings from FILE (default /etc/sysctl.conf)" \
diff --git a/loginutils/adduser.c b/loginutils/adduser.c
index 8a5d902e6..df4fad694 100644
--- a/loginutils/adduser.c
+++ b/loginutils/adduser.c
@@ -60,7 +60,7 @@ static void passwd_wrapper(const char *login)
60 static const char prog[] ALIGN1 = "passwd"; 60 static const char prog[] ALIGN1 = "passwd";
61 61
62 BB_EXECLP(prog, prog, login, NULL); 62 BB_EXECLP(prog, prog, login, NULL);
63 bb_error_msg_and_die("cannot execute %s, you must set password manually", prog); 63 bb_error_msg_and_die("can't execute %s, you must set password manually", prog);
64} 64}
65 65
66#if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS 66#if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS
diff --git a/selinux/runcon.c b/selinux/runcon.c
index e94ff1454..6ecd7899d 100644
--- a/selinux/runcon.c
+++ b/selinux/runcon.c
@@ -129,10 +129,10 @@ int runcon_main(int argc UNUSED_PARAM, char **argv)
129 context_str(con)); 129 context_str(con));
130 130
131 if (setexeccon(context_str(con))) 131 if (setexeccon(context_str(con)))
132 bb_error_msg_and_die("cannot set up security context '%s'", 132 bb_error_msg_and_die("can't set up security context '%s'",
133 context_str(con)); 133 context_str(con));
134 134
135 execvp(argv[0], argv); 135 execvp(argv[0], argv);
136 136
137 bb_perror_msg_and_die("cannot execute '%s'", argv[0]); 137 bb_perror_msg_and_die("can't execute '%s'", argv[0]);
138} 138}
diff --git a/shell/cttyhack.c b/shell/cttyhack.c
index 0aa4b8a2c..572a3af03 100644
--- a/shell/cttyhack.c
+++ b/shell/cttyhack.c
@@ -73,5 +73,5 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv)
73 } 73 }
74 74
75 BB_EXECVP(argv[0], argv); 75 BB_EXECVP(argv[0], argv);
76 bb_perror_msg_and_die("cannot exec '%s'", argv[0]); 76 bb_perror_msg_and_die("can't execute '%s'", argv[0]);
77} 77}
diff --git a/shell/hush.c b/shell/hush.c
index 53b1f3f8b..56b12cebc 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -3048,7 +3048,7 @@ static void pseudo_exec_argv(nommu_save_t *nommu_save,
3048 debug_printf_exec("execing '%s'\n", argv[0]); 3048 debug_printf_exec("execing '%s'\n", argv[0]);
3049 sigprocmask(SIG_SETMASK, &G.inherited_set, NULL); 3049 sigprocmask(SIG_SETMASK, &G.inherited_set, NULL);
3050 execvp(argv[0], argv); 3050 execvp(argv[0], argv);
3051 bb_perror_msg("can't exec '%s'", argv[0]); 3051 bb_perror_msg("can't execute '%s'", argv[0]);
3052 _exit(EXIT_FAILURE); 3052 _exit(EXIT_FAILURE);
3053} 3053}
3054 3054
diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c
index 08aa72597..f9e3444d5 100644
--- a/util-linux/switch_root.c
+++ b/util-linux/switch_root.c
@@ -5,11 +5,10 @@
5 * 5 *
6 * Licensed under GPL version 2, see file LICENSE in this tarball for details. 6 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
7 */ 7 */
8
9#include "libbb.h" 8#include "libbb.h"
10#include <sys/vfs.h> 9#include <sys/vfs.h>
11 10
12// Make up for header deficiencies. 11// Make up for header deficiencies
13#ifndef RAMFS_MAGIC 12#ifndef RAMFS_MAGIC
14#define RAMFS_MAGIC ((unsigned)0x858458f6) 13#define RAMFS_MAGIC ((unsigned)0x858458f6)
15#endif 14#endif
@@ -22,7 +21,7 @@
22#define MS_MOVE 8192 21#define MS_MOVE 8192
23#endif 22#endif
24 23
25// Recursively delete contents of rootfs. 24// Recursively delete contents of rootfs
26static void delete_contents(const char *directory, dev_t rootdev) 25static void delete_contents(const char *directory, dev_t rootdev)
27{ 26{
28 DIR *dir; 27 DIR *dir;
@@ -33,7 +32,7 @@ static void delete_contents(const char *directory, dev_t rootdev)
33 if (lstat(directory, &st) || st.st_dev != rootdev) 32 if (lstat(directory, &st) || st.st_dev != rootdev)
34 return; 33 return;
35 34
36 // Recursively delete the contents of directories. 35 // Recursively delete the contents of directories
37 if (S_ISDIR(st.st_mode)) { 36 if (S_ISDIR(st.st_mode)) {
38 dir = opendir(directory); 37 dir = opendir(directory);
39 if (dir) { 38 if (dir) {
@@ -51,42 +50,47 @@ static void delete_contents(const char *directory, dev_t rootdev)
51 } 50 }
52 closedir(dir); 51 closedir(dir);
53 52
54 // Directory should now be empty. Zap it. 53 // Directory should now be empty, zap it
55 rmdir(directory); 54 rmdir(directory);
56 } 55 }
57 56 } else {
58 // It wasn't a directory. Zap it. 57 // It wasn't a directory, zap it
59 } else unlink(directory); 58 unlink(directory);
59 }
60} 60}
61 61
62int switch_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 62int switch_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
63int switch_root_main(int argc UNUSED_PARAM, char **argv) 63int switch_root_main(int argc UNUSED_PARAM, char **argv)
64{ 64{
65 char *newroot, *console = NULL; 65 char *newroot, *console = NULL;
66 struct stat st1, st2; 66 struct stat st;
67 struct statfs stfs; 67 struct statfs stfs;
68 dev_t rootdev; 68 dev_t rootdev;
69 69
70 // Parse args (-c console) 70 // Parse args (-c console)
71 opt_complementary = "-2"; // minimum 2 params 71 opt_complementary = "-2"; // minimum 2 params
72 getopt32(argv, "+c:", &console); // '+': stop parsing at first non-option 72 getopt32(argv, "+c:", &console); // '+': stop at first non-option
73 argv += optind; 73 argv += optind;
74
75 // Change to new root directory and verify it's a different fs.
76 newroot = *argv++; 74 newroot = *argv++;
77 75
76 // Change to new root directory and verify it's a different fs
78 xchdir(newroot); 77 xchdir(newroot);
79 if (lstat(".", &st1) || lstat("/", &st2) || st1.st_dev == st2.st_dev) { 78 xstat("/", &st);
80 bb_error_msg_and_die("bad newroot %s", newroot); 79 rootdev = st.st_dev;
80 xstat(".", &st);
81 if (st.st_dev == rootdev || getpid() != 1) {
82 // Show usage, it says new root must be a mountpoint
83 // and we must be PID 1
84 bb_show_usage();
81 } 85 }
82 rootdev = st2.st_dev; 86
83 87 // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE
84 // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE 88 // we mean it. I could make this a CONFIG option, but I would get email
85 // we mean it. (I could make this a CONFIG option, but I would get email 89 // from all the people who WILL destroy their filesystems.
86 // from all the people who WILL eat their filesystems.) 90 statfs("/", &stfs); // this never fails
87 if (lstat("/init", &st1) || !S_ISREG(st1.st_mode) || statfs("/", &stfs) 91 if (lstat("/init", &st) != 0 || !S_ISREG(st.st_mode)
88 || (((unsigned)stfs.f_type != RAMFS_MAGIC) && ((unsigned)stfs.f_type != TMPFS_MAGIC)) 92 || ((unsigned)stfs.f_type != RAMFS_MAGIC
89 || (getpid() != 1) 93 && (unsigned)stfs.f_type != TMPFS_MAGIC)
90 ) { 94 ) {
91 bb_error_msg_and_die("not rootfs"); 95 bb_error_msg_and_die("not rootfs");
92 } 96 }
@@ -94,14 +98,16 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv)
94 // Zap everything out of rootdev 98 // Zap everything out of rootdev
95 delete_contents("/", rootdev); 99 delete_contents("/", rootdev);
96 100
97 // Overmount / with newdir and chroot into it. The chdir is needed to 101 // Overmount / with newdir and chroot into it
98 // recalculate "." and ".." links. 102 if (mount(".", "/", NULL, MS_MOVE, NULL)) {
99 if (mount(".", "/", NULL, MS_MOVE, NULL)) 103 // For example, fails when newroot is not a mountpoint
100 bb_perror_msg_and_die("error moving root"); 104 bb_perror_msg_and_die("error moving root");
105 }
106 // The chdir is needed to recalculate "." and ".." links
101 xchroot("."); 107 xchroot(".");
102 xchdir("/"); 108 xchdir("/");
103 109
104 // If a new console specified, redirect stdin/stdout/stderr to that. 110 // If a new console specified, redirect stdin/stdout/stderr to it
105 if (console) { 111 if (console) {
106 close(0); 112 close(0);
107 xopen(console, O_RDWR); 113 xopen(console, O_RDWR);
@@ -109,7 +115,7 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv)
109 xdup2(0, 2); 115 xdup2(0, 2);
110 } 116 }
111 117
112 // Exec real init. (This is why we must be pid 1.) 118 // Exec real init
113 execv(argv[0], argv); 119 execv(argv[0], argv);
114 bb_perror_msg_and_die("bad init %s", argv[0]); 120 bb_perror_msg_and_die("can't execute '%s'", argv[0]);
115} 121}