diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-21 20:40:51 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-21 20:40:51 +0000 |
commit | f9d4fc3cf8ca91dbebfa305c5c08f8781caa1a0f (patch) | |
tree | b341f97661b629cc112ebe09933c044ebb31a6f7 | |
parent | 950bd729665cecf1fbee65bc6e57e087c93aaab6 (diff) | |
download | busybox-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.c | 2 | ||||
-rw-r--r-- | archival/tar.c | 2 | ||||
-rw-r--r-- | coreutils/chroot.c | 2 | ||||
-rw-r--r-- | debianutils/run_parts.c | 2 | ||||
-rw-r--r-- | include/usage.h | 11 | ||||
-rw-r--r-- | loginutils/adduser.c | 2 | ||||
-rw-r--r-- | selinux/runcon.c | 4 | ||||
-rw-r--r-- | shell/cttyhack.c | 2 | ||||
-rw-r--r-- | shell/hush.c | 2 | ||||
-rw-r--r-- | util-linux/switch_root.c | 62 |
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 |
26 | static void delete_contents(const char *directory, dev_t rootdev) | 25 | static 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 | ||
62 | int switch_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 62 | int switch_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
63 | int switch_root_main(int argc UNUSED_PARAM, char **argv) | 63 | int 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 | } |