At 12:12 23.01.99 +0000, you wrote:
>> Doesn't work for new raid tool - all you get is an error message stating
>> that the device is already used.
>> 
>> Currently, I'm experimenting with a hack to raid1.c which will allow the
>> creation of a single-disk mirror (easy) and expand this to a normal mirror
>> when hotadding a second disk (not quite so easy, but getting closer)
>
>Wish List for Development
>
>This sort of thing needs to be supported so that it is not too 
>painful to move and EXISTING hosts OS and files to raid.

I've just thrown together a patch for raid1.c which will allow you to 
1) mkraid a raid-1 device with just one device (thanks to mingo for the
patch).
2) change this single-disk mirror to a normal 2-disk mirror by adding
another device using raidhotadd. While it does work (at least for me) I'm
not at all sure this does the Right Thing.

I wonder if it wouldn't be a better solution to allow building of degraded
raid devices, say, by omitting disk definitions from /etc/raidtab. That
way, you'd create a raid device with the right number of raid disks in the
superblock, so no fiddling around with raidhotadd requests would be necessary.

Bye, Martin
--- linux/drivers/block/raid1.c Sat Jan 23 17:04:47 1999
+++ linux-2.0.36-mb/drivers/block/raid1.c       Sat Jan 23 21:30:39 1999
@@ -575,11 +575,12 @@
 {
        int err = 0;
        int i, failed_disk=-1, spare_disk=-1, removed_disk=-1, added_disk=-1;
+       int added_disk_test=0;
        raid1_conf_t *conf = mddev->private;
        struct mirror_info *tmp, *sdisk, *fdisk, *rdisk, *adisk;
        unsigned long flags;
        mdp_super_t *sb = mddev->sb;
-       mdp_disk_t *failed_desc, *spare_desc, *added_desc;
+       mdp_disk_t *failed_desc, *spare_desc, *added_desc, *fake_desc;
 
        save_flags(flags);
        cli();
@@ -660,7 +661,12 @@
 
                for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
                        tmp = conf->mirrors + i;
-                       if (!tmp->used_slot) {
+                       /* if adding to mirror with just one disk,
+                          leave free slot so we can make it a real mirror */
+                       if (!tmp->used_slot && !added_disk_test)
+                               added_disk_test = i;
+                       if (!tmp->used_slot && 
+                       (conf->raid_disks > 1 || i > conf->raid_disks)) {
                                added_disk = i;
                                break;
                        }
@@ -792,7 +798,7 @@
                adisk = conf->mirrors + added_disk;
                added_desc = *d;
 
-               if (added_disk != added_desc->number) {
+               if (added_disk_test != added_desc->number) {
                        MD_BUG();       
                        err = 1;
                        goto abort;
@@ -808,6 +814,27 @@
                adisk->used_slot = 1;
                conf->nr_disks++;
 
+               /* If raid device is mirror with just one disk,
+                  add new disk as 2nd mirror */ 
+               if (conf->raid_disks==1) { 
+                       conf->raid_disks++;
+                       sb->raid_disks++;
+                       adisk->number = added_disk;
+                       adisk->raid_disk = added_disk;
+                       adisk = conf->mirrors + added_disk_test;
+                       adisk->number = added_desc->number;
+                       adisk->raid_disk = added_desc->raid_disk;
+                       adisk->operational = 0;
+                       adisk->spare = 0;
+                       adisk->write_only = 0;
+                       adisk->used_slot = 1;
+                       fake_desc = mddev->sb->disks + added_disk;
+                       fake_desc->number = added_disk;
+                       fake_desc->raid_disk = added_disk;
+                       xchg_values (added_desc->major, fake_desc->major);
+                       xchg_values (added_desc->minor, fake_desc->minor);
+               }
+
                break;
 
        default:
@@ -1170,7 +1197,9 @@
                }
        }
 
-       if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN))) {
+       if ((conf->raid_disks > 1) && !start_recovery && 
+               !(sb->state & (1 << MD_SB_CLEAN))) { 
+
                const char * name = "raid1syncd";
 
                conf->resync_thread = md_register_thread(raid1syncd, conf,name);

--------------------------------------------------
 Martin Bene               vox: +43-664-3251047
 simon media               fax: +43-316-813824-6
 Andreas-Hofer-Platz 9     e-mail: [EMAIL PROTECTED]
 8010 Graz, Austria        
--------------------------------------------------
finger [EMAIL PROTECTED] for PGP public key

Reply via email to