Thursday, August 16, 2007

fdisk, sfdisk, mdadm and SCSI hard drive geometry

At work, one of our servers, uses Linux software RAIDand we have two mirrored hard drives setup as RAID1.
Smartmontools reported that one of the hard drives was starting to fail:
# smartctl -a /dev/sda
SMART Health Status: LOGICAL UNIT FAILURE PREDICTION THRESHOLD EXCEEDED [asc=5d,ascq=2]
# smartctl -l selftest /dev/sda
SMART Self-test log
Num Test Status segment LifeTime LBA_first_err [SK ASC ASQ]
Description number (hours)
# 1 Background long Failed in segment --> 2 10572 0x 22f0e6c [0x4 0x40 0x85]
# 2 Background long Failed in segment --> 2 10404 0x 22f0e6c [0x3 0x11 0x0]
# 3 Background long Failed in segment --> 2 10236 0x 22f0e63 [0x4 0x40 0x85]

So we executed the following commands:
mdadm --manage /dev/md0 --set-faulty  /dev/sda1
mdadm --manage /dev/md0 --remove /dev/sda1
mdadm --manage /dev/md1 --set-faulty /dev/sda2
mdadm --manage /dev/md1 --remove /dev/sda2
mdadm --manage /dev/md2 --set-faulty /dev/sda3
mdadm --manage /dev/md2 --remove /dev/sda3
mdadm --manage /dev/md3 --set-faulty /dev/sda5
mdadm --manage /dev/md3 --remove /dev/sda5

And then hot un-plugged the drive.
When the replacement drive arrived, although it was an identical model
to the original, and had an identical total size, the new drive had a different geometry.
[root@ifsclstr02 ~]# smartctl -i /dev/sda
Device: IBM-ESXS BBD036C3ESTT0ZFN Version: JP86
Device type: disk
Transport protocol: Parallel SCSI (SPI-4)

[root@ifsclstr02 ~]# smartctl -i /dev/sdb
Device: IBM-ESXS BBD036C3ESTT0ZFN Version: JP85
Device type: disk
Transport protocol: Parallel SCSI (SPI-4)

# fdisk -l /dev/sda
Disk /dev/sda: 36.4 GB, 36401479680 bytes
64 heads, 32 sectors/track, 34715 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes

# fdisk -l /dev/sdb
Disk /dev/sdb: 36.4 GB, 36401479680 bytes
255 heads, 63 sectors/track, 4425 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

The potential problem was that if we had to specify the start and end of the partition in terms of cylinders, then we would not be able to get an exact match in the size of the partitions between the new disk and the existing working half of the mirror.
After some googling, we concluded that having to align the partition boundaries with the cylinders was a DOS legacy issue, and was not something that would cause a problem for Linux.
So to copy the partitions from the working disk to the new disk we used the following:
# sfdisk -d /dev/sdb | sfdisk --Linux /dev/sda
Checking that no-one is using this disk right now ...
OK
Disk /dev/sda: 34715 cylinders, 64 heads, 32 sectors/track
Old situation:
Units = cylinders of 1048576 bytes, blocks of 1024 bytes, counting from 0

Device Boot Start End #cyls #blocks Id System
/dev/sda1 0 - 0 0 0 Empty
/dev/sda2 0 - 0 0 0 Empty
/dev/sda3 0 - 0 0 0 Empty
/dev/sda4 0 - 0 0 0 Empty
New situation:
Units = sectors of 512 bytes, counting from 0

Device Boot Start End #sectors Id System
/dev/sda1 * 63 208844 208782 fd Linux raid autodetect
/dev/sda2 208845 16980704 16771860 fd Linux raid autodetect
/dev/sda3 16980705 25366634 8385930 fd Linux raid autodetect
/dev/sda4 25366635 71087624 45720990 5 Extended
/dev/sda5 25366698 71087624 45720927 fd Linux raid autodetect
Warning: partition 1 does not end at a cylinder boundary
Warning: partition 2 does not start at a cylinder boundary
Warning: partition 2 does not end at a cylinder boundary
Warning: partition 3 does not start at a cylinder boundary
Warning: partition 3 does not end at a cylinder boundary
Warning: partition 4 does not start at a cylinder boundary
Warning: partition 4 does not end at a cylinder boundary
Warning: partition 5 does not end at a cylinder boundary
Successfully wrote the new partition table
Re-reading the partition table ...
# mdadm --manage /dev/md0 --add /dev/sda1
# mdadm --manage /dev/md1 --add /dev/sda2
# mdadm --manage /dev/md2 --add /dev/sda3
# mdadm --manage /dev/md3 --add /dev/sda5
# cat /proc/mdstat
Personalities : [raid1]
md1 : active raid1 sda2[0] sdb2[1]
8385856 blocks [2/2] [UU]

