Linus, it is possible to start an md array from the boot command line with, e.g. md=0,/dev/something,/dev/somethingelse However only names recognised by name_to_kdev_t work here. devfs based names do not work. To fix this, the follow patch moves the name lookup from __setup time to __init time so that the devfs routines can be called. This patch is largely due to Dave Cinege, though I have made a few improvements (particularly removing the devices array from md_setup_args). The "#ifdef MODULE" that this patch removes it wholy within another "#ifdef MODULE" and so it totally pointless. NeilBrown --- ./drivers/md/md.c 2001/06/21 00:51:42 1.2 +++ ./drivers/md/md.c 2001/06/21 00:53:09 1.3 @@ -3638,7 +3638,7 @@ char device_set [MAX_MD_DEVS]; int pers[MAX_MD_DEVS]; int chunk[MAX_MD_DEVS]; - kdev_t devices[MAX_MD_DEVS][MD_SB_DISKS]; + char *device_names[MAX_MD_DEVS]; } md_setup_args md__initdata; /* @@ -3657,14 +3657,15 @@ * md=n,device-list reads a RAID superblock from the devices * elements in device-list are read by name_to_kdev_t so can be * a hex number or something like /dev/hda1 /dev/sdb + * 2001-06-03: Dave Cinege <[EMAIL PROTECTED]> + * Shifted name_to_kdev_t() and related operations to md_set_drive() + * for later execution. Rewrote section to make devfs compatible. */ -#ifndef MODULE -extern kdev_t name_to_kdev_t(char *line) md__init; static int md__init md_setup(char *str) { - int minor, level, factor, fault, i=0; - kdev_t device; - char *devnames, *pername = ""; + int minor, level, factor, fault; + char *pername = ""; + char *str1 = str; if (get_option(&str, &minor) != 2) { /* MD Number */ printk("md: Too few arguments supplied to md=.\n"); @@ -3673,9 +3674,8 @@ if (minor >= MAX_MD_DEVS) { printk ("md: Minor device number too high.\n"); return 0; - } else if (md_setup_args.device_set[minor]) { - printk ("md: Warning - md=%d,... has been specified twice;\n" - " will discard the first definition.\n", minor); + } else if (md_setup_args.device_names[minor]) { + printk ("md: md=%d, Specified more then once. Replacing previous +definition.\n", minor); } switch (get_option(&str, &level)) { /* RAID Personality */ case 2: /* could be 0 or -1.. */ @@ -3706,53 +3706,72 @@ } /* FALL THROUGH */ case 1: /* the first device is numeric */ - md_setup_args.devices[minor][i++] = level; + str = str1; /* FALL THROUGH */ case 0: md_setup_args.pers[minor] = 0; pername="super-block"; } - devnames = str; - for (; i<MD_SB_DISKS && str; i++) { - if ((device = name_to_kdev_t(str))) { - md_setup_args.devices[minor][i] = device; - } else { - printk ("md: Unknown device name, %s.\n", str); - return 0; - } - if ((str = strchr(str, ',')) != NULL) - str++; - } - if (!i) { - printk ("md: No devices specified for md%d?\n", minor); - return 0; - } - + printk ("md: Will configure md%d (%s) from %s, below.\n", - minor, pername, devnames); - md_setup_args.devices[minor][i] = (kdev_t) 0; - md_setup_args.device_set[minor] = 1; + minor, pername, str); + md_setup_args.device_names[minor] = str; + return 1; } -#endif /* !MODULE */ +extern kdev_t name_to_kdev_t(char *line) md__init; void md__init md_setup_drive(void) { int minor, i; kdev_t dev; mddev_t*mddev; + kdev_t devices[MD_SB_DISKS+1]; for (minor = 0; minor < MAX_MD_DEVS; minor++) { + int err = 0; + char *devname; mdu_disk_info_t dinfo; - int err = 0; - if (!md_setup_args.device_set[minor]) + if ((devname = md_setup_args.device_names[minor]) == 0) continue; + + for (i = 0; i < MD_SB_DISKS && devname != 0; i++) { + + char *p; + void *handle; + + if ((p = strchr(devname, ',')) != NULL) + *p++ = 0; + + dev = name_to_kdev_t(devname); + handle = devfs_find_handle(NULL, devname, MAJOR (dev), MINOR +(dev), + DEVFS_SPECIAL_BLK, 1); + if (handle != 0) { + unsigned major, minor; + devfs_get_maj_min(handle, &major, &minor); + dev = MKDEV(major, minor); + } + if (dev == 0) { + printk ("md: Unknown device name: %s\n", devname); + break; + } + + devices[i] = dev; + md_setup_args.device_set[minor] = 1; + + devname = p; + } + devices[i] = 0; + + if (md_setup_args.device_set[minor] == 0) continue; - printk("md: Loading md%d.\n", minor); + if (mddev_map[minor].mddev) { - printk(".. md%d already autodetected - use raid=noautodetect\n", minor); + printk("md: Ignoring md=%d, already autodetected. (Use +raid=noautodetect)\n", minor); continue; } + printk("md: Loading md%d: %s\n", minor, +md_setup_args.device_names[minor]); + mddev = alloc_mddev(MKDEV(MD_MAJOR,minor)); if (mddev == NULL) { printk("md: kmalloc failed - cannot start array %d\n", minor); @@ -3776,7 +3795,7 @@ ainfo.layout = 0; ainfo.chunk_size = md_setup_args.chunk[minor]; err = set_array_info(mddev, &ainfo); - for (i = 0; !err && (dev = md_setup_args.devices[minor][i]); i++) { + for (i = 0; !err && (dev = devices[i]); i++) { dinfo.number = i; dinfo.raid_disk = i; dinfo.state = (1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC); @@ -3790,7 +3809,7 @@ } } else { /* persistent */ - for (i = 0; (dev = md_setup_args.devices[minor][i]); i++) { + for (i = 0; (dev = devices[i]); i++) { dinfo.major = MAJOR(dev); dinfo.minor = MINOR(dev); add_new_disk (mddev, &dinfo); - To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to [EMAIL PROTECTED]