MFen 1.32 -> 1.37

Local revisions: 1.1.1000.1 -> 1.1.1000.8 (delphij)

Obtained from:	The FreeBSD Simplified Chinese Project CVS
This commit is contained in:
Xin LI 2005-04-06 11:04:13 +00:00
parent ce44acb481
commit e879cff35d
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=24224

View file

@ -2,13 +2,13 @@
The Vinum Volume Manager
By Greg Lehey (grog at lemis dot com)
Added to the Handbook by Hiten Pandya <hiten@FreeBSD.org>
Added to the Handbook by Hiten Pandya <hmp@FreeBSD.org>
and Tom Rhodes <trhodes@FreeBSD.org>
For the FreeBSD Documentation Project
The FreeBSD Simplified Chinese Project
Original Revision: 1.32
Original Revision: 1.37
$FreeBSD$
-->
@ -62,7 +62,7 @@ FreeBSD
<indexterm><primary>Vinum</primary></indexterm>
<indexterm><primary>RAID</primary>
<secondary>Software</secondary></indexterm>
<secondary>software</secondary></indexterm>
<para><emphasis>Vinum</emphasis> 是一个所谓的 <emphasis>卷管
理工具</emphasis>, 是能够解决这三个问题的虚拟磁盘驱动程序。
@ -127,15 +127,13 @@ FreeBSD
在下面的讨论中, 将磁盘存储想象成一个巨大的数据扇区,像一本书的页
那样用编号来设定地址. 最明显的方法是把虚拟磁盘分成许多连续的扇区组,
每个扇区大小就是独立的磁盘大小,用这种方法来存储数据,
就像把一本厚厚的书分成很多小的章节。
这个方法叫做
<emphasis>串联</emphasis> 它有一个优点就是磁盘不需要
有任何特定的大小关系。
当访问到的虚拟磁盘根据它的地址空间来分布的时候,它能工作得
很好。当访问集中在一个比较小的区域的时候,性能的提高没有显著的改进。
就像把一本厚厚的书分成很多小的章节。 这个方法叫做
<emphasis>串联</emphasis>
它有一个优点就是磁盘不需要有任何特定的大小关系。
当访问到的虚拟磁盘根据它的地址空间来分布的时候, 它能工作得很好。
当访问集中在一个比较小的区域的时候,性能的提高没有显著的改进。
<xref linkend="vinum-concat">
举例说明了用串联组织的方式来分配存储单元的顺序。
</para>
举例说明了用串联组织的方式来分配存储单元的顺序。</para>
<para>
<figure id="vinum-concat">
@ -145,11 +143,14 @@ FreeBSD
</para>
<indexterm>
<primary>disk striping</primary>
<primary>条带盘</primary>
</indexterm>
<indexterm>
<primary>Vinum</primary>
<secondary>striping</secondary>
<secondary>条带</secondary>
</indexterm>
<indexterm>
<primary>RAID</primary>
</indexterm>
<para>另外一种影射方法是把地址空间分布在比较小的容量相同的磁盘上,
@ -159,16 +160,14 @@ FreeBSD
<emphasis>分段(striping)</emphasis> 或者 <acronym>RAID-0</acronym>
<footnote>
<indexterm><primary>RAID</primary></indexterm>
<para><acronym>RAID</acronym> 代表<emphasis>廉价磁盘容错(Redundant
Array of Inexpensive Disks)</emphasis> 提供各种容错机制,
但后面这个术语可能会有些让人误解:它不提供冗余功能。</para> </footnote>.
分段要求很精确地寻址,通过多个磁盘进行数据传输的时候,它
可能会引起额外的I/O 负载,但它也可能提供更多的连续负载。
<xref linkend="vinum-striped"> 显示了用分段形式分配的存储单元的顺序。
</para>
<xref linkend="vinum-striped">
显示了用分段形式分配的存储单元的顺序。</para>
<para>
<figure id="vinum-striped">
@ -188,11 +187,11 @@ FreeBSD
</para>
<indexterm>
<primary>disk mirroring</primary>
<primary>磁盘镜像</primary>
</indexterm>
<indexterm>
<primary>Vinum</primary>
<secondary>mirroring</secondary>
<secondary>镜像</secondary>
</indexterm>
<indexterm>
<primary>RAID-1</primary>
@ -222,26 +221,32 @@ FreeBSD
<para><indexterm><primary>RAID-5</primary></indexterm>一个
可选的方案采用 <emphasis>parity</emphasis>,
其实现了 <acronym>RAID</acronym> 2, 3, 4 和
5. 当然, <acronym>RAID-5</acronym> 是最有趣的。
As implemented in Vinum, it is a variant on a
striped organization which dedicates one block of each stripe
to parity of the other blocks. As implemented by Vinum, a
<acronym>RAID-5</acronym> plex is similar to a striped plex,
except that it implements <acronym>RAID-5</acronym> by
including a parity block in each stripe. As required by
<acronym>RAID-5</acronym>, the location of this parity block
changes from one stripe to the next. The numbers in the data
blocks indicate the relative block numbers.</para>
5. 而其中, <acronym>RAID-5</acronym> 是我们最感兴趣的。
在 Vinum 的实现中, 这是一个条带组织结构的变体,
其中, 每一个条带中都以一个专用的块,
来保存其它块的奇偶校验值。 这样,
<acronym>RAID-5</acronym> plex 除了在每个块中都包含了一个奇偶校验块之外,
实现 <acronym>RAID-5</acronym> 时也就和普通的条带 plex
一样了。 作为
<acronym>RAID-5</acronym> 的一项要求,
奇偶校验块在每一个条带中的顺序都是不同的。 数据块的编号,
决定了它的相对块号。</para>
<para>
<figure id="vinum-raid5-org">
<title>RAID-5 Organization ** 翻译进行中 **</title>
<title>RAID-5 的组织</title>
<graphic fileref="vinum/vinum-raid5-org">
</figure>
</para>
<!-- WIP -->
<para>本节尚未翻译</para>
<para>与镜像相比, <acronym>RAID-5</acronym>
最显著的优势在于只需使用少得多的存储空间。
读取类似于条带式存储的组织, 但写入会慢得多,
大约仅相当于读性能的 25%。 如果一个驱动器失效,
则阵列仍然可以在降级的模式运行:
读取来自正常的驱动器数据的操作照常进行,
但读取失效的驱动器的数据, 则来自于余下驱动器上相关的计算结果。
</para>
</sect1>
<sect1 id="vinum-objects">
@ -482,37 +487,162 @@ FreeBSD
在这个小小的例子中卷包含一个plexplex 包含一个subdisk。
</para>
<para>这个特殊的卷与一个传统的磁盘分区没有什么特别的优势。
下面的章节会描述到几个非常有趣的配置方法。
This particular volume has no specific advantage over a
conventional disk partition. It contains a single plex, so it
is not redundant. The plex contains a single subdisk, so
there is no difference in storage allocation from a
conventional disk partition. The following sections
illustrate various more interesting configuration
methods.</para>
<para>这个卷本身和普通的磁盘分区相比并没有什么特别的优越性,
它包含了一个 plex 因此不是冗余的。 这个 plex
中包括了一个子磁盘, 因此这和从磁盘分区分配存储没什么两样。
接下来的几节, 将介绍一些更有用的配置方法。</para>
</sect2>
<sect2>
<title>增强的可靠性:镜象 ** 翻译进行中 **</title>
<title>提高容错性: 镜像</title>
<para></para>
<para>卷的容错性可以通过镜像来提高。 在配置镜像卷时,
确保 plex 分布在不同的驱动器上十分重要, 这样一个驱动器坏掉时,
就不会同时影响两个 plex。 下面的配置将映射卷:</para>
<programlisting>
drive b device /dev/da4h
volume mirror
plex org concat
sd length 512m drive a
plex org concat
sd length 512m drive b</programlisting>
<para>上面的例子中,
并不需要再次指定驱动器 <emphasis>a</emphasis> 因为 Vinum
监控所有其配置数据库的对象。 完成定义之后,
配置如下所示:</para>
<programlisting width="97">
Drives: 2 (4 configured)
Volumes: 2 (4 configured)
Plexes: 3 (8 configured)
Subdisks: 3 (16 configured)
D a State: up Device /dev/da3h Avail: 1549/2573 MB (60%)
D b State: up Device /dev/da4h Avail: 2061/2573 MB (80%)
V myvol State: up Plexes: 1 Size: 512 MB
V mirror State: up Plexes: 2 Size: 512 MB
P myvol.p0 C State: up Subdisks: 1 Size: 512 MB
P mirror.p0 C State: up Subdisks: 1 Size: 512 MB
P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB
S myvol.p0.s0 State: up PO: 0 B Size: 512 MB
S mirror.p0.s0 State: up PO: 0 B Size: 512 MB
S mirror.p1.s0 State: empty PO: 0 B Size: 512 MB</programlisting>
<para><xref linkend="vinum-mirrored-vol"> 以图形方式展示了其结构。</para>
<para>
<figure id="vinum-mirrored-vol">
<title>镜像 Vinum 卷</title>
<graphic fileref="vinum/vinum-mirrored-vol">
</figure>
</para>
<para>这个例子中, 每一个 plex 包含了完整的 512&nbsp;MB
地址空间。 在前面的例子中, plex 则只包括一个子盘。</para>
</sect2>
<sect2>
<title>Optimizing Performance ** 翻译进行中 **</title>
<title>优化性能</title>
<para></para>
<para>恰面例子中的镜像卷要比没有镜像的卷具有更好的容灾能力,
但它的性能要差一些: 每一次写入卷时, 需要同时写道两个驱动器上,
因而也就需要更大的磁盘访问带宽。 如果希望非常好的性能,
则需要另外一种方式: 不做镜像,
而将数据分成条带放到尽可能多的、不同的磁盘上。
下面给出了一个跨越四个磁盘驱动器的 plex 卷:</para>
<programlisting>
drive c device /dev/da5h
drive d device /dev/da6h
volume stripe
plex org striped 512k
sd length 128m drive a
sd length 128m drive b
sd length 128m drive c
sd length 128m drive d</programlisting>
<para>和之前类似, 并不需要定义 Vinum 已经知道的驱动器。
在完成定义之后, 将得到如下配置:</para>
<programlisting width="92">
Drives: 4 (4 configured)
Volumes: 3 (4 configured)
Plexes: 4 (8 configured)
Subdisks: 7 (16 configured)
D a State: up Device /dev/da3h Avail: 1421/2573 MB (55%)
D b State: up Device /dev/da4h Avail: 1933/2573 MB (75%)
D c State: up Device /dev/da5h Avail: 2445/2573 MB (95%)
D d State: up Device /dev/da6h Avail: 2445/2573 MB (95%)
V myvol State: up Plexes: 1 Size: 512 MB
V mirror State: up Plexes: 2 Size: 512 MB
V striped State: up Plexes: 1 Size: 512 MB
P myvol.p0 C State: up Subdisks: 1 Size: 512 MB
P mirror.p0 C State: up Subdisks: 1 Size: 512 MB
P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB
P striped.p1 State: up Subdisks: 1 Size: 512 MB
S myvol.p0.s0 State: up PO: 0 B Size: 512 MB
S mirror.p0.s0 State: up PO: 0 B Size: 512 MB
S mirror.p1.s0 State: empty PO: 0 B Size: 512 MB
S striped.p0.s0 State: up PO: 0 B Size: 128 MB
S striped.p0.s1 State: up PO: 512 kB Size: 128 MB
S striped.p0.s2 State: up PO: 1024 kB Size: 128 MB
S striped.p0.s3 State: up PO: 1536 kB Size: 128 MB</programlisting>
<para>
<figure id="vinum-striped-vol">
<title>条带化的 Vinum 卷</title>
<graphic fileref="vinum/vinum-striped-vol">
</figure>
</para>
<para>这个卷在
<xref linkend="vinum-striped-vol"> 中给出。 条带的阴影部分,
表示在 plex 地址空间中的位置: 颜色最浅的在最前面,
而最深的在最后。</para>
</sect2>
<sect2>
<title>Resilience and Performance ** 翻译进行中 **</title>
<title>高性能容在</title>
<para><anchor id="vinum-resilience"></para>
<para><anchor id="vinum-resilience">如果硬件足够多,
也能够构建比标准
&unix; 分区同时提高了容灾性和性能的卷。
典型的配置文件类似:</para>
<programlisting>
volume raid10
plex org striped 512k
sd length 102480k drive a
sd length 102480k drive b
sd length 102480k drive c
sd length 102480k drive d
sd length 102480k drive e
plex org striped 512k
sd length 102480k drive c
sd length 102480k drive d
sd length 102480k drive e
sd length 102480k drive a
sd length 102480k drive b</programlisting>
<para>第二个 plex 中的子盘和第一个 plex 中的错开了两个驱动器:
这能够帮助确保即使同时访问两个驱动器,
写操作也不会同时发生在同一个盘上。</para>
<para><xref linkend="vinum-raid10-vol"> 给出了该卷的结构。</para>
<para>
<figure id="vinum-raid10-vol">
<title>A Mirrored, Striped Vinum Volume</title>
<title>镜像并条带化的 Vinum 卷</title>
<graphic fileref="vinum/vinum-raid10-vol">
</figure>
</para>
@ -520,90 +650,649 @@ FreeBSD
</sect1>
<sect1 id="vinum-object-naming">
<title>Object Naming ** 翻译进行中 **</title>
<title>对象命名</title>
<para></para>
<para>如前面所描述的那样, Vinum 会给 plex 和子盘指定默认的名字,
而这些名字也是可以定制的。 不推荐盖面默认的名字:
使用允许给对象任意命名的 VERITAS
卷管理器的经验证明, 这一灵活性并没有带来太多的好处,
相反, 它很容易导致对象的混淆。</para>
<para>名字中可以包括任何非空白的字符, 但一般来说,
建议只使用字母、 数字和下划线。 卷、 plex 以及子盘的名字,
可以包含最多 64 个字符, 而驱动器的名字, 则最长可以使用
32 个字符。</para>
<para>Vinum 对象会在
<filename>/dev/vinum</filename> 之下生成设备接点。
前述的配置将使 Vinum 创建以下设备节点:</para>
<itemizedlist>
<listitem>
<para>控制设备
<filename>/dev/vinum/control</filename> 和
<filename>/dev/vinum/controld</filename>
分别由 &man.vinum.8; 和 Vinum 服务使用。</para>
</listitem>
<listitem>
<para>每一个卷缩对应的块设备和字符设备。
这些是 Vinum 中用到的主要设备。 块设备的名字就是卷的名字,
而字符设备的名字, 则遵循 BSD 的习惯, 在卷的名字前面增加
<emphasis>r</emphasis>。 因此, 前面的配置对应的块设备是
<filename>/dev/vinum/myvol</filename>,
<filename>/dev/vinum/mirror</filename>,
<filename>/dev/vinum/striped</filename>,
<filename>/dev/vinum/raid5</filename> 和
<filename>/dev/vinum/raid10</filename>, 而字符设备则是
<filename>/dev/vinum/rmyvol</filename>,
<filename>/dev/vinum/rmirror</filename>,
<filename>/dev/vinum/rstriped</filename>,
<filename>/dev/vinum/rraid5</filename> 和
<filename>/dev/vinum/rraid10</filename>。
显然, 这有时会造成问题: 有可能有两个卷,
分别叫做 <emphasis>r</emphasis> 和 <emphasis>rr</emphasis>
这样, 在创建设备节点
<filename>/dev/vinum/rr</filename> 时就会产生冲突:
它到底是卷 <emphasis>r</emphasis> 对应的字符设备,
还是卷 <emphasis>rr</emphasis> 的块设备?
目前, Vinum 并不处理这样的冲突: 先定义的卷,
将得到希望的设备名。</para>
</listitem>
<listitem>
<para>一个包含每个驱动器对应项的 <filename>/dev/vinum/drive</filename>
目录。 这些项事实上是指向对应磁盘节点的符号连接。</para>
</listitem>
<listitem>
<para>包含每个卷对应项的 <filename>/dev/vinum/volume</filename>
目录。 每一个 plex 对应一个子目录, 而这些目录中,
则是组成它们的子盘。</para>
</listitem>
<listitem>
<para>目录
<filename>/dev/vinum/plex</filename>,
<filename>/dev/vinum/sd</filename>, 以及
<filename>/dev/vinum/rsd</filename>, 它们中包括了每一个 plex
的设备节点, 以及每一个子盘的块设备和字符设备。</para>
</listitem>
</itemizedlist>
<para>例如, 考虑下面的配置文件:</para>
<programlisting>
drive drive1 device /dev/sd1h
drive drive2 device /dev/sd2h
drive drive3 device /dev/sd3h
drive drive4 device /dev/sd4h
volume s64 setupstate
plex org striped 64k
sd length 100m drive drive1
sd length 100m drive drive2
sd length 100m drive drive3
sd length 100m drive drive4</programlisting>
<para>处理这个文件之后, &man.vinum.8; 将在
<filename>/dev/vinum</filename> 中建立下面的结构:</para>
<programlisting>
brwx------ 1 root wheel 25, 0x40000001 Apr 13 16:46 Control
brwx------ 1 root wheel 25, 0x40000002 Apr 13 16:46 control
brwx------ 1 root wheel 25, 0x40000000 Apr 13 16:46 controld
drwxr-xr-x 2 root wheel 512 Apr 13 16:46 drive
drwxr-xr-x 2 root wheel 512 Apr 13 16:46 plex
crwxr-xr-- 1 root wheel 91, 2 Apr 13 16:46 rs64
drwxr-xr-x 2 root wheel 512 Apr 13 16:46 rsd
drwxr-xr-x 2 root wheel 512 Apr 13 16:46 rvol
brwxr-xr-- 1 root wheel 25, 2 Apr 13 16:46 s64
drwxr-xr-x 2 root wheel 512 Apr 13 16:46 sd
drwxr-xr-x 3 root wheel 512 Apr 13 16:46 vol
/dev/vinum/drive:
total 0
lrwxr-xr-x 1 root wheel 9 Apr 13 16:46 drive1 -&gt; /dev/sd1h
lrwxr-xr-x 1 root wheel 9 Apr 13 16:46 drive2 -&gt; /dev/sd2h
lrwxr-xr-x 1 root wheel 9 Apr 13 16:46 drive3 -&gt; /dev/sd3h
lrwxr-xr-x 1 root wheel 9 Apr 13 16:46 drive4 -&gt; /dev/sd4h
/dev/vinum/plex:
total 0
brwxr-xr-- 1 root wheel 25, 0x10000002 Apr 13 16:46 s64.p0
/dev/vinum/rsd:
total 0
crwxr-xr-- 1 root wheel 91, 0x20000002 Apr 13 16:46 s64.p0.s0
crwxr-xr-- 1 root wheel 91, 0x20100002 Apr 13 16:46 s64.p0.s1
crwxr-xr-- 1 root wheel 91, 0x20200002 Apr 13 16:46 s64.p0.s2
crwxr-xr-- 1 root wheel 91, 0x20300002 Apr 13 16:46 s64.p0.s3
/dev/vinum/rvol:
total 0
crwxr-xr-- 1 root wheel 91, 2 Apr 13 16:46 s64
/dev/vinum/sd:
total 0
brwxr-xr-- 1 root wheel 25, 0x20000002 Apr 13 16:46 s64.p0.s0
brwxr-xr-- 1 root wheel 25, 0x20100002 Apr 13 16:46 s64.p0.s1
brwxr-xr-- 1 root wheel 25, 0x20200002 Apr 13 16:46 s64.p0.s2
brwxr-xr-- 1 root wheel 25, 0x20300002 Apr 13 16:46 s64.p0.s3
/dev/vinum/vol:
total 1
brwxr-xr-- 1 root wheel 25, 2 Apr 13 16:46 s64
drwxr-xr-x 3 root wheel 512 Apr 13 16:46 s64.plex
/dev/vinum/vol/s64.plex:
total 1
brwxr-xr-- 1 root wheel 25, 0x10000002 Apr 13 16:46 s64.p0
drwxr-xr-x 2 root wheel 512 Apr 13 16:46 s64.p0.sd
/dev/vinum/vol/s64.plex/s64.p0.sd:
total 0
brwxr-xr-- 1 root wheel 25, 0x20000002 Apr 13 16:46 s64.p0.s0
brwxr-xr-- 1 root wheel 25, 0x20100002 Apr 13 16:46 s64.p0.s1
brwxr-xr-- 1 root wheel 25, 0x20200002 Apr 13 16:46 s64.p0.s2
brwxr-xr-- 1 root wheel 25, 0x20300002 Apr 13 16:46 s64.p0.s3</programlisting>
<para>虽然 plex 和子盘一般并不推荐指定名字, 但还是必须给 Vinum
驱动器命名。 这样, 当把驱动器转移到不同的地方时,
它仍然能够被自动地识别出来。 驱动器名最长可以包含
32 个字符。</para>
<sect2>
<title>Creating File Systems ** 翻译进行中 **</title>
<title>创建文件系统</title>
<para></para>
<para>对于系统而言, 卷和磁盘是一样的。
唯一的例外是, 与 &unix; 驱动器不同, Vinum 并不对卷进行分区,
因而它也就不包含分区表。 这导致修改了某些磁盘工具,
特别是 &man.newfs.8; 它会试图将 Vinum 卷名当作分区标识。
例如, 磁盘驱动器的名字可能是 <filename>/dev/ad0a</filename> 或
<filename>/dev/da2h</filename>。
这些名字分别表达在第一个 (0) IDE (<devicename>ad</devicename>)
磁盘上的第一个分区 (<devicename>a</devicename>)
以及第三个 (2) SCSI 磁盘 (<devicename>da</devicename>)
上的第八个分区 (<devicename>h</devicename>)。
于此相反, Vinum 卷可能叫做
<filename>/dev/vinum/concat</filename>
这个名字和分区名没有什么关系。</para>
<para>一般而言, &man.newfs.8; 会试图解释磁盘的名字,
如果它无法理解这个名字, 则会给出错误提示。 例如:</para>
<screen>&prompt.root; <userinput>newfs /dev/vinum/concat</userinput>
newfs: /dev/vinum/concat: can't figure out file system partition</screen>
<note><para>对于 FreeBSD 5.0 之前的版本:</para></note>
<para>要在卷上创建文件系统, 应使用 &man.newfs.8; 的
<option>-v</option> 参数:</para>
<screen>&prompt.root; <userinput>newfs -v /dev/vinum/concat</userinput></screen>
</sect2>
</sect1>
<sect1 id="vinum-config">
<title>Configuring Vinum ** 翻译进行中 **</title>
<title>配置 Vinum</title>
<para></para>
<para>在 <filename>GENERIC</filename> 内核中, 并不包含
Vinum。 可以编译一个定制的包含
Vinum 的内核, 然而并不推荐这样做。 启动
Vinum 的标准方法, 是使用内核模块 (<acronym>kld</acronym>)。
甚至不需要使用 &man.kldload.8; 来启动 Vinum 在启动
&man.vinum.8; 时, 它会检查这一模块是否已经加载,
如果没有, 则会自动地加载它。</para>
<sect2>
<title>Startup ** 翻译进行中 **</title>
<title>启动</title>
<para></para>
<para>Vinum 将配置信息, 采用与配置文件一样的形式来存放到磁盘分区上。
当从配置数据库中读取时, Vinum 会识别一系列在配置文件中不可用的关键字。
例如, 磁盘配置文件可能包含下面的文字:</para>
<programlisting width="119">volume myvol state up
volume bigraid state down
plex name myvol.p0 state up org concat vol myvol
plex name myvol.p1 state up org concat vol myvol
plex name myvol.p2 state init org striped 512b vol myvol
plex name bigraid.p0 state initializing org raid5 512b vol bigraid
sd name myvol.p0.s0 drive a plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 0b
sd name myvol.p0.s1 drive b plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 1048576b
sd name myvol.p1.s0 drive c plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 0b
sd name myvol.p1.s1 drive d plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 1048576b
sd name myvol.p2.s0 drive a plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 0b
sd name myvol.p2.s1 drive b plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 524288b
sd name myvol.p2.s2 drive c plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1048576b
sd name myvol.p2.s3 drive d plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1572864b
sd name bigraid.p0.s0 drive a plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 0b
sd name bigraid.p0.s1 drive b plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 4194304b
sd name bigraid.p0.s2 drive c plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 8388608b
sd name bigraid.p0.s3 drive d plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 12582912b
sd name bigraid.p0.s4 drive e plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 16777216b</programlisting>
<para>这里最明显的区别是, 指定了配置的位置信息、名称
(这些在配置文件中还是可用的, 但不鼓励用户自行指定)
以及状态信息 (这是用户不能指定的)。 Vinum
并不在配置信息中保存关于驱动器的信息:
它会扫描已经配置的磁盘驱动器上包含 Vinum 标识的分区。
这使得 Vinum 能够在 &unix; 驱动器被指定了不同的
ID 时也能够正确识别它们。</para>
<sect3 id="vinum-rc-startup">
<title>Automatic Startup ** 翻译进行中 **</title>
<title>自动启动</title>
<para></para>
<para>要在引导系统时自动启动 Vinum 需要在
<filename>/etc/rc.conf</filename> 中加入下面的配置:</para>
<programlisting>start_vinum="YES" # set to YES to start vinum</programlisting>
<para>如果您的系统中没有
<filename>/etc/rc.conf</filename> 创建一个并加入这些设置就可以了。
这样, 系统就会在启动时自动加载 Vinum 的
<acronym>kld</acronym> 并启动配置中所提到的所有对象。
这是在挂接文件系统之前进行的, 因此,
&man.fsck.8; 和挂接文件系统都能够自动地在 Vinum 卷上进行。</para>
<para>当使用 <command>vinum
start</command> 命令来启动 Vinum 时, Vinum 会从某一个 Vinum
驱动器中读取配置数据库。 正常情况下,
每个驱动器上都包含了同样的配置数据库副本,
因此从哪个驱动器上读取是无所谓的。 但是, 在系统崩溃之后,
Vinum 就必须检测哪一个驱动器上的配置数据库是最新的,
并从上面读取配置。 如果需要, 它会更新其它驱动器上的配置。</para>
</sect3>
</sect2>
</sect1>
<sect1 id="vinum-root">
<title>Using Vinum for the Root Filesystem ** 翻译进行中 **</title>
<title>使用 Vinum 作为根文件系统</title>
<para></para>
<para>如果文件系统使用完全镜像的
Vinum 配置, 有时也会希望根文件系统也作了镜像。
这种配置要比镜像其它文件系统麻烦一些, 因为:</para>
<itemizedlist>
<listitem>
<para>根文件系统在引导过程中很早的时候就必须处于可用状态,
因此 Vinum 的基础设施在这一时刻就应该可用了。</para>
</listitem>
<listitem>
<para>包含根文件系统的卷, 同时也保存了系统的引导程序和内核,
因此它们必须能够被宿主系统的内建工具 (例如 PC 机的 BIOS)
识别, 而通常是没办法让它们了解 Vinum 的细节的。</para>
</listitem>
</itemizedlist>
<para>下面几节中, 术语 <quote>根卷</quote>
标识包含根文件系统的 Vinum 卷。
把这个卷命名为 <literal>"root"</literal> 可能是个不错的主意,
不过从技术上说, 并不严格地要求这样做。 不过,
接下来的命令例子都使用这个名字。</para>
<sect2>
<title>Starting up Vinum Early Enough for the Root
Filesystem ** 翻译进行中 **</title>
<title>及早启动 Vinum 以适应对根文件系统的要求</title>
<para></para>
<para>有许多关于它的尺度:</para>
<itemizedlist>
<listitem>
<para>Vinum 必须在启动时可以被内核使用。 因此, 在
<xref linkend="vinum-rc-startup"> 中所介绍的方法,
也就无法适应这一任务的需要了。 在接下来的配置中, 也
<emphasis>不能</emphasis> 设置
<literal>start_vinum</literal> 参数。 第一种方法是通过将
Vinum 静态联编到内核中来实现, 这样,
它就在任何时候都可用了, 虽然一般并不需要这样。
另一种方法是通过
<filename>/boot/loader</filename> (<xref
linkend="boot-loader">) 来尽早加载 vinum 内核模块,
这一操作发生在内核加载之前。 这可以通过将下面的配置:</para>
<programlisting>vinum_load="YES"</programlisting>
<para>加入到
<filename>/boot/loader.conf</filename> 文件中来实现。</para>
</listitem>
<listitem>
<para>Vinum 必须尽早初始化, 因为需要由它来提供根文件系统的卷。
默认情况下, Vinum 的内核部分并不主动地查找可能包含 Vinum
卷信息的驱动器, 而会等待管理员
(或者某个启动脚本) 来执行 <command>vinum
start</command> 命令。</para>
<note><para>下面介绍的是 FreeBSD 5.X 和更高版本所需的配置。 对于
FreeBSD 4.X 的配置方法与此不同, 在 <xref
linkend="vinum-root-4x"> 中有所买噢书。</para></note>
<para>通过将下面的配置:</para>
<programlisting>vinum.autostart="YES"</programlisting>
<para>加入 <filename>/boot/loader.conf</filename> Vinum
将在内核部分初始化的过程中, 自动地扫描所有的驱动器以查找 Vinum
信息。</para>
<para>需要说明的是, 并不需要指定内核到什么地方去找根文件系统。
<filename>/boot/loader</filename> 会在 <filename>/etc/fstab</filename>
中查找根文件系统的设备名, 并将这一信息转交给内核。
当需要挂接根文件系统时, 内核会根据设备名来知道它由哪个驱动提供,
并将其转译为内部设备 ID (major/minor 编号)。</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Making a Vinum-based Root Volume Accessible to the
Bootstrap ** 翻译进行中 **</title>
<title>让基于 Vinum 的卷在引导时可以访问</title>
<para></para>
<para>因为目前的 FreeBSD 引导程序只有 7.5 KB 的代码,
并且已经承担了从 UFS 文件系统中读取文件 (例如
<filename>/boot/loader</filename>) 的重任,
因此完全没有办法再让它去分析 Vinum 配置数据中的 Vinum 结构,
并找到引导卷本身的信息。 因此,
需要一些技巧来为引导代码提供标准的 <literal>"a"</literal>
分区, 而它则包含了根文件系统。</para>
<para>要让这些得以实现, 根卷需要满足下面的条件:</para>
<itemizedlist>
<listitem>
<para>根卷不能是条带卷或 RAID-5 卷。</para>
</listitem>
<listitem>
<para>根卷 plex 不能包含连接的子盘。</para>
</listitem>
</itemizedlist>
<para>需要说明的是, 使用多个 plex 每个 plex
都复制一份根文件系统的副本, 是需要而且是可行的。
然而, 引导过程只能使用这些副本中的一个来引导系统,
直到内核最终自行挂接根文件系统为止。 这些 plex 中的每个子盘,
在这之后会有它们自己的 <literal>"a"</literal>
分区, 以表达每一个可以引导的设备。
每一个 <literal>"a"</literal> 分区, 尽管并不需要和其它包含根卷的
plex 处于各自驱动器的同一位置。 但是, 这样创建 Vinum
卷使得镜像卷相互对称, 从而能够避免了混淆。</para>
<para>为了创建每一个根卷的 <literal>"a"</literal> 分区,
需要完成下面的操作:</para>
<procedure>
<step>
<para>使用下面的命令来了解根卷成员子盘的位置
(从设备开始的偏移量) 和尺寸:</para>
<screen>&prompt.root; <userinput>vinum l -rv root</userinput></screen>
<para>需要注意的是, Vinum 偏移量和尺寸的单位是字节。
它们必须是 512 的整数倍, 才能得到
<command>disklabel</command> 命令所需的块号。</para>
</step>
<step>
<para>在每一个根卷成员设备上, 执行命令:</para>
<screen>&prompt.root; <userinput>disklabel -e <replaceable>devname</replaceable></userinput></screen>
<para>这其中, 对于没有 slice (也就是 fdisk) 表的磁盘,
<replaceable>devname</replaceable> 必须是磁盘的名字
(例如 <devicename>da0</devicename>) 或者是 slice
的名字 (例如 <devicename>ad0s1</devicename>)。</para>
<para>如果设备上已经有了 <literal>"a"</literal> 分区
(比如说, 包含 Vinum 之前的根文件系统)
则应改为其它的名字, 以便继续访问 (如果需要的话)
但它并不会继续用于启动系统。 注意, 活动的分区
(类似正挂接的根文件系统) 不能被改名, 因此,
要完成这项工作, 必须从
<quote>Fixit</quote> 盘启动, 或者分两步操作,
并 (在镜像情形中) 首先操作那些非引导盘。</para>
<para>然后, 设备上 Vinum 分区的偏移 (如果有的话)
必须加到这个设备上根卷对应的子盘上。
其结果值, 将成为新的
<literal>"a"</literal> 分区的
<literal>"offset"</literal> 值。 这个分区的
<literal>"size"</literal> 值, 可以根据前面的配置计算得出。
<literal>"fstype"</literal> 应该是
<literal>4.2BSD</literal>。
<literal>"fsize"</literal>、 <literal>"bsize"</literal>
以及 <literal>"cpg"</literal> 值, 则应与文件系统的实际情况匹配,
尽管在配置 Vinum 时并不重要。</para>
<para>这样, 新的 <literal>"a"</literal> 分区,
将创建并覆盖这一设备上的 Vinum 分区的范围。
注意, <command>disklabel</command> 只有在
Vinum 分区的 fstype 被标记为 <literal>"vinum"</literal>
时, 才允许这样做。</para>
</step>
<step>
<para>这就成了! 所有的 <literal>"a"</literal> 分区现在都已存在,
而且是根卷的一份副本。 强烈建议您再次验证其结果,
方法是:</para>
<screen>&prompt.root; <userinput>fsck -n /dev/<replaceable>devname</replaceable>a</userinput></screen>
</step>
</procedure>
<para>务必注意, 所有包含控制信息的文件, 都必须放到
Vinum 卷上的根文件系统。 在启动新的 Vinum 根卷时,
它们可能和实际在用的根文件系统不匹配。
因此, <filename>/etc/fstab</filename>
和 <filename>/boot/loader.conf</filename> 这两个文件需要特别地注意。</para>
<para>在下次重启时, 引导程序需要从新的基于 Vinum
的根文件系统中获取适当的控制信息, 并据此工作。
在内核初始化过程的结尾部分, 在所有的设备都被宣示之后,
如果显示了下面的信息, 则表示配置成功:</para>
<screen>Mounting root from ufs:/dev/vinum/root</screen>
</sect2>
<sect2>
<title>Example of a Vinum-based Root Setup ** 翻译进行中 **</title>
<title>基于 Vinum 的根文件系统的配置范例</title>
<para></para>
<para>在 Vinum 根卷配置好之后,
<command>vinum l -rv root</command> 的输出可能类似下面的样子:</para>
<screen>
...
Subdisk root.p0.s0:
Size: 125829120 bytes (120 MB)
State: up
Plex root.p0 at offset 0 (0 B)
Drive disk0 (/dev/da0h) at offset 135680 (132 kB)
Subdisk root.p1.s0:
Size: 125829120 bytes (120 MB)
State: up
Plex root.p1 at offset 0 (0 B)
Drive disk1 (/dev/da1h) at offset 135680 (132 kB)
</screen>
<para>需要注意的值是 <literal>135680</literal>
也就是偏移量 (相对于
<filename>/dev/da0h</filename> 分区)。 这相当于 <command>disklabel</command>
记法中的 265 个 512-字节的磁盘块。 类似地, 根卷的尺寸是 245760
个 512-字节的磁盘块。 <filename>/dev/da1h</filename> 中,
包含了根卷的第二个副本, 采用了同样的配置。</para>
<para>这些设备的 disklabel 类似下面的样子:</para>
<screen>
...
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 245760 281 4.2BSD 2048 16384 0 # (Cyl. 0*- 15*)
c: 71771688 0 unused 0 0 # (Cyl. 0 - 4467*)
h: 71771672 16 vinum # (Cyl. 0*- 4467*)
</screen>
<para>可以看到, 伪装的 <literal>"a"</literal>
分区的 <literal>"size"</literal> 参数和前面的一样, 而
<literal>"offset"</literal> 参数则是 Vinum
分区 <literal>"h"</literal> 以及设备中这一分区
(或 slice) 的偏移量之和。 这是一种典型的配置,
它能够避免在 <xref linkend="vinum-root-panic">
中介绍的问题。 此外, 我们也看到整个 <literal>"a"</literal>
分区完全处于设备上包含了 Vinum 数据的 <literal>"h"</literal>
分区之中。</para>
<para>注意, 在上面的配置中, 整个设备都是 Vinum 专用的,
而且没有留下 Vinum 之前的根分区, 因为它永久性地成为了新建的
Vinum 配置中的一个子盘。</para>
</sect2>
<sect2>
<title>Troubleshooting ** 翻译进行中 **</title>
<title>故障排除</title>
<para>如果遇到了问题, 则需要从中恢复的办法。
下面列出了一些常见的缺陷, 及其解决方法。</para>
<sect3>
<title>System Bootstrap Loads, but System Does Not Boot</title>
<para></para>
<title>系统的引导程序加载了, 但无法启动</title>
<para>如果由于某种原因系统不再继续启动,
引导程序可以在 10-秒 倒计时的时候, 按
<keycap>space</keycap> 键来停止。
加载器变量 (例如 <literal>vinum.autostart</literal>)
可以通过使用 <command>show</command> 命令来查看,
并使用 <command>set</command> 和
<command>unset</command> 命令来设置。</para>
<para>如果遇到的问题是由于 Vinum 的内核模块没有列入预加载的列表,
而没有正确加载, 则可以简单使用
<command>load vinum</command> 会有所帮助。</para>
<para>此后, 可以使用
<command>boot -as</command> 来继续启动过程。 选项
<option>-as</option> 会要求内核询问所挂接的根文件系统
(<option>-a</option>) 并使引导过程在单用户模式停止
(<option>-s</option>) 此时根文件系统是以只读方式挂接的。
这样, 及时只挂接了多 plex 卷中的一个 plex
也不会引致 plex 之间数据不一致的问题。</para>
<para>当提示输入要挂接的根文件系统时,
可以输入任何一个包含根文件系统的设备。
如果正确地配置了 <filename>/etc/fstab</filename>
则默认的应该是类似
<literal>ufs:/dev/vinum/root</literal>。
一般可以使用类似
<literal>ufs:da0d</literal> 这样的设备来代替它,
因为它通常包括了 Vinum 之前的根文件系统。
需要注意的是, 如果在这里输入了
<literal>"a"</literal> 分区, 则它可能表达的实际上是
Vinum 根设备的一个子盘, 而在镜像式配置中,
这只会挂接镜像的根设备中的一个。
如果之后将这个文件系统以读写方式挂接,
则需要从 Vinum 根卷中删去其他的 plex
否则这些卷中可能会包含不一致的数据。</para>
</sect3>
<sect3>
<title>Only Primary Bootstrap Loads ** 翻译进行中 **</title>
<title>只加载了主引导程序</title>
<para></para>
<para>如果 <filename>/boot/loader</filename> 加载失败,
而主引导程序加载正常 (在启动时, 屏幕最左边一列有一个旋转的线)
则可以尝试在此时中断主引导程序的过程, 方法是按
<keycap>space</keycap> 键。 这将在引导的第二阶段暂停,
具体可以参见 <xref linkend="boot-boot1">。
此时, 可以尝试从另一个分区, 例如原先包含根文件系统,
并不再叫作 <literal>"a"</literal> 的那个分区, 启动。</para>
</sect3>
<sect3 id="vinum-root-panic">
<title>Nothing Boots, the Bootstrap
Panics ** 翻译进行中 **</title>
<title>无法启动, 引导程序发生 panic</title>
<para></para>
<para>这种情况一般是由于 Vinum 安装过程中破坏了引导程序造成的。
不幸的是, Vinum 目前只在分区开始的地方保留了 4 KB
的空间, 之后就开始写 Vinum 头信息了。 然而,
目前第一阶段和第二阶段的引导程序, 加上 disklabel
嵌入的内容则需要 8 KB。 因此, 如果 Vinum
分区从偏移量 0 开始, 而这个 slice 或磁盘能够启动,
则 Vinum 的安装将毁掉引导程序。</para>
<para>类似地, 如果从上述情形中恢复, 例如,
从 <quote>Fixit</quote> 盘启动, 并通过
<command>disklabel -B</command> 按照 <xref
linkend="boot-boot1"> 中介绍的方法来恢复引导程序,
则引导程序会覆盖掉 Vinum 头, 这样 Vinum 也就找不到它的磁盘了。
尽管这并不会真的毁掉 Vinum 的配置数据, 或者 Vinum 卷上的数据,
并且可以通过输入一模一样的 Vinum 配置数据来恢复,
但从这种状况中完全恢复是非常困难的。 要真正解决问题,
必须将整个 Vinum 分区向后移动至少 4 KB
以便使 Vinum 头和系统的引导程序不再冲突。</para>
</sect3>
</sect2>
<sect2 id="vinum-root-4x">
<title>Differences for FreeBSD 4.X ** 翻译进行中 **</title>
<title>与 FreeBSD 4.X 的区别</title>
<para></para>
<para>在 FreeBSD 4.X 中, 由于缺少那些让 Vinum
自动扫描所有磁盘所需的内部函数, 而检测根设备的内部 ID
的代码不够智能, 以至于无法自动处理类似
<filename>/dev/vinum/root</filename> 这样的名字。
因此, 会有一些小差异。</para>
<para>必须明确地告诉 Vinum 要扫描哪些磁盘, 方法是在
<filename>/boot/loader.conf</filename> 中加入:</para>
<programlisting>vinum.drives="/dev/<replaceable>da0</replaceable> /dev/<replaceable>da1</replaceable>"</programlisting>
<para>所有可能包含 Vinum 数据的盘在这里都应提及。 基本原则是,
<emphasis>宁多毋缺</emphasis>。 此外, 也无需明确指定 slice
或分区, 因为
Vinum 在指定的驱动器上的所有 slice 和分区上扫描 Vinum 头。</para>
<para>由于用以分析根文件系统名字, 并产生设备 ID
(major/minor 编号) 的程序, 只能够处理 <quote>传统的</quote>
类似 <filename>/dev/ad0s1a</filename> 这样的设备名,
因此它们不可能处理类似
<filename>/dev/vinum/root</filename> 这样的根卷名。 因此,
Vinum 本身需要预先配置内核的一些内部参数,
以便在初始化时能够保持根设备的 ID。 这可以通过加载器变量
<literal>vinum.root</literal> 来配置, 对应的
<filename>/boot/loader.conf</filename> 设置是:</para>
<programlisting>vinum.root="root"</programlisting>
<para>现在, 当内核初始化过程尝试找到要挂接的 root 设备时,
它将能看到是否已经有某个内核模块预先初始化了所需要的内核参数。
这种情况下, <emphasis>并且</emphasis>
所指定的根设备和来自加载器的根设备
(也就是我们的 <literal>"vinum"</literal> ) 的 major 编号相符,
则就是用预先分配的设备 ID 而不是自己去找一个。
这样, 在通常的自动启动过程中, 它就能够继续挂接 Vinum
根卷来作为根文件系统了。</para>
<para>但是, 当指定了 <command>boot -a</command>
来要求在启动时手工选择根设备时,
仍然是无法自动地分析 Vinum 卷名的。 如果输入的设备名与 Vinum
设备不匹配, 则 major
编号的不匹配会使这个过程采用普通的分析过程, 这样, 输入
<literal>ufs:da0d</literal> 就能够正常工作了。
注意, 一旦这个过程失败, 则再输入 <literal>ufs:vinum/root</literal>
将不能正常工作, 因为它无法再被解析了。 唯一的解决办法是,
重新启动并从头开始 (在
<quote>askroot</quote> 提示处, 可以省略
<filename>/dev/</filename>。)</para>
</sect2>
</sect1>
</chapter>
<!--
Local Variables:
mode: sgml
sgml-declaration: "../chapter.decl"
sgml-indent-data: t
sgml-omittag: nil
sgml-always-quote-attributes: t
sgml-parent-document: ("../book.sgml" "part" "chapter")
End:
-->