[NBLUG/talk] RAID on the cheap?

Lincoln Peters sampln at sbcglobal.net
Mon Jan 10 14:14:27 PST 2005


I'll assume that the reason I didn't get any responses to this was
because I'm doing something that nobody has tried before...

Anyway, I seem to have gotten it to work well enough that I can use a
RAID-1 array consisting of an internal IDE hard disk and an external USB
hard disk as my root filesystem.  I did this by using a modified version
of the kernel hack described here (which was provided by Augie when I
was trying to use a USB disk as a boot device):

http://www.uwsg.iu.edu/hypermail/linux/kernel/0307.0/0847.html

(Note that the code provided on this page does not work with 2.6
kernels; you'll have to refer to the version of "change_floppy" in
"init/do_mounts.c" in the version of the kernel you're running.)

However, the delay produced by this hack does not work for RAID unless
it is executed AFTER the usb-storage module initializes but BEFORE the
md module initializes.  To accomplish this, I placed the new code at the
beginning of the md_init() in the file "drivers/md/md.c".  The new
version of the function looks like this:

int __init md_init(void)
{
	int minor;
	
	/* NEW CODE BY LINCOLN! */
	/* Need a way to register USB devices! */
	struct termios termios;
	char buf[80];
	char c;
	int fd;
	
	printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
	fd = sys_open("/dev/console", O_RDWR, 0);
	if (fd >= 0) {
		sys_ioctl(fd, TCGETS, (long)&termios);
		termios.c_lflag &= ~ICANON;
		sys_ioctl(fd, TCSETSF, (long)&termios);
		sys_read(fd, &c, 1);
		termios.c_lflag |= ICANON;
		sys_ioctl(fd, TCSETSF, (long)&termios);
		sys_close(fd);
	}
	/* End new code */


	printk(KERN_INFO "md: md driver %d.%d.%d MAX_MD_DEVS=%d,"
			" MD_SB_DISKS=%d\n",
			MD_MAJOR_VERSION, MD_MINOR_VERSION,
			MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);

	if (register_blkdev(MAJOR_NR, "md"))
		return -1;
	if ((mdp_major=register_blkdev(0, "mdp"))<=0) {
		unregister_blkdev(MAJOR_NR, "md");
		return -1;
	}
	devfs_mk_dir("md");
	blk_register_region(MKDEV(MAJOR_NR, 0), MAX_MD_DEVS, THIS_MODULE,
				md_probe, NULL, NULL);
	blk_register_region(MKDEV(mdp_major, 0), MAX_MD_DEVS<<MdpMinorShift, THIS_MODULE,
			    md_probe, NULL, NULL);

	for (minor=0; minor < MAX_MD_DEVS; ++minor)
		devfs_mk_bdev(MKDEV(MAJOR_NR, minor),
				S_IFBLK|S_IRUSR|S_IWUSR,
				"md/%d", minor);

	for (minor=0; minor < MAX_MD_DEVS; ++minor)
		devfs_mk_bdev(MKDEV(mdp_major, minor<<MdpMinorShift),
			      S_IFBLK|S_IRUSR|S_IWUSR,
			      "md/d%d", minor);


	register_reboot_notifier(&md_notifier);
	raid_table_header = register_sysctl_table(raid_root_table, 1);

	md_geninit();
	return (0);
}

You will also need to place the following line of code somewhere near
the top of the file, preferably amongst the other #include statements:

#include <linux/tty.h>

Note that the prompt to press ENTER is unlikely to be noticed during the
boot procedure, as the usb modules will start spewing messages to the
console afterward that may cause the prompt to scroll off the top of the
screen.  Just wait until the boot process has been hanging for about 3
seconds (unless such a delay is normal on your machine), then press
ENTER.

Don't forget, however, that when you configure the kernel, you MUST
ensure that the following modules are built directly into the kernel
(not as modules): scsi, sd_mod, usbcore, ehci-hcd, usb-storage.  If
you're using IDE hard drives, you will need to compile support for them
directly into the kernel as well.  This will result in a rather bloated
kernel, but it works.


Two notes to anyone who wishes to build a similar RAID setup:

1. You probably do not need to perform any kernel hacking if you want to
use software RAID on a filesystem that is not the root filesystem.  You
should be able to get the same results simply by modifying your boot
scripts (specifically, a carefully-placed "sleep" command, possibly
preceded by a few "modprobe" commands).

2. You could probably get the exact same results using an initrd, but I
wanted to find a way to make this work without using one (since I
haven't yet figured out how to make an initrd capable of this).

3. There may be issues if you attach multiple USB storage devices to a
Linux box for use in a RAID array, but I haven't yet gotten that far in
my project.

---
Lincoln Peters
<sampln at sbcglobal.net>

There are ten or twenty basic truths, and life is the process of
discovering them over and over and over.
		-- David Nichols





More information about the talk mailing list