md2 : active raid1 sda3[2] sdb3[1]
4192896 blocks [2/1] [_U]
resync=DELAYED
md3 : active raid1 sda5[2] sdb5[1]
22860352 blocks [2/1] [_U]
[============>........] recovery = 61.8% (14148928/22860352) finish=2.1min speed=67707K/sec
md0 : active raid1 sda1[0] sdb1[1]
104320 blocks [2/2] [UU]

unused devices:

Using the sfdisk command, you can specify the unit of measure when listing the partition table. Use '-uS' for Sectors and '-uC' for Cylinders:
# sfdisk -l -uS /dev/sda
Disk /dev/sda: 34715 cylinders, 64 heads, 32 sectors/track
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Units = sectors of 512 bytes, counting from 0

Device Boot Start End #sectors Id System
/dev/sda1 * 63 208844 208782 fd Linux raid autodetect
/dev/sda2 208845 16980704 16771860 fd Linux raid autodetect
/dev/sda3 16980705 25366634 8385930 fd Linux raid autodetect
/dev/sda4 25366635 71087624 45720990 5 Extended
/dev/sda5 25366698 71087624 45720927 fd Linux raid autodetect

# sfdisk -l -uS /dev/sdb
Disk /dev/sdb: 4425 cylinders, 255 heads, 63 sectors/track
Units = sectors of 512 bytes, counting from 0

Device Boot Start End #sectors Id System
/dev/sdb1 * 63 208844 208782 fd Linux raid autodetect
/dev/sdb2 208845 16980704 16771860 fd Linux raid autodetect
/dev/sdb3 16980705 25366634 8385930 fd Linux raid autodetect
/dev/sdb4 25366635 71087624 45720990 5 Extended
/dev/sdb5 25366698 71087624 45720927 fd Linux raid autodetect

It's only when you think in terms of cylinders, that there appears to be a problem:
# sfdisk -l -uC /dev/sda
Disk /dev/sda: 34715 cylinders, 64 heads, 32 sectors/track
Warning: extended partition does not start at a cylinder boundary.
DOS and Linux will interpret the contents differently.
Units = cylinders of 1048576 bytes, blocks of 1024 bytes, counting from 0

Device Boot Start End #cyls #blocks Id System
/dev/sda1 * 0+ 101- 102- 104391 fd Linux raid autodetect
/dev/sda2 101+ 8291- 8190- 8385930 fd Linux raid autodetect
/dev/sda3 8291+ 12386- 4095- 4192965 fd Linux raid autodetect
/dev/sda4 12386+ 34710- 22325- 22860495 5 Extended
/dev/sda5 12386+ 34710- 22325- 22860463+ fd Linux raid autodetect

# sfdisk -l -uC /dev/sdb
Disk /dev/sdb: 4425 cylinders, 255 heads, 63 sectors/track
Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0

Device Boot Start End #cyls #blocks Id System
/dev/sdb1 * 0+ 12 13- 104391 fd Linux raid autodetect
/dev/sdb2 13 1056 1044 8385930 fd Linux raid autodetect
/dev/sdb3 1057 1578 522 4192965 fd Linux raid autodetect
/dev/sdb4 1579 4424 2846 22860495 5 Extended
/dev/sdb5 1579+ 4424 2846- 22860463+ fd Linux raid autodetect

The pluses and minuses, just mean that the numbers are not exact and are rounded up or down.
For comparison, here is what fdisk reports:
# fdisk -l /dev/sda
Disk /dev/sda: 36.4 GB, 36401479680 bytes
64 heads, 32 sectors/track, 34715 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes

Device Boot Start End Blocks Id System
/dev/sda1 * 1 102 104391 fd Linux raid autodetect
Partition 1 does not end on cylinder boundary.
/dev/sda2 102 8292 8385930 fd Linux raid autodetect
/dev/sda3 8292 12387 4192965 fd Linux raid autodetect
/dev/sda4 12387 34711 22860495 5 Extended
/dev/sda5 12387 34711 22860463+ fd Linux raid autodetect

# fdisk -l /dev/sdb
Disk /dev/sdb: 36.4 GB, 36401479680 bytes
255 heads, 63 sectors/track, 4425 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot Start End Blocks Id System
/dev/sdb1 * 1 13 104391 fd Linux raid autodetect
/dev/sdb2 14 1057 8385930 fd Linux raid autodetect
/dev/sdb3 1058 1579 4192965 fd Linux raid autodetect
/dev/sdb4 1580 4425 22860495 5 Extended
/dev/sdb5 1580 4425 22860463+ fd Linux raid autodetect

1 comment:

Charles said...

I had the exact same problem setting up my RAID 1 array with two drives of different geometries. You answered my question excellently, thank you very much. I am having a great first day with Linux.