Rss聚合
Posts
Comments

最近整理了一下在NetBSD下建立Raid1的过程,当时建立bsdchina.org服务器的时候由于时间仓促没有将整个的制作过程记录下来,前两天抽时间在虚机中重新做了这个过程,跟大家分享。

起因:现在一些SATA的主板上自带的Raid控制器并不能被NetBSD识别,因此如何将双硬盘制作为Raid1从而提高数据安全性成为一个比较头疼的问题,最终在bsdchina.org服务器上,采用了软件模拟Raid控制器的方式来实现Raid1。使用的软件是NetBSD标准安装中自带的RaidFrame软件。

过程:

1 在VMware中建立虚拟机,两块硬盘大小10G。
2 安装NetBSD4.0系统至disk0。
3 启动系统后,dmesg|grep -i raid 检查内核是否支持RaidFrame,如果输出类似下面的格式则表示内核有RaidFrame支持。
# dmesg|grep -i raid
Kernelized RAIDframe activated
4 如果没有RaidFrame支持,请先编译内核使其支持RaidFrame。
5 执行df,查看硬盘使用情况。
2.bmp

disklabel -r wd0

3.bmp

 # fdisk /dev/rwd0d
4.bmp

 通过上面的一些命令,可以帮助我了解目前虚机中第一块硬盘的情况,接下来要在第二块硬盘上做一些准备工作,核心的操作就是将第二块硬盘wd1中的全部扇区用0填充,命令如下:
# dd if=/dev/zero of=/dev/rwd1d bs=8k count=1


执行完毕后,通过如下的命令来确认第二块硬盘上的mbr和全部的数据已经被清空。
# disklabel -r wd1
6.bmp
观察上面的信息,offset都为0证明全部分区没有数据占用。由此可以确定硬盘上既没有数据也没有mbr引导记录。
接下来,我将第一块硬盘上的mbr中的引导记录传送至第二块硬盘。在此之前,先将第二块硬盘wd1设置为可启动。
# fdisk -0ua /dev/rwd1d
按照如下的内容进行回答。

fdisk: primary partition table invalid, no magic in sector 0
Disk: /dev/rwd1d
NetBSD disklabel disk geometry:
cylinders: 19386, heads: 16, sectors/track: 63 (1008 sectors/cylinder)
total sectors: 19541088
BIOS disk geometry:
cylinders: 1023, heads: 255, sectors/track: 63 (16065 sectors/cylinder)
total sectors: 19541088
Do you want to change our idea of what BIOS thinks? [n]Partition 0:The data for partition 0 is:sysid: [0..255 default: 169]
start: [0..1216cyl default: 63, 0cyl, 0MB]
size: [0..1216cyl default: 19541025, 1216cyl, 9542MB]
bootmenu: []
Do you want to change the active partition? [n] y
Choosing 4 will make no partition active.
active partition: [0..4 default: 0] 0
Are you happy with this choice? [n] y

We haven’t written the MBR back to disk yet.  This is your last chance.
Partition table:
0: NetBSD (sysid 169)
start 63, size 19541025 (9542 MB, Cyls 0-1216/96/1), Active
1:
2:
3:
Bootselector disabled.
Should we write new partition table? [n] y
接下来查看第二块硬盘的数据情况:
# disklabel -r -e -I wd1
输出类似如下所示:

type: unknown
disk: Disk1
label:
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 16
sectors/cylinder: 1008
cylinders: 19386
total sectors: 19541088
[...snip...]
16 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
a:  19541025        63       RAID                     # (Cyl.      0*-19385)
c:  19541025        63     unused      0     0        # (Cyl.      0*-19385)
d:  19541088         0     unused      0     0        # (Cyl.      0 -19385)
可以看到在a:区的offset为63,那么a区前面的部分便是mbr的引导记录,这表示引导记录已经传送至wd1。

接下来建立Raidframe设备的配置文件:
# vi /var/tmp/raid0.conf
START array
1 2 0
START disks
/dev/wd9a
/dev/wd1a
START layout
128 1 1 1
START queue
fifo 100
我们看到配置文件中写了wd9这个设备,这个设备对于系统来说是一个虚拟设备(psudeo设备),我们最后会用wd0替换掉它。
尽管如此,还是必须在系统中建立这个设备节点。
# cd /dev
# sh MAKEDEV wd9
# cd -

