Back to home page

LXR

 
 

    


0001 /*
0002  * Many of the syscalls used in this file expect some of the arguments
0003  * to be __user pointers not __kernel pointers.  To limit the sparse
0004  * noise, turn off sparse checking for this file.
0005  */
0006 #ifdef __CHECKER__
0007 #undef __CHECKER__
0008 #warning "Sparse checking disabled for this file"
0009 #endif
0010 
0011 #include <linux/delay.h>
0012 #include <linux/raid/md_u.h>
0013 #include <linux/raid/md_p.h>
0014 
0015 #include "do_mounts.h"
0016 
0017 /*
0018  * When md (and any require personalities) are compiled into the kernel
0019  * (not a module), arrays can be assembles are boot time using with AUTODETECT
0020  * where specially marked partitions are registered with md_autodetect_dev(),
0021  * and with MD_BOOT where devices to be collected are given on the boot line
0022  * with md=.....
0023  * The code for that is here.
0024  */
0025 
0026 #ifdef CONFIG_MD_AUTODETECT
0027 static int __initdata raid_noautodetect;
0028 #else
0029 static int __initdata raid_noautodetect=1;
0030 #endif
0031 static int __initdata raid_autopart;
0032 
0033 static struct {
0034     int minor;
0035     int partitioned;
0036     int level;
0037     int chunk;
0038     char *device_names;
0039 } md_setup_args[256] __initdata;
0040 
0041 static int md_setup_ents __initdata;
0042 
0043 /*
0044  * Parse the command-line parameters given our kernel, but do not
0045  * actually try to invoke the MD device now; that is handled by
0046  * md_setup_drive after the low-level disk drivers have initialised.
0047  *
0048  * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
0049  *             assigns the task of parsing integer arguments to the
0050  *             invoked program now).  Added ability to initialise all
0051  *             the MD devices (by specifying multiple "md=" lines)
0052  *             instead of just one.  -- KTK
0053  * 18May2000: Added support for persistent-superblock arrays:
0054  *             md=n,0,factor,fault,device-list   uses RAID0 for device n
0055  *             md=n,-1,factor,fault,device-list  uses LINEAR for device n
0056  *             md=n,device-list      reads a RAID superblock from the devices
0057  *             elements in device-list are read by name_to_kdev_t so can be
0058  *             a hex number or something like /dev/hda1 /dev/sdb
0059  * 2001-06-03: Dave Cinege <dcinege@psychosis.com>
0060  *      Shifted name_to_kdev_t() and related operations to md_set_drive()
0061  *      for later execution. Rewrote section to make devfs compatible.
0062  */
0063 static int __init md_setup(char *str)
0064 {
0065     int minor, level, factor, fault, partitioned = 0;
0066     char *pername = "";
0067     char *str1;
0068     int ent;
0069 
0070     if (*str == 'd') {
0071         partitioned = 1;
0072         str++;
0073     }
0074     if (get_option(&str, &minor) != 2) {    /* MD Number */
0075         printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
0076         return 0;
0077     }
0078     str1 = str;
0079     for (ent=0 ; ent< md_setup_ents ; ent++)
0080         if (md_setup_args[ent].minor == minor &&
0081             md_setup_args[ent].partitioned == partitioned) {
0082             printk(KERN_WARNING "md: md=%s%d, Specified more than once. "
0083                    "Replacing previous definition.\n", partitioned?"d":"", minor);
0084             break;
0085         }
0086     if (ent >= ARRAY_SIZE(md_setup_args)) {
0087         printk(KERN_WARNING "md: md=%s%d - too many md initialisations\n", partitioned?"d":"", minor);
0088         return 0;
0089     }
0090     if (ent >= md_setup_ents)
0091         md_setup_ents++;
0092     switch (get_option(&str, &level)) { /* RAID level */
0093     case 2: /* could be 0 or -1.. */
0094         if (level == 0 || level == LEVEL_LINEAR) {
0095             if (get_option(&str, &factor) != 2 ||   /* Chunk Size */
0096                     get_option(&str, &fault) != 2) {
0097                 printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
0098                 return 0;
0099             }
0100             md_setup_args[ent].level = level;
0101             md_setup_args[ent].chunk = 1 << (factor+12);
0102             if (level ==  LEVEL_LINEAR)
0103                 pername = "linear";
0104             else
0105                 pername = "raid0";
0106             break;
0107         }
0108         /* FALL THROUGH */
0109     case 1: /* the first device is numeric */
0110         str = str1;
0111         /* FALL THROUGH */
0112     case 0:
0113         md_setup_args[ent].level = LEVEL_NONE;
0114         pername="super-block";
0115     }
0116 
0117     printk(KERN_INFO "md: Will configure md%d (%s) from %s, below.\n",
0118         minor, pername, str);
0119     md_setup_args[ent].device_names = str;
0120     md_setup_args[ent].partitioned = partitioned;
0121     md_setup_args[ent].minor = minor;
0122 
0123     return 1;
0124 }
0125 
0126 static void __init md_setup_drive(void)
0127 {
0128     int minor, i, ent, partitioned;
0129     dev_t dev;
0130     dev_t devices[MD_SB_DISKS+1];
0131 
0132     for (ent = 0; ent < md_setup_ents ; ent++) {
0133         int fd;
0134         int err = 0;
0135         char *devname;
0136         mdu_disk_info_t dinfo;
0137         char name[16];
0138 
0139         minor = md_setup_args[ent].minor;
0140         partitioned = md_setup_args[ent].partitioned;
0141         devname = md_setup_args[ent].device_names;
0142 
0143         sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor);
0144         if (partitioned)
0145             dev = MKDEV(mdp_major, minor << MdpMinorShift);
0146         else
0147             dev = MKDEV(MD_MAJOR, minor);
0148         create_dev(name, dev);
0149         for (i = 0; i < MD_SB_DISKS && devname != NULL; i++) {
0150             char *p;
0151             char comp_name[64];
0152             u32 rdev;
0153 
0154             p = strchr(devname, ',');
0155             if (p)
0156                 *p++ = 0;
0157 
0158             dev = name_to_dev_t(devname);
0159             if (strncmp(devname, "/dev/", 5) == 0)
0160                 devname += 5;
0161             snprintf(comp_name, 63, "/dev/%s", devname);
0162             rdev = bstat(comp_name);
0163             if (rdev)
0164                 dev = new_decode_dev(rdev);
0165             if (!dev) {
0166                 printk(KERN_WARNING "md: Unknown device name: %s\n", devname);
0167                 break;
0168             }
0169 
0170             devices[i] = dev;
0171 
0172             devname = p;
0173         }
0174         devices[i] = 0;
0175 
0176         if (!i)
0177             continue;
0178 
0179         printk(KERN_INFO "md: Loading md%s%d: %s\n",
0180             partitioned ? "_d" : "", minor,
0181             md_setup_args[ent].device_names);
0182 
0183         fd = sys_open(name, 0, 0);
0184         if (fd < 0) {
0185             printk(KERN_ERR "md: open failed - cannot start "
0186                     "array %s\n", name);
0187             continue;
0188         }
0189         if (sys_ioctl(fd, SET_ARRAY_INFO, 0) == -EBUSY) {
0190             printk(KERN_WARNING
0191                    "md: Ignoring md=%d, already autodetected. (Use raid=noautodetect)\n",
0192                    minor);
0193             sys_close(fd);
0194             continue;
0195         }
0196 
0197         if (md_setup_args[ent].level != LEVEL_NONE) {
0198             /* non-persistent */
0199             mdu_array_info_t ainfo;
0200             ainfo.level = md_setup_args[ent].level;
0201             ainfo.size = 0;
0202             ainfo.nr_disks =0;
0203             ainfo.raid_disks =0;
0204             while (devices[ainfo.raid_disks])
0205                 ainfo.raid_disks++;
0206             ainfo.md_minor =minor;
0207             ainfo.not_persistent = 1;
0208 
0209             ainfo.state = (1 << MD_SB_CLEAN);
0210             ainfo.layout = 0;
0211             ainfo.chunk_size = md_setup_args[ent].chunk;
0212             err = sys_ioctl(fd, SET_ARRAY_INFO, (long)&ainfo);
0213             for (i = 0; !err && i <= MD_SB_DISKS; i++) {
0214                 dev = devices[i];
0215                 if (!dev)
0216                     break;
0217                 dinfo.number = i;
0218                 dinfo.raid_disk = i;
0219                 dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
0220                 dinfo.major = MAJOR(dev);
0221                 dinfo.minor = MINOR(dev);
0222                 err = sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
0223             }
0224         } else {
0225             /* persistent */
0226             for (i = 0; i <= MD_SB_DISKS; i++) {
0227                 dev = devices[i];
0228                 if (!dev)
0229                     break;
0230                 dinfo.major = MAJOR(dev);
0231                 dinfo.minor = MINOR(dev);
0232                 sys_ioctl(fd, ADD_NEW_DISK, (long)&dinfo);
0233             }
0234         }
0235         if (!err)
0236             err = sys_ioctl(fd, RUN_ARRAY, 0);
0237         if (err)
0238             printk(KERN_WARNING "md: starting md%d failed\n", minor);
0239         else {
0240             /* reread the partition table.
0241              * I (neilb) and not sure why this is needed, but I cannot
0242              * boot a kernel with devfs compiled in from partitioned md
0243              * array without it
0244              */
0245             sys_close(fd);
0246             fd = sys_open(name, 0, 0);
0247             sys_ioctl(fd, BLKRRPART, 0);
0248         }
0249         sys_close(fd);
0250     }
0251 }
0252 
0253 static int __init raid_setup(char *str)
0254 {
0255     int len, pos;
0256 
0257     len = strlen(str) + 1;
0258     pos = 0;
0259 
0260     while (pos < len) {
0261         char *comma = strchr(str+pos, ',');
0262         int wlen;
0263         if (comma)
0264             wlen = (comma-str)-pos;
0265         else    wlen = (len-1)-pos;
0266 
0267         if (!strncmp(str, "noautodetect", wlen))
0268             raid_noautodetect = 1;
0269         if (!strncmp(str, "autodetect", wlen))
0270             raid_noautodetect = 0;
0271         if (strncmp(str, "partitionable", wlen)==0)
0272             raid_autopart = 1;
0273         if (strncmp(str, "part", wlen)==0)
0274             raid_autopart = 1;
0275         pos += wlen+1;
0276     }
0277     return 1;
0278 }
0279 
0280 __setup("raid=", raid_setup);
0281 __setup("md=", md_setup);
0282 
0283 static void __init autodetect_raid(void)
0284 {
0285     int fd;
0286 
0287     /*
0288      * Since we don't want to detect and use half a raid array, we need to
0289      * wait for the known devices to complete their probing
0290      */
0291     printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
0292     printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
0293 
0294     wait_for_device_probe();
0295 
0296     fd = sys_open("/dev/md0", 0, 0);
0297     if (fd >= 0) {
0298         sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
0299         sys_close(fd);
0300     }
0301 }
0302 
0303 void __init md_run_setup(void)
0304 {
0305     create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
0306 
0307     if (raid_noautodetect)
0308         printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=autodetect will force)\n");
0309     else
0310         autodetect_raid();
0311     md_setup_drive();
0312 }