]>
Commit | Line | Data |
---|---|---|
ae85b8dc AM |
1 | diff -urN busybox-1.00-rc3.org/include/applets.h busybox-1.00-rc3/include/applets.h |
2 | --- busybox-1.00-rc3.org/include/applets.h 2004-09-25 18:10:24.215527160 +0200 | |
3 | +++ busybox-1.00-rc3/include/applets.h 2004-09-25 19:07:03.622283988 +0200 | |
4 | @@ -547,6 +547,9 @@ | |
5 | #ifdef CONFIG_SWAPONOFF | |
6 | APPLET(swapon, swap_on_off_main, _BB_DIR_SBIN, _BB_SUID_NEVER) | |
7 | #endif | |
8 | +#ifdef CONFIG_SWITCHROOT | |
9 | + APPLET(switchroot, switchroot_main, _BB_DIR_SBIN, _BB_SUID_NEVER) | |
10 | +#endif | |
11 | #ifdef CONFIG_SYNC | |
12 | APPLET(sync, sync_main, _BB_DIR_BIN, _BB_SUID_NEVER) | |
13 | #endif | |
14 | diff -urN busybox-1.00-rc3.org/include/usage.h busybox-1.00-rc3/include/usage.h | |
15 | --- busybox-1.00-rc3.org/include/usage.h 2004-09-25 18:10:24.213527588 +0200 | |
16 | +++ busybox-1.00-rc3/include/usage.h 2004-09-25 19:09:49.403769193 +0200 | |
17 | @@ -2261,6 +2261,11 @@ | |
18 | "Options:\n" \ | |
19 | "\t-a\tStart swapping on all swap devices" | |
20 | ||
21 | +#define switchroot_trivial_usage \ | |
22 | + "NEW_ROOT" | |
23 | +#define switchroot_full_usage \ | |
24 | + "Make NEW_ROOT the new root file system." | |
25 | + | |
26 | #define sync_trivial_usage \ | |
27 | "" | |
28 | #define sync_full_usage \ | |
29 | diff -urN busybox-1.00-rc3.org/util-linux/Config.in busybox-1.00-rc3/util-linux/Config.in | |
30 | --- busybox-1.00-rc3.org/util-linux/Config.in 2004-09-25 18:10:25.736201391 +0200 | |
31 | +++ busybox-1.00-rc3/util-linux/Config.in 2004-09-25 18:30:59.861818921 +0200 | |
32 | @@ -261,6 +261,12 @@ | |
33 | of wild and crazy things with your Linux system and is far more | |
34 | powerful than 'chroot'. | |
35 | ||
36 | +config CONFIG_SWITCHROOT | |
37 | + bool "switchroot" | |
38 | + default n | |
39 | + help | |
40 | + Utility for changing root (like 'chroot' but) for initramfs. | |
41 | + | |
42 | config CONFIG_RDATE | |
43 | bool "rdate" | |
44 | default n | |
45 | diff -urN busybox-1.00-rc3.org/util-linux/Makefile.in busybox-1.00-rc3/util-linux/Makefile.in | |
46 | --- busybox-1.00-rc3.org/util-linux/Makefile.in 2004-09-25 18:10:25.771193895 +0200 | |
47 | +++ busybox-1.00-rc3/util-linux/Makefile.in 2004-09-25 18:31:52.266592428 +0200 | |
48 | @@ -41,6 +41,7 @@ | |
49 | UTILLINUX-$(CONFIG_RAID_START) +=raid_start.o | |
50 | UTILLINUX-$(CONFIG_NFSMOUNT) +=nfsmount.o | |
51 | UTILLINUX-$(CONFIG_PIVOT_ROOT) +=pivot_root.o | |
52 | +UTILLINUX-$(CONFIG_SWITCHROOT) +=switchroot.o | |
53 | UTILLINUX-$(CONFIG_RDATE) +=rdate.o | |
54 | UTILLINUX-$(CONFIG_SWAPONOFF) +=swaponoff.o | |
55 | UTILLINUX-$(CONFIG_UMOUNT) +=umount.o | |
56 | diff -urN busybox-1.00-rc3.org/util-linux/switchroot.c busybox-1.00-rc3/util-linux/switchroot.c | |
57 | --- busybox-1.00-rc3.org/util-linux/switchroot.c 1970-01-01 01:00:00.000000000 +0100 | |
58 | +++ busybox-1.00-rc3/util-linux/switchroot.c 2004-09-25 19:03:58.933849154 +0200 | |
59 | @@ -0,0 +1,208 @@ | |
60 | +/* vi: set sw=4 ts=4: */ | |
61 | +/* | |
62 | + * switchroot.c - Change root file system (initramfs). | |
63 | + * based on GPL v2 nash from RH. | |
64 | + * | |
65 | + */ | |
66 | +#include <stdlib.h> | |
67 | +#include <stdio.h> | |
68 | +#include <unistd.h> | |
69 | +#include <string.h> | |
70 | +#include <ctype.h> | |
71 | +#include <sys/types.h> | |
72 | +#include <sys/stat.h> | |
73 | +#include <fcntl.h> | |
74 | +#include <errno.h> | |
75 | +#include <sys/mount.h> | |
76 | +#include "busybox.h" | |
77 | + | |
78 | +#ifndef MS_MOVE | |
79 | +#define MS_MOVE 8192 | |
80 | +#endif | |
81 | + | |
82 | +#define MAX_INIT_ARGS 32 | |
83 | + | |
84 | +char * getArg(char * cmd, char * end, char ** arg) { | |
85 | + char quote = '\0'; | |
86 | + | |
87 | + if (cmd >= end) return NULL; | |
88 | + | |
89 | + while (isspace(*cmd) && cmd < end) cmd++; | |
90 | + if (cmd >= end) return NULL; | |
91 | + | |
92 | + if (*cmd == '"') | |
93 | + cmd++, quote = '"'; | |
94 | + else if (*cmd == '\'') | |
95 | + cmd++, quote = '\''; | |
96 | + | |
97 | + if (quote) { | |
98 | + *arg = cmd; | |
99 | + | |
100 | + /* This doesn't support \ escapes */ | |
101 | + while (cmd < end && *cmd != quote) cmd++; | |
102 | + | |
103 | + if (cmd == end) { | |
104 | + bb_error_msg("error: quote mismatch for %s\n", *arg); | |
105 | + return NULL; | |
106 | + } | |
107 | + | |
108 | + *cmd = '\0'; | |
109 | + cmd++; | |
110 | + } else { | |
111 | + *arg = cmd; | |
112 | + while (!isspace(*cmd) && cmd < end) cmd++; | |
113 | + *cmd = '\0'; | |
114 | + } | |
115 | + | |
116 | + cmd++; | |
117 | + | |
118 | + while (isspace(*cmd)) cmd++; | |
119 | + | |
120 | + return cmd; | |
121 | +} | |
122 | + | |
123 | +#ifdef __powerpc__ | |
124 | +#define CMDLINESIZE 256 | |
125 | +#else | |
126 | +#define CMDLINESIZE 1024 | |
127 | +#endif | |
128 | + | |
129 | +/* get the contents of the kernel command line from /proc/cmdline */ | |
130 | +static char * getKernelCmdLine(void) { | |
131 | + int fd, i; | |
132 | + char * buf; | |
133 | + | |
134 | + fd = open("/proc/cmdline", O_RDONLY, 0); | |
135 | + if (fd < 0) { | |
136 | + bb_error_msg("getKernelCmdLine: failed to open /proc/cmdline: %d\n", errno); | |
137 | + return NULL; | |
138 | + } | |
139 | + | |
140 | + buf = malloc(CMDLINESIZE); | |
141 | + if (!buf) | |
142 | + return buf; | |
143 | + | |
144 | + i = read(fd, buf, CMDLINESIZE); | |
145 | + if (i < 0) { | |
146 | + bb_error_msg("getKernelCmdLine: failed to read /proc/cmdline: %d\n", errno); | |
147 | + close(fd); | |
148 | + return NULL; | |
149 | + } | |
150 | + | |
151 | + close(fd); | |
152 | + if (i == 0) | |
153 | + buf[0] = '\0'; | |
154 | + else | |
155 | + buf[i - 1] = '\0'; | |
156 | + return buf; | |
157 | +} | |
158 | + | |
159 | +/* get the start of a kernel arg "arg". returns everything after it | |
160 | + * (useful for things like getting the args to init=). so if you only | |
161 | + * want one arg, you need to terminate it at the n */ | |
162 | +static char * getKernelArg(char * arg) { | |
163 | + char * start, * cmdline; | |
164 | + | |
165 | + cmdline = start = getKernelCmdLine(); | |
166 | + if (start == NULL) return NULL; | |
167 | + while (*start) { | |
168 | + if (isspace(*start)) { | |
169 | + start++; | |
170 | + continue; | |
171 | + } | |
172 | + if (strncmp(start, arg, strlen(arg)) == 0) { | |
173 | + return start + strlen(arg); | |
174 | + } | |
175 | + while (*++start && !isspace(*start)) | |
176 | + ; | |
177 | + } | |
178 | + | |
179 | + return NULL; | |
180 | +} | |
181 | + | |
182 | +int switchroot_main(int argc, char **argv) { | |
183 | + char * new; | |
184 | + const char * initprogs[] = { "/sbin/init", "/etc/init", | |
185 | + "/bin/init", "/bin/sh", NULL }; | |
186 | + char * init, * cmdline = NULL; | |
187 | + char ** initargs; | |
188 | + int fd, i = 0; | |
189 | + | |
190 | + if (argc != 1) | |
191 | + bb_show_usage(); | |
192 | + | |
193 | + new = argv[1]; | |
194 | + | |
195 | + if (chdir(new)) { | |
196 | + bb_perror_msg_and_die("chdir(%s) failed: %d\n", new, errno); | |
197 | + } | |
198 | + | |
199 | + if ((fd = open("/dev/console", O_RDWR)) < 0) { | |
200 | + bb_error_msg("ERROR opening /dev/console!!!!: %d\n", errno); | |
201 | + } | |
202 | + | |
203 | + if (dup2(fd, 0) != 0) bb_error_msg("error dup2'ing fd of %d to 0\n", fd); | |
204 | + if (dup2(fd, 1) != 1) bb_error_msg("error dup2'ing fd of %d to 1\n", fd); | |
205 | + if (dup2(fd, 2) != 2) bb_error_msg("error dup2'ing fd of %d to 2\n", fd); | |
206 | + if (fd > 2) | |
207 | + close(fd); | |
208 | + | |
209 | + init = getKernelArg("init="); | |
210 | + if (init == NULL) | |
211 | + cmdline = getKernelCmdLine(); | |
212 | + | |
213 | + if (mount(".", "/", NULL, MS_MOVE, NULL)) { | |
214 | + bb_perror_msg_and_die("switchroot: mount failed: %d\n", errno); | |
215 | + } | |
216 | + | |
217 | + if (chroot(".") || chdir("/")) { | |
218 | + bb_perror_msg_and_die("switchroot: chroot() failed: %d\n", errno); | |
219 | + } | |
220 | + | |
221 | + if (init == NULL) { | |
222 | + int j; | |
223 | + for (j = 0; initprogs[j] != NULL; j++) { | |
224 | + if (!access(initprogs[j], X_OK)) { | |
225 | + init = strdup(initprogs[j]); | |
226 | + break; | |
227 | + } | |
228 | + } | |
229 | + } | |
230 | + | |
231 | + initargs = (char **)malloc(sizeof(char *)*(MAX_INIT_ARGS+1)); | |
232 | + if (cmdline && init) { | |
233 | + initargs[i++] = strdup(init); | |
234 | + } else { | |
235 | + cmdline = init; | |
236 | + initargs[0] = NULL; | |
237 | + } | |
238 | + | |
239 | + if (cmdline != NULL) { | |
240 | + char * chptr, * start; | |
241 | + | |
242 | + start = chptr = cmdline; | |
243 | + for (; (i < MAX_INIT_ARGS) && (*start != '\0'); i++) { | |
244 | + while (*chptr && !isspace(*chptr)) chptr++; | |
245 | + if (*chptr != '\0') *(chptr++) = '\0'; | |
246 | + initargs[i] = strdup(start); | |
247 | + start = chptr; | |
248 | + } | |
249 | + } | |
250 | + | |
251 | + initargs[i] = NULL; | |
252 | + | |
253 | + if (access(initargs[0], X_OK)) { | |
254 | + bb_error_msg("WARNING: can't access %s\n", initargs[0]); | |
255 | + } | |
256 | + execv(initargs[0], initargs); | |
257 | + bb_error_msg_and_die("exec of init (%s) failed!!!: %d\n", initargs[0], errno); | |
258 | + return 1; | |
259 | +} | |
260 | + | |
261 | +/* | |
262 | +Local Variables: | |
263 | +c-file-style: "linux" | |
264 | +c-basic-offset: 4 | |
265 | +tab-width: 4 | |
266 | +End: | |
267 | +*/ |