kern/126419: [ata] Fails to boot from RAID10 volume under the Intel ICH9R

Hideki Sakamoto hsakamt at tsnr.com
Tue Sep 9 06:40:06 UTC 2008


The following reply was made to PR kern/126419; it has been noted by GNATS.

From: Hideki Sakamoto <hsakamt at tsnr.com>
To: bug-followup at FreeBSD.org, fukui.FreeBSD at fanet.net
Cc:  
Subject: Re: kern/126419: [ata] Fails to boot from RAID10 volume under the
 Intel ICH9R
Date: Tue, 09 Sep 2008 15:35:50 +0900

 Hi,
 
 I think one simple solution is to swap disk order in metadata at read/write
 timing from/to BIOS.
 
 I attach a patch for 7.1-PRERELEASE. It can apply properly on 6.4-PRERELEASE
 with offset warning. I aim to work a sytem more than 4 disks but just test it
 with 4 disks machine.
 
 You must install FreeBSD with patched kernel. ISO image of bootonly installer
 is available at:
 http://www.tsnr.com/FreeBSD/7.0-bootonly_patched.iso
 MD5 (7.0-bootonly_patched.iso) = 27d9aff696be335143a781b3ece24e94
 
 Please don't forget to change "Release Name" of install option to "7.0-RELEASE"
 or so. Go Alt+F4 console and copy patched kernel in installer CD-ROM to ar0 /
 partition before rebooting the installed system, or it will panic.
 
 Thanks,
 Hideki Sakamoto
 
 ==============================
 *** ata-raid.c.orig	Tue Sep  9 14:10:26 2008
 --- ata-raid.c	Tue Sep  9 14:15:15 2008
 ***************
 *** 2146,2152 ****
   		break;
 
   	    case INTEL_T_RAID1:
 ! 		if (map->total_disks == 4)
   		    raid->type = AR_T_RAID01;
   		else
   		    raid->type = AR_T_RAID1;
 --- 2146,2152 ----
   		break;
 
   	    case INTEL_T_RAID1:
 ! 		if (map->total_disks >= 4)
   		    raid->type = AR_T_RAID01;
   		else
   		    raid->type = AR_T_RAID1;
 ***************
 *** 2214,2219 ****
 --- 2214,2234 ----
   		if (meta->disk[map->disk_idx[disk]].flags & INTEL_F_DOWN)
   		    raid->disks[disk].flags &= ~AR_DF_ONLINE;
   	    }
 + 	    if (raid->type == AR_T_RAID01) {
 + 		/* swap disk info */
 + 		char *tmp1;
 + 		int i;
 + 		int sz = sizeof(raid->disks[1]);
 + 		int pair_num = raid->total_disks / 2;
 +
 + 		tmp1 = (char *)malloc(sz * (raid->total_disks - 2), M_AR, M_NOWAIT | M_ZERO);
 + 		for (i = 0; i < pair_num - 1; i++) {
 + 		    bcopy(&raid->disks[2 * (i + 1)], tmp1 + sz * i, sz);
 + 		    bcopy(&raid->disks[2 * i + 1], tmp1 + sz * (i + pair_num - 1), sz);
 + 		}
 + 		bcopy(tmp1, &raid->disks[1], sz * (raid->total_disks - 2));
 + 		free(tmp1, M_AR);
 + 	    }
   	}
   	if (meta->generation >= raid->generation) {
   	    for (disk = 0; disk < raid->total_disks; disk++) {
 ***************
 *** 2325,2330 ****
 --- 2340,2361 ----
   	break;
       case AR_T_RAID01:
   	map->type = INTEL_T_RAID1;
 + 	{
 + 	    /* swap disk info */
 + 	    char *tmp1;
 + 	    int i;
 + 	    int sz = sizeof(meta->disk[1]);
 + 	    int buflen = sz * (meta->total_disks - 2);
 + 	    int pair_num = meta->total_disks / 2;
 +
 + 	    tmp1 = (char *)malloc(buflen, M_AR, M_NOWAIT | M_ZERO);
 + 	    for (i = 0; i < pair_num - 1; i++) {
 + 		bcopy(&meta->disk[i+1], tmp1 + sz * (2 * i + 1), sz);
 + 		bcopy(&meta->disk[i+pair_num], tmp1 + sz * 2 * i, sz);
 + 	    }
 + 	    bcopy(tmp1, &meta->disk[1], buflen);
 + 	    free(tmp1, M_AR);
 + 	}
   	break;
       case AR_T_RAID5:
   	map->type = INTEL_T_RAID5;


More information about the freebsd-bugs mailing list