Hi,

there is AFAIK no solution for safe booting from RAID1 devices such as in the
typical case of two harddrives in a PC (Primary Master+Primary Slave or
Primary Master+Secondary Master).

Created a BIOS wrapper to automatically detect disk failure and swap
0x80<->0x81 reading so it applies to stage1/stage2/kernel/initrd/whatever
loading. It was tested using QEMU patches simulating various disk failures.

        
http://cvs.jankratochvil.net/viewcvs/biosautoraid/biosautoraid.tar.gz?tarball=1
        http://cvs.jankratochvil.net/viewcvs/biosautoraid/README?rev=HEAD

WHY:

The loading of stage2 can be fixed only for 0x80 or 0x81 but there is never
a foolproof choice. Sometimes the primary drive 0x80 dies while becoming
unreadable, in some other cases it dies while disappearing from POST so 0x81
becomes 0x80. If you set 0x80 or 0x81 there are always some disk crash cases
where the booting will fail.

Fallback to the second drive during failure of the kernel load is AFAIK not
possible with LILO and it is even a bit complicated to configure with GRUB.

REQUIREMENTS:

This solution is fully independent of the used loader. Either LILO or GRUB can
be used, both have been tested. Just the sectors required for booting need to
be exactly at the same sectors of both disks. This is satisfied with standard
Linux-RAID devices /dev/md* if both disks are partitioned the same way.

DISADVANTAGE:

Currently it does not support LBA32 handling so you must install the boot stuff
under the first 8GB. I have some draft LBA32 support done but it never got
debugged/finished as there are no business needs for it. The whole swapping
wrapper no longer fits into 1 sector so it needs its own stage2 loader (also
with automatic drives swapping) etc.

TESTING/DEBUGGING:

Used the attached "block-limit.diff" QEMU patch, it is user unfriendly to use.

SPONSORSHIP:

Development paid by the courtesy of JK Labs s.r.o.

Some integration into GRUB/LILO would be wised? Do you find it useful?



Regards,
Lace
Index: block-qcow.c
===================================================================
RCS file: /sources/qemu/qemu/block-qcow.c,v
retrieving revision 1.6
diff -u -p -r1.6 block-qcow.c
--- block-qcow.c        18 Dec 2005 18:28:15 -0000      1.6
+++ block-qcow.c        27 Feb 2006 21:07:09 -0000
@@ -458,6 +458,15 @@ static int qcow_read(BlockDriverState *b
     int ret, index_in_cluster, n;
     uint64_t cluster_offset;
     
+    static BlockDriverState *bs_first=NULL;
+    if (!bs_first)
+       bs_first=bs;
+    if (bs==bs_first && sector_num) {
+fprintf(stderr,"%p:%lld+%d: %s\n",bs,(long 
long)sector_num,nb_sectors,bs->filename);
+puts("fail");
+        return -1;
+    }
+
     while (nb_sectors > 0) {
         cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
         index_in_cluster = sector_num & (s->cluster_sectors - 1);
Index: block.c
===================================================================
RCS file: /sources/qemu/qemu/block.c,v
retrieving revision 1.25
diff -u -p -r1.25 block.c
--- block.c     18 Dec 2005 18:28:15 -0000      1.25
+++ block.c     27 Feb 2006 21:07:10 -0000
@@ -709,6 +709,25 @@ static int raw_read(BlockDriverState *bs
     BDRVRawState *s = bs->opaque;
     int ret;
     
+    static BlockDriverState *bs_first=NULL;
+    if (!bs_first)
+       bs_first=bs;
+    if (!strcmp(bs->filename,"/tmp/sda-head.bin") && bs==bs_first && 
sector_num) {
+fprintf(stderr,"%p:%lld+%d: %s\n",bs,(long 
long)sector_num,nb_sectors,bs->filename);
+puts("fail");
+        return -1;
+    }
+#if 0
+    fprintf(stderr,"%p:%lld+%d: %s\n",bs,(long 
long)sector_num,nb_sectors,bs->filename);
+    if (!strcmp(bs->filename,"/tmp/sda-head.bin") && bs==bs_first &&  
((sector_num/63)&1)) {
+puts("fail");
+        return -1;
+    }
+    if (!strcmp(bs->filename,"/tmp/sda-head.bin") && bs!=bs_first && 
!((sector_num/63)&1)) {
+puts("fail");
+        return -1;
+    }
+#endif
     lseek(s->fd, sector_num * 512, SEEK_SET);
     ret = read(s->fd, buf, nb_sectors * 512);
     if (ret != nb_sectors * 512) 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to