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 | } |
