1
2#include <linux/module.h>
3#include <linux/sched.h>
4#include <linux/ctype.h>
5#include <linux/fd.h>
6#include <linux/tty.h>
7#include <linux/suspend.h>
8#include <linux/root_dev.h>
9#include <linux/security.h>
10#include <linux/delay.h>
11#include <linux/genhd.h>
12#include <linux/mount.h>
13#include <linux/device.h>
14#include <linux/init.h>
15#include <linux/fs.h>
16#include <linux/initrd.h>
17#include <linux/async.h>
18#include <linux/fs_struct.h>
19#include <linux/slab.h>
20#include <linux/ramfs.h>
21#include <linux/shmem_fs.h>
22
23#include <linux/nfs_fs.h>
24#include <linux/nfs_fs_sb.h>
25#include <linux/nfs_mount.h>
26#include <uapi/linux/mount.h>
27
28#include "do_mounts.h"
29
30int __initdata rd_doload;
31
32int root_mountflags = MS_RDONLY | MS_SILENT;
33static char * __initdata root_device_name;
34static char __initdata saved_root_name[64];
35static int root_wait;
36
37dev_t ROOT_DEV;
38
39static int __init load_ramdisk(char *str)
40{
41 rd_doload = simple_strtol(str,NULL,0) & 3;
42 return 1;
43}
44__setup("load_ramdisk=", load_ramdisk);
45
46static int __init readonly(char *str)
47{
48 if (*str)
49 return 0;
50 root_mountflags |= MS_RDONLY;
51 return 1;
52}
53
54static int __init readwrite(char *str)
55{
56 if (*str)
57 return 0;
58 root_mountflags &= ~MS_RDONLY;
59 return 1;
60}
61
62__setup("ro", readonly);
63__setup("rw", readwrite);
64
65#ifdef CONFIG_BLOCK
66struct uuidcmp {
67 const char *uuid;
68 int len;
69};
70
71
72
73
74
75
76
77
78static int match_dev_by_uuid(struct device *dev, const void *data)
79{
80 const struct uuidcmp *cmp = data;
81 struct hd_struct *part = dev_to_part(dev);
82
83 if (!part->info)
84 goto no_match;
85
86 if (strncasecmp(cmp->uuid, part->info->uuid, cmp->len))
87 goto no_match;
88
89 return 1;
90no_match:
91 return 0;
92}
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108static dev_t devt_from_partuuid(const char *uuid_str)
109{
110 dev_t res = 0;
111 struct uuidcmp cmp;
112 struct device *dev = NULL;
113 struct gendisk *disk;
114 struct hd_struct *part;
115 int offset = 0;
116 bool clear_root_wait = false;
117 char *slash;
118
119 cmp.uuid = uuid_str;
120
121 slash = strchr(uuid_str, '/');
122
123 if (slash) {
124 char c = 0;
125
126 if (sscanf(slash + 1,
127 "PARTNROFF=%d%c", &offset, &c) != 1) {
128 clear_root_wait = true;
129 goto done;
130 }
131 cmp.len = slash - uuid_str;
132 } else {
133 cmp.len = strlen(uuid_str);
134 }
135
136 if (!cmp.len) {
137 clear_root_wait = true;
138 goto done;
139 }
140
141 dev = class_find_device(&block_class, NULL, &cmp,
142 &match_dev_by_uuid);
143 if (!dev)
144 goto done;
145
146 res = dev->devt;
147
148
149 if (!offset)
150 goto no_offset;
151
152 res = 0;
153 disk = part_to_disk(dev_to_part(dev));
154 part = disk_get_part(disk, dev_to_part(dev)->partno + offset);
155 if (part) {
156 res = part_devt(part);
157 put_device(part_to_dev(part));
158 }
159
160no_offset:
161 put_device(dev);
162done:
163 if (clear_root_wait) {
164 pr_err("VFS: PARTUUID= is invalid.\n"
165 "Expected PARTUUID=<valid-uuid-id>[/PARTNROFF=%%d]\n");
166 if (root_wait)
167 pr_err("Disabling rootwait; root= is invalid.\n");
168 root_wait = 0;
169 }
170 return res;
171}
172
173
174
175
176
177
178
179
180static int match_dev_by_label(struct device *dev, const void *data)
181{
182 const char *label = data;
183 struct hd_struct *part = dev_to_part(dev);
184
185 if (part->info && !strcmp(label, part->info->volname))
186 return 1;
187
188 return 0;
189}
190#endif
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223dev_t name_to_dev_t(const char *name)
224{
225 char s[32];
226 char *p;
227 dev_t res = 0;
228 int part;
229
230#ifdef CONFIG_BLOCK
231 if (strncmp(name, "PARTUUID=", 9) == 0) {
232 name += 9;
233 res = devt_from_partuuid(name);
234 if (!res)
235 goto fail;
236 goto done;
237 } else if (strncmp(name, "PARTLABEL=", 10) == 0) {
238 struct device *dev;
239
240 dev = class_find_device(&block_class, NULL, name + 10,
241 &match_dev_by_label);
242 if (!dev)
243 goto fail;
244
245 res = dev->devt;
246 put_device(dev);
247 goto done;
248 }
249#endif
250
251 if (strncmp(name, "/dev/", 5) != 0) {
252 unsigned maj, min, offset;
253 char dummy;
254
255 if ((sscanf(name, "%u:%u%c", &maj, &min, &dummy) == 2) ||
256 (sscanf(name, "%u:%u:%u:%c", &maj, &min, &offset, &dummy) == 3)) {
257 res = MKDEV(maj, min);
258 if (maj != MAJOR(res) || min != MINOR(res))
259 goto fail;
260 } else {
261 res = new_decode_dev(simple_strtoul(name, &p, 16));
262 if (*p)
263 goto fail;
264 }
265 goto done;
266 }
267
268 name += 5;
269 res = Root_NFS;
270 if (strcmp(name, "nfs") == 0)
271 goto done;
272 res = Root_CIFS;
273 if (strcmp(name, "cifs") == 0)
274 goto done;
275 res = Root_RAM0;
276 if (strcmp(name, "ram") == 0)
277 goto done;
278
279 if (strlen(name) > 31)
280 goto fail;
281 strcpy(s, name);
282 for (p = s; *p; p++)
283 if (*p == '/')
284 *p = '!';
285 res = blk_lookup_devt(s, 0);
286 if (res)
287 goto done;
288
289
290
291
292
293 while (p > s && isdigit(p[-1]))
294 p--;
295 if (p == s || !*p || *p == '0')
296 goto fail;
297
298
299 part = simple_strtoul(p, NULL, 10);
300 *p = '\0';
301 res = blk_lookup_devt(s, part);
302 if (res)
303 goto done;
304
305
306 if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
307 goto fail;
308 p[-1] = '\0';
309 res = blk_lookup_devt(s, part);
310 if (res)
311 goto done;
312
313fail:
314 return 0;
315done:
316 return res;
317}
318EXPORT_SYMBOL_GPL(name_to_dev_t);
319
320static int __init root_dev_setup(char *line)
321{
322 strlcpy(saved_root_name, line, sizeof(saved_root_name));
323 return 1;
324}
325
326__setup("root=", root_dev_setup);
327
328static int __init rootwait_setup(char *str)
329{
330 if (*str)
331 return 0;
332 root_wait = 1;
333 return 1;
334}
335
336__setup("rootwait", rootwait_setup);
337
338static char * __initdata root_mount_data;
339static int __init root_data_setup(char *str)
340{
341 root_mount_data = str;
342 return 1;
343}
344
345static char * __initdata root_fs_names;
346static int __init fs_names_setup(char *str)
347{
348 root_fs_names = str;
349 return 1;
350}
351
352static unsigned int __initdata root_delay;
353static int __init root_delay_setup(char *str)
354{
355 root_delay = simple_strtoul(str, NULL, 0);
356 return 1;
357}
358
359__setup("rootflags=", root_data_setup);
360__setup("rootfstype=", fs_names_setup);
361__setup("rootdelay=", root_delay_setup);
362
363static void __init get_fs_names(char *page)
364{
365 char *s = page;
366
367 if (root_fs_names) {
368 strcpy(page, root_fs_names);
369 while (*s++) {
370 if (s[-1] == ',')
371 s[-1] = '\0';
372 }
373 } else {
374 int len = get_filesystem_list(page);
375 char *p, *next;
376
377 page[len] = '\0';
378 for (p = page-1; p; p = next) {
379 next = strchr(++p, '\n');
380 if (*p++ != '\t')
381 continue;
382 while ((*s++ = *p++) != '\n')
383 ;
384 s[-1] = '\0';
385 }
386 }
387 *s = '\0';
388}
389
390static int __init do_mount_root(const char *name, const char *fs,
391 const int flags, const void *data)
392{
393 struct super_block *s;
394 struct page *p = NULL;
395 char *data_page = NULL;
396 int ret;
397
398 if (data) {
399
400 p = alloc_page(GFP_KERNEL);
401 if (!p)
402 return -ENOMEM;
403 data_page = page_address(p);
404
405 strncpy(data_page, data, PAGE_SIZE);
406 }
407
408 ret = do_mount(name, "/root", fs, flags, data_page);
409 if (ret)
410 goto out;
411
412 ksys_chdir("/root");
413 s = current->fs->pwd.dentry->d_sb;
414 ROOT_DEV = s->s_dev;
415 printk(KERN_INFO
416 "VFS: Mounted root (%s filesystem)%s on device %u:%u.\n",
417 s->s_type->name,
418 sb_rdonly(s) ? " readonly" : "",
419 MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
420
421out:
422 if (p)
423 put_page(p);
424 return ret;
425}
426
427void __init mount_block_root(char *name, int flags)
428{
429 struct page *page = alloc_page(GFP_KERNEL);
430 char *fs_names = page_address(page);
431 char *p;
432#ifdef CONFIG_BLOCK
433 char b[BDEVNAME_SIZE];
434#else
435 const char *b = name;
436#endif
437
438 get_fs_names(fs_names);
439retry:
440 for (p = fs_names; *p; p += strlen(p)+1) {
441 int err = do_mount_root(name, p, flags, root_mount_data);
442 switch (err) {
443 case 0:
444 goto out;
445 case -EACCES:
446 case -EINVAL:
447 continue;
448 }
449
450
451
452
453
454#ifdef CONFIG_BLOCK
455 __bdevname(ROOT_DEV, b);
456#endif
457 printk("VFS: Cannot open root device \"%s\" or %s: error %d\n",
458 root_device_name, b, err);
459 printk("Please append a correct \"root=\" boot option; here are the available partitions:\n");
460
461 printk_all_partitions();
462#ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT
463 printk("DEBUG_BLOCK_EXT_DEVT is enabled, you need to specify "
464 "explicit textual name for \"root=\" boot option.\n");
465#endif
466 panic("VFS: Unable to mount root fs on %s", b);
467 }
468 if (!(flags & SB_RDONLY)) {
469 flags |= SB_RDONLY;
470 goto retry;
471 }
472
473 printk("List of all partitions:\n");
474 printk_all_partitions();
475 printk("No filesystem could mount root, tried: ");
476 for (p = fs_names; *p; p += strlen(p)+1)
477 printk(" %s", p);
478 printk("\n");
479#ifdef CONFIG_BLOCK
480 __bdevname(ROOT_DEV, b);
481#endif
482 panic("VFS: Unable to mount root fs on %s", b);
483out:
484 put_page(page);
485}
486
487#ifdef CONFIG_ROOT_NFS
488
489#define NFSROOT_TIMEOUT_MIN 5
490#define NFSROOT_TIMEOUT_MAX 30
491#define NFSROOT_RETRY_MAX 5
492
493static int __init mount_nfs_root(void)
494{
495 char *root_dev, *root_data;
496 unsigned int timeout;
497 int try, err;
498
499 err = nfs_root_data(&root_dev, &root_data);
500 if (err != 0)
501 return 0;
502
503
504
505
506
507
508 timeout = NFSROOT_TIMEOUT_MIN;
509 for (try = 1; ; try++) {
510 err = do_mount_root(root_dev, "nfs",
511 root_mountflags, root_data);
512 if (err == 0)
513 return 1;
514 if (try > NFSROOT_RETRY_MAX)
515 break;
516
517
518 ssleep(timeout);
519 timeout <<= 1;
520 if (timeout > NFSROOT_TIMEOUT_MAX)
521 timeout = NFSROOT_TIMEOUT_MAX;
522 }
523 return 0;
524}
525#endif
526
527#ifdef CONFIG_CIFS_ROOT
528
529extern int cifs_root_data(char **dev, char **opts);
530
531#define CIFSROOT_TIMEOUT_MIN 5
532#define CIFSROOT_TIMEOUT_MAX 30
533#define CIFSROOT_RETRY_MAX 5
534
535static int __init mount_cifs_root(void)
536{
537 char *root_dev, *root_data;
538 unsigned int timeout;
539 int try, err;
540
541 err = cifs_root_data(&root_dev, &root_data);
542 if (err != 0)
543 return 0;
544
545 timeout = CIFSROOT_TIMEOUT_MIN;
546 for (try = 1; ; try++) {
547 err = do_mount_root(root_dev, "cifs", root_mountflags,
548 root_data);
549 if (err == 0)
550 return 1;
551 if (try > CIFSROOT_RETRY_MAX)
552 break;
553
554 ssleep(timeout);
555 timeout <<= 1;
556 if (timeout > CIFSROOT_TIMEOUT_MAX)
557 timeout = CIFSROOT_TIMEOUT_MAX;
558 }
559 return 0;
560}
561#endif
562
563#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
564void __init change_floppy(char *fmt, ...)
565{
566 struct termios termios;
567 char buf[80];
568 char c;
569 int fd;
570 va_list args;
571 va_start(args, fmt);
572 vsprintf(buf, fmt, args);
573 va_end(args);
574 fd = ksys_open("/dev/root", O_RDWR | O_NDELAY, 0);
575 if (fd >= 0) {
576 ksys_ioctl(fd, FDEJECT, 0);
577 ksys_close(fd);
578 }
579 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
580 fd = ksys_open("/dev/console", O_RDWR, 0);
581 if (fd >= 0) {
582 ksys_ioctl(fd, TCGETS, (long)&termios);
583 termios.c_lflag &= ~ICANON;
584 ksys_ioctl(fd, TCSETSF, (long)&termios);
585 ksys_read(fd, &c, 1);
586 termios.c_lflag |= ICANON;
587 ksys_ioctl(fd, TCSETSF, (long)&termios);
588 ksys_close(fd);
589 }
590}
591#endif
592
593void __init mount_root(void)
594{
595#ifdef CONFIG_ROOT_NFS
596 if (ROOT_DEV == Root_NFS) {
597 if (mount_nfs_root())
598 return;
599
600 printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
601 ROOT_DEV = Root_FD0;
602 }
603#endif
604#ifdef CONFIG_CIFS_ROOT
605 if (ROOT_DEV == Root_CIFS) {
606 if (mount_cifs_root())
607 return;
608
609 printk(KERN_ERR "VFS: Unable to mount root fs via SMB, trying floppy.\n");
610 ROOT_DEV = Root_FD0;
611 }
612#endif
613#ifdef CONFIG_BLK_DEV_FD
614 if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
615
616 if (rd_doload==2) {
617 if (rd_load_disk(1)) {
618 ROOT_DEV = Root_RAM1;
619 root_device_name = NULL;
620 }
621 } else
622 change_floppy("root floppy");
623 }
624#endif
625#ifdef CONFIG_BLOCK
626 {
627 int err = create_dev("/dev/root", ROOT_DEV);
628
629 if (err < 0)
630 pr_emerg("Failed to create /dev/root: %d\n", err);
631 mount_block_root("/dev/root", root_mountflags);
632 }
633#endif
634}
635
636
637
638
639void __init prepare_namespace(void)
640{
641 int is_floppy;
642
643 if (root_delay) {
644 printk(KERN_INFO "Waiting %d sec before mounting root device...\n",
645 root_delay);
646 ssleep(root_delay);
647 }
648
649
650
651
652
653
654
655
656 wait_for_device_probe();
657
658 md_run_setup();
659
660 if (saved_root_name[0]) {
661 root_device_name = saved_root_name;
662 if (!strncmp(root_device_name, "mtd", 3) ||
663 !strncmp(root_device_name, "ubi", 3)) {
664 mount_block_root(root_device_name, root_mountflags);
665 goto out;
666 }
667 ROOT_DEV = name_to_dev_t(root_device_name);
668 if (strncmp(root_device_name, "/dev/", 5) == 0)
669 root_device_name += 5;
670 }
671
672 if (initrd_load())
673 goto out;
674
675
676 if ((ROOT_DEV == 0) && root_wait) {
677 printk(KERN_INFO "Waiting for root device %s...\n",
678 saved_root_name);
679 while (driver_probe_done() != 0 ||
680 (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)
681 msleep(5);
682 async_synchronize_full();
683 }
684
685 is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
686
687 if (is_floppy && rd_doload && rd_load_disk(0))
688 ROOT_DEV = Root_RAM0;
689
690 mount_root();
691out:
692 devtmpfs_mount();
693 do_mount(".", "/", NULL, MS_MOVE, NULL);
694 ksys_chroot(".");
695}
696
697static bool is_tmpfs;
698static int rootfs_init_fs_context(struct fs_context *fc)
699{
700 if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs)
701 return shmem_init_fs_context(fc);
702
703 return ramfs_init_fs_context(fc);
704}
705
706struct file_system_type rootfs_fs_type = {
707 .name = "rootfs",
708 .init_fs_context = rootfs_init_fs_context,
709 .kill_sb = kill_litter_super,
710};
711
712void __init init_rootfs(void)
713{
714 if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] &&
715 (!root_fs_names || strstr(root_fs_names, "tmpfs")))
716 is_tmpfs = true;
717}
718