下一步,将使用这个配置文件来建立raid设备,命令如下:
# raidctl -v -C /var/tmp/raid0.conf raid0
输出如下:
8.bmp
正如预料那样,在wd9这个设备上出现错误,当它不存在就好了。
初始化硬盘数据同步:
# raidctl -v -i raid0
Initiating re-write of parity
# tail -1 /var/log/messages
raid0: Error re-writing parity!
 
查看同步结果:
# raidctl -v -s raid0
输出:
9.bmp

 接下来要用wd0来替换掉wd9这个设备,这个环节稍微有些复杂,需要进行一定的计算操作,为了简单起见,我的硬盘分区中除了swap分区便是一个大分区,一共只有2个分区。

执行如下命令来查看刚刚建立的raid设备情况:
# disklabel -r -e -I raid0
输出类似如下信息:
type: RAID
disk: raid
label: fictitious
flags:
bytes/sector: 512
sectors/track: 128
tracks/cylinder: 8
sectors/cylinder: 1024
cylinders: 19082
total sectors: 19540864
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0
headswitch: 0 # microseconds
track-to-track seek: 0 # microseconds
drivedata: 0
#        size    offset     fstype [fsize bsize cpg/sgs]
a:  19015680         0     4.2BSD      0     0     0  # (Cyl.      0 - 18569)
b:    525184  19015680       swap                     # (Cyl.  18570 - 19082*)
d:  19540864         0     unused      0     0        # (Cyl.      0 - 19082*)
可以看出swap大小为525兆。
接下来格式化分区为4.2BSD FFSv1 File System
# newfs -O 1 /dev/rraid0a
接下来检查硬盘
# fsck -fy /dev/rraid0a

下面,需要建立真实的swap分区,刚刚看到的swap分区大小实际上是raid0这个设备的。由于raid0b作为swap分区,但是这个分区是无法作为真正的swap分区使用,因为如果系统挂掉了,进程调度停止了,那么是无法将dump出来的信息存储到raid0b这个分区的,因此这里采取了一个hack的方法,需要我们自己计算大小从而对分区表进行修改,使得我们在真实的wd1这个设备上建立一个分区大小使之与raid0b这个分区所标示的分区大小重叠一致。这步必须小心。
接下来再回顾一下刚刚的raid0分区情况以及wd1的分区情况。
  # disklabel raid0  8 partitions:
#        size    offset     fstype  [fsize bsize cpg/sgs]
a:  19015680         0     4.2BSD   1024  8192    64
b:    525184  19015680     swap
d:  19540864         0     unused      0     0     0
  # disklabel wd1  8 partitions:
#        size    offset     fstype  [fsize bsize cpg/sgs]
a:  19541025        63     RAID
c:  19541025        63     unused      0     0
d:  19541088         0     unused      0     0

在所有的RAID设备中都保留有64个block大小的预留区域来保存RAID的一些结构信息。因此我们使用dc来计算实际的swap分区的偏移大小。将那块区域空出来为raid0b分区所用。

# dc   63 # offset of wd1a   64 # RF_PROTECTED_SECTORS   +   19015680 # offset of raid0b   +p   19015807 # offset of swap within wd1   q

接下来编辑现有的wd1的分区表信息。
# disklabel wd1 > disklabel.wd1
# vi disklabel.wd1
  8 partitions:
#        size    offset     fstype  [fsize bsize cpg/sgs]
a:  19541025        63       RAID
b:    525184  19015807       swap
c:  19541025        63     unused      0     0
d:  19541088         0     unused      0     0
offset为上面计算出来的真实偏移量大小。
然后便可以应用这个修改后的配置了。
# disklabel -R -r wd1 disklabel.wd1

现在raid0的配置已经完成,但是raid0这个设备上还没有系统,接下来将wd0上的系统迁移到raid0a这个分区上:
# mount /dev/raid0a /mnt
# df -h /mnt
Filesystem    Size     Used     Avail Capacity  Mounted on
/dev/raid0a   9.0G     2.0K      8.6G     0%    /mnt
# cd /; pax -v -X -rw -pe / /mnt
然后编辑fstab文件,使用# vi /mnt/etc/fstab/dev/raid0a  /  ffs  rw  1  1
/dev/raid0b  none  swap  sw  0  0
/dev/wd0b  none  swap  dp  0  0
kernfs    /kern  kernfs  rw
procfs    /proc  procfs  rw

