Commit bdaf8529385d5126ef791e8f1914afff8cd59bcf
1 parent
a29641883f
Exists in
master
and in
4 other branches
[PATCH] devfs: Remove devfs from the init code
This patch removes the devfs code from the init/ directory. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Showing 8 changed files with 10 additions and 172 deletions Inline Diff
include/linux/devfs_fs_kernel.h
1 | #ifndef _LINUX_DEVFS_FS_KERNEL_H | 1 | #ifndef _LINUX_DEVFS_FS_KERNEL_H |
2 | #define _LINUX_DEVFS_FS_KERNEL_H | 2 | #define _LINUX_DEVFS_FS_KERNEL_H |
3 | 3 | ||
4 | #include <linux/fs.h> | 4 | #include <linux/fs.h> |
5 | #include <linux/spinlock.h> | 5 | #include <linux/spinlock.h> |
6 | #include <linux/types.h> | 6 | #include <linux/types.h> |
7 | #include <asm/semaphore.h> | 7 | #include <asm/semaphore.h> |
8 | 8 | ||
9 | static inline int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...) | 9 | static inline int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...) |
10 | { | 10 | { |
11 | return 0; | 11 | return 0; |
12 | } | 12 | } |
13 | static inline int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...) | 13 | static inline int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...) |
14 | { | 14 | { |
15 | return 0; | 15 | return 0; |
16 | } | 16 | } |
17 | static inline int devfs_mk_symlink(const char *name, const char *link) | 17 | static inline int devfs_mk_symlink(const char *name, const char *link) |
18 | { | 18 | { |
19 | return 0; | 19 | return 0; |
20 | } | 20 | } |
21 | static inline int devfs_mk_dir(const char *fmt, ...) | 21 | static inline int devfs_mk_dir(const char *fmt, ...) |
22 | { | 22 | { |
23 | return 0; | 23 | return 0; |
24 | } | 24 | } |
25 | static inline void devfs_remove(const char *fmt, ...) | 25 | static inline void devfs_remove(const char *fmt, ...) |
26 | { | 26 | { |
27 | } | 27 | } |
28 | static inline int devfs_register_tape(const char *name) | 28 | static inline int devfs_register_tape(const char *name) |
29 | { | 29 | { |
30 | return -1; | 30 | return -1; |
31 | } | 31 | } |
32 | static inline void devfs_unregister_tape(int num) | 32 | static inline void devfs_unregister_tape(int num) |
33 | { | 33 | { |
34 | } | 34 | } |
35 | static inline void mount_devfs_fs(void) | ||
36 | { | ||
37 | return; | ||
38 | } | ||
39 | #endif /* _LINUX_DEVFS_FS_KERNEL_H */ | 35 | #endif /* _LINUX_DEVFS_FS_KERNEL_H */ |
40 | 36 |
init/Makefile
1 | # | 1 | # |
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := main.o version.o mounts.o initramfs.o | 5 | obj-y := main.o version.o mounts.o initramfs.o |
6 | obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o | 6 | obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o |
7 | 7 | ||
8 | mounts-y := do_mounts.o | 8 | mounts-y := do_mounts.o |
9 | mounts-$(CONFIG_DEVFS_FS) += do_mounts_devfs.o | ||
10 | mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o | 9 | mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o |
11 | mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o | 10 | mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o |
12 | mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o | 11 | mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o |
13 | 12 | ||
14 | # files to be removed upon make clean | 13 | # files to be removed upon make clean |
15 | clean-files := ../include/linux/compile.h | 14 | clean-files := ../include/linux/compile.h |
16 | 15 | ||
17 | # dependencies on generated files need to be listed explicitly | 16 | # dependencies on generated files need to be listed explicitly |
18 | 17 | ||
19 | $(obj)/version.o: include/linux/compile.h | 18 | $(obj)/version.o: include/linux/compile.h |
20 | 19 | ||
21 | # compile.h changes depending on hostname, generation number, etc, | 20 | # compile.h changes depending on hostname, generation number, etc, |
22 | # so we regenerate it always. | 21 | # so we regenerate it always. |
23 | # mkcompile_h will make sure to only update the | 22 | # mkcompile_h will make sure to only update the |
24 | # actual file if its content has changed. | 23 | # actual file if its content has changed. |
25 | 24 | ||
26 | include/linux/compile.h: FORCE | 25 | include/linux/compile.h: FORCE |
27 | @echo ' CHK $@' | 26 | @echo ' CHK $@' |
28 | $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ | 27 | $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkcompile_h $@ \ |
29 | "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(CFLAGS)" | 28 | "$(UTS_MACHINE)" "$(CONFIG_SMP)" "$(CONFIG_PREEMPT)" "$(CC) $(CFLAGS)" |
30 | 29 |
init/do_mounts.c
1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
2 | #include <linux/sched.h> | 2 | #include <linux/sched.h> |
3 | #include <linux/ctype.h> | 3 | #include <linux/ctype.h> |
4 | #include <linux/fd.h> | 4 | #include <linux/fd.h> |
5 | #include <linux/tty.h> | 5 | #include <linux/tty.h> |
6 | #include <linux/suspend.h> | 6 | #include <linux/suspend.h> |
7 | #include <linux/root_dev.h> | 7 | #include <linux/root_dev.h> |
8 | #include <linux/security.h> | 8 | #include <linux/security.h> |
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | #include <linux/mount.h> | 10 | #include <linux/mount.h> |
11 | 11 | ||
12 | #include <linux/nfs_fs.h> | 12 | #include <linux/nfs_fs.h> |
13 | #include <linux/nfs_fs_sb.h> | 13 | #include <linux/nfs_fs_sb.h> |
14 | #include <linux/nfs_mount.h> | 14 | #include <linux/nfs_mount.h> |
15 | 15 | ||
16 | #include "do_mounts.h" | 16 | #include "do_mounts.h" |
17 | 17 | ||
18 | extern int get_filesystem_list(char * buf); | 18 | extern int get_filesystem_list(char * buf); |
19 | 19 | ||
20 | int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ | 20 | int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ |
21 | 21 | ||
22 | int root_mountflags = MS_RDONLY | MS_SILENT; | 22 | int root_mountflags = MS_RDONLY | MS_SILENT; |
23 | char * __initdata root_device_name; | 23 | char * __initdata root_device_name; |
24 | static char __initdata saved_root_name[64]; | 24 | static char __initdata saved_root_name[64]; |
25 | 25 | ||
26 | dev_t ROOT_DEV; | 26 | dev_t ROOT_DEV; |
27 | 27 | ||
28 | static int __init load_ramdisk(char *str) | 28 | static int __init load_ramdisk(char *str) |
29 | { | 29 | { |
30 | rd_doload = simple_strtol(str,NULL,0) & 3; | 30 | rd_doload = simple_strtol(str,NULL,0) & 3; |
31 | return 1; | 31 | return 1; |
32 | } | 32 | } |
33 | __setup("load_ramdisk=", load_ramdisk); | 33 | __setup("load_ramdisk=", load_ramdisk); |
34 | 34 | ||
35 | static int __init readonly(char *str) | 35 | static int __init readonly(char *str) |
36 | { | 36 | { |
37 | if (*str) | 37 | if (*str) |
38 | return 0; | 38 | return 0; |
39 | root_mountflags |= MS_RDONLY; | 39 | root_mountflags |= MS_RDONLY; |
40 | return 1; | 40 | return 1; |
41 | } | 41 | } |
42 | 42 | ||
43 | static int __init readwrite(char *str) | 43 | static int __init readwrite(char *str) |
44 | { | 44 | { |
45 | if (*str) | 45 | if (*str) |
46 | return 0; | 46 | return 0; |
47 | root_mountflags &= ~MS_RDONLY; | 47 | root_mountflags &= ~MS_RDONLY; |
48 | return 1; | 48 | return 1; |
49 | } | 49 | } |
50 | 50 | ||
51 | __setup("ro", readonly); | 51 | __setup("ro", readonly); |
52 | __setup("rw", readwrite); | 52 | __setup("rw", readwrite); |
53 | 53 | ||
54 | static dev_t try_name(char *name, int part) | 54 | static dev_t try_name(char *name, int part) |
55 | { | 55 | { |
56 | char path[64]; | 56 | char path[64]; |
57 | char buf[32]; | 57 | char buf[32]; |
58 | int range; | 58 | int range; |
59 | dev_t res; | 59 | dev_t res; |
60 | char *s; | 60 | char *s; |
61 | int len; | 61 | int len; |
62 | int fd; | 62 | int fd; |
63 | unsigned int maj, min; | 63 | unsigned int maj, min; |
64 | 64 | ||
65 | /* read device number from .../dev */ | 65 | /* read device number from .../dev */ |
66 | 66 | ||
67 | sprintf(path, "/sys/block/%s/dev", name); | 67 | sprintf(path, "/sys/block/%s/dev", name); |
68 | fd = sys_open(path, 0, 0); | 68 | fd = sys_open(path, 0, 0); |
69 | if (fd < 0) | 69 | if (fd < 0) |
70 | goto fail; | 70 | goto fail; |
71 | len = sys_read(fd, buf, 32); | 71 | len = sys_read(fd, buf, 32); |
72 | sys_close(fd); | 72 | sys_close(fd); |
73 | if (len <= 0 || len == 32 || buf[len - 1] != '\n') | 73 | if (len <= 0 || len == 32 || buf[len - 1] != '\n') |
74 | goto fail; | 74 | goto fail; |
75 | buf[len - 1] = '\0'; | 75 | buf[len - 1] = '\0'; |
76 | if (sscanf(buf, "%u:%u", &maj, &min) == 2) { | 76 | if (sscanf(buf, "%u:%u", &maj, &min) == 2) { |
77 | /* | 77 | /* |
78 | * Try the %u:%u format -- see print_dev_t() | 78 | * Try the %u:%u format -- see print_dev_t() |
79 | */ | 79 | */ |
80 | res = MKDEV(maj, min); | 80 | res = MKDEV(maj, min); |
81 | if (maj != MAJOR(res) || min != MINOR(res)) | 81 | if (maj != MAJOR(res) || min != MINOR(res)) |
82 | goto fail; | 82 | goto fail; |
83 | } else { | 83 | } else { |
84 | /* | 84 | /* |
85 | * Nope. Try old-style "0321" | 85 | * Nope. Try old-style "0321" |
86 | */ | 86 | */ |
87 | res = new_decode_dev(simple_strtoul(buf, &s, 16)); | 87 | res = new_decode_dev(simple_strtoul(buf, &s, 16)); |
88 | if (*s) | 88 | if (*s) |
89 | goto fail; | 89 | goto fail; |
90 | } | 90 | } |
91 | 91 | ||
92 | /* if it's there and we are not looking for a partition - that's it */ | 92 | /* if it's there and we are not looking for a partition - that's it */ |
93 | if (!part) | 93 | if (!part) |
94 | return res; | 94 | return res; |
95 | 95 | ||
96 | /* otherwise read range from .../range */ | 96 | /* otherwise read range from .../range */ |
97 | sprintf(path, "/sys/block/%s/range", name); | 97 | sprintf(path, "/sys/block/%s/range", name); |
98 | fd = sys_open(path, 0, 0); | 98 | fd = sys_open(path, 0, 0); |
99 | if (fd < 0) | 99 | if (fd < 0) |
100 | goto fail; | 100 | goto fail; |
101 | len = sys_read(fd, buf, 32); | 101 | len = sys_read(fd, buf, 32); |
102 | sys_close(fd); | 102 | sys_close(fd); |
103 | if (len <= 0 || len == 32 || buf[len - 1] != '\n') | 103 | if (len <= 0 || len == 32 || buf[len - 1] != '\n') |
104 | goto fail; | 104 | goto fail; |
105 | buf[len - 1] = '\0'; | 105 | buf[len - 1] = '\0'; |
106 | range = simple_strtoul(buf, &s, 10); | 106 | range = simple_strtoul(buf, &s, 10); |
107 | if (*s) | 107 | if (*s) |
108 | goto fail; | 108 | goto fail; |
109 | 109 | ||
110 | /* if partition is within range - we got it */ | 110 | /* if partition is within range - we got it */ |
111 | if (part < range) | 111 | if (part < range) |
112 | return res + part; | 112 | return res + part; |
113 | fail: | 113 | fail: |
114 | return 0; | 114 | return 0; |
115 | } | 115 | } |
116 | 116 | ||
117 | /* | 117 | /* |
118 | * Convert a name into device number. We accept the following variants: | 118 | * Convert a name into device number. We accept the following variants: |
119 | * | 119 | * |
120 | * 1) device number in hexadecimal represents itself | 120 | * 1) device number in hexadecimal represents itself |
121 | * 2) /dev/nfs represents Root_NFS (0xff) | 121 | * 2) /dev/nfs represents Root_NFS (0xff) |
122 | * 3) /dev/<disk_name> represents the device number of disk | 122 | * 3) /dev/<disk_name> represents the device number of disk |
123 | * 4) /dev/<disk_name><decimal> represents the device number | 123 | * 4) /dev/<disk_name><decimal> represents the device number |
124 | * of partition - device number of disk plus the partition number | 124 | * of partition - device number of disk plus the partition number |
125 | * 5) /dev/<disk_name>p<decimal> - same as the above, that form is | 125 | * 5) /dev/<disk_name>p<decimal> - same as the above, that form is |
126 | * used when disk name of partitioned disk ends on a digit. | 126 | * used when disk name of partitioned disk ends on a digit. |
127 | * | 127 | * |
128 | * If name doesn't have fall into the categories above, we return 0. | 128 | * If name doesn't have fall into the categories above, we return 0. |
129 | * Sysfs is used to check if something is a disk name - it has | 129 | * Sysfs is used to check if something is a disk name - it has |
130 | * all known disks under bus/block/devices. If the disk name | 130 | * all known disks under bus/block/devices. If the disk name |
131 | * contains slashes, name of sysfs node has them replaced with | 131 | * contains slashes, name of sysfs node has them replaced with |
132 | * bangs. try_name() does the actual checks, assuming that sysfs | 132 | * bangs. try_name() does the actual checks, assuming that sysfs |
133 | * is mounted on rootfs /sys. | 133 | * is mounted on rootfs /sys. |
134 | */ | 134 | */ |
135 | 135 | ||
136 | dev_t name_to_dev_t(char *name) | 136 | dev_t name_to_dev_t(char *name) |
137 | { | 137 | { |
138 | char s[32]; | 138 | char s[32]; |
139 | char *p; | 139 | char *p; |
140 | dev_t res = 0; | 140 | dev_t res = 0; |
141 | int part; | 141 | int part; |
142 | 142 | ||
143 | #ifdef CONFIG_SYSFS | 143 | #ifdef CONFIG_SYSFS |
144 | int mkdir_err = sys_mkdir("/sys", 0700); | 144 | int mkdir_err = sys_mkdir("/sys", 0700); |
145 | if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0) | 145 | if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0) |
146 | goto out; | 146 | goto out; |
147 | #endif | 147 | #endif |
148 | 148 | ||
149 | if (strncmp(name, "/dev/", 5) != 0) { | 149 | if (strncmp(name, "/dev/", 5) != 0) { |
150 | unsigned maj, min; | 150 | unsigned maj, min; |
151 | 151 | ||
152 | if (sscanf(name, "%u:%u", &maj, &min) == 2) { | 152 | if (sscanf(name, "%u:%u", &maj, &min) == 2) { |
153 | res = MKDEV(maj, min); | 153 | res = MKDEV(maj, min); |
154 | if (maj != MAJOR(res) || min != MINOR(res)) | 154 | if (maj != MAJOR(res) || min != MINOR(res)) |
155 | goto fail; | 155 | goto fail; |
156 | } else { | 156 | } else { |
157 | res = new_decode_dev(simple_strtoul(name, &p, 16)); | 157 | res = new_decode_dev(simple_strtoul(name, &p, 16)); |
158 | if (*p) | 158 | if (*p) |
159 | goto fail; | 159 | goto fail; |
160 | } | 160 | } |
161 | goto done; | 161 | goto done; |
162 | } | 162 | } |
163 | name += 5; | 163 | name += 5; |
164 | res = Root_NFS; | 164 | res = Root_NFS; |
165 | if (strcmp(name, "nfs") == 0) | 165 | if (strcmp(name, "nfs") == 0) |
166 | goto done; | 166 | goto done; |
167 | res = Root_RAM0; | 167 | res = Root_RAM0; |
168 | if (strcmp(name, "ram") == 0) | 168 | if (strcmp(name, "ram") == 0) |
169 | goto done; | 169 | goto done; |
170 | 170 | ||
171 | if (strlen(name) > 31) | 171 | if (strlen(name) > 31) |
172 | goto fail; | 172 | goto fail; |
173 | strcpy(s, name); | 173 | strcpy(s, name); |
174 | for (p = s; *p; p++) | 174 | for (p = s; *p; p++) |
175 | if (*p == '/') | 175 | if (*p == '/') |
176 | *p = '!'; | 176 | *p = '!'; |
177 | res = try_name(s, 0); | 177 | res = try_name(s, 0); |
178 | if (res) | 178 | if (res) |
179 | goto done; | 179 | goto done; |
180 | 180 | ||
181 | while (p > s && isdigit(p[-1])) | 181 | while (p > s && isdigit(p[-1])) |
182 | p--; | 182 | p--; |
183 | if (p == s || !*p || *p == '0') | 183 | if (p == s || !*p || *p == '0') |
184 | goto fail; | 184 | goto fail; |
185 | part = simple_strtoul(p, NULL, 10); | 185 | part = simple_strtoul(p, NULL, 10); |
186 | *p = '\0'; | 186 | *p = '\0'; |
187 | res = try_name(s, part); | 187 | res = try_name(s, part); |
188 | if (res) | 188 | if (res) |
189 | goto done; | 189 | goto done; |
190 | 190 | ||
191 | if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p') | 191 | if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p') |
192 | goto fail; | 192 | goto fail; |
193 | p[-1] = '\0'; | 193 | p[-1] = '\0'; |
194 | res = try_name(s, part); | 194 | res = try_name(s, part); |
195 | done: | 195 | done: |
196 | #ifdef CONFIG_SYSFS | 196 | #ifdef CONFIG_SYSFS |
197 | sys_umount("/sys", 0); | 197 | sys_umount("/sys", 0); |
198 | out: | 198 | out: |
199 | if (!mkdir_err) | 199 | if (!mkdir_err) |
200 | sys_rmdir("/sys"); | 200 | sys_rmdir("/sys"); |
201 | #endif | 201 | #endif |
202 | return res; | 202 | return res; |
203 | fail: | 203 | fail: |
204 | res = 0; | 204 | res = 0; |
205 | goto done; | 205 | goto done; |
206 | } | 206 | } |
207 | 207 | ||
208 | static int __init root_dev_setup(char *line) | 208 | static int __init root_dev_setup(char *line) |
209 | { | 209 | { |
210 | strlcpy(saved_root_name, line, sizeof(saved_root_name)); | 210 | strlcpy(saved_root_name, line, sizeof(saved_root_name)); |
211 | return 1; | 211 | return 1; |
212 | } | 212 | } |
213 | 213 | ||
214 | __setup("root=", root_dev_setup); | 214 | __setup("root=", root_dev_setup); |
215 | 215 | ||
216 | static char * __initdata root_mount_data; | 216 | static char * __initdata root_mount_data; |
217 | static int __init root_data_setup(char *str) | 217 | static int __init root_data_setup(char *str) |
218 | { | 218 | { |
219 | root_mount_data = str; | 219 | root_mount_data = str; |
220 | return 1; | 220 | return 1; |
221 | } | 221 | } |
222 | 222 | ||
223 | static char * __initdata root_fs_names; | 223 | static char * __initdata root_fs_names; |
224 | static int __init fs_names_setup(char *str) | 224 | static int __init fs_names_setup(char *str) |
225 | { | 225 | { |
226 | root_fs_names = str; | 226 | root_fs_names = str; |
227 | return 1; | 227 | return 1; |
228 | } | 228 | } |
229 | 229 | ||
230 | static unsigned int __initdata root_delay; | 230 | static unsigned int __initdata root_delay; |
231 | static int __init root_delay_setup(char *str) | 231 | static int __init root_delay_setup(char *str) |
232 | { | 232 | { |
233 | root_delay = simple_strtoul(str, NULL, 0); | 233 | root_delay = simple_strtoul(str, NULL, 0); |
234 | return 1; | 234 | return 1; |
235 | } | 235 | } |
236 | 236 | ||
237 | __setup("rootflags=", root_data_setup); | 237 | __setup("rootflags=", root_data_setup); |
238 | __setup("rootfstype=", fs_names_setup); | 238 | __setup("rootfstype=", fs_names_setup); |
239 | __setup("rootdelay=", root_delay_setup); | 239 | __setup("rootdelay=", root_delay_setup); |
240 | 240 | ||
241 | static void __init get_fs_names(char *page) | 241 | static void __init get_fs_names(char *page) |
242 | { | 242 | { |
243 | char *s = page; | 243 | char *s = page; |
244 | 244 | ||
245 | if (root_fs_names) { | 245 | if (root_fs_names) { |
246 | strcpy(page, root_fs_names); | 246 | strcpy(page, root_fs_names); |
247 | while (*s++) { | 247 | while (*s++) { |
248 | if (s[-1] == ',') | 248 | if (s[-1] == ',') |
249 | s[-1] = '\0'; | 249 | s[-1] = '\0'; |
250 | } | 250 | } |
251 | } else { | 251 | } else { |
252 | int len = get_filesystem_list(page); | 252 | int len = get_filesystem_list(page); |
253 | char *p, *next; | 253 | char *p, *next; |
254 | 254 | ||
255 | page[len] = '\0'; | 255 | page[len] = '\0'; |
256 | for (p = page-1; p; p = next) { | 256 | for (p = page-1; p; p = next) { |
257 | next = strchr(++p, '\n'); | 257 | next = strchr(++p, '\n'); |
258 | if (*p++ != '\t') | 258 | if (*p++ != '\t') |
259 | continue; | 259 | continue; |
260 | while ((*s++ = *p++) != '\n') | 260 | while ((*s++ = *p++) != '\n') |
261 | ; | 261 | ; |
262 | s[-1] = '\0'; | 262 | s[-1] = '\0'; |
263 | } | 263 | } |
264 | } | 264 | } |
265 | *s = '\0'; | 265 | *s = '\0'; |
266 | } | 266 | } |
267 | 267 | ||
268 | static int __init do_mount_root(char *name, char *fs, int flags, void *data) | 268 | static int __init do_mount_root(char *name, char *fs, int flags, void *data) |
269 | { | 269 | { |
270 | int err = sys_mount(name, "/root", fs, flags, data); | 270 | int err = sys_mount(name, "/root", fs, flags, data); |
271 | if (err) | 271 | if (err) |
272 | return err; | 272 | return err; |
273 | 273 | ||
274 | sys_chdir("/root"); | 274 | sys_chdir("/root"); |
275 | ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev; | 275 | ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev; |
276 | printk("VFS: Mounted root (%s filesystem)%s.\n", | 276 | printk("VFS: Mounted root (%s filesystem)%s.\n", |
277 | current->fs->pwdmnt->mnt_sb->s_type->name, | 277 | current->fs->pwdmnt->mnt_sb->s_type->name, |
278 | current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? | 278 | current->fs->pwdmnt->mnt_sb->s_flags & MS_RDONLY ? |
279 | " readonly" : ""); | 279 | " readonly" : ""); |
280 | return 0; | 280 | return 0; |
281 | } | 281 | } |
282 | 282 | ||
283 | void __init mount_block_root(char *name, int flags) | 283 | void __init mount_block_root(char *name, int flags) |
284 | { | 284 | { |
285 | char *fs_names = __getname(); | 285 | char *fs_names = __getname(); |
286 | char *p; | 286 | char *p; |
287 | char b[BDEVNAME_SIZE]; | 287 | char b[BDEVNAME_SIZE]; |
288 | 288 | ||
289 | get_fs_names(fs_names); | 289 | get_fs_names(fs_names); |
290 | retry: | 290 | retry: |
291 | for (p = fs_names; *p; p += strlen(p)+1) { | 291 | for (p = fs_names; *p; p += strlen(p)+1) { |
292 | int err = do_mount_root(name, p, flags, root_mount_data); | 292 | int err = do_mount_root(name, p, flags, root_mount_data); |
293 | switch (err) { | 293 | switch (err) { |
294 | case 0: | 294 | case 0: |
295 | goto out; | 295 | goto out; |
296 | case -EACCES: | 296 | case -EACCES: |
297 | flags |= MS_RDONLY; | 297 | flags |= MS_RDONLY; |
298 | goto retry; | 298 | goto retry; |
299 | case -EINVAL: | 299 | case -EINVAL: |
300 | continue; | 300 | continue; |
301 | } | 301 | } |
302 | /* | 302 | /* |
303 | * Allow the user to distinguish between failed sys_open | 303 | * Allow the user to distinguish between failed sys_open |
304 | * and bad superblock on root device. | 304 | * and bad superblock on root device. |
305 | */ | 305 | */ |
306 | __bdevname(ROOT_DEV, b); | 306 | __bdevname(ROOT_DEV, b); |
307 | printk("VFS: Cannot open root device \"%s\" or %s\n", | 307 | printk("VFS: Cannot open root device \"%s\" or %s\n", |
308 | root_device_name, b); | 308 | root_device_name, b); |
309 | printk("Please append a correct \"root=\" boot option\n"); | 309 | printk("Please append a correct \"root=\" boot option\n"); |
310 | 310 | ||
311 | panic("VFS: Unable to mount root fs on %s", b); | 311 | panic("VFS: Unable to mount root fs on %s", b); |
312 | } | 312 | } |
313 | 313 | ||
314 | printk("No filesystem could mount root, tried: "); | 314 | printk("No filesystem could mount root, tried: "); |
315 | for (p = fs_names; *p; p += strlen(p)+1) | 315 | for (p = fs_names; *p; p += strlen(p)+1) |
316 | printk(" %s", p); | 316 | printk(" %s", p); |
317 | printk("\n"); | 317 | printk("\n"); |
318 | panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b)); | 318 | panic("VFS: Unable to mount root fs on %s", __bdevname(ROOT_DEV, b)); |
319 | out: | 319 | out: |
320 | putname(fs_names); | 320 | putname(fs_names); |
321 | } | 321 | } |
322 | 322 | ||
323 | #ifdef CONFIG_ROOT_NFS | 323 | #ifdef CONFIG_ROOT_NFS |
324 | static int __init mount_nfs_root(void) | 324 | static int __init mount_nfs_root(void) |
325 | { | 325 | { |
326 | void *data = nfs_root_data(); | 326 | void *data = nfs_root_data(); |
327 | 327 | ||
328 | create_dev("/dev/root", ROOT_DEV, NULL); | 328 | create_dev("/dev/root", ROOT_DEV); |
329 | if (data && | 329 | if (data && |
330 | do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0) | 330 | do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0) |
331 | return 1; | 331 | return 1; |
332 | return 0; | 332 | return 0; |
333 | } | 333 | } |
334 | #endif | 334 | #endif |
335 | 335 | ||
336 | #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD) | 336 | #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD) |
337 | void __init change_floppy(char *fmt, ...) | 337 | void __init change_floppy(char *fmt, ...) |
338 | { | 338 | { |
339 | struct termios termios; | 339 | struct termios termios; |
340 | char buf[80]; | 340 | char buf[80]; |
341 | char c; | 341 | char c; |
342 | int fd; | 342 | int fd; |
343 | va_list args; | 343 | va_list args; |
344 | va_start(args, fmt); | 344 | va_start(args, fmt); |
345 | vsprintf(buf, fmt, args); | 345 | vsprintf(buf, fmt, args); |
346 | va_end(args); | 346 | va_end(args); |
347 | fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); | 347 | fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); |
348 | if (fd >= 0) { | 348 | if (fd >= 0) { |
349 | sys_ioctl(fd, FDEJECT, 0); | 349 | sys_ioctl(fd, FDEJECT, 0); |
350 | sys_close(fd); | 350 | sys_close(fd); |
351 | } | 351 | } |
352 | printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); | 352 | printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); |
353 | fd = sys_open("/dev/console", O_RDWR, 0); | 353 | fd = sys_open("/dev/console", O_RDWR, 0); |
354 | if (fd >= 0) { | 354 | if (fd >= 0) { |
355 | sys_ioctl(fd, TCGETS, (long)&termios); | 355 | sys_ioctl(fd, TCGETS, (long)&termios); |
356 | termios.c_lflag &= ~ICANON; | 356 | termios.c_lflag &= ~ICANON; |
357 | sys_ioctl(fd, TCSETSF, (long)&termios); | 357 | sys_ioctl(fd, TCSETSF, (long)&termios); |
358 | sys_read(fd, &c, 1); | 358 | sys_read(fd, &c, 1); |
359 | termios.c_lflag |= ICANON; | 359 | termios.c_lflag |= ICANON; |
360 | sys_ioctl(fd, TCSETSF, (long)&termios); | 360 | sys_ioctl(fd, TCSETSF, (long)&termios); |
361 | sys_close(fd); | 361 | sys_close(fd); |
362 | } | 362 | } |
363 | } | 363 | } |
364 | #endif | 364 | #endif |
365 | 365 | ||
366 | void __init mount_root(void) | 366 | void __init mount_root(void) |
367 | { | 367 | { |
368 | #ifdef CONFIG_ROOT_NFS | 368 | #ifdef CONFIG_ROOT_NFS |
369 | if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { | 369 | if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { |
370 | if (mount_nfs_root()) | 370 | if (mount_nfs_root()) |
371 | return; | 371 | return; |
372 | 372 | ||
373 | printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n"); | 373 | printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n"); |
374 | ROOT_DEV = Root_FD0; | 374 | ROOT_DEV = Root_FD0; |
375 | } | 375 | } |
376 | #endif | 376 | #endif |
377 | #ifdef CONFIG_BLK_DEV_FD | 377 | #ifdef CONFIG_BLK_DEV_FD |
378 | if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { | 378 | if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { |
379 | /* rd_doload is 2 for a dual initrd/ramload setup */ | 379 | /* rd_doload is 2 for a dual initrd/ramload setup */ |
380 | if (rd_doload==2) { | 380 | if (rd_doload==2) { |
381 | if (rd_load_disk(1)) { | 381 | if (rd_load_disk(1)) { |
382 | ROOT_DEV = Root_RAM1; | 382 | ROOT_DEV = Root_RAM1; |
383 | root_device_name = NULL; | 383 | root_device_name = NULL; |
384 | } | 384 | } |
385 | } else | 385 | } else |
386 | change_floppy("root floppy"); | 386 | change_floppy("root floppy"); |
387 | } | 387 | } |
388 | #endif | 388 | #endif |
389 | create_dev("/dev/root", ROOT_DEV, root_device_name); | 389 | create_dev("/dev/root", ROOT_DEV); |
390 | mount_block_root("/dev/root", root_mountflags); | 390 | mount_block_root("/dev/root", root_mountflags); |
391 | } | 391 | } |
392 | 392 | ||
393 | /* | 393 | /* |
394 | * Prepare the namespace - decide what/where to mount, load ramdisks, etc. | 394 | * Prepare the namespace - decide what/where to mount, load ramdisks, etc. |
395 | */ | 395 | */ |
396 | void __init prepare_namespace(void) | 396 | void __init prepare_namespace(void) |
397 | { | 397 | { |
398 | int is_floppy; | 398 | int is_floppy; |
399 | 399 | ||
400 | mount_devfs(); | ||
401 | |||
402 | if (root_delay) { | 400 | if (root_delay) { |
403 | printk(KERN_INFO "Waiting %dsec before mounting root device...\n", | 401 | printk(KERN_INFO "Waiting %dsec before mounting root device...\n", |
404 | root_delay); | 402 | root_delay); |
405 | ssleep(root_delay); | 403 | ssleep(root_delay); |
406 | } | 404 | } |
407 | 405 | ||
408 | md_run_setup(); | 406 | md_run_setup(); |
409 | 407 | ||
410 | if (saved_root_name[0]) { | 408 | if (saved_root_name[0]) { |
411 | root_device_name = saved_root_name; | 409 | root_device_name = saved_root_name; |
412 | if (!strncmp(root_device_name, "mtd", 3)) { | 410 | if (!strncmp(root_device_name, "mtd", 3)) { |
413 | mount_block_root(root_device_name, root_mountflags); | 411 | mount_block_root(root_device_name, root_mountflags); |
414 | goto out; | 412 | goto out; |
415 | } | 413 | } |
416 | ROOT_DEV = name_to_dev_t(root_device_name); | 414 | ROOT_DEV = name_to_dev_t(root_device_name); |
417 | if (strncmp(root_device_name, "/dev/", 5) == 0) | 415 | if (strncmp(root_device_name, "/dev/", 5) == 0) |
418 | root_device_name += 5; | 416 | root_device_name += 5; |
419 | } | 417 | } |
420 | 418 | ||
421 | is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; | 419 | is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; |
422 | 420 | ||
423 | if (initrd_load()) | 421 | if (initrd_load()) |
424 | goto out; | 422 | goto out; |
425 | 423 | ||
426 | if (is_floppy && rd_doload && rd_load_disk(0)) | 424 | if (is_floppy && rd_doload && rd_load_disk(0)) |
427 | ROOT_DEV = Root_RAM0; | 425 | ROOT_DEV = Root_RAM0; |
428 | 426 | ||
429 | mount_root(); | 427 | mount_root(); |
430 | out: | 428 | out: |
431 | umount_devfs("/dev"); | ||
432 | sys_mount(".", "/", NULL, MS_MOVE, NULL); | 429 | sys_mount(".", "/", NULL, MS_MOVE, NULL); |
433 | sys_chroot("."); | 430 | sys_chroot("."); |
434 | security_sb_post_mountroot(); | 431 | security_sb_post_mountroot(); |
435 | mount_devfs_fs (); | ||
436 | } | 432 | } |
437 | 433 | ||
438 | 434 |
init/do_mounts.h
1 | #include <linux/config.h> | 1 | #include <linux/config.h> |
2 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
3 | #include <linux/devfs_fs_kernel.h> | 3 | #include <linux/devfs_fs_kernel.h> |
4 | #include <linux/init.h> | 4 | #include <linux/init.h> |
5 | #include <linux/syscalls.h> | 5 | #include <linux/syscalls.h> |
6 | #include <linux/unistd.h> | 6 | #include <linux/unistd.h> |
7 | #include <linux/slab.h> | 7 | #include <linux/slab.h> |
8 | #include <linux/mount.h> | 8 | #include <linux/mount.h> |
9 | #include <linux/major.h> | 9 | #include <linux/major.h> |
10 | #include <linux/root_dev.h> | 10 | #include <linux/root_dev.h> |
11 | 11 | ||
12 | void change_floppy(char *fmt, ...); | 12 | void change_floppy(char *fmt, ...); |
13 | void mount_block_root(char *name, int flags); | 13 | void mount_block_root(char *name, int flags); |
14 | void mount_root(void); | 14 | void mount_root(void); |
15 | extern int root_mountflags; | 15 | extern int root_mountflags; |
16 | extern char *root_device_name; | 16 | extern char *root_device_name; |
17 | 17 | ||
18 | #ifdef CONFIG_DEVFS_FS | 18 | static inline int create_dev(char *name, dev_t dev) |
19 | |||
20 | void mount_devfs(void); | ||
21 | void umount_devfs(char *path); | ||
22 | int create_dev(char *name, dev_t dev, char *devfs_name); | ||
23 | |||
24 | #else | ||
25 | |||
26 | static inline void mount_devfs(void) {} | ||
27 | static inline void umount_devfs(const char *path) {} | ||
28 | |||
29 | static inline int create_dev(char *name, dev_t dev, char *devfs_name) | ||
30 | { | 19 | { |
31 | sys_unlink(name); | 20 | sys_unlink(name); |
32 | return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); | 21 | return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); |
33 | } | 22 | } |
34 | |||
35 | #endif | ||
36 | 23 | ||
37 | #if BITS_PER_LONG == 32 | 24 | #if BITS_PER_LONG == 32 |
38 | static inline u32 bstat(char *name) | 25 | static inline u32 bstat(char *name) |
39 | { | 26 | { |
40 | struct stat64 stat; | 27 | struct stat64 stat; |
41 | if (sys_stat64(name, &stat) != 0) | 28 | if (sys_stat64(name, &stat) != 0) |
42 | return 0; | 29 | return 0; |
43 | if (!S_ISBLK(stat.st_mode)) | 30 | if (!S_ISBLK(stat.st_mode)) |
44 | return 0; | 31 | return 0; |
45 | if (stat.st_rdev != (u32)stat.st_rdev) | 32 | if (stat.st_rdev != (u32)stat.st_rdev) |
46 | return 0; | 33 | return 0; |
47 | return stat.st_rdev; | 34 | return stat.st_rdev; |
48 | } | 35 | } |
49 | #else | 36 | #else |
50 | static inline u32 bstat(char *name) | 37 | static inline u32 bstat(char *name) |
51 | { | 38 | { |
52 | struct stat stat; | 39 | struct stat stat; |
53 | if (sys_newstat(name, &stat) != 0) | 40 | if (sys_newstat(name, &stat) != 0) |
54 | return 0; | 41 | return 0; |
55 | if (!S_ISBLK(stat.st_mode)) | 42 | if (!S_ISBLK(stat.st_mode)) |
56 | return 0; | 43 | return 0; |
57 | return stat.st_rdev; | 44 | return stat.st_rdev; |
58 | } | 45 | } |
59 | #endif | 46 | #endif |
60 | 47 | ||
61 | #ifdef CONFIG_BLK_DEV_RAM | 48 | #ifdef CONFIG_BLK_DEV_RAM |
62 | 49 | ||
63 | int __init rd_load_disk(int n); | 50 | int __init rd_load_disk(int n); |
64 | int __init rd_load_image(char *from); | 51 | int __init rd_load_image(char *from); |
65 | 52 | ||
66 | #else | 53 | #else |
67 | 54 | ||
68 | static inline int rd_load_disk(int n) { return 0; } | 55 | static inline int rd_load_disk(int n) { return 0; } |
69 | static inline int rd_load_image(char *from) { return 0; } | 56 | static inline int rd_load_image(char *from) { return 0; } |
70 | 57 | ||
71 | #endif | 58 | #endif |
72 | 59 | ||
73 | #ifdef CONFIG_BLK_DEV_INITRD | 60 | #ifdef CONFIG_BLK_DEV_INITRD |
74 | 61 | ||
75 | int __init initrd_load(void); | 62 | int __init initrd_load(void); |
76 | 63 | ||
77 | #else | 64 | #else |
78 | 65 | ||
79 | static inline int initrd_load(void) { return 0; } | 66 | static inline int initrd_load(void) { return 0; } |
80 | 67 | ||
81 | #endif | 68 | #endif |
82 | 69 | ||
83 | #ifdef CONFIG_BLK_DEV_MD | 70 | #ifdef CONFIG_BLK_DEV_MD |
84 | 71 | ||
85 | void md_run_setup(void); | 72 | void md_run_setup(void); |
86 | 73 | ||
87 | #else | 74 | #else |
88 | 75 | ||
89 | static inline void md_run_setup(void) {} | 76 | static inline void md_run_setup(void) {} |
90 | 77 | ||
91 | #endif | 78 | #endif |
92 | 79 |
init/do_mounts_devfs.c
1 | File was deleted | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/dirent.h> | ||
4 | #include <linux/string.h> | ||
5 | |||
6 | #include "do_mounts.h" | ||
7 | |||
8 | void __init mount_devfs(void) | ||
9 | { | ||
10 | sys_mount("devfs", "/dev", "devfs", 0, NULL); | ||
11 | } | ||
12 | |||
13 | void __init umount_devfs(char *path) | ||
14 | { | ||
15 | sys_umount(path, 0); | ||
16 | } | ||
17 | |||
18 | /* | ||
19 | * If the dir will fit in *buf, return its length. If it won't fit, return | ||
20 | * zero. Return -ve on error. | ||
21 | */ | ||
22 | static int __init do_read_dir(int fd, void *buf, int len) | ||
23 | { | ||
24 | long bytes, n; | ||
25 | char *p = buf; | ||
26 | sys_lseek(fd, 0, 0); | ||
27 | |||
28 | for (bytes = 0; bytes < len; bytes += n) { | ||
29 | n = sys_getdents64(fd, (struct linux_dirent64 *)(p + bytes), | ||
30 | len - bytes); | ||
31 | if (n < 0) | ||
32 | return n; | ||
33 | if (n == 0) | ||
34 | return bytes; | ||
35 | } | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | /* | ||
40 | * Try to read all of a directory. Returns the contents at *p, which | ||
41 | * is kmalloced memory. Returns the number of bytes read at *len. Returns | ||
42 | * NULL on error. | ||
43 | */ | ||
44 | static void * __init read_dir(char *path, int *len) | ||
45 | { | ||
46 | int size; | ||
47 | int fd = sys_open(path, 0, 0); | ||
48 | |||
49 | *len = 0; | ||
50 | if (fd < 0) | ||
51 | return NULL; | ||
52 | |||
53 | for (size = 1 << 9; size <= (PAGE_SIZE << MAX_ORDER); size <<= 1) { | ||
54 | void *p = kmalloc(size, GFP_KERNEL); | ||
55 | int n; | ||
56 | if (!p) | ||
57 | break; | ||
58 | n = do_read_dir(fd, p, size); | ||
59 | if (n > 0) { | ||
60 | sys_close(fd); | ||
61 | *len = n; | ||
62 | return p; | ||
63 | } | ||
64 | kfree(p); | ||
65 | if (n == -EINVAL) | ||
66 | continue; /* Try a larger buffer */ | ||
67 | if (n < 0) | ||
68 | break; | ||
69 | } | ||
70 | sys_close(fd); | ||
71 | return NULL; | ||
72 | } | ||
73 | |||
74 | /* | ||
75 | * recursively scan <path>, looking for a device node of type <dev> | ||
76 | */ | ||
77 | static int __init find_in_devfs(char *path, unsigned dev) | ||
78 | { | ||
79 | char *end = path + strlen(path); | ||
80 | int rest = path + 64 - end; | ||
81 | int size; | ||
82 | char *p = read_dir(path, &size); | ||
83 | char *s; | ||
84 | |||
85 | if (!p) | ||
86 | return -1; | ||
87 | for (s = p; s < p + size; s += ((struct linux_dirent64 *)s)->d_reclen) { | ||
88 | struct linux_dirent64 *d = (struct linux_dirent64 *)s; | ||
89 | if (strlen(d->d_name) + 2 > rest) | ||
90 | continue; | ||
91 | switch (d->d_type) { | ||
92 | case DT_BLK: | ||
93 | sprintf(end, "/%s", d->d_name); | ||
94 | if (bstat(path) != dev) | ||
95 | break; | ||
96 | kfree(p); | ||
97 | return 0; | ||
98 | case DT_DIR: | ||
99 | if (strcmp(d->d_name, ".") == 0) | ||
100 | break; | ||
101 | if (strcmp(d->d_name, "..") == 0) | ||
102 | break; | ||
103 | sprintf(end, "/%s", d->d_name); | ||
104 | if (find_in_devfs(path, dev) < 0) | ||
105 | break; | ||
106 | kfree(p); | ||
107 | return 0; | ||
108 | } | ||
109 | } | ||
110 | kfree(p); | ||
111 | return -1; | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * create a device node called <name> which points to | ||
116 | * <devfs_name> if possible, otherwise find a device node | ||
117 | * which matches <dev> and make <name> a symlink pointing to it. | ||
118 | */ | ||
119 | int __init create_dev(char *name, dev_t dev, char *devfs_name) | ||
120 | { | ||
121 | char path[64]; | ||
122 | |||
123 | sys_unlink(name); | ||
124 | if (devfs_name && devfs_name[0]) { | ||
125 | if (strncmp(devfs_name, "/dev/", 5) == 0) | ||
126 | devfs_name += 5; | ||
127 | sprintf(path, "/dev/%s", devfs_name); | ||
128 | if (sys_access(path, 0) == 0) | ||
129 | return sys_symlink(devfs_name, name); | ||
130 | } | ||
131 | if (!dev) | ||
132 | return -1; | ||
133 | strcpy(path, "/dev"); | ||
134 | if (find_in_devfs(path, new_encode_dev(dev)) < 0) | ||
135 | return -1; | ||
136 | return sys_symlink(path + 5, name); | ||
137 | } | ||
138 | 1 |
init/do_mounts_initrd.c
1 | #define __KERNEL_SYSCALLS__ | 1 | #define __KERNEL_SYSCALLS__ |
2 | #include <linux/unistd.h> | 2 | #include <linux/unistd.h> |
3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
4 | #include <linux/fs.h> | 4 | #include <linux/fs.h> |
5 | #include <linux/minix_fs.h> | 5 | #include <linux/minix_fs.h> |
6 | #include <linux/ext2_fs.h> | 6 | #include <linux/ext2_fs.h> |
7 | #include <linux/romfs_fs.h> | 7 | #include <linux/romfs_fs.h> |
8 | #include <linux/initrd.h> | 8 | #include <linux/initrd.h> |
9 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
10 | 10 | ||
11 | #include "do_mounts.h" | 11 | #include "do_mounts.h" |
12 | 12 | ||
13 | unsigned long initrd_start, initrd_end; | 13 | unsigned long initrd_start, initrd_end; |
14 | int initrd_below_start_ok; | 14 | int initrd_below_start_ok; |
15 | unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */ | 15 | unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */ |
16 | static int __initdata old_fd, root_fd; | 16 | static int __initdata old_fd, root_fd; |
17 | static int __initdata mount_initrd = 1; | 17 | static int __initdata mount_initrd = 1; |
18 | 18 | ||
19 | static int __init no_initrd(char *str) | 19 | static int __init no_initrd(char *str) |
20 | { | 20 | { |
21 | mount_initrd = 0; | 21 | mount_initrd = 0; |
22 | return 1; | 22 | return 1; |
23 | } | 23 | } |
24 | 24 | ||
25 | __setup("noinitrd", no_initrd); | 25 | __setup("noinitrd", no_initrd); |
26 | 26 | ||
27 | static int __init do_linuxrc(void * shell) | 27 | static int __init do_linuxrc(void * shell) |
28 | { | 28 | { |
29 | static char *argv[] = { "linuxrc", NULL, }; | 29 | static char *argv[] = { "linuxrc", NULL, }; |
30 | extern char * envp_init[]; | 30 | extern char * envp_init[]; |
31 | 31 | ||
32 | sys_close(old_fd);sys_close(root_fd); | 32 | sys_close(old_fd);sys_close(root_fd); |
33 | sys_close(0);sys_close(1);sys_close(2); | 33 | sys_close(0);sys_close(1);sys_close(2); |
34 | sys_setsid(); | 34 | sys_setsid(); |
35 | (void) sys_open("/dev/console",O_RDWR,0); | 35 | (void) sys_open("/dev/console",O_RDWR,0); |
36 | (void) sys_dup(0); | 36 | (void) sys_dup(0); |
37 | (void) sys_dup(0); | 37 | (void) sys_dup(0); |
38 | return execve(shell, argv, envp_init); | 38 | return execve(shell, argv, envp_init); |
39 | } | 39 | } |
40 | 40 | ||
41 | static void __init handle_initrd(void) | 41 | static void __init handle_initrd(void) |
42 | { | 42 | { |
43 | int error; | 43 | int error; |
44 | int pid; | 44 | int pid; |
45 | 45 | ||
46 | real_root_dev = new_encode_dev(ROOT_DEV); | 46 | real_root_dev = new_encode_dev(ROOT_DEV); |
47 | create_dev("/dev/root.old", Root_RAM0, NULL); | 47 | create_dev("/dev/root.old", Root_RAM0); |
48 | /* mount initrd on rootfs' /root */ | 48 | /* mount initrd on rootfs' /root */ |
49 | mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY); | 49 | mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY); |
50 | sys_mkdir("/old", 0700); | 50 | sys_mkdir("/old", 0700); |
51 | root_fd = sys_open("/", 0, 0); | 51 | root_fd = sys_open("/", 0, 0); |
52 | old_fd = sys_open("/old", 0, 0); | 52 | old_fd = sys_open("/old", 0, 0); |
53 | /* move initrd over / and chdir/chroot in initrd root */ | 53 | /* move initrd over / and chdir/chroot in initrd root */ |
54 | sys_chdir("/root"); | 54 | sys_chdir("/root"); |
55 | sys_mount(".", "/", NULL, MS_MOVE, NULL); | 55 | sys_mount(".", "/", NULL, MS_MOVE, NULL); |
56 | sys_chroot("."); | 56 | sys_chroot("."); |
57 | mount_devfs_fs (); | ||
58 | 57 | ||
59 | current->flags |= PF_NOFREEZE; | 58 | current->flags |= PF_NOFREEZE; |
60 | pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); | 59 | pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD); |
61 | if (pid > 0) { | 60 | if (pid > 0) { |
62 | while (pid != sys_wait4(-1, NULL, 0, NULL)) | 61 | while (pid != sys_wait4(-1, NULL, 0, NULL)) |
63 | yield(); | 62 | yield(); |
64 | } | 63 | } |
65 | 64 | ||
66 | /* move initrd to rootfs' /old */ | 65 | /* move initrd to rootfs' /old */ |
67 | sys_fchdir(old_fd); | 66 | sys_fchdir(old_fd); |
68 | sys_mount("/", ".", NULL, MS_MOVE, NULL); | 67 | sys_mount("/", ".", NULL, MS_MOVE, NULL); |
69 | /* switch root and cwd back to / of rootfs */ | 68 | /* switch root and cwd back to / of rootfs */ |
70 | sys_fchdir(root_fd); | 69 | sys_fchdir(root_fd); |
71 | sys_chroot("."); | 70 | sys_chroot("."); |
72 | sys_close(old_fd); | 71 | sys_close(old_fd); |
73 | sys_close(root_fd); | 72 | sys_close(root_fd); |
74 | umount_devfs("/old/dev"); | ||
75 | 73 | ||
76 | if (new_decode_dev(real_root_dev) == Root_RAM0) { | 74 | if (new_decode_dev(real_root_dev) == Root_RAM0) { |
77 | sys_chdir("/old"); | 75 | sys_chdir("/old"); |
78 | return; | 76 | return; |
79 | } | 77 | } |
80 | 78 | ||
81 | ROOT_DEV = new_decode_dev(real_root_dev); | 79 | ROOT_DEV = new_decode_dev(real_root_dev); |
82 | mount_root(); | 80 | mount_root(); |
83 | 81 | ||
84 | printk(KERN_NOTICE "Trying to move old root to /initrd ... "); | 82 | printk(KERN_NOTICE "Trying to move old root to /initrd ... "); |
85 | error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); | 83 | error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL); |
86 | if (!error) | 84 | if (!error) |
87 | printk("okay\n"); | 85 | printk("okay\n"); |
88 | else { | 86 | else { |
89 | int fd = sys_open("/dev/root.old", O_RDWR, 0); | 87 | int fd = sys_open("/dev/root.old", O_RDWR, 0); |
90 | if (error == -ENOENT) | 88 | if (error == -ENOENT) |
91 | printk("/initrd does not exist. Ignored.\n"); | 89 | printk("/initrd does not exist. Ignored.\n"); |
92 | else | 90 | else |
93 | printk("failed\n"); | 91 | printk("failed\n"); |
94 | printk(KERN_NOTICE "Unmounting old root\n"); | 92 | printk(KERN_NOTICE "Unmounting old root\n"); |
95 | sys_umount("/old", MNT_DETACH); | 93 | sys_umount("/old", MNT_DETACH); |
96 | printk(KERN_NOTICE "Trying to free ramdisk memory ... "); | 94 | printk(KERN_NOTICE "Trying to free ramdisk memory ... "); |
97 | if (fd < 0) { | 95 | if (fd < 0) { |
98 | error = fd; | 96 | error = fd; |
99 | } else { | 97 | } else { |
100 | error = sys_ioctl(fd, BLKFLSBUF, 0); | 98 | error = sys_ioctl(fd, BLKFLSBUF, 0); |
101 | sys_close(fd); | 99 | sys_close(fd); |
102 | } | 100 | } |
103 | printk(!error ? "okay\n" : "failed\n"); | 101 | printk(!error ? "okay\n" : "failed\n"); |
104 | } | 102 | } |
105 | } | 103 | } |
106 | 104 | ||
107 | int __init initrd_load(void) | 105 | int __init initrd_load(void) |
108 | { | 106 | { |
109 | if (mount_initrd) { | 107 | if (mount_initrd) { |
110 | create_dev("/dev/ram", Root_RAM0, NULL); | 108 | create_dev("/dev/ram", Root_RAM0); |
111 | /* | 109 | /* |
112 | * Load the initrd data into /dev/ram0. Execute it as initrd | 110 | * Load the initrd data into /dev/ram0. Execute it as initrd |
113 | * unless /dev/ram0 is supposed to be our actual root device, | 111 | * unless /dev/ram0 is supposed to be our actual root device, |
114 | * in that case the ram disk is just set up here, and gets | 112 | * in that case the ram disk is just set up here, and gets |
115 | * mounted in the normal path. | 113 | * mounted in the normal path. |
116 | */ | 114 | */ |
117 | if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) { | 115 | if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) { |
118 | sys_unlink("/initrd.image"); | 116 | sys_unlink("/initrd.image"); |
119 | handle_initrd(); | 117 | handle_initrd(); |
120 | return 1; | 118 | return 1; |
121 | } | 119 | } |
122 | } | 120 | } |
123 | sys_unlink("/initrd.image"); | 121 | sys_unlink("/initrd.image"); |
124 | return 0; | 122 | return 0; |
125 | } | 123 | } |
126 | 124 |
init/do_mounts_md.c
1 | 1 | ||
2 | #include <linux/raid/md.h> | 2 | #include <linux/raid/md.h> |
3 | 3 | ||
4 | #include "do_mounts.h" | 4 | #include "do_mounts.h" |
5 | 5 | ||
6 | /* | 6 | /* |
7 | * When md (and any require personalities) are compiled into the kernel | 7 | * When md (and any require personalities) are compiled into the kernel |
8 | * (not a module), arrays can be assembles are boot time using with AUTODETECT | 8 | * (not a module), arrays can be assembles are boot time using with AUTODETECT |
9 | * where specially marked partitions are registered with md_autodetect_dev(), | 9 | * where specially marked partitions are registered with md_autodetect_dev(), |
10 | * and with MD_BOOT where devices to be collected are given on the boot line | 10 | * and with MD_BOOT where devices to be collected are given on the boot line |
11 | * with md=..... | 11 | * with md=..... |
12 | * The code for that is here. | 12 | * The code for that is here. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | static int __initdata raid_noautodetect, raid_autopart; | 15 | static int __initdata raid_noautodetect, raid_autopart; |
16 | 16 | ||
17 | static struct { | 17 | static struct { |
18 | int minor; | 18 | int minor; |
19 | int partitioned; | 19 | int partitioned; |
20 | int level; | 20 | int level; |
21 | int chunk; | 21 | int chunk; |
22 | char *device_names; | 22 | char *device_names; |
23 | } md_setup_args[MAX_MD_DEVS] __initdata; | 23 | } md_setup_args[MAX_MD_DEVS] __initdata; |
24 | 24 | ||
25 | static int md_setup_ents __initdata; | 25 | static int md_setup_ents __initdata; |
26 | 26 | ||
27 | extern int mdp_major; | 27 | extern int mdp_major; |
28 | /* | 28 | /* |
29 | * Parse the command-line parameters given our kernel, but do not | 29 | * Parse the command-line parameters given our kernel, but do not |
30 | * actually try to invoke the MD device now; that is handled by | 30 | * actually try to invoke the MD device now; that is handled by |
31 | * md_setup_drive after the low-level disk drivers have initialised. | 31 | * md_setup_drive after the low-level disk drivers have initialised. |
32 | * | 32 | * |
33 | * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which | 33 | * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which |
34 | * assigns the task of parsing integer arguments to the | 34 | * assigns the task of parsing integer arguments to the |
35 | * invoked program now). Added ability to initialise all | 35 | * invoked program now). Added ability to initialise all |
36 | * the MD devices (by specifying multiple "md=" lines) | 36 | * the MD devices (by specifying multiple "md=" lines) |
37 | * instead of just one. -- KTK | 37 | * instead of just one. -- KTK |
38 | * 18May2000: Added support for persistent-superblock arrays: | 38 | * 18May2000: Added support for persistent-superblock arrays: |
39 | * md=n,0,factor,fault,device-list uses RAID0 for device n | 39 | * md=n,0,factor,fault,device-list uses RAID0 for device n |
40 | * md=n,-1,factor,fault,device-list uses LINEAR for device n | 40 | * md=n,-1,factor,fault,device-list uses LINEAR for device n |
41 | * md=n,device-list reads a RAID superblock from the devices | 41 | * md=n,device-list reads a RAID superblock from the devices |
42 | * elements in device-list are read by name_to_kdev_t so can be | 42 | * elements in device-list are read by name_to_kdev_t so can be |
43 | * a hex number or something like /dev/hda1 /dev/sdb | 43 | * a hex number or something like /dev/hda1 /dev/sdb |
44 | * 2001-06-03: Dave Cinege <dcinege@psychosis.com> | 44 | * 2001-06-03: Dave Cinege <dcinege@psychosis.com> |
45 | * Shifted name_to_kdev_t() and related operations to md_set_drive() | 45 | * Shifted name_to_kdev_t() and related operations to md_set_drive() |
46 | * for later execution. Rewrote section to make devfs compatible. | 46 | * for later execution. Rewrote section to make devfs compatible. |
47 | */ | 47 | */ |
48 | static int __init md_setup(char *str) | 48 | static int __init md_setup(char *str) |
49 | { | 49 | { |
50 | int minor, level, factor, fault, partitioned = 0; | 50 | int minor, level, factor, fault, partitioned = 0; |
51 | char *pername = ""; | 51 | char *pername = ""; |
52 | char *str1; | 52 | char *str1; |
53 | int ent; | 53 | int ent; |
54 | 54 | ||
55 | if (*str == 'd') { | 55 | if (*str == 'd') { |
56 | partitioned = 1; | 56 | partitioned = 1; |
57 | str++; | 57 | str++; |
58 | } | 58 | } |
59 | if (get_option(&str, &minor) != 2) { /* MD Number */ | 59 | if (get_option(&str, &minor) != 2) { /* MD Number */ |
60 | printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); | 60 | printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); |
61 | return 0; | 61 | return 0; |
62 | } | 62 | } |
63 | str1 = str; | 63 | str1 = str; |
64 | if (minor >= MAX_MD_DEVS) { | 64 | if (minor >= MAX_MD_DEVS) { |
65 | printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor); | 65 | printk(KERN_WARNING "md: md=%d, Minor device number too high.\n", minor); |
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | for (ent=0 ; ent< md_setup_ents ; ent++) | 68 | for (ent=0 ; ent< md_setup_ents ; ent++) |
69 | if (md_setup_args[ent].minor == minor && | 69 | if (md_setup_args[ent].minor == minor && |
70 | md_setup_args[ent].partitioned == partitioned) { | 70 | md_setup_args[ent].partitioned == partitioned) { |
71 | printk(KERN_WARNING "md: md=%s%d, Specified more than once. " | 71 | printk(KERN_WARNING "md: md=%s%d, Specified more than once. " |
72 | "Replacing previous definition.\n", partitioned?"d":"", minor); | 72 | "Replacing previous definition.\n", partitioned?"d":"", minor); |
73 | break; | 73 | break; |
74 | } | 74 | } |
75 | if (ent >= MAX_MD_DEVS) { | 75 | if (ent >= MAX_MD_DEVS) { |
76 | printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor); | 76 | printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor); |
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | if (ent >= md_setup_ents) | 79 | if (ent >= md_setup_ents) |
80 | md_setup_ents++; | 80 | md_setup_ents++; |
81 | switch (get_option(&str, &level)) { /* RAID level */ | 81 | switch (get_option(&str, &level)) { /* RAID level */ |
82 | case 2: /* could be 0 or -1.. */ | 82 | case 2: /* could be 0 or -1.. */ |
83 | if (level == 0 || level == LEVEL_LINEAR) { | 83 | if (level == 0 || level == LEVEL_LINEAR) { |
84 | if (get_option(&str, &factor) != 2 || /* Chunk Size */ | 84 | if (get_option(&str, &factor) != 2 || /* Chunk Size */ |
85 | get_option(&str, &fault) != 2) { | 85 | get_option(&str, &fault) != 2) { |
86 | printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); | 86 | printk(KERN_WARNING "md: Too few arguments supplied to md=.\n"); |
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
89 | md_setup_args[ent].level = level; | 89 | md_setup_args[ent].level = level; |
90 | md_setup_args[ent].chunk = 1 << (factor+12); | 90 | md_setup_args[ent].chunk = 1 << (factor+12); |
91 | if (level == LEVEL_LINEAR) | 91 | if (level == LEVEL_LINEAR) |
92 | pername = "linear"; | 92 | pername = "linear"; |
93 | else | 93 | else |
94 | pername = "raid0"; | 94 | pername = "raid0"; |
95 | break; | 95 | break; |
96 | } | 96 | } |
97 | /* FALL THROUGH */ | 97 | /* FALL THROUGH */ |
98 | case 1: /* the first device is numeric */ | 98 | case 1: /* the first device is numeric */ |
99 | str = str1; | 99 | str = str1; |
100 | /* FALL THROUGH */ | 100 | /* FALL THROUGH */ |
101 | case 0: | 101 | case 0: |
102 | md_setup_args[ent].level = LEVEL_NONE; | 102 | md_setup_args[ent].level = LEVEL_NONE; |
103 | pername="super-block"; | 103 | pername="super-block"; |
104 | } | 104 | } |
105 | 105 | ||
106 | printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n", | 106 | printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n", |
107 | minor, pername, str); | 107 | minor, pername, str); |
108 | md_setup_args[ent].device_names = str; | 108 | md_setup_args[ent].device_names = str; |
109 | md_setup_args[ent].partitioned = partitioned; | 109 | md_setup_args[ent].partitioned = partitioned; |
110 | md_setup_args[ent].minor = minor; | 110 | md_setup_args[ent].minor = minor; |
111 | 111 | ||
112 | return 1; | 112 | return 1; |
113 | } | 113 | } |
114 | 114 | ||
115 | #define MdpMinorShift 6 | 115 | #define MdpMinorShift 6 |
116 | 116 | ||
117 | static void __init md_setup_drive(void) | 117 | static void __init md_setup_drive(void) |
118 | { | 118 | { |
119 | int minor, i, ent, partitioned; | 119 | int minor, i, ent, partitioned; |
120 | dev_t dev; | 120 | dev_t dev; |
121 | dev_t devices[MD_SB_DISKS+1]; | 121 | dev_t devices[MD_SB_DISKS+1]; |
122 | 122 | ||
123 | for (ent = 0; ent < md_setup_ents ; ent++) { | 123 | for (ent = 0; ent < md_setup_ents ; ent++) { |
124 | int fd; | 124 | int fd; |
125 | int err = 0; | 125 | int err = 0; |
126 | char *devname; | 126 | char *devname; |
127 | mdu_disk_info_t dinfo; | 127 | mdu_disk_info_t dinfo; |
128 | char name[16], devfs_name[16]; | 128 | char name[16]; |
129 | 129 | ||
130 | minor = md_setup_args[ent].minor; | 130 | minor = md_setup_args[ent].minor; |
131 | partitioned = md_setup_args[ent].partitioned; | 131 | partitioned = md_setup_args[ent].partitioned; |
132 | devname = md_setup_args[ent].device_names; | 132 | devname = md_setup_args[ent].device_names; |
133 | 133 | ||
134 | sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor); | 134 | sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor); |
135 | sprintf(devfs_name, "/dev/md/%s%d", partitioned?"d":"", minor); | ||
136 | if (partitioned) | 135 | if (partitioned) |
137 | dev = MKDEV(mdp_major, minor << MdpMinorShift); | 136 | dev = MKDEV(mdp_major, minor << MdpMinorShift); |
138 | else | 137 | else |
139 | dev = MKDEV(MD_MAJOR, minor); | 138 | dev = MKDEV(MD_MAJOR, minor); |
140 | create_dev(name, dev, devfs_name); | 139 | create_dev(name, dev); |
141 | for (i = 0; i < MD_SB_DISKS && devname != 0; i++) { | 140 | for (i = 0; i < MD_SB_DISKS && devname != 0; i++) { |
142 | char *p; | 141 | char *p; |
143 | char comp_name[64]; | 142 | char comp_name[64]; |
144 | u32 rdev; | 143 | u32 rdev; |
145 | 144 | ||
146 | p = strchr(devname, ','); | 145 | p = strchr(devname, ','); |
147 | if (p) | 146 | if (p) |
148 | *p++ = 0; | 147 | *p++ = 0; |
149 | 148 | ||
150 | dev = name_to_dev_t(devname); | 149 | dev = name_to_dev_t(devname); |
151 | if (strncmp(devname, "/dev/", 5) == 0) | 150 | if (strncmp(devname, "/dev/", 5) == 0) |
152 | devname += 5; | 151 | devname += 5; |
153 | snprintf(comp_name, 63, "/dev/%s", devname); | 152 | snprintf(comp_name, 63, "/dev/%s", devname); |
154 | rdev = bstat(comp_name); | 153 | rdev = bstat(comp_name); |
155 | if (rdev) | 154 | if (rdev) |
156 | dev = new_decode_dev(rdev); | 155 | dev = new_decode_dev(rdev); |
157 | if (!dev) { | 156 | if (!dev) { |
158 | printk(KERN_WARNING "md: Unknown device name: %s\n", devname); | 157 | printk(KERN_WARNING "md: Unknown device name: %s\n", devname); |
159 | break; | 158 | break; |
160 | } | 159 | } |
161 | 160 | ||
162 | devices[i] = dev; | 161 | devices[i] = dev; |
163 | 162 | ||
164 | devname = p; | 163 | devname = p; |
165 | } | 164 | } |
166 | devices[i] = 0; | 165 | devices[i] = 0; |
167 | 166 | ||
168 | if (!i) | 167 | if (!i) |
169 | continue; | 168 | continue; |
170 | 169 | ||
171 | printk(KERN_INFO "md: Loading md%s%d: %s\n", | 170 | printk(KERN_INFO "md: Loading md%s%d: %s\n", |
172 | partitioned ? "_d" : "", minor, | 171 | partitioned ? "_d" : "", minor, |
173 | md_setup_args[ent].device_names); | 172 | md_setup_args[ent].device_names); |
174 | 173 | ||
175 | fd = sys_open(name, 0, 0); | 174 | fd = sys_open(name, 0, 0); |
176 | if (fd < 0) { | 175 | if (fd < 0) { |
177 | printk(KERN_ERR "md: open failed - cannot start " | 176 | printk(KERN_ERR "md: open failed - cannot start " |
178 | "array %s\n", name); | 177 | "array %s\n", name); |
179 | continue; | 178 | continue; |
180 | } | 179 | } |
181 | if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) { | 180 | if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) { |
182 | printk(KERN_WARNING | 181 | printk(KERN_WARNING |
183 | "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n", | 182 | "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n", |
184 | minor); | 183 | minor); |
185 | sys_close(fd); | 184 | sys_close(fd); |
186 | continue; | 185 | continue; |
187 | } | 186 | } |
188 | 187 | ||
189 | if (md_setup_args[ent].level != LEVEL_NONE) { | 188 | if (md_setup_args[ent].level != LEVEL_NONE) { |
190 | /* non-persistent */ | 189 | /* non-persistent */ |
191 | mdu_array_info_t ainfo; | 190 | mdu_array_info_t ainfo; |
192 | ainfo.level = md_setup_args[ent].level; | 191 | ainfo.level = md_setup_args[ent].level; |
193 | ainfo.size = 0; | 192 | ainfo.size = 0; |
194 | ainfo.nr_disks =0; | 193 | ainfo.nr_disks =0; |
195 | ainfo.raid_disks =0; | 194 | ainfo.raid_disks =0; |
196 | while (devices[ainfo.raid_disks]) | 195 | while (devices[ainfo.raid_disks]) |
197 | ainfo.raid_disks++; | 196 | ainfo.raid_disks++; |
198 | ainfo.md_minor =minor; | 197 | ainfo.md_minor =minor; |
199 | ainfo.not_persistent = 1; | 198 | ainfo.not_persistent = 1; |
200 | 199 | ||
201 | ainfo.state = (1 << MD_SB_CLEAN); | 200 | ainfo.state = (1 << MD_SB_CLEAN); |
202 | ainfo.layout = 0; | 201 | ainfo.layout = 0; |
203 | ainfo.chunk_size = md_setup_args[ent].chunk; | 202 | ainfo.chunk_size = md_setup_args[ent].chunk; |
204 | err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo); | 203 | err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo); |
205 | for (i = 0; !err && i <= MD_SB_DISKS; i++) { | 204 | for (i = 0; !err && i <= MD_SB_DISKS; i++) { |
206 | dev = devices[i]; | 205 | dev = devices[i]; |
207 | if (!dev) | 206 | if (!dev) |
208 | break; | 207 | break; |
209 | dinfo.number = i; | 208 | dinfo.number = i; |
210 | dinfo.raid_disk = i; | 209 | dinfo.raid_disk = i; |
211 | dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC); | 210 | dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC); |
212 | dinfo.major = MAJOR(dev); | 211 | dinfo.major = MAJOR(dev); |
213 | dinfo.minor = MINOR(dev); | 212 | dinfo.minor = MINOR(dev); |
214 | err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo); | 213 | err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo); |
215 | } | 214 | } |
216 | } else { | 215 | } else { |
217 | /* persistent */ | 216 | /* persistent */ |
218 | for (i = 0; i <= MD_SB_DISKS; i++) { | 217 | for (i = 0; i <= MD_SB_DISKS; i++) { |
219 | dev = devices[i]; | 218 | dev = devices[i]; |
220 | if (!dev) | 219 | if (!dev) |
221 | break; | 220 | break; |
222 | dinfo.major = MAJOR(dev); | 221 | dinfo.major = MAJOR(dev); |
223 | dinfo.minor = MINOR(dev); | 222 | dinfo.minor = MINOR(dev); |
224 | sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo); | 223 | sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo); |
225 | } | 224 | } |
226 | } | 225 | } |
227 | if (!err) | 226 | if (!err) |
228 | err = sys_ioctl(fd, RUN_ARRAY, 0); | 227 | err = sys_ioctl(fd, RUN_ARRAY, 0); |
229 | if (err) | 228 | if (err) |
230 | printk(KERN_WARNING "md: starting md%d failed\n", minor); | 229 | printk(KERN_WARNING "md: starting md%d failed\n", minor); |
231 | else { | 230 | else { |
232 | /* reread the partition table. | 231 | /* reread the partition table. |
233 | * I (neilb) and not sure why this is needed, but I cannot | 232 | * I (neilb) and not sure why this is needed, but I cannot |
234 | * boot a kernel with devfs compiled in from partitioned md | 233 | * boot a kernel with devfs compiled in from partitioned md |
235 | * array without it | 234 | * array without it |
236 | */ | 235 | */ |
237 | sys_close(fd); | 236 | sys_close(fd); |
238 | fd = sys_open(name, 0, 0); | 237 | fd = sys_open(name, 0, 0); |
239 | sys_ioctl(fd, BLKRRPART, 0); | 238 | sys_ioctl(fd, BLKRRPART, 0); |
240 | } | 239 | } |
241 | sys_close(fd); | 240 | sys_close(fd); |
242 | } | 241 | } |
243 | } | 242 | } |
244 | 243 | ||
245 | static int __init raid_setup(char *str) | 244 | static int __init raid_setup(char *str) |
246 | { | 245 | { |
247 | int len, pos; | 246 | int len, pos; |
248 | 247 | ||
249 | len = strlen(str) + 1; | 248 | len = strlen(str) + 1; |
250 | pos = 0; | 249 | pos = 0; |
251 | 250 | ||
252 | while (pos < len) { | 251 | while (pos < len) { |
253 | char *comma = strchr(str+pos, ','); | 252 | char *comma = strchr(str+pos, ','); |
254 | int wlen; | 253 | int wlen; |
255 | if (comma) | 254 | if (comma) |
256 | wlen = (comma-str)-pos; | 255 | wlen = (comma-str)-pos; |
257 | else wlen = (len-1)-pos; | 256 | else wlen = (len-1)-pos; |
258 | 257 | ||
259 | if (!strncmp(str, "noautodetect", wlen)) | 258 | if (!strncmp(str, "noautodetect", wlen)) |
260 | raid_noautodetect = 1; | 259 | raid_noautodetect = 1; |
261 | if (strncmp(str, "partitionable", wlen)==0) | 260 | if (strncmp(str, "partitionable", wlen)==0) |
262 | raid_autopart = 1; | 261 | raid_autopart = 1; |
263 | if (strncmp(str, "part", wlen)==0) | 262 | if (strncmp(str, "part", wlen)==0) |
264 | raid_autopart = 1; | 263 | raid_autopart = 1; |
265 | pos += wlen+1; | 264 | pos += wlen+1; |
266 | } | 265 | } |
267 | return 1; | 266 | return 1; |
268 | } | 267 | } |
269 | 268 | ||
270 | __setup("raid=", raid_setup); | 269 | __setup("raid=", raid_setup); |
271 | __setup("md=", md_setup); | 270 | __setup("md=", md_setup); |
272 | 271 | ||
273 | void __init md_run_setup(void) | 272 | void __init md_run_setup(void) |
274 | { | 273 | { |
275 | create_dev("/dev/md0", MKDEV(MD_MAJOR, 0), "md/0"); | 274 | create_dev("/dev/md0", MKDEV(MD_MAJOR, 0)); |
276 | if (raid_noautodetect) | 275 | if (raid_noautodetect) |
277 | printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n"); | 276 | printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n"); |
278 | else { | 277 | else { |
279 | int fd = sys_open("/dev/md0", 0, 0); | 278 | int fd = sys_open("/dev/md0", 0, 0); |
280 | if (fd >= 0) { | 279 | if (fd >= 0) { |
281 | sys_ioctl(fd, RAID_AUTORUN, raid_autopart); | 280 | sys_ioctl(fd, RAID_AUTORUN, raid_autopart); |
282 | sys_close(fd); | 281 | sys_close(fd); |
283 | } | 282 | } |
284 | } | 283 | } |
285 | md_setup_drive(); | 284 | md_setup_drive(); |
286 | } | 285 | } |
287 | 286 |
init/do_mounts_rd.c
1 | 1 | ||
2 | #include <linux/kernel.h> | 2 | #include <linux/kernel.h> |
3 | #include <linux/fs.h> | 3 | #include <linux/fs.h> |
4 | #include <linux/minix_fs.h> | 4 | #include <linux/minix_fs.h> |
5 | #include <linux/ext2_fs.h> | 5 | #include <linux/ext2_fs.h> |
6 | #include <linux/romfs_fs.h> | 6 | #include <linux/romfs_fs.h> |
7 | #include <linux/cramfs_fs.h> | 7 | #include <linux/cramfs_fs.h> |
8 | #include <linux/initrd.h> | 8 | #include <linux/initrd.h> |
9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
10 | 10 | ||
11 | #include "do_mounts.h" | 11 | #include "do_mounts.h" |
12 | 12 | ||
13 | #define BUILD_CRAMDISK | 13 | #define BUILD_CRAMDISK |
14 | 14 | ||
15 | int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ | 15 | int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ |
16 | 16 | ||
17 | static int __init prompt_ramdisk(char *str) | 17 | static int __init prompt_ramdisk(char *str) |
18 | { | 18 | { |
19 | rd_prompt = simple_strtol(str,NULL,0) & 1; | 19 | rd_prompt = simple_strtol(str,NULL,0) & 1; |
20 | return 1; | 20 | return 1; |
21 | } | 21 | } |
22 | __setup("prompt_ramdisk=", prompt_ramdisk); | 22 | __setup("prompt_ramdisk=", prompt_ramdisk); |
23 | 23 | ||
24 | int __initdata rd_image_start; /* starting block # of image */ | 24 | int __initdata rd_image_start; /* starting block # of image */ |
25 | 25 | ||
26 | static int __init ramdisk_start_setup(char *str) | 26 | static int __init ramdisk_start_setup(char *str) |
27 | { | 27 | { |
28 | rd_image_start = simple_strtol(str,NULL,0); | 28 | rd_image_start = simple_strtol(str,NULL,0); |
29 | return 1; | 29 | return 1; |
30 | } | 30 | } |
31 | __setup("ramdisk_start=", ramdisk_start_setup); | 31 | __setup("ramdisk_start=", ramdisk_start_setup); |
32 | 32 | ||
33 | static int __init crd_load(int in_fd, int out_fd); | 33 | static int __init crd_load(int in_fd, int out_fd); |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * This routine tries to find a RAM disk image to load, and returns the | 36 | * This routine tries to find a RAM disk image to load, and returns the |
37 | * number of blocks to read for a non-compressed image, 0 if the image | 37 | * number of blocks to read for a non-compressed image, 0 if the image |
38 | * is a compressed image, and -1 if an image with the right magic | 38 | * is a compressed image, and -1 if an image with the right magic |
39 | * numbers could not be found. | 39 | * numbers could not be found. |
40 | * | 40 | * |
41 | * We currently check for the following magic numbers: | 41 | * We currently check for the following magic numbers: |
42 | * minix | 42 | * minix |
43 | * ext2 | 43 | * ext2 |
44 | * romfs | 44 | * romfs |
45 | * cramfs | 45 | * cramfs |
46 | * gzip | 46 | * gzip |
47 | */ | 47 | */ |
48 | static int __init | 48 | static int __init |
49 | identify_ramdisk_image(int fd, int start_block) | 49 | identify_ramdisk_image(int fd, int start_block) |
50 | { | 50 | { |
51 | const int size = 512; | 51 | const int size = 512; |
52 | struct minix_super_block *minixsb; | 52 | struct minix_super_block *minixsb; |
53 | struct ext2_super_block *ext2sb; | 53 | struct ext2_super_block *ext2sb; |
54 | struct romfs_super_block *romfsb; | 54 | struct romfs_super_block *romfsb; |
55 | struct cramfs_super *cramfsb; | 55 | struct cramfs_super *cramfsb; |
56 | int nblocks = -1; | 56 | int nblocks = -1; |
57 | unsigned char *buf; | 57 | unsigned char *buf; |
58 | 58 | ||
59 | buf = kmalloc(size, GFP_KERNEL); | 59 | buf = kmalloc(size, GFP_KERNEL); |
60 | if (buf == 0) | 60 | if (buf == 0) |
61 | return -1; | 61 | return -1; |
62 | 62 | ||
63 | minixsb = (struct minix_super_block *) buf; | 63 | minixsb = (struct minix_super_block *) buf; |
64 | ext2sb = (struct ext2_super_block *) buf; | 64 | ext2sb = (struct ext2_super_block *) buf; |
65 | romfsb = (struct romfs_super_block *) buf; | 65 | romfsb = (struct romfs_super_block *) buf; |
66 | cramfsb = (struct cramfs_super *) buf; | 66 | cramfsb = (struct cramfs_super *) buf; |
67 | memset(buf, 0xe5, size); | 67 | memset(buf, 0xe5, size); |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * Read block 0 to test for gzipped kernel | 70 | * Read block 0 to test for gzipped kernel |
71 | */ | 71 | */ |
72 | sys_lseek(fd, start_block * BLOCK_SIZE, 0); | 72 | sys_lseek(fd, start_block * BLOCK_SIZE, 0); |
73 | sys_read(fd, buf, size); | 73 | sys_read(fd, buf, size); |
74 | 74 | ||
75 | /* | 75 | /* |
76 | * If it matches the gzip magic numbers, return -1 | 76 | * If it matches the gzip magic numbers, return -1 |
77 | */ | 77 | */ |
78 | if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) { | 78 | if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) { |
79 | printk(KERN_NOTICE | 79 | printk(KERN_NOTICE |
80 | "RAMDISK: Compressed image found at block %d\n", | 80 | "RAMDISK: Compressed image found at block %d\n", |
81 | start_block); | 81 | start_block); |
82 | nblocks = 0; | 82 | nblocks = 0; |
83 | goto done; | 83 | goto done; |
84 | } | 84 | } |
85 | 85 | ||
86 | /* romfs is at block zero too */ | 86 | /* romfs is at block zero too */ |
87 | if (romfsb->word0 == ROMSB_WORD0 && | 87 | if (romfsb->word0 == ROMSB_WORD0 && |
88 | romfsb->word1 == ROMSB_WORD1) { | 88 | romfsb->word1 == ROMSB_WORD1) { |
89 | printk(KERN_NOTICE | 89 | printk(KERN_NOTICE |
90 | "RAMDISK: romfs filesystem found at block %d\n", | 90 | "RAMDISK: romfs filesystem found at block %d\n", |
91 | start_block); | 91 | start_block); |
92 | nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; | 92 | nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; |
93 | goto done; | 93 | goto done; |
94 | } | 94 | } |
95 | 95 | ||
96 | if (cramfsb->magic == CRAMFS_MAGIC) { | 96 | if (cramfsb->magic == CRAMFS_MAGIC) { |
97 | printk(KERN_NOTICE | 97 | printk(KERN_NOTICE |
98 | "RAMDISK: cramfs filesystem found at block %d\n", | 98 | "RAMDISK: cramfs filesystem found at block %d\n", |
99 | start_block); | 99 | start_block); |
100 | nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; | 100 | nblocks = (cramfsb->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS; |
101 | goto done; | 101 | goto done; |
102 | } | 102 | } |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Read block 1 to test for minix and ext2 superblock | 105 | * Read block 1 to test for minix and ext2 superblock |
106 | */ | 106 | */ |
107 | sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); | 107 | sys_lseek(fd, (start_block+1) * BLOCK_SIZE, 0); |
108 | sys_read(fd, buf, size); | 108 | sys_read(fd, buf, size); |
109 | 109 | ||
110 | /* Try minix */ | 110 | /* Try minix */ |
111 | if (minixsb->s_magic == MINIX_SUPER_MAGIC || | 111 | if (minixsb->s_magic == MINIX_SUPER_MAGIC || |
112 | minixsb->s_magic == MINIX_SUPER_MAGIC2) { | 112 | minixsb->s_magic == MINIX_SUPER_MAGIC2) { |
113 | printk(KERN_NOTICE | 113 | printk(KERN_NOTICE |
114 | "RAMDISK: Minix filesystem found at block %d\n", | 114 | "RAMDISK: Minix filesystem found at block %d\n", |
115 | start_block); | 115 | start_block); |
116 | nblocks = minixsb->s_nzones << minixsb->s_log_zone_size; | 116 | nblocks = minixsb->s_nzones << minixsb->s_log_zone_size; |
117 | goto done; | 117 | goto done; |
118 | } | 118 | } |
119 | 119 | ||
120 | /* Try ext2 */ | 120 | /* Try ext2 */ |
121 | if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { | 121 | if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { |
122 | printk(KERN_NOTICE | 122 | printk(KERN_NOTICE |
123 | "RAMDISK: ext2 filesystem found at block %d\n", | 123 | "RAMDISK: ext2 filesystem found at block %d\n", |
124 | start_block); | 124 | start_block); |
125 | nblocks = le32_to_cpu(ext2sb->s_blocks_count) << | 125 | nblocks = le32_to_cpu(ext2sb->s_blocks_count) << |
126 | le32_to_cpu(ext2sb->s_log_block_size); | 126 | le32_to_cpu(ext2sb->s_log_block_size); |
127 | goto done; | 127 | goto done; |
128 | } | 128 | } |
129 | 129 | ||
130 | printk(KERN_NOTICE | 130 | printk(KERN_NOTICE |
131 | "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n", | 131 | "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n", |
132 | start_block); | 132 | start_block); |
133 | 133 | ||
134 | done: | 134 | done: |
135 | sys_lseek(fd, start_block * BLOCK_SIZE, 0); | 135 | sys_lseek(fd, start_block * BLOCK_SIZE, 0); |
136 | kfree(buf); | 136 | kfree(buf); |
137 | return nblocks; | 137 | return nblocks; |
138 | } | 138 | } |
139 | 139 | ||
140 | int __init rd_load_image(char *from) | 140 | int __init rd_load_image(char *from) |
141 | { | 141 | { |
142 | int res = 0; | 142 | int res = 0; |
143 | int in_fd, out_fd; | 143 | int in_fd, out_fd; |
144 | unsigned long rd_blocks, devblocks; | 144 | unsigned long rd_blocks, devblocks; |
145 | int nblocks, i, disk; | 145 | int nblocks, i, disk; |
146 | char *buf = NULL; | 146 | char *buf = NULL; |
147 | unsigned short rotate = 0; | 147 | unsigned short rotate = 0; |
148 | #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) | 148 | #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) |
149 | char rotator[4] = { '|' , '/' , '-' , '\\' }; | 149 | char rotator[4] = { '|' , '/' , '-' , '\\' }; |
150 | #endif | 150 | #endif |
151 | 151 | ||
152 | out_fd = sys_open("/dev/ram", O_RDWR, 0); | 152 | out_fd = sys_open("/dev/ram", O_RDWR, 0); |
153 | if (out_fd < 0) | 153 | if (out_fd < 0) |
154 | goto out; | 154 | goto out; |
155 | 155 | ||
156 | in_fd = sys_open(from, O_RDONLY, 0); | 156 | in_fd = sys_open(from, O_RDONLY, 0); |
157 | if (in_fd < 0) | 157 | if (in_fd < 0) |
158 | goto noclose_input; | 158 | goto noclose_input; |
159 | 159 | ||
160 | nblocks = identify_ramdisk_image(in_fd, rd_image_start); | 160 | nblocks = identify_ramdisk_image(in_fd, rd_image_start); |
161 | if (nblocks < 0) | 161 | if (nblocks < 0) |
162 | goto done; | 162 | goto done; |
163 | 163 | ||
164 | if (nblocks == 0) { | 164 | if (nblocks == 0) { |
165 | #ifdef BUILD_CRAMDISK | 165 | #ifdef BUILD_CRAMDISK |
166 | if (crd_load(in_fd, out_fd) == 0) | 166 | if (crd_load(in_fd, out_fd) == 0) |
167 | goto successful_load; | 167 | goto successful_load; |
168 | #else | 168 | #else |
169 | printk(KERN_NOTICE | 169 | printk(KERN_NOTICE |
170 | "RAMDISK: Kernel does not support compressed " | 170 | "RAMDISK: Kernel does not support compressed " |
171 | "RAM disk images\n"); | 171 | "RAM disk images\n"); |
172 | #endif | 172 | #endif |
173 | goto done; | 173 | goto done; |
174 | } | 174 | } |
175 | 175 | ||
176 | /* | 176 | /* |
177 | * NOTE NOTE: nblocks is not actually blocks but | 177 | * NOTE NOTE: nblocks is not actually blocks but |
178 | * the number of kibibytes of data to load into a ramdisk. | 178 | * the number of kibibytes of data to load into a ramdisk. |
179 | * So any ramdisk block size that is a multiple of 1KiB should | 179 | * So any ramdisk block size that is a multiple of 1KiB should |
180 | * work when the appropriate ramdisk_blocksize is specified | 180 | * work when the appropriate ramdisk_blocksize is specified |
181 | * on the command line. | 181 | * on the command line. |
182 | * | 182 | * |
183 | * The default ramdisk_blocksize is 1KiB and it is generally | 183 | * The default ramdisk_blocksize is 1KiB and it is generally |
184 | * silly to use anything else, so make sure to use 1KiB | 184 | * silly to use anything else, so make sure to use 1KiB |
185 | * blocksize while generating ext2fs ramdisk-images. | 185 | * blocksize while generating ext2fs ramdisk-images. |
186 | */ | 186 | */ |
187 | if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) | 187 | if (sys_ioctl(out_fd, BLKGETSIZE, (unsigned long)&rd_blocks) < 0) |
188 | rd_blocks = 0; | 188 | rd_blocks = 0; |
189 | else | 189 | else |
190 | rd_blocks >>= 1; | 190 | rd_blocks >>= 1; |
191 | 191 | ||
192 | if (nblocks > rd_blocks) { | 192 | if (nblocks > rd_blocks) { |
193 | printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n", | 193 | printk("RAMDISK: image too big! (%dKiB/%ldKiB)\n", |
194 | nblocks, rd_blocks); | 194 | nblocks, rd_blocks); |
195 | goto done; | 195 | goto done; |
196 | } | 196 | } |
197 | 197 | ||
198 | /* | 198 | /* |
199 | * OK, time to copy in the data | 199 | * OK, time to copy in the data |
200 | */ | 200 | */ |
201 | if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) | 201 | if (sys_ioctl(in_fd, BLKGETSIZE, (unsigned long)&devblocks) < 0) |
202 | devblocks = 0; | 202 | devblocks = 0; |
203 | else | 203 | else |
204 | devblocks >>= 1; | 204 | devblocks >>= 1; |
205 | 205 | ||
206 | if (strcmp(from, "/initrd.image") == 0) | 206 | if (strcmp(from, "/initrd.image") == 0) |
207 | devblocks = nblocks; | 207 | devblocks = nblocks; |
208 | 208 | ||
209 | if (devblocks == 0) { | 209 | if (devblocks == 0) { |
210 | printk(KERN_ERR "RAMDISK: could not determine device size\n"); | 210 | printk(KERN_ERR "RAMDISK: could not determine device size\n"); |
211 | goto done; | 211 | goto done; |
212 | } | 212 | } |
213 | 213 | ||
214 | buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); | 214 | buf = kmalloc(BLOCK_SIZE, GFP_KERNEL); |
215 | if (buf == 0) { | 215 | if (buf == 0) { |
216 | printk(KERN_ERR "RAMDISK: could not allocate buffer\n"); | 216 | printk(KERN_ERR "RAMDISK: could not allocate buffer\n"); |
217 | goto done; | 217 | goto done; |
218 | } | 218 | } |
219 | 219 | ||
220 | printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ", | 220 | printk(KERN_NOTICE "RAMDISK: Loading %dKiB [%ld disk%s] into ram disk... ", |
221 | nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : ""); | 221 | nblocks, ((nblocks-1)/devblocks)+1, nblocks>devblocks ? "s" : ""); |
222 | for (i = 0, disk = 1; i < nblocks; i++) { | 222 | for (i = 0, disk = 1; i < nblocks; i++) { |
223 | if (i && (i % devblocks == 0)) { | 223 | if (i && (i % devblocks == 0)) { |
224 | printk("done disk #%d.\n", disk++); | 224 | printk("done disk #%d.\n", disk++); |
225 | rotate = 0; | 225 | rotate = 0; |
226 | if (sys_close(in_fd)) { | 226 | if (sys_close(in_fd)) { |
227 | printk("Error closing the disk.\n"); | 227 | printk("Error closing the disk.\n"); |
228 | goto noclose_input; | 228 | goto noclose_input; |
229 | } | 229 | } |
230 | change_floppy("disk #%d", disk); | 230 | change_floppy("disk #%d", disk); |
231 | in_fd = sys_open(from, O_RDONLY, 0); | 231 | in_fd = sys_open(from, O_RDONLY, 0); |
232 | if (in_fd < 0) { | 232 | if (in_fd < 0) { |
233 | printk("Error opening disk.\n"); | 233 | printk("Error opening disk.\n"); |
234 | goto noclose_input; | 234 | goto noclose_input; |
235 | } | 235 | } |
236 | printk("Loading disk #%d... ", disk); | 236 | printk("Loading disk #%d... ", disk); |
237 | } | 237 | } |
238 | sys_read(in_fd, buf, BLOCK_SIZE); | 238 | sys_read(in_fd, buf, BLOCK_SIZE); |
239 | sys_write(out_fd, buf, BLOCK_SIZE); | 239 | sys_write(out_fd, buf, BLOCK_SIZE); |
240 | #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) | 240 | #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES) |
241 | if (!(i % 16)) { | 241 | if (!(i % 16)) { |
242 | printk("%c\b", rotator[rotate & 0x3]); | 242 | printk("%c\b", rotator[rotate & 0x3]); |
243 | rotate++; | 243 | rotate++; |
244 | } | 244 | } |
245 | #endif | 245 | #endif |
246 | } | 246 | } |
247 | printk("done.\n"); | 247 | printk("done.\n"); |
248 | 248 | ||
249 | successful_load: | 249 | successful_load: |
250 | res = 1; | 250 | res = 1; |
251 | done: | 251 | done: |
252 | sys_close(in_fd); | 252 | sys_close(in_fd); |
253 | noclose_input: | 253 | noclose_input: |
254 | sys_close(out_fd); | 254 | sys_close(out_fd); |
255 | out: | 255 | out: |
256 | kfree(buf); | 256 | kfree(buf); |
257 | sys_unlink("/dev/ram"); | 257 | sys_unlink("/dev/ram"); |
258 | return res; | 258 | return res; |
259 | } | 259 | } |
260 | 260 | ||
261 | int __init rd_load_disk(int n) | 261 | int __init rd_load_disk(int n) |
262 | { | 262 | { |
263 | if (rd_prompt) | 263 | if (rd_prompt) |
264 | change_floppy("root floppy disk to be loaded into RAM disk"); | 264 | change_floppy("root floppy disk to be loaded into RAM disk"); |
265 | create_dev("/dev/root", ROOT_DEV, root_device_name); | 265 | create_dev("/dev/root", ROOT_DEV); |
266 | create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL); | 266 | create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n)); |
267 | return rd_load_image("/dev/root"); | 267 | return rd_load_image("/dev/root"); |
268 | } | 268 | } |
269 | 269 | ||
270 | #ifdef BUILD_CRAMDISK | 270 | #ifdef BUILD_CRAMDISK |
271 | 271 | ||
272 | /* | 272 | /* |
273 | * gzip declarations | 273 | * gzip declarations |
274 | */ | 274 | */ |
275 | 275 | ||
276 | #define OF(args) args | 276 | #define OF(args) args |
277 | 277 | ||
278 | #ifndef memzero | 278 | #ifndef memzero |
279 | #define memzero(s, n) memset ((s), 0, (n)) | 279 | #define memzero(s, n) memset ((s), 0, (n)) |
280 | #endif | 280 | #endif |
281 | 281 | ||
282 | typedef unsigned char uch; | 282 | typedef unsigned char uch; |
283 | typedef unsigned short ush; | 283 | typedef unsigned short ush; |
284 | typedef unsigned long ulg; | 284 | typedef unsigned long ulg; |
285 | 285 | ||
286 | #define INBUFSIZ 4096 | 286 | #define INBUFSIZ 4096 |
287 | #define WSIZE 0x8000 /* window size--must be a power of two, and */ | 287 | #define WSIZE 0x8000 /* window size--must be a power of two, and */ |
288 | /* at least 32K for zip's deflate method */ | 288 | /* at least 32K for zip's deflate method */ |
289 | 289 | ||
290 | static uch *inbuf; | 290 | static uch *inbuf; |
291 | static uch *window; | 291 | static uch *window; |
292 | 292 | ||
293 | static unsigned insize; /* valid bytes in inbuf */ | 293 | static unsigned insize; /* valid bytes in inbuf */ |
294 | static unsigned inptr; /* index of next byte to be processed in inbuf */ | 294 | static unsigned inptr; /* index of next byte to be processed in inbuf */ |
295 | static unsigned outcnt; /* bytes in output buffer */ | 295 | static unsigned outcnt; /* bytes in output buffer */ |
296 | static int exit_code; | 296 | static int exit_code; |
297 | static int unzip_error; | 297 | static int unzip_error; |
298 | static long bytes_out; | 298 | static long bytes_out; |
299 | static int crd_infd, crd_outfd; | 299 | static int crd_infd, crd_outfd; |
300 | 300 | ||
301 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) | 301 | #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) |
302 | 302 | ||
303 | /* Diagnostic functions (stubbed out) */ | 303 | /* Diagnostic functions (stubbed out) */ |
304 | #define Assert(cond,msg) | 304 | #define Assert(cond,msg) |
305 | #define Trace(x) | 305 | #define Trace(x) |
306 | #define Tracev(x) | 306 | #define Tracev(x) |
307 | #define Tracevv(x) | 307 | #define Tracevv(x) |
308 | #define Tracec(c,x) | 308 | #define Tracec(c,x) |
309 | #define Tracecv(c,x) | 309 | #define Tracecv(c,x) |
310 | 310 | ||
311 | #define STATIC static | 311 | #define STATIC static |
312 | #define INIT __init | 312 | #define INIT __init |
313 | 313 | ||
314 | static int __init fill_inbuf(void); | 314 | static int __init fill_inbuf(void); |
315 | static void __init flush_window(void); | 315 | static void __init flush_window(void); |
316 | static void __init *malloc(size_t size); | 316 | static void __init *malloc(size_t size); |
317 | static void __init free(void *where); | 317 | static void __init free(void *where); |
318 | static void __init error(char *m); | 318 | static void __init error(char *m); |
319 | static void __init gzip_mark(void **); | 319 | static void __init gzip_mark(void **); |
320 | static void __init gzip_release(void **); | 320 | static void __init gzip_release(void **); |
321 | 321 | ||
322 | #include "../lib/inflate.c" | 322 | #include "../lib/inflate.c" |
323 | 323 | ||
324 | static void __init *malloc(size_t size) | 324 | static void __init *malloc(size_t size) |
325 | { | 325 | { |
326 | return kmalloc(size, GFP_KERNEL); | 326 | return kmalloc(size, GFP_KERNEL); |
327 | } | 327 | } |
328 | 328 | ||
329 | static void __init free(void *where) | 329 | static void __init free(void *where) |
330 | { | 330 | { |
331 | kfree(where); | 331 | kfree(where); |
332 | } | 332 | } |
333 | 333 | ||
334 | static void __init gzip_mark(void **ptr) | 334 | static void __init gzip_mark(void **ptr) |
335 | { | 335 | { |
336 | } | 336 | } |
337 | 337 | ||
338 | static void __init gzip_release(void **ptr) | 338 | static void __init gzip_release(void **ptr) |
339 | { | 339 | { |
340 | } | 340 | } |
341 | 341 | ||
342 | 342 | ||
343 | /* =========================================================================== | 343 | /* =========================================================================== |
344 | * Fill the input buffer. This is called only when the buffer is empty | 344 | * Fill the input buffer. This is called only when the buffer is empty |
345 | * and at least one byte is really needed. | 345 | * and at least one byte is really needed. |
346 | * Returning -1 does not guarantee that gunzip() will ever return. | 346 | * Returning -1 does not guarantee that gunzip() will ever return. |
347 | */ | 347 | */ |
348 | static int __init fill_inbuf(void) | 348 | static int __init fill_inbuf(void) |
349 | { | 349 | { |
350 | if (exit_code) return -1; | 350 | if (exit_code) return -1; |
351 | 351 | ||
352 | insize = sys_read(crd_infd, inbuf, INBUFSIZ); | 352 | insize = sys_read(crd_infd, inbuf, INBUFSIZ); |
353 | if (insize == 0) { | 353 | if (insize == 0) { |
354 | error("RAMDISK: ran out of compressed data"); | 354 | error("RAMDISK: ran out of compressed data"); |
355 | return -1; | 355 | return -1; |
356 | } | 356 | } |
357 | 357 | ||
358 | inptr = 1; | 358 | inptr = 1; |
359 | 359 | ||
360 | return inbuf[0]; | 360 | return inbuf[0]; |
361 | } | 361 | } |
362 | 362 | ||
363 | /* =========================================================================== | 363 | /* =========================================================================== |
364 | * Write the output window window[0..outcnt-1] and update crc and bytes_out. | 364 | * Write the output window window[0..outcnt-1] and update crc and bytes_out. |
365 | * (Used for the decompressed data only.) | 365 | * (Used for the decompressed data only.) |
366 | */ | 366 | */ |
367 | static void __init flush_window(void) | 367 | static void __init flush_window(void) |
368 | { | 368 | { |
369 | ulg c = crc; /* temporary variable */ | 369 | ulg c = crc; /* temporary variable */ |
370 | unsigned n, written; | 370 | unsigned n, written; |
371 | uch *in, ch; | 371 | uch *in, ch; |
372 | 372 | ||
373 | written = sys_write(crd_outfd, window, outcnt); | 373 | written = sys_write(crd_outfd, window, outcnt); |
374 | if (written != outcnt && unzip_error == 0) { | 374 | if (written != outcnt && unzip_error == 0) { |
375 | printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n", | 375 | printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n", |
376 | written, outcnt, bytes_out); | 376 | written, outcnt, bytes_out); |
377 | unzip_error = 1; | 377 | unzip_error = 1; |
378 | } | 378 | } |
379 | in = window; | 379 | in = window; |
380 | for (n = 0; n < outcnt; n++) { | 380 | for (n = 0; n < outcnt; n++) { |
381 | ch = *in++; | 381 | ch = *in++; |
382 | c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); | 382 | c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); |
383 | } | 383 | } |
384 | crc = c; | 384 | crc = c; |
385 | bytes_out += (ulg)outcnt; | 385 | bytes_out += (ulg)outcnt; |
386 | outcnt = 0; | 386 | outcnt = 0; |
387 | } | 387 | } |
388 | 388 | ||
389 | static void __init error(char *x) | 389 | static void __init error(char *x) |
390 | { | 390 | { |
391 | printk(KERN_ERR "%s\n", x); | 391 | printk(KERN_ERR "%s\n", x); |
392 | exit_code = 1; | 392 | exit_code = 1; |
393 | unzip_error = 1; | 393 | unzip_error = 1; |
394 | } | 394 | } |
395 | 395 | ||
396 | static int __init crd_load(int in_fd, int out_fd) | 396 | static int __init crd_load(int in_fd, int out_fd) |
397 | { | 397 | { |
398 | int result; | 398 | int result; |
399 | 399 | ||
400 | insize = 0; /* valid bytes in inbuf */ | 400 | insize = 0; /* valid bytes in inbuf */ |
401 | inptr = 0; /* index of next byte to be processed in inbuf */ | 401 | inptr = 0; /* index of next byte to be processed in inbuf */ |
402 | outcnt = 0; /* bytes in output buffer */ | 402 | outcnt = 0; /* bytes in output buffer */ |
403 | exit_code = 0; | 403 | exit_code = 0; |
404 | bytes_out = 0; | 404 | bytes_out = 0; |
405 | crc = (ulg)0xffffffffL; /* shift register contents */ | 405 | crc = (ulg)0xffffffffL; /* shift register contents */ |
406 | 406 | ||
407 | crd_infd = in_fd; | 407 | crd_infd = in_fd; |
408 | crd_outfd = out_fd; | 408 | crd_outfd = out_fd; |
409 | inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); | 409 | inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); |
410 | if (inbuf == 0) { | 410 | if (inbuf == 0) { |
411 | printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); | 411 | printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); |
412 | return -1; | 412 | return -1; |
413 | } | 413 | } |
414 | window = kmalloc(WSIZE, GFP_KERNEL); | 414 | window = kmalloc(WSIZE, GFP_KERNEL); |
415 | if (window == 0) { | 415 | if (window == 0) { |
416 | printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); | 416 | printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); |
417 | kfree(inbuf); | 417 | kfree(inbuf); |
418 | return -1; | 418 | return -1; |
419 | } | 419 | } |
420 | makecrc(); | 420 | makecrc(); |
421 | result = gunzip(); | 421 | result = gunzip(); |
422 | if (unzip_error) | 422 | if (unzip_error) |
423 | result = 1; | 423 | result = 1; |
424 | kfree(inbuf); | 424 | kfree(inbuf); |
425 | kfree(window); | 425 | kfree(window); |
426 | return result; | 426 | return result; |
427 | } | 427 | } |
428 | 428 | ||
429 | #endif /* BUILD_CRAMDISK */ | 429 | #endif /* BUILD_CRAMDISK */ |
430 | 430 |