CTC++ Coverage Report - Execution Profile    #4/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: init/do_mounts.c
Instrumentation mode: function-decision-multicondition
TER: 38 % ( 64/169)

Start/ End/    
True False - Line Source

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

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last | Top