# vi /mnt/etc/rc.conf
swapoff=YES
这是为了防止重启后出现同步错误。在wd1硬盘上安装启动文件。
# /usr/sbin/installboot -o timeout=30 -v /dev/rwd1a /usr/mdec/bootxx_ffsv1通过下面的命令将raid0设置成可自动配置。
# raidctl -v -A root raid0
raid0: Autoconfigure: Yes
raid0: Root: Yes
# tail -2 /var/log/messages
raid0: New autoconfig value is: 1
raid0: New rootpartition value is: 1
# raidctl -v -s raid0
[...snip...]
Autoconfig: Yes
Root partition: Yes
Last configured as: raid0
[...snip...]
# shutdown -r now
一定要用shutdown重启,而不要使用reboot。重启后通过下面的命令查看raid0设备情况。

#
egrep -i “raid|root” /var/run/dmesg.boot
raid0: RAID Level 1
raid0: Components: component0[**FAILED**] /dev/wd1a
raid0: Total Sectors: 19540864 (9541 MB)
boot device: raid0
root on raid0a dumps on raid0b
root file system type: ffs
# df -h
Filesystem    Size     Used     Avail Capacity  Mounted on
/dev/raid0a   8.9G     196M      8.3G     2%    /
kernfs        1.0K     1.0K        0B   100%    /kern
# swapctl -l
Device      1K-blocks     Used    Avail Capacity  Priority
/dev/raid0b    262592        0   262592     0%    0
# raidctl -s raid0
Components:
component0: failed
/dev/wd1a: optimal
No spares.
component0 status is: failed.  Skipping label.
Component label for /dev/wd1a:
Row: 0, Column: 1, Num Rows: 1, Num Columns: 2
Version: 2, Serial Number: 2004082401, Mod Counter: 65
Clean: No, Status: 0
sectPerSU: 128, SUsPerPU: 1, SUsPerRU: 1
Queue size: 100, blocksize: 512, numBlocks: 19540864
RAID Level: 1
Autoconfig: Yes
Root partition: Yes
Last configured as: raid0
Parity status: DIRTY
Reconstruction is 100% complete.
Parity Re-write is 100% complete.
Copyback is 100% complete.

可以看出wd9那个设备还是error状态,接下来我们就需要将wd0这个设备替换掉wd9这个根本不存在的设备。在这之前将所有的两个硬盘的分区表、disklabel等信息进行备份。
# disklabel -r wd1 > /tmp/disklabel.wd1
# disklabel -R -r wd0 /tmp/disklabel.wd1
# disklabel -r wd0 > /tmp/disklabel.wd0
# disklabel -r wd1 > /tmp/disklabel.wd1
# diff /tmp/disklabel.wd0 /tmp/disklabel.wd1
# fdisk /dev/rwd0 > /tmp/fdisk.wd0
# fdisk /dev/rwd1 > /tmp/fdisk.wd1
# diff /tmp/fdisk.wd0 /tmp/fdisk.wd1
# mkdir /root/RFbackup
#
cp -p /tmp/{disklabel,fdisk}* /root/RFbackup

将wd0a设备添加至raid0
# raidctl -v -a /dev/wd0a raid0
/netbsd: Warning: truncating spare disk /dev/wd0a to 241254528 blocks
# raidctl -v -s raid0
Components:
component0: failed
/dev/wd1a: optimal
Spares:
/dev/wd0a: spare
[...snip...]
# raidctl -F component0 raid0
RECON: initiating reconstruction on col 0 -> spare at col 2
11% |****                                   | ETA:    04:26 \

#
raidctl -S raid0
Reconstruction is 0% complete.
Parity Re-write is 100% complete.
Copyback is 100% complete.
Reconstruction status:
17% |******                                 | ETA: 03:08 -
# raidctl -v -s raid0
Components:
component0: spared
/dev/wd1a: optimal
Spares:
/dev/wd0a: used_spare
[...snip...] # /usr/sbin/installboot -o timeout=15 -v /dev/rwd0a /usr/mdec/bootxx_ffsv1# shutdown -r now
完成。
最后可以考虑测试一下我们的swap分区设置的是否正确,以免将来真的发生kernel panic的时候dump出来的文件造成我们的生产数据丢失。
具体方法如下:
在系统中按下Ctrl+Alt+Esc。进入内核调试模式输入命令 sync 或者 reboot 0×104 。这会强制将当前的内核映像存储到dump区域(wd0b)。如果一切都正常,那么我们的swap计算是正确的,如果失败了,那么好好检查一下,重新来过吧。:)

Trackback URI | Comments RSS

Leave a Reply

京ICP备05029144