linux/init/do_mounts.c
<<
>>
Prefs
   1#include <linux/module.h>
   2#include <linux/sched.h>
   3#include <linux/ctype.h>
   4#include <linux/fd.h>
   5#include <linux/tty.h>
   6#include <linux/suspend.h>
   7#include <linux/root_dev.h>
   8#include <linux/security.h>
   9#include <linux/delay.h>
  10#include <linux/genhd.h>
  11#include <linux/mount.h>
  12#include <linux/device.h>
  13#include <linux/init.h>
  14#include <linux/fs.h>
  15#include <linux/initrd.h>
  16#include <linux/async.h>
  17#include <linux/fs_struct.h>
  18
  19#include <linux/nfs_fs.h>
  20#include <linux/nfs_fs_sb.h>
  21#include <linux/nfs_mount.h>
  22
  23#include "do_mounts.h"
  24
  25int __initdata rd_doload;       /* 1 = load RAM disk, 0 = don't load */
  26
  27int root_mountflags = MS_RDONLY | MS_SILENT;
  28static char * __initdata root_device_name;
  29static char __initdata saved_root_name[64];
  30static int __initdata root_wait;
  31
  32dev_t ROOT_DEV;
  33
  34static int __init load_ramdisk(char *str)
  35{
  36        rd_doload = simple_strtol(str,NULL,0) & 3;
  37        return 1;
  38}
  39__setup("load_ramdisk=", load_ramdisk);
  40
  41static int __init readonly(char *str)
  42{
  43        if (*str)
  44                return 0;
  45        root_mountflags |= MS_RDONLY;
  46        return 1;
  47}
  48
  49static int __init readwrite(char *str)
  50{
  51        if (*str)
  52                return 0;
  53        root_mountflags &= ~MS_RDONLY;
  54        return 1;
  55}
  56
  57__setup("ro", readonly);
  58__setup("rw", readwrite);
  59
  60/*
  61 *      Convert a name into device number.  We accept the following variants:
  62 *
  63 *      1) device number in hexadecimal represents itself
  64 *      2) /dev/nfs represents Root_NFS (0xff)
  65 *      3) /dev/<disk_name> represents the device number of disk
  66 *      4) /dev/<disk_name><decimal> represents the device number
  67 *         of partition - device number of disk plus the partition number
  68 *      5) /dev/<disk_name>p<decimal> - same as the above, that form is
  69 *         used when disk name of partitioned disk ends on a digit.
  70 *
  71 *      If name doesn't have fall into the categories above, we return (0,0).
  72 *      block_class is used to check if something is a disk name. If the disk
  73 *      name contains slashes, the device name has them replaced with
  74 *      bangs.
  75 */
  76
  77dev_t name_to_dev_t(char *name)
  78{
  79        char s[32];
  80        char *p;
  81        dev_t res = 0;
  82        int part;
  83
  84        if (strncmp(name, "/dev/", 5) != 0) {
  85                unsigned maj, min;
  86
  87                if (sscanf(name, "%u:%u", &maj, &min) == 2) {
  88                        res = MKDEV(maj, min);
  89                        if (maj != MAJOR(res) || min != MINOR(res))
  90                                goto fail;
  91                } else {
  92                        res = new_decode_dev(simple_strtoul(name, &p, 16));
  93                        if (*p)
  94                                goto fail;
  95                }
  96                goto done;
  97        }
  98
  99        name += 5;
 100        res = Root_NFS;
 101        if (strcmp(name, "nfs") == 0)
 102                goto done;
 103        res = Root_RAM0;
 104        if (strcmp(name, "ram") == 0)
 105                goto done;
 106
 107        if (strlen(name) > 31)
 108                goto fail;
 109        strcpy(s, name);
 110        for (p = s; *p; p++)
 111                if (*p == '/')
 112                        *p = '!';
 113        res = blk_lookup_devt(s, 0);
 114        if (res)
 115                goto done;
 116
 117        /*
 118         * try non-existant, but valid partition, which may only exist
 119         * after revalidating the disk, like partitioned md devices
 120         */
 121        while (p > s && isdigit(p[-1]))
 122                p--;
 123        if (p == s || !*p || *p == '0')
 124                goto fail;
 125
 126        /* try disk name without <part number> */
 127        part = simple_strtoul(p, NULL, 10);
 128        *p = '\0';
 129        res = blk_lookup_devt(s, part);
 130        if (res)
 131                goto done;
 132
 133        /* try disk name without p<part number> */
 134        if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
 135                goto fail;
 136        p[-1] = '\0';
 137        res = blk_lookup_devt(s, part);
 138        if (res)
 139                goto done;
 140
 141fail:
 142        return 0;
 143done:
 144        return res;
 145}
 146
 147static int __init root_dev_setup(char *line)
 148{
 149        strlcpy(saved_root_name, line, sizeof(saved_root_name));
 150        return 1;
 151}
 152
 153__setup("root=", root_dev_setup);
 154
 155static int __init rootwait_setup(char *str)
 156{
 157        if (*str)
 158                return 0;
 159        root_wait = 1;
 160        return 1;
 161}
 162
 163__setup("rootwait", rootwait_setup);
 164
 165static char * __initdata root_mount_data;
 166static int __init root_data_setup(char *str)
 167{
 168        root_mount_data = str;
 169        return 1;
 170}
 171
 172static char * __initdata root_fs_names;
 173static int __init fs_names_setup(char *str)
 174{
 175        root_fs_names = str;
 176        return 1;
 177}
 178
 179static unsigned int __initdata root_delay;
 180static int __init root_delay_setup(char *str)
 181{
 182        root_delay = simple_strtoul(str, NULL, 0);
 183        return 1;
 184}
 185
 186__setup("rootflags=", root_data_setup);
 187__setup("rootfstype=", fs_names_setup);
 188__setup("rootdelay=", root_delay_setup);
 189
 190static void __init get_fs_names(char *page)
 191{
 192        char *s = page;
 193
 194        if (root_fs_names) {
 195                strcpy(page, root_fs_names);
 196                while (*s++) {
 197                        if (s[-1] == ',')
 198                                s[-1] = '\0';
 199                }
 200        } else {
 201                int len = get_filesystem_list(page);
 202                char *p, *next;
 203
 204                page[len] = '\0';
 205                for (p = page-1; p; p = next) {
 206                        next = strchr(++p, '\n');
 207                        if (*p++ != '\t')
 208                                continue;
 209                        while ((*s++ = *p++) != '\n')
 210                                ;
 211                        s[-1] = '\0';
 212                }
 213        }
 214        *s = '\0';
 215}
 216
 217static int __init do_mount_root(char *name, char *fs, int flags, void *data)
 218{
 219        int err = sys_mount(name, "/root", fs, flags, data);
 220        if (err)
 221                return err;
 222
 223        sys_chdir("/root");
 224        ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
 225        printk("VFS: Mounted root (%s filesystem)%s on device %u:%u.\n",
 226               current->fs->pwd.mnt->mnt_sb->s_type->name,
 227               current->fs->pwd.mnt->mnt_sb->s_flags & MS_RDONLY ?
 228               " readonly" : "", MAJOR(ROOT_DEV), MINOR(ROOT_DEV));
 229        return 0;
 230}
 231
 232void __init mount_block_root(char *name, int flags)
 233{
 234        char *fs_names = __getname_gfp(GFP_KERNEL
 235                | __GFP_NOTRACK_FALSE_POSITIVE);
 236        char *p;
 237#ifdef CONFIG_BLOCK
 238        char b[BDEVNAME_SIZE];
 239#else
 240        const char *b = name;
 241#endif
 242
 243        get_fs_names(fs_names);
 244retry:
 245        for (p = fs_names; *p; p += strlen(p)+1) {
 246                int err = do_mount_root(name, p, flags, root_mount_data);
 247                switch (err) {
 248                        case 0:
 249                                goto out;
 250                        case -EACCES:
 251                                flags |= MS_RDONLY;
 252                                goto retry;
 253                        case -EINVAL:
 254                                continue;
 255                }
 256                /*
 257                 * Allow the user to distinguish between failed sys_open
 258                 * and bad superblock on root device.
 259                 * and give them a list of the available devices
 260                 */
 261#ifdef CONFIG_BLOCK
 262                __bdevname(ROOT_DEV, b);
 263#endif
 264                printk("VFS: Cannot open root device \"%s\" or %s\n",
 265                                root_device_name, b);
 266                printk("Please append a correct \"root=\" boot option; here are the available partitions:\n");
 267
 268                printk_all_partitions();
 269#ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT
 270                printk("DEBUG_BLOCK_EXT_DEVT is enabled, you need to specify "
 271                       "explicit textual name for \"root=\" boot option.\n");
 272#endif
 273                panic("VFS: Unable to mount root fs on %s", b);
 274        }
 275
 276        printk("List of all partitions:\n");
 277        printk_all_partitions();
 278        printk("No filesystem could mount root, tried: ");
 279        for (p = fs_names; *p; p += strlen(p)+1)
 280                printk(" %s", p);
 281        printk("\n");
 282#ifdef CONFIG_BLOCK
 283        __bdevname(ROOT_DEV, b);
 284#endif
 285        panic("VFS: Unable to mount root fs on %s", b);
 286out:
 287        putname(fs_names);
 288}
 289 
 290#ifdef CONFIG_ROOT_NFS
 291static int __init mount_nfs_root(void)
 292{
 293        void *data = nfs_root_data();
 294
 295        create_dev("/dev/root", ROOT_DEV);
 296        if (data &&
 297            do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0)
 298                return 1;
 299        return 0;
 300}
 301#endif
 302
 303#if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD)
 304void __init change_floppy(char *fmt, ...)
 305{
 306        struct termios termios;
 307        char buf[80];
 308        char c;
 309        int fd;
 310        va_list args;
 311        va_start(args, fmt);
 312        vsprintf(buf, fmt, args);
 313        va_end(args);
 314        fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
 315        if (fd >= 0) {
 316                sys_ioctl(fd, FDEJECT, 0);
 317                sys_close(fd);
 318        }
 319        printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
 320        fd = sys_open("/dev/console", O_RDWR, 0);
 321        if (fd >= 0) {
 322                sys_ioctl(fd, TCGETS, (long)&termios);
 323                termios.c_lflag &= ~ICANON;
 324                sys_ioctl(fd, TCSETSF, (long)&termios);
 325                sys_read(fd, &c, 1);
 326                termios.c_lflag |= ICANON;
 327                sys_ioctl(fd, TCSETSF, (long)&termios);
 328                sys_close(fd);
 329        }
 330}
 331#endif
 332
 333void __init mount_root(void)
 334{
 335#ifdef CONFIG_ROOT_NFS
 336        if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
 337                if (mount_nfs_root())
 338                        return;
 339
 340                printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
 341                ROOT_DEV = Root_FD0;
 342        }
 343#endif
 344#ifdef CONFIG_BLK_DEV_FD
 345        if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
 346                /* rd_doload is 2 for a dual initrd/ramload setup */
 347                if (rd_doload==2) {
 348                        if (rd_load_disk(1)) {
 349                                ROOT_DEV = Root_RAM1;
 350                                root_device_name = NULL;
 351                        }
 352                } else
 353                        change_floppy("root floppy");
 354        }
 355#endif
 356#ifdef CONFIG_BLOCK
 357        create_dev("/dev/root", ROOT_DEV);
 358        mount_block_root("/dev/root", root_mountflags);
 359#endif
 360}
 361
 362/*
 363 * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
 364 */
 365void __init prepare_namespace(void)
 366{
 367        int is_floppy;
 368
 369        if (root_delay) {
 370                printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
 371                       root_delay);
 372                ssleep(root_delay);
 373        }
 374
 375        /*
 376         * wait for the known devices to complete their probing
 377         *
 378         * Note: this is a potential source of long boot delays.
 379         * For example, it is not atypical to wait 5 seconds here
 380         * for the touchpad of a laptop to initialize.
 381         */
 382        wait_for_device_probe();
 383
 384        md_run_setup();
 385
 386        if (saved_root_name[0]) {
 387                root_device_name = saved_root_name;
 388                if (!strncmp(root_device_name, "mtd", 3) ||
 389                    !strncmp(root_device_name, "ubi", 3)) {
 390                        mount_block_root(root_device_name, root_mountflags);
 391                        goto out;
 392                }
 393                ROOT_DEV = name_to_dev_t(root_device_name);
 394                if (strncmp(root_device_name, "/dev/", 5) == 0)
 395                        root_device_name += 5;
 396        }
 397
 398        if (initrd_load())
 399                goto out;
 400
 401        /* wait for any asynchronous scanning to complete */
 402        if ((ROOT_DEV == 0) && root_wait) {
 403                printk(KERN_INFO "Waiting for root device %s...\n",
 404                        saved_root_name);
 405                while (driver_probe_done() != 0 ||
 406                        (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0)
 407                        msleep(100);
 408                async_synchronize_full();
 409        }
 410
 411        is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
 412
 413        if (is_floppy && rd_doload && rd_load_disk(0))
 414                ROOT_DEV = Root_RAM0;
 415
 416        mount_root();
 417out:
 418        devtmpfs_mount("dev");
 419        sys_mount(".", "/", NULL, MS_MOVE, NULL);
 420        sys_chroot(".");
 421}
 422