Copyright © 2002-2003 Sistina Software, Inc
Copyright © 2004-2005 Red Hat, Inc
Copyright © 2005-2006 Terrascale Technologies, Inc
Copyright © 2006 Rackable Systems, Inc
修订历史 | ||
---|---|---|
修订版本 0.19 | 2006-11-27 | 修订者:ajl |
在第 3.8 节和第 13.4.1 节中澄清了完整快照的条件,并添加了关于调整快照源大小的注释;修复了 Rackable 版权;修复了电子邮件地址 | ||
修订版本 0.18 | 2006-11-27 | 修订者:ajl |
在第 11.1 节中澄清了整个磁盘的使用;更新了版权;更新了电子邮件地址 | ||
修订版本 0.17 | 2005-10-03 | 修订者:ajl |
为 LVM2 中 LV 的最大大小添加了 FAQ 条目;清理了“恢复物理卷元数据”部分;更新了电子邮件地址 | ||
修订版本 0.16 | 2005-07-15 | 修订者:ajl |
添加了 lvm2 启动时脚本信息;添加了“恢复物理卷元数据”部分 - 感谢 Maximilian Attems 提供的补丁 | ||
修订版本 0.15 | 2005-06-09 | 修订者:ajl |
删除了对 xfs_freeze 的引用 - 现在不再需要它;更新了 LVM 剖析部分中的快照子部分;向 LVM2 FAQ 添加了几个条目;修复了一些拼写错误 | ||
修订版本 0.14 | 2004-10-06 | 修订者:ajl |
在源代码树中添加了对 lvm2_createinitrd 的引用;稍微调整了 lvcreate 示例;在“将卷组移动到另一个系统”配方中添加了“vgchange -ay” | ||
修订版本 0.13 | 2004-08-16 | 修订者:ajl |
澄清了符号链接农场的描述;修复了 dm 控制设备主设备号;从小型的 lvm 设置示例中删除 /boot 中的 vg;添加了关于 /boot 和 / 在 LVM 上的注释;删除了过时的链接; | ||
修订版本 0.12 | 2004-06-07 | 修订者:ajl |
更新了 LVM2 FAQ 条目 | ||
修订版本 0.11 | 2004-05-03 | 修订者:ajl |
更新了 LVM2 FAQ 条目 | ||
修订版本 0.10 | 2004-04-22 | 修订者:ajl |
在收到报告说它不起作用后,从 find 命令中删除了 -print0 | ||
修订版本 0.9 | 2004-04-16 | 修订者:ajl |
将 -print0 添加到 find 命令,然后再将其管道到 cpio;更改了 LVM 2 的 vgimport 命令行;将 ext3 添加到 ext2 调整大小部分;更新了 FAQ;更新了链接部分 | ||
修订版本 0.8 | 2004-02-25 | 修订者:ajl |
更新了 CVS 位置和 FTP 链接;添加了关于扩展 JFS 文件系统的部分;修复了拼写错误 - 对文档运行了 aspell | ||
修订版本 0.7 | 2004-02-16 | 修订者:ajl |
更新为包含 LVM 2 和设备映射器信息;更新了电子邮件地址;更新了版权;添加了 FAQ 部分;添加了文档许可证;更新到 docbook 4.2 | ||
修订版本 0.6 | 2003-12-09 | 修订者:ajl |
更新为 LVM 1.0.8;修复了损坏的链接;澄清了 redhat init 脚本部分; | ||
修订版本 0.5 | 2003-02-10 | 修订者:ajl |
更新了 7.0 及更高版本的 Redhat initscript 信息;如果 pvcreate 失败,添加了从磁盘中删除分区表的信息;默认 PE 大小现在为 32MB;更新了 XFS 下的快照方法。 | ||
修订版本 0.4 | 2002-12-16 | 修订者:ajl |
更新为 LVM 1.0.6 | ||
修订版本 0.3 | 2002-09-16 | 修订者:ajl |
从命令操作部分中删除了示例 pvmove - 我们现在只是指向关于 pvmove 的更详细的配方,其中包含各种警告等 | ||
修订版本 0.2 | 2002-09-11 | 修订者:ajl |
更新为 LVM 1.0.5 并转换为 DocBook XML 4.1.2。 | ||
修订版本 0.1 | 2002-04-28 | 修订者:gf |
从 Sistina 的 LaTeX 源代码进行初始转换并以 LinuxDoc 格式导入到 tLDP。 |
允许在自由软件基金会发布的 GNU 自由文档许可证 1.2 版的条款下复制、分发和/或修改本文档;不包含不变部分、封面文字和封底文字。 许可证的副本包含在题为“GNU 自由文档许可证”的部分中。
本文档的发布是为了希望能对您有所帮助,但不作任何明示或暗示的担保。 虽然已尽一切努力确保本文档所记录信息的准确性,但作者/编辑/维护者/贡献者不对任何错误,或因使用本文档所记录信息而造成的任何直接或间接损害承担任何责任。
本文试图收集所有需要了解的内容,以便启动并运行 LVM。 将涵盖获取、编译、安装和设置 LVM 的整个过程。 还将包括指向经过测试的 LVM 配置的指针。 此版本的 HowTo 适用于带有 device-mapper 的 LVM 2 和 LVM 1.0.8。
以前所有版本的 LVM 都被认为是过时的,并且仅出于历史原因而保留。 本文档不试图解释或描述这些版本的工作原理或使用方法。
我们将把此 HowTo 的最新版本与 CVS 中其他 LDP Howto 一起保留。 您可以通过从 tLDP CVS 服务器检出 ``LDP/howto/docbook/LVM-HOWTO.xml'' 来获取它。 您应该始终能够从 http://www.tldp.org/HOWTO/LVM-HOWTO.html 获得此 HowTo 的人类可读版本
本文档的发布是为了希望能对您有所帮助,但不作任何明示或暗示的担保。 虽然已尽一切努力确保本文档所记录信息的准确性,但作者/编辑/维护者/贡献者不对任何错误,或因使用本文档所记录信息而造成的任何直接或间接损害承担任何责任。
LVM 是 Linux 操作系统的一个逻辑卷管理器。 现在有两个 Linux LVM 版本
LVM 2 - Linux 的最新和最棒的 LVM 版本。
LVM 2 几乎与 LVM 1 创建的卷完全向后兼容。此例外的快照(升级到 LVM 2 之前必须删除快照卷)
LVM 2 使用设备映射器内核驱动程序。 设备映射器支持在 2.6 内核树中,并且有适用于当前 2.4 内核的补丁。
LVM 1 - 2.4 系列内核中的版本,
LVM 1 是一个成熟的产品,几年来一直被认为是稳定的。 LVM 1 的内核驱动程序包含在 2.4 系列内核中,但这并不意味着您的 2.4.x 内核是 LVM 最新版本。 请查看 README 以获取有关哪些内核包含当前代码的最新信息。
与传统的磁盘和分区视图相比,逻辑卷管理提供了计算机系统上磁盘存储的更高级别视图。 这使得系统管理员在向应用程序和用户分配存储时具有更大的灵活性。
在逻辑卷管理器控制下创建的存储卷可以几乎随意地调整大小和移动,尽管这可能需要升级一些文件系统工具。
逻辑卷管理器还允许在用户定义的组中管理存储卷,从而使系统管理员可以处理诸如“开发”和“销售”等具有合理名称的卷组,而不是诸如“sda”和“sdb”之类的物理磁盘名称。
新用户首次安装 Linux 时面临的难题之一是如何对磁盘驱动器进行分区。需要估计系统文件和用户文件可能需要多少空间,这使得安装比必要的更复杂,一些用户只是选择将所有数据放入一个大分区中,试图避免这个问题。
一旦用户猜测了 /home /usr / 需要多少空间(或者让安装程序来做),通常其中一个分区会填满,即使另一个分区中有大量磁盘空间。
使用逻辑卷管理,整个磁盘将被分配给单个卷组,并创建逻辑卷来保存 / /usr 和 /home 文件系统。例如,如果 /home 逻辑卷后来填满,但 /usr 上仍有可用空间,则可以将 /usr 缩小几兆字节,并将该空间重新分配给 /home。
另一种方法是为每个逻辑卷分配最少的空间,并保留一些未分配的磁盘空间。 然后,当分区开始填满时,可以根据需要扩展它们。
例如:Joe 购买了一台带有 8.4 GB 磁盘的 PC,并使用以下分区系统安装了 Linux
/boot /dev/hda1 10 Megabytes swap /dev/hda2 256 Megabytes / /dev/hda3 2 Gigabytes /home /dev/hda4 6 Gigabytes |
稍后,Joe 决定安装最新的办公套件和桌面 UI,但他意识到根分区不够大。 但是,在将所有 MP3 归档到新的可写 DVD 驱动器后,/home 上有足够的空间。
他的选择不好
重新格式化磁盘,更改分区方案并重新安装。
购买新磁盘,并找出一些新的分区方案,这将需要最少的数据移动。
在 / 上设置一个符号链接农场,指向 /home,并将新软件安装在 /home 上
使用 LVM 这变得容易得多
Jane 购买了一台类似的 PC,但使用 LVM 以类似的方式划分磁盘
/boot /dev/hda1 10 Megabytes swap /dev/vg00/swap 256 Megabytes / /dev/vg00/root 2 Gigabytes /home /dev/vg00/home 6 Gigabytes |
![]() | 引导程序不包含在 LV 上,因为引导加载程序还不理解 LVM 卷。 在 LVM 上引导是可行的,但您有启动不了系统的风险。 |
![]() | LVM 上的根目录应仅供高级用户使用 |
---|---|
LVM 上的根目录需要一个激活根 LV 的 initrd 镜像。 如果内核在没有构建必要的 initrd 镜像的情况下升级,则该内核将无法启动。 较新的发行版在其 mkinitrd 脚本以及打包的 initrd 镜像中支持 lvm,因此这个问题随着时间的推移变得越来越少。 |
当她遇到类似的问题时,她可以将 /home 的大小减少 1 GB,并将该空间添加到根分区。
假设 Joe 和 Jane 随后也设法填满了 /home 分区,并决定向他们的系统添加一个 20 GB 的新磁盘。
Joe 将整个磁盘格式化为一个分区 (/dev/hdb1),并将他现有的 /home 数据移动到该分区上,并将新磁盘用作 /home。 但是他有 6 GB 未使用,或者必须使用符号链接使该磁盘显示为 /home 的扩展,例如 /home/joe/old-mp3s。
Jane 只是将新磁盘添加到她现有的卷组,并扩展她的 /home 逻辑卷以包含新磁盘。 或者,实际上,她可以将数据从旧磁盘上的 /home 移动到新磁盘,然后扩展现有的根卷以覆盖旧磁盘的所有内容。
逻辑卷管理的好处在具有许多磁盘驱动器的大型系统上更为明显。
管理大型磁盘阵列是一项耗时的工作,如果系统包含许多不同大小的磁盘,则尤其复杂。 平衡各个用户(通常是冲突的)存储需求可能是一场噩梦。
用户组可以分配给卷组和逻辑卷,这些卷组和逻辑卷可以根据需要进行扩展。 系统管理员可以“保留”磁盘存储,直到需要为止。 然后,可以将其添加到具有最紧迫需求的卷(用户)组。
当新驱动器添加到系统时,不再需要移动用户文件以充分利用新存储; 只需将新磁盘添加到现有卷组或多个卷组,并根据需要扩展逻辑卷即可。
通过将数据从旧驱动器移动到较新的驱动器,也很容易将旧驱动器停止使用 - 这可以在线完成,而不会中断用户服务。
此图概述了 LVM 系统中的主要元素
+-- Volume Group --------------------------------+ | | | +----------------------------------------+ | | PV | PE | PE | PE | PE | PE | PE | PE | PE | | | +----------------------------------------+ | | . . . . | | . . . . | | +----------------------------------------+ | | LV | LE | LE | LE | LE | LE | LE | LE | LE | | | +----------------------------------------+ | | . . . . | | . . . . | | +----------------------------------------+ | | PV | PE | PE | PE | PE | PE | PE | PE | PE | | | +----------------------------------------+ | | | +------------------------------------------------+ |
另一种看待它的方式是这样(由来自 linux-lvm 邮件列表的 Erik B�gfors 提供)
hda1 hdc1 (PV:s on partitions or whole disks) \ / \ / diskvg (VG) / | \ / | \ usrlv rootlv varlv (LV:s) | | | ext2 reiserfs xfs (filesystems) |
一个具体的例子会有帮助
假设我们有一个名为 VG1 的卷组,该卷组的物理扩展大小为 4MB。 在此卷组中,我们引入了 2 个硬盘分区,/dev/hda1 和 /dev/hdb1。 这些分区将成为物理卷 PV1 和 PV2(可以在管理员的自由裁量权下给出更有意义的名称)。 由于这是卷组的扩展大小,PV 被划分为 4MB 的块。 磁盘的大小不同,我们在 PV1 中获得 99 个扩展,在 PV2 中获得 248 个扩展。 现在我们可以为自己创建一个逻辑卷,该逻辑卷的大小可以在 1 到 347 (248 + 99) 个扩展之间。 创建逻辑卷时,定义了逻辑扩展和物理扩展之间的映射,例如,逻辑扩展 1 可以映射到 PV1 的物理扩展 51,写入逻辑卷的前 4 MB 的数据实际上将被写入到 PV1 的第 51 个扩展。
管理员可以选择几种将逻辑扩展映射到物理扩展的通用策略
线性映射 将按顺序将一系列 PE 分配给 LV 的一个区域,例如,LE 1 - 99 映射到 PV1,LE 100 - 347 映射到 PV2。
条带化映射 将跨多个物理卷交错逻辑扩展的块,例如,
1st chunk of LE[1] -> PV1[1], 2nd chunk of LE[1] -> PV2[1], 3rd chunk of LE[1] -> PV3[1], 4th chunk of LE[1] -> PV1[2], |
![]() | LVM 1 警告 |
---|---|
使用条带化创建的 LV 无法在 LVM 1 中扩展超过最初创建它们的 PV。 |
LVM 提供的一个奇妙的功能是“快照”。 这允许管理员创建一个新的块设备,该设备呈现逻辑卷的精确副本,冻结在某个时间点。 通常,当需要在逻辑卷上执行一些批处理(例如备份)时,会使用此功能,但您不想停止正在更改数据的实时系统。 完成快照设备后,系统管理员只需删除该设备。 此功能确实要求在逻辑卷上的数据处于一致状态时创建快照 - 用于 LVM1 的 VFS 锁补丁确保某些文件系统在创建快照时自动执行此操作,并且 2.6 内核中的许多文件系统在创建快照时自动执行此操作,而无需修补。
![]() | 完整的快照会自动禁用 |
---|---|
如果快照逻辑卷已满,它将被丢弃(变得不可用),因此分配足够的空间至关重要。 所需的空间量取决于快照的使用情况,因此没有固定的规则可以遵循。 如果快照大小等于原始大小,则永远不会溢出。 |
LVM1 具有只读快照。 只读快照的工作方式是创建一个异常表,该表用于跟踪已更改的块。 如果要更改原始卷上的块,则首先将其复制到快照,在异常表中标记为已复制,然后将新数据写入原始卷。
在 LVM2 中,默认情况下快照是读/写的。 读/写快照的工作方式类似于只读快照,但增加了一个额外功能,即如果将数据写入快照,则该块将在异常表中标记为已使用,并且永远不会从原始卷复制。 这开辟了许多使用 LVM1 的只读快照不可能实现的新可能性。 一个示例是快照一个卷,挂载该快照,并尝试一个实验程序,该程序会更改该卷上的文件。 如果您不喜欢它所做的,您可以卸载快照,删除它,并将原始文件系统挂载到其位置。 它也可用于创建与 Xen 一起使用的卷。 您可以创建一个磁盘镜像,然后对其进行快照并修改该快照以用于特定的 domU 实例。 然后,您可以创建原始卷的另一个快照,并修改该快照以用于不同的 domU 实例。 由于快照使用的唯一存储是原始卷或快照上已更改的块,因此大部分卷由 domU 共享。
![]() | 使用当前的 LVM2/device-mapper 代码,可以扩展原始卷,但不能缩小原始卷。 使用 LVM1,您无法调整原始卷的大小。 |
![]() | LVM 1 -> LVM 2 升级信息 |
---|---|
在从 LVM 1 升级到 LVM 2 之前,请务必移除快照 LV。(参见第 4.1 节) |
这是快速入门说明:)
首先移除系统上的所有快照 LV。LVM 2 不会处理这些快照 LV,并且会阻止在 LVM 2 启动时激活源。
确保你有除了标准启动分区之外的其他方式来启动系统。在上面准备好 LVM 1 工具、标准系统工具 (mount) 和 LVM 1 兼容的内核,以防你需要返回并修复一些问题。
获取 LVM 2 工具源代码和设备映射器源代码并编译它们。在使用 LVM 2 工具进行编译之前,你需要使用 "make install" 安装设备映射器库。还要将 dm/scripts/devmap_mknod.sh 脚本复制到 /sbin 中。我建议目前只安装 'lvm' 二进制文件,这样如果需要,你就可以访问 LVM 1 工具。如果你可以访问 LVM 2 和设备映射器的软件包,你可以安装它们,但请注意它们可能会覆盖你的 LVM 1 工具集。
获取一个设备映射器兼容的内核,无论是内置的还是作为内核模块。
找出 LVM 1 在你的启动脚本中激活的位置。确保设备映射器模块在该点之前已加载(如果你使用设备映射器作为模块),并在之后添加 '/sbin/devmap_mknod.sh; lvm vgscan; lvm vgchange -ay'。
安装带有设备映射器支持的内核。重启。如果一切顺利,你应该在运行 lvm2。
不需要。你需要设备映射器。lvm2 工具使用设备映射器与内核接口并进行所有设备映射(因此称为设备映射器)。只要你有设备映射器,你应该就可以使用 LVM2。
主要原因是重新启动到支持 dm 的内核后,没有运行 "dmsetup mknodes"。此脚本会生成设备映射器的控制节点。
如果你没有 "dmsetup mknodes",请不要绝望!(虽然你可能应该升级到最新版本的设备映射器。)自己创建/dev/mapper/control文件很容易
确保你已加载设备映射器模块(如果你没有将其构建到你的内核中)。
运行
# cat /proc/misc | grep device-mapper | awk '{print $1}' |
运行
# mkdir /dev/mapper |
运行
# mknod /dev/mapper/control c 10 $number |
如果你使用的是来自 lvm2 tarball 的稳定 2.4 设备映射器补丁,则使用 lvm2 工具支持你使用 lvm1 期望的所有主要功能。(你仍然需要先移除快照,然后才能从 lvm1 升级到 lvm2)
如果你使用的是 2.6 kernel.org 内核系列中的设备映射器版本,则不支持以下命令和 LV 类型
pvmove
快照
是的。LVM 2 使用 lvm 2 格式的元数据。此格式比 LVM 1 格式的元数据灵活得多,从而消除或减少了 LVM 1 的大多数限制。
是的。LVM 2 将激活并操作使用 LVM 1 创建的 VG 和 LV。此例外情况是使用 LVM 1 创建的快照 - 应在升级之前将其删除。升级后保留的快照必须先删除,然后才能由 LVM 2 激活其源。
是的。使用 vgconvert 将你的 VG 和其中包含的所有 LV 转换为新的 lvm 2 格式元数据。请注意,并不总是可以恢复到 lvm 1 格式的元数据。
一种可能的原因是某些版本的 LVM 1(最初报告此错误的用戶使用的是 Mandrake 9.2,但并不一定仅限于该发行版)没有按预期将 UUID 放入 PV 和 VG 结构中。最新版本的 LVM 2 工具会自动为结构填充 UUID,如果它们发现 UUID 丢失,因此你应该获取一个更新的版本,你的问题应该得到解决。如果不是,请发布到 linux-lvm 邮件列表
在 LVM 上安装根目录时,升级到 LVM 2 有点棘手,但并非不可能。你需要排队一个支持设备映射器的内核,并安装 lvm2 工具(你可能想要备份 lvm 1 工具,或者找到一个内置了 lvm 工具的救援磁盘,以防你在完成之前需要它们)。然后找到一个 mkinitrd 脚本,该脚本支持你的发行版和 lvm 2。
目前,这是我知道支持 lvm2 的 mkinitrd 脚本的列表,按发行版排序
没问题 - LVM 通过 UUID 而不是设备名称来识别 PV。
每个磁盘 (PV) 都标记有一个 UUID,该 UUID 唯一地标识它到系统。“vgscan”在添加更改你的驱动器编号的新磁盘后会识别这一点。大多数发行版在 lvm 启动脚本中运行 vgscan,以便在添加硬件后重新启动时处理此问题。如果你正在进行热添加,我认为你必须手动运行它。另一方面,如果你的 vg 已激活并正在使用,则重新编号根本不会影响它。只有激活需要标识符,最坏的情况是在没有 vgscan 的情况下激活将失败,并提示缺少 PV。
![]() | LVM 当前正在使用的驱动器的故障或移除将导致当前使用以及将来激活使用它的 VG 时出现问题。 |
4.1.11. 我正在尝试填满我的 vg,并且 vgdisplay/vgs 显示我有 1.87 GB 的可用空间,但是当我执行 lvcreate vg -L1.87G 时,它说“insufficient free extends”。这是怎么回事?
1.87 GB 的数字四舍五入到小数点后 2 位,因此它可能是 1.866 GB 或其他值。这是一个人类可读的输出,可以让你大致了解 VG 的大小。如果你想指定一个确切的大小,你必须使用盘区而不是字节的倍数。
对于 vgdisplay,请使用空闲 PE 计数而不是人类可读的容量。
Free PE / Size 478 / 1.87 GB ^^^ |
# lvcreate vg -l478 |
对于 vgs,你需要指示它告诉你可用多少个盘区
# vgs -o +vg_free_count,vg_extent_count |
在LVM2中,快照默认是可读写的,而在LVM1中,快照是只读的。更多细节请参考第3.8节。
您需要做的第一件事是获取LVM的副本。
通过FTP下载LVM的tarball压缩包。
通过CVS下载正在积极开发中的源代码
注意: CVS 仓库中的代码状态波动很大。它可能包含错误。 也许是会导致 LVM 或内核崩溃的错误。 它甚至可能无法编译。 将其视为 alpha 质量的代码。 你可能会丢失数据。 已警告过您。
要跟踪 LVM 的开发进度,请订阅 LVM 邮件列表 linux-lvm 和相应的提交列表(请参见 第 C.1 节)。
要从 CVS 源代码构建 LVM,您必须拥有几个 GNU 工具
CVS 客户端 1.9 或更高版本
GCC 2.95.2
GNU make 3.79
autoconf,版本 2.13 或更高版本
为了将来更容易更新 CVS 树,请创建文件$HOME/.cvsrc并插入以下行。 这为三个最常用的 CVS 命令配置了有用的默认值。 现在就这样做,然后再继续。
diff -u -b -B checkout -P update -d -P |
此外,如果您使用的是慢速网络连接(如拨号连接),则需要添加包含以下内容的行cvs -z5在这个文件中。 这为所有 CVS 命令打开了一个有用的压缩级别。
设备映射器库和工具
构建 LVM 2 需要设备映射器库。
第一次从 cvs 下载时,您必须登录
# cvs -d :pserver:cvs@sources.redhat.com:/cvs/dm login cvs |
密码是 `cvs`。 如果成功,该命令不输出任何内容,如果失败,则输出错误消息。 只需要初始登录。 所有后续 CVS 命令都会读取存储在文件中的密码$HOME/.cvspass用于身份验证。
使用以下命令检出代码的副本
# cvs -d :pserver:cvs@sources.redhat.com:/cvs/dm checkout device-mapper |
这将创建一个新目录device-mapper在您当前目录中,其中包含最新的设备映射器代码。
LVM 2
第一次从 cvs 下载时,您必须登录
# cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 login cvs |
密码是 `cvs`。 如果成功,该命令不输出任何内容,如果失败,则输出错误消息。 只需要初始登录。 所有后续 CVS 命令都会读取存储在文件中的密码$HOME/.cvspass用于身份验证。
使用以下命令检出代码的副本
# cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm2 checkout LVM2 |
这将创建一个新目录LVM2在您当前目录中,其中包含最新的 LVM 2 代码。
LVM 1
第一次从 cvs 下载时,您必须登录
# cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm login cvs |
密码是 `cvs`。 如果成功,该命令不输出任何内容,如果失败,则输出错误消息。 只需要初始登录。 所有后续 CVS 命令都会读取存储在文件中的密码$HOME/.cvspass用于身份验证。
使用以下命令检出代码的副本
# cvs -d :pserver:cvs@sources.redhat.com:/cvs/lvm checkout LVM |
这将创建一个新目录LVM在您当前目录中,其中包含最新的 LVM 1 代码。
CVS 命令从源代码树中的任何地方工作,并向下递归。 因此,如果您恰好从“tools”子目录中发出更新,它将工作正常,但仅更新 tools 目录及其子目录。 在下面的命令示例中,假设您位于源代码树的顶部。
代码更改在 CVS 存储库中相当频繁地进行。 此公告会自动发送到 lvm-commit 列表。
您可以使用 update 命令将您的源代码副本更新为与主存储库匹配。 无需检出新副本。 使用 update 命令明显更快更简单,因为它只会下载补丁而不是整个文件,并且只会更新自上次更新以来已更改的文件。 它还会自动将 CVS 存储库中的任何更改与您所做的任何本地更改合并。 只需 cd 到您想要更新的目录,然后键入以下内容。
# cvs update |
如果您在检出源代码时没有指定标签,这将将您的源代码更新为主要分支上的最新版本。 如果您指定了分支标签,它将更新到该分支上的最新版本。 如果您指定了版本标签,它将不做任何事情。
那么,您是否找到了想要修复的错误? 想要实现 TODO 列表中的功能? 是否有要实现的新功能? 编写代码再简单不过了。 只需编辑您的源代码副本。 无需将文件复制到.orig或任何东西。 CVS 拥有原始文件的副本。
当您的代码处于工作状态并且已尽最大努力使用您拥有的硬件进行测试时,针对 CVS 存储库中的当前源代码生成一个补丁。
# cvs update # cvs diff > patchfile |
将补丁通过邮件发送到 linux-lvm 或 dm-devel 列表(第 C.1 节),并描述您实现的变化或添加。
如果其他人一直在处理与您相同的文件,您可能会发现存在冲突的修改。 当您尝试更新源代码时,您会发现这一点。
# cvs update RCS file: LVM/tools/pvcreate.c,v retrieving revision 1.5 retrieving revision 1.6 Merging differences between 1.5 and 1.6 into pvcreate.c rcsmerge: warning: conflicts during merge cvs server: conflicts found in tools/pvcreate.c C tools/pvcreate.c |
不要惊慌! 您的工作文件,在更新之前存在的文件,保存在文件名下.#pvcreate.c.1.5。 如果出现任何严重错误,您始终可以恢复它。 名为“pvcreate.c”的文件现在包含 旧(即您的)版本和新版本的冲突行。 您只需编辑该文件并通过删除不需要的行版本来解决每个冲突。
<<<<<<< pvcreate.c j++; ======= j--; >>>>>>> 1.6 |
不要忘记删除带有所有``<'', ``='', 和 ``>'' 符号的行。
Device mapper 在 2.6.9 及更高版本中可用,因此您只需确保它已启用为模块或内置于内核中。 查找 /sys/class/misc/device-mapper 或在 /proc/devices 中查找 device-mapper 条目,以查看它是否已启用。 如果两者都不存在,请尝试 modprobe dm_mod,然后再次检查。 对于 2.6.9 之前的版本,您或您的发行版必须修补内核才能支持它。 请查看 device mapper 网页以获取更多信息。
要使用 LVM 1,您必须构建 LVM 1 内核模块(推荐),或者如果您愿意,可以重新构建内核,并将 LVM 1 代码静态链接到其中。
您的 Linux 系统可能基于流行的发行版之一(例如,Red Hat、SuSE、Debian),在这种情况下,您可能已经拥有 LVM 1 模块。 检查您系统上工具的版本。 您可以通过使用“-h”标志运行任何 LVM 命令行工具来执行此操作。 如果您不知道任何命令,请使用 pvscan -h。 如果帮助列表顶部列出的版本号是 LVM 1.0.8,请使用您当前的设置,并避免本节的其余部分。
为了修补 linux 内核以支持 LVM 1.0.8,您必须执行以下操作
解压 LVM 1.0.8
# tar zxf lvm_1.0.8.tar.gz |
进入该版本的根目录。
# cd LVM/1.0.8 |
运行 configure
# ./configure |
您需要传递选项--with-kernel_dir如果您 Linux 内核源代码不在/usr/src/linux中。(运行 ./configure --help 查看所有可用的选项)
进入 PATCHES 目录
# cd PATCHES |
运行 'make'
# make |
您现在应该有一个名为lvm-1.0.8-$KERNELVERSION.patch的补丁在 patches 目录中。 这是本指南后面部分引用的 LVM 内核补丁。
修补内核
# cd /usr/src/linux ; patch -pX < /directory/lvm-1.0.8-$KERNELVERSION.patch |
在开始构建之前,需要修补 2.2 系列内核,请在其他地方查找有关如何修补内核的说明。
补丁
rawio 补丁
Stephen Tweedie 的 raw_io 补丁,可以在 https://linuxkernel.org.cn/pub/linux/kernel/people/sct/raw-io 找到
lvm 补丁
相关的 LVM 1 补丁,应该从 LVM 发行版的 PATCHES 子目录中构建。 更多信息可以在 第 6.2.1 节,为您的内核构建补丁中找到。
正确应用补丁后,您需要确保实际构建了模块,LVM 1 位于内核配置的块设备部分下,您可能还应该请求将 LVM /proc 信息也编译进去。
像往常一样构建内核模块。
2.4 内核已经包含了 LVM 1,尽管您应该在 Sistina 网站上查看更新(例如,v2.4.9 内核及更早版本必须应用 最新的 LVM 1 补丁)。 在配置内核时,在 Multi-device support (RAID and LVM) 下查找 LVM 1。 LVM 1 可以编译到内核中或作为模块。 构建您的内核和模块,然后以通常的方式安装它们。 如果您选择将 LVM 构建为模块,它将被称为lvm-mod.o
如果您想将快照与 ReiserFS 一起使用,请确保应用linux-2.4.x-VFS-lock补丁(在LVM/1.0.8/PATCHES目录中有副本。)
LVM 发行版不提供启动时脚本,但是自己编写这些脚本非常简单。
LVM 的启动只需要以下两个命令
# vgscan # vgchange -ay |
关闭只需要一个命令
# vgchange -an |
根据您正在运行的 Linux 发行版,按照以下说明操作。
需要编辑文件/etc/rc.d/rc.boot。找到包含 "Mounting local filesystems" 的行,并在其之前插入 vgscan 和 vgchange 命令。
您可能还需要编辑文件/etc/rc.d/init.d/halt以在关闭时停用卷组。在此文件末尾附近插入
vgchange -an |
如果您下载 Debian lvm 工具包,则应该为您安装一个 initscript。
如果您从源代码安装 LVM,您仍然需要构建自己的 initscript
在以下位置创建一个启动脚本/etc/init.d/lvm包含以下内容
#!/bin/sh case "$1" in start) /sbin/vgscan /sbin/vgchange -ay ;; stop) /sbin/vgchange -an ;; restart|force-reload) ;; esac exit 0 |
然后执行命令
# chmod 0755 /etc/init.d/lvm # update-rc.d lvm start 26 S . stop 82 1 . |
对于 Redhat 7.0 及更高版本,如果 LVM 构建到内核中,则无需修改任何 initscript 即可在启动时启用 LVM。 如果 LVM 作为模块构建,则可能需要修改/etc/rc.d/rc.sysinit通过在读取以下内容的段落之前添加 "modprobe lvm-mod" 来加载 LVM 模块
# LVM initialization, take 2 (it could be on top of RAID) if [ -e /proc/lvm -a -x /sbin/vgchange -a -f /etc/lvmtab ]; then action $"Setting up Logical Volume Management:" /sbin/vgscan && /sbin/vgchange -a y fi |
![]() | 此 init 脚本片段来自 Red Hat 7.3 - 其他版本的 Redhat 可能略有不同。 |
对于早于 7.0 的 Redhat 版本,需要编辑文件/etc/rc.d/rc.sysinit。找到包含 "Mount all other filesystems" 的行,并在其之前插入 vgscan 和 vgchange 命令。您应确保在运行 LVM 命令之前,根文件系统已挂载为读/写。
您可能还需要编辑文件/etc/rc.d/init.d/halt以在关闭时停用卷组。在此文件末尾附近插入
vgchange -an |
Slackware 8.1 不需要更新启动时脚本即可使 LVM 工作。
对于早于 Slackware 8.1 的版本,您应将以下补丁应用于/etc/rc.d/rc.S
cd /etc/rc.d cp -a rc.S rc.S.old patch -p0 < rc.S.diff |
----- snip snip file: rc.S.diff--------------- --- rc.S.or Tue Jul 17 18:11:20 2001 +++ rc.S Tue Jul 17 17:57:36 2001 @@ -4,6 +4,7 @@ # # Mostly written by: Patrick J. Volkerding, <volkerdi@slackware.com> # +# Added LVM support <tgs@iafrica.com> PATH=/sbin:/usr/sbin:/bin:/usr/bin @@ -28,19 +29,21 @@ READWRITE=yes fi + # Check the integrity of all filesystems if [ ! READWRITE = yes ]; then - /sbin/fsck -A -a + /sbin/fsck -a / + # Check only the root fs first, but no others # If there was a failure, drop into single-user mode. if [ ? -gt 1 ] ; then echo echo - echo "*******************************************************" - echo "*** An error occurred during the file system check. ***" - echo "*** You will now be given a chance to log into the ***" - echo "*** system in single-user mode to fix the problem. ***" - echo "*** Running 'e2fsck -v -y <partition>' might help. ***" - echo "*******************************************************" + echo "************************************************************" + echo "*** An error occurred during the root file system check. ***" + echo "*** You will now be given a chance to log into the ***" + echo "*** system in single-user mode to fix the problem. ***" + echo "*** Running 'e2fsck -v -y <partition>' might help. ***" + echo "************************************************************" echo echo "Once you exit the single-user shell, the system will reboot." echo @@ -82,6 +85,44 @@ echo -n "get into your machine and start looking for the problem. " read junk; fi + # okay / fs is clean, and mounted as rw + # This was an addition, limits vgscan to /proc thus + # speeding up the scan immensely. + /sbin/mount /proc + + # Initialize Logical Volume Manager + /sbin/vgscan + /sbin/vgchange -ay + + /sbin/fsck -A -a -R + #Check all the other filesystem, including the LVM's, excluding / + + # If there was a failure, drop into single-user mode. + if [ ? -gt 1 ] ; then + echo + echo + echo "*******************************************************" + echo "*** An error occurred during the file system check. ***" + echo "*** You will now be given a chance to log into the ***" + echo "*** system in single-user mode to fix the problem. ***" + echo "*** Running 'e2fsck -v -y <partition>' might help. ***" + echo "*** The root filesystem is ok and mounted readwrite ***" + echo "*******************************************************" + echo + echo "Once you exit the single-user shell, the system will reboot." + echo + + PS1="(Repair filesystem) #"; export PS1 + sulogin + + echo "Unmounting file systems." + umount -a -r + mount -n -o remount,ro / + echo "Rebooting system." + sleep 2 + reboot + fi + else echo "Testing filesystem status: read-write filesystem" if cat /etc/fstab | grep ' / ' | grep umsdos 1> /dev/null 2> /dev/null ; then @@ -111,14 +152,16 @@ echo -n "Press ENTER to continue. " read junk; fi + fi + # remove /etc/mtab* so that mount will create it with a root entry /bin/rm -f /etc/mtab* /etc/nologin /etc/shutdownpid # mount file systems in fstab (and create an entry for /) # but not NFS or SMB because TCP/IP is not yet configured -/sbin/mount -a -v -t nonfs,nosmbfs +/sbin/mount -a -v -t nonfs,nosmbfs,proc # Clean up temporary files on the /var volume: /bin/rm -f /var/run/utmp /var/run/*.pid /var/log/setup/tmp/* --snip snip snip end of file--------------- |
对于 initrds,您应该有
dmsetup mknodes vgscan --ignorelockingfailure vgchange -ay --ignorelockingfailure |
从以前版本的 LVM 转换为 LVM 1.0.8 应该相当容易。 我们已经找到了一种方法来读取 PV 版本 1 元数据(LVM 0.9.1 Beta7 及更早版本)以及 PV 版本 2 元数据(LVM 0.9.1 Beta8 和 LVM 1.0)。
警告:使用 LVM 1.0.8 初始化的新 PV 是使用 PV 版本 1 磁盘结构创建的。 这意味着 LVM 0.9.1 Beta8 和 LVM 1.0 无法读取或使用使用 1.0.8 创建的 PV。
转换此设置只需几个简单的步骤,但仍然建议您在尝试之前备份您的数据。 警告已经发出。
构建 LVM 内核和模块
构建 LVM 用户工具
按照 第 9 章中的步骤构建和安装 LVM 的用户工具。
设置您的 init 脚本
确保您已按照 第 7 章设置了正确的 init 脚本。
启动到新内核中
确保您的引导加载程序设置为加载新的 LVM 增强型内核,如果您正在使用 LVM 模块,请将 insmod lvm-mod 放入您的启动脚本中,或者扩展/etc/modules.conf(以前是/etc/conf.modules) 通过添加
alias block-major-58 lvm-mod alias char-major-109 lvm-mod |
重新启动并享受。
如果您仔细按照步骤操作,这相对简单。 建议您有一个良好的备份和一个合适的救援磁盘,以防万一。
运行 LVM 根文件系统的 "正常" 方式是拥有一个称为的单个非 LVM 分区/boot其中包含启动系统所需的内核和初始 RAM 磁盘。 我升级的系统如下
# df Filesystem 1k-blocks Used Available Use% Mounted on /dev/rootvg/root 253871 93384 147380 39% / /dev/hda1 17534 12944 3685 78% /boot /dev/rootvg/home 4128448 4568 3914168 0% /home /dev/rootvg/usr 1032088 332716 646944 34% /usr /dev/rootvg/var 253871 31760 209004 13% /var |
# ls /boot System.map lost+found vmlinux-2.2.16lvm map module-info boot.0300 boot.b os2_d.b chain.b initrd.gz # tail /etc/lilo.conf image=/boot/vmlinux-2.2.16lvm label=lvm08 read-only root=/dev/rootvg/root initrd=/boot/initrd.gz append="ramdisk_size=8192" |
构建 LVM 内核和模块
构建 LVM 用户工具
按照 第 6.2 节中的步骤构建和安装 LVM 的用户工具。
安装新工具。 完成此操作后,您将无法执行任何 LVM 操作,因为它们与您当前正在运行的内核不兼容。
重命名现有的 initrd.gz
这是为了防止它被新的文件覆盖
# mv /boot/initrd.gz /boot/initrd08.gz |
编辑/etc/lilo.conf
使现有的引导条目指向重命名的文件。 如果下一次重启出现问题,您将需要使用它来重启。 更改后的条目将如下所示
image=/boot/vmlinux-2.2.16lvm label=lvm08 read-only root=/dev/rootvg/root initrd=/boot/initrd08.gz append="ramdisk_size=8192" |
运行 lvmcreate_initrd 以创建新的初始 RAM 磁盘
# lvmcreate_initrd 2.4.9 |
在 /etc/lilo.conf 中添加新条目
这个新条目用于启动新的内核及其新的 initrd。
image=/boot/vmlinux-2.4.9lvm label=lvm10 read-only root=/dev/rootvg/root initrd=/boot/initrd.gz append="ramdisk_size=8192" |
重新运行 lilo
这将安装新的引导块
# /sbin/lilo |
重新启动
当您获得 LILO 提示符时,选择新的条目名称(在此示例中为 lvm10),您的系统应该使用新的 LVM 版本启动到 Linux 中。
如果新内核未启动,则只需启动旧内核并尝试解决问题。 可能是新内核没有构建所有正确的设备驱动程序,或者它们在 initrd 中不可用。 请记住,访问根设备所需的所有设备驱动程序(除了 LVM)都应编译到内核中,而不是作为模块。
如果您需要在启动回旧版本后执行任何 LVM 操作,只需重新编译旧工具并使用以下命令安装它们
# make install |
以下各节概述了 LVM 系统的一些常见管理任务。 这不能替代阅读手册页。
在将磁盘或磁盘分区用作物理卷之前,您必须对其进行初始化
对于整个磁盘
在磁盘上运行 pvcreate
# pvcreate /dev/hdb |
![]() | 不建议 |
---|---|
不建议将整个磁盘用作 PV(而不是跨越整个磁盘的分区),因为它会产生管理问题。 任何其他查看磁盘的操作系统都不会识别 LVM 元数据,并将磁盘显示为空闲,因此很可能会被覆盖。 LVM 本身可以很好地与整个磁盘 PV 一起使用。 |
如果您收到一条错误消息,指出 LVM 无法初始化带有分区表的磁盘,请首先确保您正在操作的磁盘是正确的磁盘。 如果您非常确定它是,请运行以下命令
![]() | 危险 |
---|---|
以下命令将销毁正在操作的磁盘上的分区表。 非常确定它是正确的磁盘。 |
# dd if=/dev/zero of=/dev/diskname bs=1k count=1 # blockdev --rereadpt /dev/diskname |
在具有 DOS 分区的 PC 上使用 LVM 1 时,请使用 fdisk 或其他类似程序将分区类型设置为 0x8e。 在 PPC 系统上或使用 LVM 2 时,此步骤是不必要的。
在分区上运行 pvcreate
# pvcreate /dev/hdb1 |
使用 'vgcreate' 程序
# vgcreate my_volume_group /dev/hda1 /dev/hdb1 |
中的符号链接名称/dev。所以以上将是
# vgcreate my_volume_group /dev/ide/host0/bus0/target0/lun0/part1 \ /dev/ide/host0/bus0/target1/lun0/part1 |
如果默认的 32MB 不适合您,您还可以使用此命令通过 '-s' 开关指定范围大小。 此外,您可以对卷可以拥有的物理卷或逻辑卷的数量设置一些限制。
确保卷组中不存在任何逻辑卷,有关如何执行此操作,请参阅后面的章节。
停用卷组
# vgchange -a n my_volume_group |
现在您实际上删除了卷组
# vgremove my_volume_group |
使用 'vgextend' 将初始化的物理卷添加到现有的卷组。
# vgextend my_volume_group /dev/hdc1 ^^^^^^^^^ new physical volume |
通过使用 'pvdisplay' 命令确保物理卷未被任何逻辑卷使用
# pvdisplay /dev/hda1 --- Physical volume --- PV Name /dev/hda1 VG Name myvg PV Size 1.95 GB / NOT usable 4 MB [LVM: 122 KB] PV# 1 PV Status available Allocatable yes (but full) Cur LV 1 PE Size (KByte) 4096 Total PE 499 Free PE 0 Allocated PE 499 PV UUID Sd44tK-9IRw-SrMC-MOkn-76iP-iftz-OVSen7 |
如果物理卷仍在使用中,您将必须使用 pvmove 将数据迁移到另一个物理卷。
然后使用 'vgreduce' 删除物理卷
# vgreduce my_volume_group /dev/hda1 |
要创建一个名为“testlv”的 1500MB 线性 LV 及其块设备特殊文件“/dev/testvg/testlv”
# lvcreate -L1500 -ntestlv testvg |
要创建一个 100 LE 大小的逻辑卷,它有 2 个条带且条带大小为 4 KB。
# lvcreate -i2 -I4 -l100 -nanothertestlv testvg |
如果您想创建一个使用整个 VG 的 LV,请使用 vgdisplay 查找 "Total PE" 大小,然后在运行 lvcreate 时使用它。
# vgdisplay testvg | grep "Total PE" Total PE 10230 # lvcreate -l 10230 testvg -n mylv |
如果你希望从卷组中的特定物理卷分配逻辑卷,请在 lvcreate 命令行末尾指定 PV 或多个 PV。
# lvcreate -L 1500 -ntestlv testvg /dev/sdg |
逻辑卷必须先关闭才能被移除
# umount /dev/myvg/homevol # lvremove /dev/myvg/homevol lvremove -- do you really want to remove "/dev/myvg/homevol"? [y/n]: y lvremove -- doing automatic backup of volume group "myvg" lvremove -- logical volume "/dev/myvg/homevol" successfully removed |
要扩展逻辑卷,只需告诉 lvextend 命令要增加多少大小。你可以指定要将卷增加多少,或者指定你想让卷增长到多大
# lvextend -L12G /dev/myvg/homevol lvextend -- extending logical volume "/dev/myvg/homevol" to 12 GB lvextend -- doing automatic backup of volume group "myvg" lvextend -- logical volume "/dev/myvg/homevol" successfully extended |
# lvextend -L+1G /dev/myvg/homevol lvextend -- extending logical volume "/dev/myvg/homevol" to 13 GB lvextend -- doing automatic backup of volume group "myvg" lvextend -- logical volume "/dev/myvg/homevol" successfully extended |
在扩展逻辑卷后,需要调整文件系统大小以匹配。具体如何操作取决于你使用的文件系统。
默认情况下,大多数文件系统调整大小的工具会将文件系统的大小调整为与底层逻辑卷的大小相同,因此你无需担心为每个命令指定相同的大小。
ext2/ext3
除非你用 ext2online 补丁修补了你的内核,否则必须先卸载文件系统才能调整其大小。(在线调整大小的补丁似乎相当危险,因此请自行承担风险)
# umount /dev/myvg/homevol/dev/myvg/homevol # resize2fs /dev/myvg/homevol # mount /dev/myvg/homevol /home |
如果你没有 e2fsprogs 1.19 或更高版本,你可以从 ext2resize.sourceforge.net 下载 ext2resize 命令并使用它
# umount /dev/myvg/homevol/dev/myvg/homevol # ext2resize /dev/myvg/homevol # mount /dev/myvg/homevol /home |
对于 ext2,有一种更简单的方法。LVM 1 附带了一个名为 e2fsadm 的实用程序,它可以为你执行 lvextend 和 resize2fs(它还可以进行文件系统收缩,请参阅下一节)。
![]() | LVM 2 注意事项 |
---|---|
目前没有适用于 LVM 2 的 e2fsadm 等效项,并且 LVM 1 附带的 e2fsadm 不适用于 LVM 2。 |
# e2fsadm -L+1G /dev/myvg/homevol |
# lvextend -L+1G /dev/myvg/homevol # resize2fs /dev/myvg/homevol |
![]() | 注意 |
---|---|
在运行 e2fsadm 之前,你仍然需要卸载文件系统。 |
reiserfs
Reiserfs 文件系统可以在挂载或卸载时调整大小,这取决于你的喜好
在线
# resize_reiserfs -f /dev/myvg/homevol |
离线
# umount /dev/myvg/homevol # resize_reiserfs /dev/myvg/homevol # mount -treiserfs /dev/myvg/homevol /home |
xfs
XFS 文件系统必须挂载后才能调整大小,并且指定的是挂载点而不是设备名称。
# xfs_growfs /home |
jfs
与 XFS 一样,JFS 文件系统必须挂载后才能调整大小,并且指定的是挂载点而不是设备名称。你需要至少 1.0.21 版本的 jfs-utils 才能执行此操作。
# mount -o remount,resize /home |
![]() | 已知内核 Bug | |
---|---|---|
某些内核版本在此语法上存在问题(已知 2.6.0 存在此问题)。 在这种情况下,你必须以块为单位显式指定文件系统的新大小。 这是非常容易出错的,因为你必须知道文件系统的块大小并根据这些单位计算新大小。 示例:如果要将 JFS 文件系统调整为 4 GB,并且块大小为 4k,则可以编写
|
逻辑卷可以缩小也可以增大。但是,非常重要的是要记住,在缩小卷本身之前,先缩小文件系统或卷中存在的任何内容,否则你可能会丢失数据。
ext2
如果你正在使用带有 ext2 作为文件系统的 LVM 1,那么你可以使用前面提到的 e2fsadm 命令来处理文件系统和卷调整大小,如下所示
# umount /home # e2fsadm -L-1G /dev/myvg/homevol # mount /home |
![]() | LVM 2 注意事项 |
---|---|
目前没有适用于 LVM 2 的 e2fsadm 等效项,并且 LVM 1 附带的 e2fsadm 不适用于 LVM 2。 |
如果你喜欢手动执行此操作,你必须知道卷的新大小(以块为单位),并使用以下命令
# umount /home # resize2fs /dev/myvg/homevol 524288 # lvreduce -L-1G /dev/myvg/homevol # mount /home |
reiserfs
Reiserfs 似乎更喜欢在收缩时卸载
# umount /home # resize_reiserfs -s-1G /dev/myvg/homevol # lvreduce -L-1G /dev/myvg/homevol # mount -treiserfs /dev/myvg/homevol /home |
xfs
没有办法缩小 XFS 文件系统。
jfs
没有办法缩小 JFS 文件系统。
要使磁盘停止使用,必须首先将其所有活动的物理扩展区移动到一个或多个卷组中剩余的磁盘。剩余的 PV 中必须有足够的可用物理扩展区来容纳从旧磁盘复制的扩展区。 更多详情请参见 第 13.5 节。
LVM 允许你从几乎任何块设备创建 PV(物理卷),因此,例如,以下都是有效的命令,并且可以在 LVM 环境中正常工作
# pvcreate /dev/sda1 # pvcreate /dev/sdf # pvcreate /dev/hda8 # pvcreate /dev/hda6 # pvcreate /dev/md1 |
在“正常”生产系统中,建议一个真实磁盘上仅存在一个 PV,原因如下
管理方便
如果每个真实磁盘仅出现一次,则更容易跟踪系统中的硬件。如果磁盘发生故障,尤其如此。
避免条带化性能问题
LVM 无法分辨两个 PV 是否在同一物理磁盘上,因此,如果你创建一个条带化 LV,则条带可能位于同一磁盘上的不同分区上,从而导致性能降低而不是提高。
将现有系统迁移到 LVM
在磁盘数量较少的系统上,可能需要移动分区上的数据以进行转换(请参阅 第 13.8 节)
在卷组之间分割一个大磁盘
如果你有一个非常大的磁盘,并且出于管理目的想要拥有多个卷组,则必须将驱动器划分为多个区域。
如果你确实有一个磁盘,其中包含多个分区,并且这两个分区都位于同一卷组中,请注意在创建条带化卷时指定哪些分区包含在逻辑卷中。
分区磁盘的推荐方法是创建一个覆盖整个磁盘的单个分区。这样可以避免任何与整个磁盘驱动器设备节点有关的糟糕事故,并防止内核在启动时发出有关未知分区类型的警告。
本节详细介绍了设置 lvm 的几种不同的“示例”。 希望读者能够根据自己的系统和需求调整这些示例。
对于此示例,设置有三个 SCSI 磁盘,它们将使用 LVM 放入一个逻辑卷中。 这些磁盘位于 /dev/sda、/dev/sdb 和 /dev/sdc。
在卷组中使用磁盘之前,你必须对其进行准备
![]() | 警告! |
---|---|
以下操作将销毁 /dev/sda、/dev/sdb 和 /dev/sdc 上的所有数据 |
在磁盘上运行 pvcreate
# pvcreate /dev/sda # pvcreate /dev/sdb # pvcreate /dev/sdc |
创建一个卷组
# vgcreate my_volume_group /dev/sda /dev/sdb /dev/sdc/ |
运行 vgdisplay 以验证卷组
# vgdisplay # vgdisplay --- Volume Group --- VG Name my_volume_group VG Access read/write VG Status available/resizable VG # 1 MAX LV 256 Cur LV 0 Open LV 0 MAX LV Size 255.99 GB Max PV 256 Cur PV 3 Act PV 3 VG Size 1.45 GB PE Size 4 MB Total PE 372 Alloc PE / Size 0 / 0 Free PE / Size 372/ 1.45 GB VG UUID nP2PY5-5TOS-hLx0-FDu0-2a6N-f37x-0BME0Y |
如果卷组看起来正确,那么就可以在卷组之上创建一个逻辑卷了。
你可以根据自己的喜好设置逻辑卷的任何大小。(它类似于非 LVM 设置上的分区。)对于此示例,我们将在卷组上创建一个大小仅为 1GB 的单个逻辑卷。我们将不使用条带化,因为在创建逻辑卷后,当前无法向条带集添加磁盘。
# lvcreate -L1G -nmy_logical_volume my_volume_group lvcreate -- doing automatic backup of "my_volume_group" lvcreate -- logical volume "/dev/my_volume_group/my_logical_volume" successfully created |
在逻辑卷上创建 ext2 文件系统
# mke2fs /dev/my_volume_group/my_logical_volume mke2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09 Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) 131072 inodes, 262144 blocks 13107 blocks (5.00%) reserved for the super user First data block=0 9 block groups 32768 blocks per group, 32768 fragments per group 16384 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Writing inode tables: done Writing superblocks and filesystem accounting information: done |
对于此示例,设置有三个 SCSI 磁盘,它们将使用 LVM 放入一个逻辑卷中。 这些磁盘位于 /dev/sda、/dev/sdb 和 /dev/sdc。
![]() | 注意 |
---|---|
目前无法在 LVM 1 中向条带化逻辑卷添加磁盘。 如果你希望能够这样做,请使用带有 lvm 2 格式元数据的 LVM 2。 |
在卷组中使用磁盘之前,你必须对其进行准备
![]() | 警告! |
---|---|
以下操作将销毁 /dev/sda、/dev/sdb 和 /dev/sdc 上的所有数据 |
在磁盘上运行 pvcreate
# pvcreate /dev/sda # pvcreate /dev/sdb # pvcreate /dev/sdc |
创建一个卷组
# vgcreate my_volume_group /dev/sda /dev/sdb /dev/sdc |
运行 vgdisplay 以验证卷组
# vgdisplay --- Volume Group --- VG Name my_volume_group VG Access read/write VG Status available/resizable VG # 1 MAX LV 256 Cur LV 0 Open LV 0 MAX LV Size 255.99 GB Max PV 256 Cur PV 3 Act PV 3 VG Size 1.45 GB PE Size 4 MB Total PE 372 Alloc PE / Size 0 / 0 Free PE / Size 372/ 1.45 GB VG UUID nP2PY5-5TOS-hLx0-FDu0-2a6N-f37x-0BME0Y |
如果卷组看起来正确,那么就可以在卷组之上创建一个逻辑卷了。
你可以根据自己的喜好设置逻辑卷的任何大小(最大为你在其上创建的 VG 的大小; 它类似于非 LVM 设置上的分区)。 对于此示例,我们将在卷组上创建一个大小仅为 1GB 的单个逻辑卷。 逻辑卷将是一个条带化集,使用 4k 条带大小。 这应该会提高逻辑卷的性能。
# lvcreate -i3 -I4 -L1G -nmy_logical_volume my_volume_group lvcreate -- rounding 1048576 KB to stripe boundary size 1056768 KB / 258 PE lvcreate -- doing automatic backup of "my_volume_group" lvcreate -- logical volume "/dev/my_volume_group/my_logical_volume" successfully created |
![]() | 注意 |
---|---|
如果你使用 '-i2' 创建逻辑卷,那么你将仅使用卷组中的两个磁盘。 如果你想从同一物理卷创建两个逻辑卷,这将很有用,但是我们不会在本示例中涉及。 |
在逻辑卷上创建 ext2 文件系统
# mke2fs /dev/my_volume_group/my_logical_volume mke2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09 Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) 132192 inodes, 264192 blocks 13209 blocks (5.00%) reserved for the super user First data block=0 9 block groups 32768 blocks per group, 32768 fragments per group 14688 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Writing inode tables: done Writing superblocks and filesystem accounting information: done |
数据中心机器有 6 个磁盘连接如下
# pvscan pvscan -- ACTIVE PV "/dev/sda" of VG "dev" [1.95 GB / 0 free] pvscan -- ACTIVE PV "/dev/sdb" of VG "sales" [1.95 GB / 0 free] pvscan -- ACTIVE PV "/dev/sdc" of VG "ops" [1.95 GB / 44 MB free] pvscan -- ACTIVE PV "/dev/sdd" of VG "dev" [1.95 GB / 0 free] pvscan -- ACTIVE PV "/dev/sde1" of VG "ops" [996 MB / 52 MB free] pvscan -- ACTIVE PV "/dev/sde2" of VG "sales" [996 MB / 944 MB free] pvscan -- ACTIVE PV "/dev/sdf1" of VG "ops" [996 MB / 0 free] pvscan -- ACTIVE PV "/dev/sdf2" of VG "dev" [996 MB / 72 MB free] pvscan -- total: 8 [11.72 GB] / in use: 8 [11.72 GB] / in no VG: 0 [0] # df Filesystem 1k-blocks Used Available Use% Mounted on /dev/dev/cvs 1342492 516468 757828 41% /mnt/dev/cvs /dev/dev/users 2064208 2060036 4172 100% /mnt/dev/users /dev/dev/build 1548144 1023041 525103 66% /mnt/dev/build /dev/ops/databases 2890692 2302417 588275 79% /mnt/ops/databases /dev/sales/users 2064208 871214 1192994 42% /mnt/sales/users /dev/ops/batch 1032088 897122 134966 86% /mnt/ops/batch |
新磁盘将在 ops 和 dev 之间平均共享,因此将其分区为两个物理卷 /dev/sdg1 和 /dev/sdg2
# fdisk /dev/sdg Device contains neither a valid DOS partition table, nor Sun or SGI disklabel Building a new DOS disklabel. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won't be recoverable. Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-1000, default 1): Using default value 1 Last cylinder or +size or +sizeM or +sizeK (1-1000, default 1000): 500 Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First cylinder (501-1000, default 501): Using default value 501 Last cylinder or +size or +sizeM or +sizeK (501-1000, default 1000): Using default value 1000 Command (m for help): t Partition number (1-4): 1 Hex code (type L to list codes): 8e Changed system type of partition 1 to 8e (Unknown) Command (m for help): t Partition number (1-4): 2 Hex code (type L to list codes): 8e Changed system type of partition 2 to 8e (Unknown) Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. WARNING: If you have created or modified any DOS 6.x partitions, please see the fdisk manual page for additional information. |
接下来,在此分区上创建物理卷
# pvcreate /dev/sdg1 pvcreate -- physical volume "/dev/sdg1" successfully created # pvcreate /dev/sdg2 pvcreate -- physical volume "/dev/sdg2" successfully created |
然后将卷添加到 dev 和 ops 卷组
# vgextend ops /dev/sdg1 vgextend -- INFO: maximum logical volume size is 255.99 Gigabyte vgextend -- doing automatic backup of volume group "ops" vgextend -- volume group "ops" successfully extended # vgextend dev /dev/sdg2 vgextend -- INFO: maximum logical volume size is 255.99 Gigabyte vgextend -- doing automatic backup of volume group "dev" vgextend -- volume group "dev" successfully extended # pvscan pvscan -- reading all physical volumes (this may take a while...) pvscan -- ACTIVE PV "/dev/sda" of VG "dev" [1.95 GB / 0 free] pvscan -- ACTIVE PV "/dev/sdb" of VG "sales" [1.95 GB / 0 free] pvscan -- ACTIVE PV "/dev/sdc" of VG "ops" [1.95 GB / 44 MB free] pvscan -- ACTIVE PV "/dev/sdd" of VG "dev" [1.95 GB / 0 free] pvscan -- ACTIVE PV "/dev/sde1" of VG "ops" [996 MB / 52 MB free] pvscan -- ACTIVE PV "/dev/sde2" of VG "sales" [996 MB / 944 MB free] pvscan -- ACTIVE PV "/dev/sdf1" of VG "ops" [996 MB / 0 free] pvscan -- ACTIVE PV "/dev/sdf2" of VG "dev" [996 MB / 72 MB free] pvscan -- ACTIVE PV "/dev/sdg1" of VG "ops" [996 MB / 996 MB free] pvscan -- ACTIVE PV "/dev/sdg2" of VG "dev" [996 MB / 996 MB free] pvscan -- total: 10 [13.67 GB] / in use: 10 [13.67 GB] / in no VG: 0 [0] |
接下来要做的是扩展文件系统,以便用户可以利用额外的空间。
有一些工具允许在线调整 ext2 文件系统的大小,但在这里我们采取更安全的方法,在调整大小之前卸载这两个文件系统。
# umount /mnt/ops/batch # umount /mnt/dev/users |
然后,我们使用 e2fsadm 命令在一个操作中调整逻辑卷和 ext2 文件系统的大小。我们使用 ext2resize 代替 resize2fs(这是 e2fsadm 的默认命令),因此我们定义环境变量 E2FSADM_RESIZE_CMD 来告诉 e2fsadm 使用该命令。
# export E2FSADM_RESIZE_CMD=ext2resize # e2fsadm /dev/ops/batch -L+500M e2fsck 1.18, 11-Nov-1999 for EXT2 FS 0.5b, 95/08/09 Pass 1: Checking inodes, blocks, and sizes Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information /dev/ops/batch: 11/131072 files (0.0<!-- non-contiguous), 4127/262144 blocks lvextend -- extending logical volume "/dev/ops/batch" to 1.49 GB lvextend -- doing automatic backup of volume group "ops" lvextend -- logical volume "/dev/ops/batch" successfully extended ext2resize v1.1.15 - 2000/08/08 for EXT2FS 0.5b e2fsadm -- ext2fs in logical volume "/dev/ops/batch" successfully extended to 1.49 GB # e2fsadm /dev/dev/users -L+900M e2fsck 1.18, 11-Nov-1999 for EXT2 FS 0.5b, 95/08/09 Pass 1: Checking inodes, blocks, and sizes Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information /dev/dev/users: 12/262144 files (0.0% non-contiguous), 275245/524288 blocks lvextend -- extending logical volume "/dev/dev/users" to 2.88 GB lvextend -- doing automatic backup of volume group "dev" lvextend -- logical volume "/dev/dev/users" successfully extended ext2resize v1.1.15 - 2000/08/08 for EXT2FS 0.5b e2fsadm -- ext2fs in logical volume "/dev/dev/users" successfully extended to 2.88 GB |
现在我们可以重新挂载文件系统,并看到有足够的空间。
# mount /dev/ops/batch # mount /dev/dev/users # df Filesystem 1k-blocks Used Available Use% Mounted on /dev/dev/cvs 1342492 516468 757828 41% /mnt/dev/cvs /dev/dev/users 2969360 2060036 909324 69% /mnt/dev/users /dev/dev/build 1548144 1023041 525103 66% /mnt/dev/build /dev/ops/databases 2890692 2302417 588275 79% /mnt/ops/databases /dev/sales/users 2064208 871214 1192994 42% /mnt/sales/users /dev/ops/batch 1535856 897122 638734 58% /mnt/ops/batch |
在前面的示例的基础上,我们现在希望利用 "ops" 卷组中的额外空间,每天晚上进行数据库备份。为了确保写入磁带的数据是一致的,我们使用 LVM 快照逻辑卷。
快照卷是一种特殊类型的卷,它呈现创建快照时卷中的所有数据。有关更详细的描述,请参阅第 3.8 节,快照。这意味着我们可以备份该卷,而不必担心备份进行时数据被更改,而且我们不必在备份期间使数据库卷脱机。
![]() | 在 LVM1 中,这种类型的卷是只读的,但 LVM2 默认创建读/写快照。 |
"ops" 卷组中还有 500 多兆字节的可用空间,因此我们将使用所有可用空间来为快照逻辑卷分配空间。快照卷可以根据需要设置大小,但它必须足够大,才能容纳快照生命周期内可能对原始卷发生的所有更改。因此,在这里,允许数据库卷进行 500 兆字节的更改应该足够了。
# lvcreate -L592M -s -n dbbackup /dev/ops/databases lvcreate -- WARNING: the snapshot must be disabled if it gets full lvcreate -- INFO: using default snapshot chunk size of 64 KB for "/dev/ops/dbbackup" lvcreate -- doing automatic backup of "ops" lvcreate -- logical volume "/dev/ops/dbbackup" successfully created |
![]() | 完整的快照会自动禁用 |
---|---|
如果快照逻辑卷已满,它将被丢弃(变得不可用),因此分配足够的空间至关重要。 所需的空间量取决于快照的使用情况,因此没有固定的规则可以遵循。 如果快照大小等于原始大小,则永远不会溢出。 |
我们现在可以创建一个挂载点并挂载卷
# mkdir /mnt/ops/dbbackup # mount /dev/ops/dbbackup /mnt/ops/dbbackup mount: block device /dev/ops/dbbackup is write-protected, mounting read-only |
如果使用 XFS 作为文件系统,则需要添加nouuid选项到 mount 命令
# mount /dev/ops/dbbackup /mnt/ops/dbbackup -onouuid,ro |
我想您会有一个比这更复杂的备份策略!
# tar -cf /dev/rmt0 /mnt/ops/dbbackup tar: Removing leading `/' from member names |
备份完成后,您现在可以卸载卷并将其从系统中移除。 完成后,应删除快照卷,因为它们会复制写入原始卷的所有数据,这可能会影响性能。
# umount /mnt/ops/dbbackup # lvremove /dev/ops/dbbackup lvremove -- do you really want to remove "/dev/ops/dbbackup"? [y/n]: y lvremove -- doing automatic backup of volume group "ops" lvremove -- logical volume "/dev/ops/dbbackup" successfully removed |
假设您在 /dev/hdb 上有一个旧 IDE 驱动器。 您想要移除该旧磁盘,但上面有很多文件。
![]() | 备份您的系统 |
---|---|
在尝试 pvmove 操作之前,应始终备份系统。 |
如果在卷组中的其他磁盘上有足够的可用区段,则很容易。 只需运行
# pvmove /dev/hdb pvmove -- moving physical extents in active volume group "dev" pvmove -- WARNING: moving of active logical volumes may cause data loss! pvmove -- do you want to continue? [y/n] y pvmove -- 249 extents of physical volume "/dev/hdb" successfully moved |
![]() | pvmove 很慢 |
---|---|
请注意,pvmove 相当慢,因为它必须逐块地将磁盘的内容复制到一个或多个磁盘。 如果您想要从 pvmove 获得更稳定的状态报告,请使用-v标志。 |
如果没有足够的可用物理区段来分配旧的物理区段,则必须将磁盘添加到卷组并将区段移动到其中。
首先,您需要 pvcreate 新磁盘,使其可用于 LVM。 在此示例中,我们显示您不需要对磁盘进行分区即可使用它。
# pvcreate /dev/sdf pvcreate -- physical volume "/dev/sdf" successfully created |
由于开发人员使用大量的磁盘空间,因此这是一个将其添加到其中的好卷组。
# vgextend dev /dev/sdf vgextend -- INFO: maximum logical volume size is 255.99 Gigabyte vgextend -- doing automatic backup of volume group "dev" vgextend -- volume group "dev" successfully extended |
接下来,我们将数据从旧磁盘移动到新磁盘。 请注意,在执行此操作之前,无需卸载文件系统。 虽然 *强烈* 建议您在尝试此操作之前进行完整备份,以防发生电源中断或可能中断它的其他问题。 pvmove 命令可能需要相当长的时间才能完成,并且还会对两个卷产生性能影响,因此,虽然不是必需的,但建议在卷不太忙时执行此操作。
# pvmove /dev/hdb /dev/sdf pvmove -- moving physical extents in active volume group "dev" pvmove -- WARNING: moving of active logical volumes may cause data loss! pvmove -- do you want to continue? [y/n] y pvmove -- 249 extents of physical volume "/dev/hdb" successfully moved |
如果用户部门获得了新的服务器,则将整个卷组移动到另一个系统非常容易。 为此,我们使用 vgexport 和 vgimport 命令。
![]() | vgexport/vgimport 不是将驱动器从一个系统移动到另一个系统所必需的。 它是一种管理策略工具,用于防止在移动卷所需的时间内访问卷。 |
将卷组标记为非活动会将其从内核中移除,并阻止对其进行任何进一步的活动。
# vgchange -an design vgchange -- volume group "design" successfully deactivated |
现在必须导出卷组。 这可以防止在“旧”主机系统上访问它,并准备将其移除。
# vgexport design vgexport -- volume group "design" successfully exported |
插入新系统后,它变为 /dev/sdb,因此初始 pvscan 显示
# pvscan pvscan -- reading all physical volumes (this may take a while...) pvscan -- inactive PV "/dev/sdb1" is in EXPORTED VG "design" [996 MB / 996 MB free] pvscan -- inactive PV "/dev/sdb2" is in EXPORTED VG "design" [996 MB / 244 MB free] pvscan -- total: 2 [1.95 GB] / in use: 2 [1.95 GB] / in no VG: 0 [0] |
如果您在 LVM 2 系统上进行导入,请运行
# vgimport design Volume group "vg" successfully imported |
如果您在 LVM 1 系统上进行导入,请添加需要导入的 PV
# vgimport design /dev/sdb1 /dev/sdb2 vgimport -- doing automatic backup of volume group "design" vgimport -- volume group "design" successfully imported and activated |
有一个新的用户组“design”要添加到系统中。 处理此问题的一种方法是创建一个新的卷组来保存他们的数据。 没有新的磁盘,但现有磁盘上有足够的可用空间可以重新分配。
# pvscan pvscan -- reading all physical volumes (this may take a while...) pvscan -- ACTIVE PV "/dev/sda" of VG "dev" [1.95 GB / 0 free] pvscan -- ACTIVE PV "/dev/sdb" of VG "sales" [1.95 GB / 1.27 GB free] pvscan -- ACTIVE PV "/dev/sdc" of VG "ops" [1.95 GB / 564 MB free] pvscan -- ACTIVE PV "/dev/sdd" of VG "dev" [1.95 GB / 0 free] pvscan -- ACTIVE PV "/dev/sde" of VG "ops" [1.95 GB / 1.9 GB free] pvscan -- ACTIVE PV "/dev/sdf" of VG "dev" [1.95 GB / 1.33 GB free] pvscan -- ACTIVE PV "/dev/sdg1" of VG "ops" [996 MB / 432 MB free] pvscan -- ACTIVE PV "/dev/sdg2" of VG "dev" [996 MB / 632 MB free] pvscan -- total: 8 [13.67 GB] / in use: 8 [13.67 GB] / in no VG: 0 [0] |
所选卷上仍使用一些空间,因此有必要将该已用空间移到其他卷上。
将所有已使用的物理区段从 /dev/sdg1 移动到 /dev/sde,并从 /dev/sdg2 移动到 /dev/sdf
# pvmove /dev/sdg1 /dev/sde pvmove -- moving physical extents in active volume group "ops" pvmove -- WARNING: moving of active logical volumes may cause data loss! pvmove -- do you want to continue? [y/n] y pvmove -- doing automatic backup of volume group "ops" pvmove -- 141 extents of physical volume "/dev/sdg1" successfully moved # pvmove /dev/sdg2 /dev/sdf pvmove -- moving physical extents in active volume group "dev" pvmove -- WARNING: moving of active logical volumes may cause data loss! pvmove -- do you want to continue? [y/n] y pvmove -- doing automatic backup of volume group "dev" pvmove -- 91 extents of physical volume "/dev/sdg2" successfully moved |
现在,从 dev 中拆分 /dev/sdg2 并将其添加到名为“design”的新组中。 可以使用 vgreduce 和 vgcreate 来执行此操作,但 vgsplit 命令将两者结合在一起。
# vgsplit dev design /dev/sdg2 vgsplit -- doing automatic backup of volume group "dev" vgsplit -- doing automatic backup of volume group "design" vgsplit -- volume group "dev" successfully split into "dev" and "design" |
接下来,从 ops 中移除 /dev/sdg1 并将其添加到 design 中。
# vgreduce ops /dev/sdg1 vgreduce -- doing automatic backup of volume group "ops" vgreduce -- volume group "ops" successfully reduced by physical volume: vgreduce -- /dev/sdg1 # vgextend design /dev/sdg1 vgextend -- INFO: maximum logical volume size is 255.99 Gigabyte vgextend -- doing automatic backup of volume group "design" vgextend -- volume group "design" successfully extended |
现在创建一个逻辑卷。 不要分配所有可用空间,留出一些备用空间,以防其他地方需要。
# lvcreate -L750M -n users design lvcreate -- rounding up size to physical extent boundary "752 MB" lvcreate -- doing automatic backup of "design" lvcreate -- logical volume "/dev/design/users" successfully created |
# mke2fs /dev/design/users mke2fs 1.18, 11-Nov-1999 for EXT2 FS 0.5b, 95/08/09 Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) 96384 inodes, 192512 blocks 9625 blocks (5.00<!-- ) reserved for the super user First data block=0 6 block groups 32768 blocks per group, 32768 fragments per group 16064 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840 Writing inode tables: done Writing superblocks and filesystem accounting information: done |
![]() | 备份您的系统 |
---|---|
强烈建议您在尝试在 LVM 1 上转换为 root 之前,对系统进行完整备份。 |
![]() | 升级复杂性 |
---|---|
在 LVM 1 上拥有根文件系统可能会大大增加升级过程的复杂性(取决于您的发行版),因此不应轻易尝试。 特别是,您必须考虑如何在升级之前、期间和之后确保 LVM 1 内核模块(如果您没有将 LVM 1 编译到内核中)以及 vgscan/vgchange 工具可用。 |
![]() | 恢复复杂性 |
---|---|
在 LVM 1 上拥有根文件系统可能会大大增加损坏文件系统的恢复难度。 如果您丢失了 initrd,则很难启动系统。 您需要有一个包含内核、LVM 1 模块和 LVM 1 工具以及恢复损坏文件系统所需的任何工具的恢复磁盘。 请务必定期备份,并拥有最新的替代启动方法,以允许恢复 LVM 1。 |
在此示例中,整个系统都安装在单个根分区中,但 /boot 除外。 该系统有一个 2 GB 的磁盘,分区如下:
/dev/hda1 /boot /dev/hda2 swap /dev/hda3 / |
/ 分区覆盖了 /boot 和 swap 未使用的所有磁盘空间。 此过程的一个重要前提条件是根分区未满一半(以便可以在逻辑卷中创建它的副本)。 如果不是这种情况,则应使用第二个磁盘驱动器。 在这种情况下,该过程类似,但无需缩小现有根分区,并且示例中的 /dev/hda4 应替换为(例如)/dev/hdb1。
为此,最容易使用 GNU parted。 此软件允许您增长和缩小包含文件系统的分区。 可以使用 resize2fs 和 fdisk 来执行此操作,但 GNU parted 使其不易出错。 它可能包含在您的发行版中,如果没有,您可以从 ftp://ftp.gnu.org/pub/gnu/parted 下载它。
一旦你在系统上使用过 parted,并且**备份了系统**
运行 parted 来缩小根分区。 这样做是为了在磁盘上为逻辑卷中的完整副本留出空间。 在本例中,一个 1.8 GB 的分区被缩小到 1 GB。 这会显示磁盘上分区的大小和名称。
# parted /dev/hda (parted) p . . . |
现在调整分区大小
(parted) resize 3 145 999 |
创建一个新分区
(parted) mkpart primary ext2 1000 1999 |
退出 parted
(parted) q |
将新创建的分区上的分区类型从 Linux 更改为 LVM (8e)。 Parted 不理解 LVM 1 分区,因此必须使用 fdisk 来完成此操作。
# fdisk /dev/hda Command (m for help): t Partition number (1-4): 4 Hex code (type L to list codes): 8e Changed system type of partition 4 to 8e (Unknown) Command (m for help): w |
初始化 LVM 1 (vgscan)
# vgscan |
将新分区转换为 PV
# pvcreate /dev/hda4 |
创建一个新的卷组
# vgcreate vg /dev/hda4 |
创建一个逻辑卷来保存新的根目录。
# lvcreate -L250M -n root vg |
在逻辑卷中创建一个文件系统,并将根文件复制到其中。
# mke2fs /dev/vg/root # mount /dev/vg/root /mnt/ # find / -xdev | cpio -pvmd /mnt |
在新根目录下编辑 /mnt/etc/fstab,以便将 / 挂载到 /dev/vg/root。 例如
/dev/hda3 / ext2 defaults 1 1 |
/dev/vg/root / ext2 defaults 1 1 |
在 /etc/lilo.conf 中为 LVM 1 添加一个条目。 它应该类似于以下内容
image = /boot/KERNEL_IMAGE_NAME label = lvm root = /dev/vg/root initrd = /boot/INITRD_IMAGE_NAME ramdisk = 8192 |
lvmcreate_initrd -- making loopback file (6189 kB) |
您还应该将这个新的 lilo.conf 复制到新根文件系统的 /etc 中。
# cp /etc/lilo.conf /mnt/etc/ |
重新启动 - 在 LILO 提示符下键入 "lvm"。 系统应该使用新创建的逻辑卷重新启动到 Linux。
如果这有效,那么您应该通过添加以下行使 lvm 成为默认的 LILO 引导目标
default=lvm |
如果它不起作用,则正常重新启动并尝试诊断问题。 这可能是 lilo.conf 中的输入错误,或者初始 RAM 磁盘或其内核中没有 LVM 1。 仔细检查启动时产生的消息。
将磁盘的其余部分添加到 LVM 1。 当您对此设置感到满意时,您可以将旧的根分区添加到 LVM 1 并扩展到整个磁盘。
首先将分区类型设置为 8e(LVM)
# fdisk /dev/hda Command (m for help): t Partition number (1-4): 3 Hex code (type L to list codes): 8e Changed system type of partition 3 to 8e (Unknown) Command (m for help): w |
将其转换为 PV 并将其添加到卷组
# pvcreate /dev/hda3 # vgextend vg /dev/hda3 |
如果您收到警告 "incorrect metadata area header checksum" 或无法找到具有 UUID foo 的 PV 的消息,则您可能破坏了卷组描述符区域,并且无法启动 lvm。
![]() | 仅在非功能性 VG 上运行 |
---|---|
不要在正常工作的 lvm 上执行此操作。 您需要指定正确的物理卷到 pvcreate,否则可能会丢失数据。 |
从文件中提取被覆盖的 PV 的确切 uuid/etc/lvm/archive/VolumeGroupName_XXXXX.vg. (其中 XXXXX 代表最后一个已知的良好归档 lvm 元数据的编号)。
使用 pvcreate 恢复元数据: pvcreate --uuid "<some_long_string>" --restorefile /etc/lvm/archive/VolumeGroupName_XXXXX.vg <PhysicalVolume>
如果您幸运的话,您会发现磁盘上的 lvm 元数据占用的空间至少与它被覆盖的空间一样多。 上述命令已知可以恢复被 mkswap 覆盖的 PV。 如果覆盖 VGDA 的任何东西写入到该区域之外,则可能会影响 LV。 在这种情况下,fsck 也许能够修复 LV 上的文件系统,或者您可能需要采取更严厉的措施才能从中提取数据。 请联系您当地友好的文件系统专家寻求帮助。
![]() | pvcreate 只会覆盖磁盘上的 lvm 元数据区域,而不会触及数据区域(逻辑卷)。 |
![]() | 警告 |
---|---|
除非你真的确定你在做什么,否则不要这样做。 您可能会丢失所有数据。 |
如果您已将 LVM 从以前的版本升级到早期的 0.9 和 0.9.1 版本的 LVM 并且 vgscan 说vgscan -- 没有找到卷组,这是一种解决方法。
从 Sistina 的贡献者目录下载 UUID fixer 程序。
它位于 ftp://ftp.sistina.com/pub/LVM/contrib/uuid_fixer-0.3-IOP10.tar.gz
提取uuid_fixer-0.3-IOP10.tar.gz
# tar zxf uuid_fixer-0.3-IOP10.tar.gz |
cd 到 uuid_fixer
# cd uuid_fixer |
此时您有两种选择之一
使用预构建的二进制文件(它是为 i386 架构构建的)。
确保您列出了要恢复的 VG 中的所有 PV,并按照提示进行操作
# ./uuid_fixer <LIST OF ALL PVS IN VG TO BE RESTORED> |
从源代码构建 uuid_builder 程序
使用您喜欢的编辑器编辑 Makefile,并确保 LVMDIR 指向您的 LVM 源代码。
然后运行 make。
# make |
现在运行 uuid_fixer。 确保您列出了要恢复的 VG 中的所有 PV,并按照提示进行操作。
# ./uuid_fixer <LIST OF ALL PVS IN VG TO BE RESTORED> |
停用任何活动的卷组 (可选)
# vgchange -an |
运行 vgscan
# vgscan |
重新激活卷组
# vgchange -ay |
![]() | LVM 不具备集群感知能力 |
---|---|
这样做时要非常小心,LVM 目前不具备集群感知能力,而且很容易丢失所有数据。 |
如果您有光纤通道或共享 SCSI 环境,其中多台机器可以物理访问一组磁盘,那么您可以使用 LVM 将这些磁盘划分为逻辑卷。 如果您想共享数据,您应该真正考虑使用 GFS 或其他集群文件系统。
共享卷时要记住的关键是,所有 LVM 管理都必须仅在一个节点上完成,并且所有其他节点必须在管理节点上更改任何内容之前关闭 LVM。 然后,在进行更改后,必须在其他节点上运行 vgscan,然后才能重新加载卷组。 此外,除非您在卷上运行集群感知文件系统(例如 GFS)或应用程序,否则每个文件系统只能由一个节点挂载。 作为系统管理员,您有责任执行此操作,LVM 不会阻止您损坏数据。
每个节点的启动顺序与单节点设置相同,其中包含
vgscan vgchange -ay |
如果您需要对 LVM 元数据进行**任何**更改(无论它是否影响挂载在其他节点上的卷),您都必须执行以下序列。 在下面的步骤中,“管理节点”是集群中任意选择的节点。
Admin node Other nodes ---------- ----------- Close all Logical volumes (umount) vgchange -an <make changes, eg lvextend> vgscan vgchange -ay |
![]() | VG 应该在管理节点上处于活动状态 |
---|---|
您不需要,也不应该在管理节点上卸载 VG,因此这可以是具有最高正常运行时间要求的节点。 |
我再说一遍:**这样做时要非常小心**
仅仅告诉我们 LVM 不起作用并不能为我们提供足够的帮助信息。 我们需要了解您的设置和配置的各种组件。 您应该做的第一件事是检查 linux-lvm 邮件列表存档,看看是否有人已经报告了相同的 bug。 如果您没有找到与您的问题类似的错误报告,您应该尽可能多地收集以下信息。 该列表分为三个错误类别。
对于编译错误
详细说明您拥有的 LVM 的特定版本。 如果您从 tarball 中提取了 LVM,请提供 tar 文件的名称并列出您应用的任何补丁。 如果您从公共 CVS 服务器获取了 LVM,请提供您检出它的日期和时间。
提供确切的错误消息。 复制实际错误消息之前的输出行以及之后的行。 这些行有时会提示错误发生的原因。
按顺序列出产生错误的步骤。 该错误是否可重现? 如果您从干净状态开始,相同的步骤序列是否会重现该错误?
对于 LVM 错误
包括编译部分中请求的所有信息。
附上您的硬件的简短描述:机器和磁盘的类型,磁盘接口(SCSI、FC、NBD)。 您认为重要的有关您的硬件的任何其他信息。
用于使用 LVM 产生错误的命令行。
运行有问题的命令时生成的日志文件。 确保您的/etc/lvm/lvm.conf文件中包含以下内容
log { file="/tmp/lvm2.log" level=7 activation=1 } |
当 LVM 遇到 panic trap 时
包括上面两个部分中请求的所有信息。
提供机器的调试转储。 如果您通过串行链接监视计算机的控制台输出,这将是最好的方法,因为您无法很好地从出现 panic 的机器上复制和粘贴,并且如果您尝试手动复制输出,很容易输入错误。
这可能有很多信息。 如果您最终得到多个文件,请将它们 tar 和 gzip 到一个存档中。 将指向此文件的链接提交到相应的邮件列表(请参阅 C.1 节),并简要描述错误。 如果您没有可以发布信息的公共网站或 ftp 站点,您可以尝试将文件提交到列表。
版权 (C) 2000,2001,2002 自由软件基金会, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 每个人都可以复制和分发此许可证文档的完整副本,但不允许更改它。
此许可证的目的是使手册、教科书或其他功能性和有用的文档在自由的意义上是“自由的”:以确保每个人都拥有复制和重新分发它的有效自由,无论是否对其进行修改,无论是商业用途还是非商业用途。 其次,此许可证为作者和出版商保留了一种方式来获得对其作品的认可,同时不被认为对他人所做的修改负责。
此许可证是一种“反版权”,这意味着文档的派生作品本身必须在同一意义上是自由的。它补充了 GNU 通用公共许可证,该许可证是为自由软件设计的反版权许可证。
我们设计此许可证是为了将其用于自由软件的手册,因为自由软件需要自由文档:自由程序应附带提供与软件相同自由的手册。 但是,此许可证不仅限于软件手册; 它可以用于任何文本作品,无论主题如何,或者是否以印刷书籍的形式出版。 我们主要建议将此许可证用于其目的是指导或参考的作品。
本许可证适用于任何手册或其他作品,以任何媒介形式,其中包含版权所有者放置的声明,表明它可以在本许可证的条款下分发。 这样的声明授予在全球范围内、免版税的许可,无限期地在本协议规定的条件下使用该作品。“文档”,以下,是指任何此类手册或作品。 任何公众成员都是被许可人,并被称为“您”。 如果您以需要版权法许可的方式复制、修改或分发作品,则您接受该许可。
文档的“修改版本”是指包含文档或其一部分的任何作品,无论是逐字复制,还是经过修改和/或翻译成另一种语言。
“次要部分”是文档的命名附录或前言部分,专门处理文档的出版商或作者与文档的总体主题(或与相关事项)的关系,并且不包含任何可以直接属于该总体主题的内容。 (因此,如果文档部分是数学教科书,则次要部分可能不解释任何数学知识。)该关系可能是与该主题或相关事项的历史联系,或者与它们的法律、商业、哲学、伦理或政治立场有关。
“不变部分”是某些次要部分,其标题被指定为不变部分的标题,在声明该文档是根据本许可证发布的声明中。 如果某个部分不符合上述次要部分的定义,则不允许将其指定为不变部分。 文档可能包含零个不变部分。 如果文档未识别任何不变部分,则不存在不变部分。
“封面文字”是简短的文本段落,这些文本段落在声明该文档是根据本许可证发布的声明中被列为封面文本或封底文本。 封面文字最多可以有 5 个字,封底文字最多可以有 25 个字。
文档的“透明”副本是指机器可读的副本,以一种通用格式表示,其规范可供公众使用,适用于使用通用文本编辑器(对于由像素组成的图像)或通用绘画程序(对于绘图)或一些广泛使用的绘图编辑器直接修改文档,并且适用于输入文本格式化程序或自动翻译成适用于输入文本格式化程序的各种格式。 以其他方式透明的文件格式制作的副本,其标记或缺少标记已被安排为阻挠或阻止读者进行后续修改,则不是透明的。 如果将图像格式用于大量文本,则该图像格式不是透明的。 非“透明”的副本称为“不透明”。
透明副本的合适格式示例包括没有标记的纯 ASCII、Texinfo 输入格式、LaTeX 输入格式、使用公开可用的 DTD 的 SGML 或 XML,以及符合标准的简单 HTML、PostScript 或 PDF,专为人工修改而设计。 透明图像格式的示例包括 PNG、XCF 和 JPG。 不透明格式包括只能由专有字处理器读取和编辑的专有格式、DTD 和/或处理工具通常不可用的 SGML 或 XML,以及某些字处理器仅出于输出目的而生成的机器生成的 HTML、PostScript 或 PDF。
“标题页”对于印刷书籍是指标题页本身,以及清晰地容纳本许可证要求出现在标题页中的材料所需的后续页面。 对于没有标题页格式的作品,“标题页”是指作品标题最突出显示附近的文本,位于正文文本的开头之前。
“标题为 XYZ”的部分是指文档的命名子单元,其标题要么完全是 XYZ,要么包含 XYZ,并在文本后面用括号括起来,该文本以另一种语言翻译 XYZ。 (此处 XYZ 代表下面提到的特定部分名称,例如“致谢”、“奉献”、“认可”或“历史”。)当您修改文档时,“保留”此类部分的“标题”意味着它仍然是根据此定义“标题为 XYZ”的部分。
文档可能在声明本许可证适用于文档的声明旁边包含免责声明。 这些免责声明被认为是通过引用包含在本许可证中,但仅限于放弃保证:这些免责声明可能具有的任何其他含义均无效,并且对本许可证的含义没有影响。
您可以在任何介质上复制和分发文档,无论是商业用途还是非商业用途,前提是本许可证、版权声明以及声明本许可证适用于文档的许可证声明在所有副本中都得以复制,并且您不得对本许可证的条款添加任何其他条件。 您不得使用技术措施来阻碍或控制您制作或分发的副本的阅读或进一步复制。 但是,您可以接受报酬以换取副本。 如果您分发足够多的副本,则还必须遵守第 3 节中的条件。
您也可以在上述相同条件下借出副本,并且可以公开展示副本。
如果您发布文档的印刷副本(或通常带有印刷封面的媒体中的副本),数量超过 100 份,并且文档的许可证声明要求提供封面文字,则必须将副本封闭在封面上,清晰易懂地带有所有这些封面文字:封面上的封面文字和封底上的封底文字。 两个封面还必须清晰易懂地将您标识为这些副本的出版商。 封面必须以同样突出和可见的方式呈现标题的所有单词的完整标题。 您可以在封面上添加其他材料。 仅限于封面的更改的复制,只要它们保留文档的标题并满足这些条件,就可以在其他方面视为逐字复制。
如果任何一个封面的所需文本过于庞大而无法清晰易懂地容纳,则应将列出的第一个(尽可能合理地容纳)放在实际封面上,并将其余文本继续放到相邻页面上。
如果您发布或分发超过 100 份文档的不透明副本,则必须在每个不透明副本中附带机器可读的透明副本,或者在每个不透明副本中或随附声明一个计算机网络位置,普通网络用户可以访问该位置,使用公共标准网络协议下载文档的完整透明副本,且不添加任何材料。 如果您使用后一种选项,则必须在开始大量分发不透明副本时采取合理谨慎的步骤,以确保该透明副本在该声明的位置保持可访问,直到您将该版本的最后一个不透明副本(直接或通过您的代理商或零售商)分发给公众之后至少一年。
建议但不要求您在重新分发大量副本之前与文档的作者联系,让他们有机会向您提供文档的更新版本。
您可以按照上述第2节和第3节的条件,复制和分发文档的修改版本,但前提是您必须以完全相同的本许可协议发布修改版本,使修改版本扮演文档的角色,从而向拥有副本的任何人授予修改版本的分发和修改许可。此外,您必须在修改版本中执行以下操作:
在标题页(以及封面,如果有的话)上使用与文档标题不同的标题,并且与以前版本(如果有的话,应在文档的历史记录部分列出)的标题不同。如果该版本的原始出版者允许,您可以使用与以前版本相同的标题。
在标题页上,列出对修改版本中的修改负责的一位或多位人士或实体作为作者,以及文档的至少五位主要作者(如果文档的主要作者少于五位,则列出所有主要作者),除非他们免除您的此项要求。
在标题页上注明修改版本的出版者名称。
保留文档的所有版权声明。
在其他版权声明旁边添加适用于您所做的修改的版权声明。
在版权声明之后立即包含许可声明,授予公众按照本许可协议的条款使用修改版本的许可,格式如下面的附录所示。
在该许可声明中,保留文档的许可声明中给出的不变部分和必需封面文本的完整列表。
包含本许可协议的未修改副本。
保留标题为“历史记录”的章节,保留其标题,并在其中添加至少包含修改版本的标题、年份、新作者和出版者的项目,这些信息与标题页上给出的相同。如果文档中没有标题为“历史记录”的章节,则创建一个章节,说明文档的标题、年份、作者和出版者,这些信息与标题页上给出的相同,然后添加一个项目,描述修改版本,如前一句所述。
保留文档中提供的用于公开访问文档的透明副本的网络位置(如果有的话),以及文档中提供的基于其先前版本的网络位置。这些可以放在“历史记录”部分中。您可以省略在文档本身发布前至少四年发布的作品的网络位置,或者如果它所指的版本的原始出版者允许。
对于任何标题为“致谢”或“题献”的章节,保留该章节的标题,并保留该章节中所有贡献者致谢和/或题献的实质内容和语气。
保留文档的所有不变部分,保持其文本和标题不变。章节编号或等效内容不被视为章节标题的一部分。
删除任何标题为“认可”的章节。修改版本中不得包含此类章节。
不要将任何现有章节重命名为“认可”,也不要使其标题与任何不变部分的标题冲突。
保留任何保证免责声明。
如果修改版本包含符合次要章节资格的新前言章节或附录,并且不包含从文档中复制的材料,您可以选择将其中一些或所有章节指定为不变章节。为此,请将它们的标题添加到修改版本的许可声明中的不变部分列表中。这些标题必须与任何其他章节标题不同。
您可以添加一个标题为“认可”的章节,前提是它只包含对您的修改版本的认可——例如,同行评审的声明或文本已被某个组织批准为标准的权威定义。
您可以在修改版本的封面文本列表末尾添加一段最多五个单词的封面文本,以及一段最多 25 个单词的封底文本。任何一个实体只能添加(或通过安排)一段封面文本和一段封底文本。如果文档已经包含同一封面的封面文本,该文本先前由您或通过您代表的同一实体进行安排而添加,则您不得添加另一个封面文本;但是,您可以在明确获得先前添加旧封面文本的出版商的许可后更换旧封面文本。
文档的作者和出版者不通过本许可协议授予使用他们的名字进行宣传或断言或暗示对任何修改版本的认可的许可。
您可以按照上述第 4 节中定义的修改版本条款将文档与根据本许可协议发布的其他文档合并,前提是您在合并作品中包含所有原始文档的所有不变部分,且未经修改,并在其许可声明中将它们全部列为合并作品的不变部分,并且您保留它们的所有保证免责声明。
合并后的作品只需要包含一份本许可协议的副本,并且多个相同的不变部分可以替换为单个副本。如果存在多个名称相同但内容不同的不变部分,请通过在其末尾添加括号,并在括号中注明该部分的原始作者或出版者的姓名(如果已知),或者添加一个唯一的数字,使每个部分的标题都是唯一的。在合并作品的许可声明的不变部分列表中对章节标题进行相同的调整。
在合并中,您必须合并各个原始文档中标题为“历史记录”的任何章节,形成一个标题为“历史记录”的章节;同样合并任何标题为“致谢”的章节,以及任何标题为“题献”的章节。您必须删除所有标题为“认可”的章节。
您可以创建一个由文档和根据本许可协议发布的其他文档组成的集合,并将各个文档中本许可协议的单独副本替换为包含在集合中的单个副本,前提是您在所有其他方面都遵循本许可协议关于每个文档的逐字复制的规则。
您可以从这样的集合中提取单个文档,并根据本许可协议单独分发它,前提是您将本许可协议的副本插入到提取的文档中,并在所有其他方面都遵循本许可协议关于该文档的逐字复制的规定。
将文档或其衍生作品与其他单独且独立的文档或作品一起汇编在一个存储或分发介质的卷中或之上,如果汇编产生的版权不是用于限制汇编用户超出各个作品允许的合法权利,则称为“聚合”。当文档包含在聚合中时,本许可协议不适用于聚合中的其他作品,这些作品本身不是文档的衍生作品。
如果第 3 节的封面文本要求适用于这些文档副本,那么如果文档小于整个聚合的一半,则文档的封面文本可以放置在括起聚合中文档的封面上,或者如果文档是电子形式,则放置在封面的电子等效物上。否则,它们必须出现在括起整个聚合的印刷封面上。
翻译被认为是一种修改,因此您可以按照第 4 节的条款分发文档的翻译。用翻译替换不变部分需要其版权持有者的特殊许可,但您可以包含一些或所有不变部分的翻译,以及这些不变部分的原始版本。您可以包含本许可协议的翻译,以及文档中的所有许可声明和任何保证免责声明,前提是您还包含本许可协议的原始英文版本以及这些声明和免责声明的原始版本。如果本许可协议的翻译版本与原始版本之间,或者声明或免责声明的翻译版本与原始版本之间存在分歧,则以原始版本为准。
如果文档中的一个章节标题为“致谢”、“题献”或“历史记录”,则保留其标题(第 4 节)的要求通常需要更改实际标题。
除非本许可协议明确规定,否则您不得复制、修改、再许可或分发文档。任何其他试图复制、修改、再许可或分发文档的行为均无效,并将自动终止您在本许可协议下的权利。但是,根据本许可协议从您那里收到副本或权利的当事方,只要这些当事方保持完全遵守,其许可协议就不会终止。
自由软件基金会可能会不时发布 GNU 自由文档许可证的新修订版本。这些新版本在精神上与当前版本相似,但在细节上可能有所不同,以解决新的问题或疑虑。请参阅 https://gnu.ac.cn/copyleft/。
每个版本的许可协议都给出了一个独特的版本号。如果文档指定本许可协议的特定编号版本“或任何后续版本”适用于它,您可以选择遵循该指定版本或自由软件基金会发布的任何后续版本(不是草案)的条款和条件。如果文档未指定本许可协议的版本号,您可以选择自由软件基金会发布的任何版本(不是草案)。
要在您编写的文档中使用本许可协议,请在文档中包含本许可协议的副本,并将以下版权和许可声明放在标题页之后:
版权所有 (c) 年份 您的姓名。允许根据 GNU 自由文档许可证 1.2 版或自由软件基金会发布的任何后续版本的条款复制、分发和/或修改本文档;不包含不变部分、封面文本和封底文本。许可证副本包含在标题为“GNU 自由文档许可证”的章节中。
如果您有不变部分、封面文本和封底文本,请将“不包含...文本。”行替换为此:
不变部分为列表其标题,封面文本为列表,封底文本为列表。
如果您有不变部分但没有封面文本,或者有其他三种文本的组合,请合并这两种选择以适应具体情况。
如果您的文档包含程序代码的非平凡示例,我们建议在您选择的自由软件许可证(例如 GNU 通用公共许可证)下并行发布这些示例,以允许它们在自由软件中使用。