Date: Wed, 28 May 2008 21:47:59 +0900 (JST) From: Hideki Sakamoto <hsakamt@tsnr.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/124064: [ar] cannot handle >16 serial number with Intel MatrixRAID Message-ID: <20080528124759.3B5102298C@sv.tsnr.com> Resent-Message-ID: <200805281310.m4SDA3VY062581@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 124064 >Category: kern >Synopsis: [ar] cannot handle >16 serial number with Intel MatrixRAID >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed May 28 13:10:02 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Hideki Sakamoto >Release: FreeBSD 6.2-RELEASE-p11, 7.0 and 8.0-CURRENT i386 >Organization: Tsukuba Secure Network Research >Environment: System: FreeBSD sv.tsnr.com 6.2-RELEASE-p11 FreeBSD 6.2-RELEASE-p11 #3: Sat Feb 16 15:11:43 JST 2008 root@sv.tsnr.com:/usr/obj/usr/src/sys/GENERIC i386 System: FreeBSD inst.tsnr.com 8.0-CURRENT FreeBSD 8.0-CURRENT #12: Tue May 27 00:33:33 JST 2008 root@inst.tsnr.com:/usr/obj/usr/src/sys/GENERIC i386 Intel BOX33TLM(ICH9R) >Description: By chance I got two HDD those serial numbers are almost same. And I cannot build raid because ataraid cut off a serial number at 16-th characters and write it to HDD as RAID information. Another problem is: I checked source and I found Intel MatrixRAID BIOS use last 16 character of device's serial number though ataraid use first 16 character of it. So, ataraid cannot recognize raid drive built in BIOS menu. >How-To-Repeat: Get HDD which returns serial number longer than 16 chars. And build a raid with atacontrol command. I confirmed that a HGST 2.5inch HDD(5K250) raise problems. >Fix: This is a patch for 8-CURRENT. note: HGST HDD returns <real serial nunber> + 0x03 0x00 --- /sys/dev/ata/ata-raid.c 2008-04-17 21:29:35.000000000 +0900 +++ ata/ata-raid.c 2008-05-27 02:37:24.000000000 +0900 @@ -2086,6 +2086,7 @@ u_int32_t checksum, *ptr; int array, count, disk, volume = 1, retval = 0; char *tmp; + int snlen, snidx; if (!(meta = (struct intel_raid_conf *) malloc(1536, M_AR, M_NOWAIT | M_ZERO))) @@ -2228,8 +2229,18 @@ for (disk = 0; disk < raid->total_disks; disk++) { struct ata_device *atadev = device_get_softc(parent); - if (!strncmp(raid->disks[disk].serial, atadev->param.serial, - sizeof(raid->disks[disk].serial))) { + for (snlen=0;;snlen++) { + if ((char)atadev->param.serial[snlen] == '\0' || + (char)atadev->param.serial[snlen] == 3) { /* ascii EOT */ + if (snlen < 16) + snidx = 0; + else + snidx = snlen - 16; + break; + } + } + if (!strncmp(raid->disks[disk].serial, atadev->param.serial + snidx, + min(snlen,sizeof(raid->disks[disk].serial)))) { raid->disks[disk].dev = parent; raid->disks[disk].flags |= (AR_DF_PRESENT | AR_DF_ONLINE); ars->raid[raid->volume] = raid; @@ -2273,6 +2284,7 @@ u_int32_t checksum, *ptr; int count, disk, error = 0; char *tmp; + int snlen,snidx; if (!(meta = (struct intel_raid_conf *) malloc(1536, M_AR, M_NOWAIT | M_ZERO))) { @@ -2299,8 +2311,19 @@ struct ata_device *atadev = device_get_softc(rdp->disks[disk].dev); - bcopy(atadev->param.serial, meta->disk[disk].serial, - sizeof(rdp->disks[disk].serial)); + for (snlen=0;;snlen++) { + if ((char)atadev->param.serial[snlen] == '\0' || + (char)atadev->param.serial[snlen] == 3) { /* ascii EOT */ + if (snlen < 16) + snidx = 0; + else { + snidx = snlen - 16; + } + break; + } + } + bcopy(atadev->param.serial + snidx, meta->disk[disk].serial, + min(snlen,sizeof(rdp->disks[disk].serial))); meta->disk[disk].sectors = rdp->disks[disk].sectors; meta->disk[disk].id = (ch->unit << 16) | atadev->unit; } >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20080528124759.3B5102298C>