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