GPT fdisk(又称 gdisk、cgdisk 和 sgdisk)与 FixParts 作者:Roderick W. Smith,[email protected]
本软件包包含四个相关磁盘分区程序的源代码:
gdisk —— 此程序模仿 Linux fdisk,但操作的是 GUID 分区表(GPT)磁盘,而非 fdisk 所修改的主引导记录(MBR)磁盘。因此,gdisk 是一个交互式文本模式工具,用于操作分区,但它不会改动这些分区的内容(通常是文件系统,有时是交换空间或其他数据)。
cgdisk —— 此程序模仿 Linux cfdisk,但操作的是 GPT 磁盘,而非 cfdisk 所修改的 MBR 磁盘。因此,cgdisk 是一个基于 curses 的文本模式工具,用于操作分区,也就是说,它使用依赖方向键和动态显示的界面,而非像 gdisk 那样使用命令字母和滚动显示。
sgdisk —— 此程序在概念上类似于 Linux sfdisk 和 FreeBSD gpt 程序,但其操作细节有所不同。它通过命令行选项来操作 GPT 磁盘,因此适合在脚本中使用,或由专家执行特定任务,而这些任务在 gdisk 中可能需要多条命令才能完成。
fixparts —— 与前三个程序不同,此程序操作的是 MBR 磁盘。它旨在修复各种工具可能造成的某些问题。具体来说,它可以修复尺寸错误的扩展分区以及位于扩展分区内部的 primary 分区。它还可以更改 primary 与 logical 分区的状态(在 MBR 方案允许的范围内),并进行一些其他小改动。它不支持创建新分区;如需创建,应使用 fdisk、parted 或其他工具。
下文将详细介绍这些工具的功能。
这四个程序都依赖于同一套底层代码,仅控制接口(分别在 gdisk.cc、cgdisk.cc、sgdisk.cc 和 fixparts.cc 中定义)以及所使用的支持代码有所不同。
gdisk 程序旨在作为 GPT 分区磁盘的(某种程度上)fdisk 替代品,cgdisk 类似地是 cfdisk 的替代品,而 sgdisk 则以更适用于脚本的程序形式提供 gdisk 的大部分功能。尽管 libparted 及其使用的程序(GNU Parted、gparted 等)能够处理 GPT 磁盘,但它们存在 gdisk 可以克服的某些局限性。gdisk、cgdisk 和 sgdisk 的具体优势包括:
能够在不丢失数据的情况下,原地将 MBR 分区磁盘转换为 GPT 格式
能够在不丢失数据的情况下,原地将 BSD 磁盘标签转换为 GPT 分区
能够在不丢失数据的情况下,从 GPT 格式转换为 MBR 格式(仅限 gdisk 和 sgdisk)
更灵活地指定文件系统类型代码 GUID,而 GNU Parted 往往会导致其损坏
清晰显示磁盘上未分配扇区的数量
用户界面对长期使用 Linux fdisk 和 cfdisk 的用户来说很熟悉(仅限 gdisk 和 cgdisk)
MBR 引导加载程序代码保持不变
能够创建混合 MBR,使不识别 GPT 的操作系统能够访问磁盘上最多三个 GPT 分区(仅限 gdisk 和 sgdisk)
当然,GPT fdisk 也有其局限性。最值得注意的是,它缺少 GParted 那样的文件系统感知能力和文件系统相关功能。例如,您无法使用 gdisk 调整分区文件系统的大小,或创建已经包含文件系统的分区。也没有 gdisk 的 GUI 版本。
GPT fdisk 软件包提供三个程序文件:交互式文本模式 gdisk、基于 curses 的交互式 cgdisk,以及命令行驱动的 sgdisk。前两个用于手动划分磁盘或更改分区细节;sgdisk 用于脚本中,帮助自动化诸如磁盘克隆或为 Linux 安装准备多个磁盘等任务。
创建此程序的初衷源于我在在线论坛上看到的用户求助,他们发现自己的分区表被各种有缺陷的分区工具破坏了。尽管大多数操作系统都能正常处理受影响的磁盘,但基于 libparted 的工具(GParted、parted、大多数 Linux 安装程序等)面对这些磁盘时往往会出现问题。通常的症状是磁盘显示为空,没有分区;但有时,libparted 工具显示的分区与操作系统看到的不一致。
我观察到导致这些症状的四个原因,其中三个 FixParts 可以修复:
旧的 GPT 数据 —— 如果磁盘曾被用作 GPT 磁盘,然后又被重新用作 MBR 磁盘,GPT 数据可能未被完全擦除。例如,使用 fdisk 或 Microsoft Windows 安装程序重新分区时会发生这种情况。(基于 libparted 的工具在从 GPT 转换为 MBR 格式时会正确移除旧的 GPT 数据。)FixParts 在启动时会检查此问题,并提供修复选项。如果选择擦除 GPT 数据,此擦除会立即执行,不同于程序所做的其他更改。
尺寸错误的扩展分区 —— 某些工具创建的扩展分区过大,通常结束于磁盘最后一个扇区之后。FixParts 会自动修复此问题(如果使用 'w' 选项保存分区表)。
primary 分区位于扩展分区内部 —— 某些工具创建或移动 primary 分区至扩展分区覆盖的范围内。FixParts 通常可以通过将 primary 分区转换为 logical 分区,或更改一个或多个其他 logical 分区为 primary 分区来修复此问题。不过,这种修复并非总是可行,至少在不删除或调整其他分区的情况下不可行。
遗留的 RAID 数据 —— 如果磁盘曾在 RAID 阵列中使用,然后被重新用作非 RAID 磁盘,某些工具可能会混淆,无法识别该磁盘。FixParts 无法修复此问题。您必须销毁旧的 RAID 数据,或者从系统中移除 dmraid 软件包,才能解决此问题。
运行时,FixParts 提供一个类似 fdisk 的界面,使您可以调整分区类型(primary、logical 或省略)、更改类型代码、更改可引导标志等。虽然可以删除分区(通过省略),但程序不能创建新分区。如果您习惯使用分区工具(尤其是 Linux fdisk),FixParts 有两个不寻常的特性需要说明:
无扩展分区 —— 在内部,FixParts 读取分区表,并丢弃找到的任何扩展分区数据。保存分区表时,程序会生成一个新的扩展分区。这种设计意味着程序会自动修复许多与扩展分区相关的问题。这也意味着在 FixParts 用户界面中看不到扩展分区的痕迹,尽管它会跟踪要求,并阻止您创建非法布局,例如在两个 logical 分区之间放置一个 primary 分区。
分区编号 —— 在大多数 Linux 工具中,分区 1-4 是 primary 分区,分区 5 及以上是 logical 分区。虽然加载到 FixParts 中的合法分区表最初会遵守这一约定,但某些类型的损坏表可能不会,并且您所做的各种更改也可能导致偏离。FixParts 写入分区表时,其编号将根据标准 MBR 约定进行调整,但您应使用分区明确标注为 primary 或 logical 的方式,而非分区编号,来判断分区的状态。
要编译 GPT fdisk,您必须安装适当的开发工具,最主要是 GNU 编译器套件(GCC)及其用于 C++ 的 g++ 编译器。我也测试过使用 Clang 编译,似乎也能工作;不过,除了检查一些基本功能外,我没有对生成的二进制文件进行广泛测试。在 Windows 下,可以使用 Microsoft Visual C++ 2008 代替。此外,请注意以下要求:
在 Linux、FreeBSD、OS X 和 Solaris 上,必须安装 libuuid。这是 Linux 和 OS X 的标准配置,但您可能需要安装名为 uuid-dev 或类似名称的软件包才能获取头文件。在 FreeBSD 上,必须安装 e2fsprogs-libuuid 端口。
ICU 库(http://site.icu-project.org)提供 Unicode 分区名称支持,在所有平台上都是可选的,Windows 平台除外(Windows 不支持该库)。在 GPT fdisk 0.8.9 版本之前,必须使用此库才能获得正确的 UTF-16 分区名称支持,但从该版本开始应该不再需要。不过,如果您的新 UTF-16 支持遇到问题,仍可以使用它。该库通常安装在 Linux 和 OS X 中,但您可能需要安装开发头文件(Linux 下的 libicu-dev 或类似软件包;或者 OS X 下的 libicu36-dev Fink 包)。要启用 ICU 支持编译,您必须修改 Makefile:查找被注释掉的、引用 USE_UTF16、-licuuc、-licudata 或 -licucore 的行。取消注释,并注释掉缺少这些行的等效行。
cgdisk 程序需要 ncurses 库及其开发文件(头文件)。大多数 Linux 发行版默认安装 ncurses,但您可能需要安装名为 libncurses5-dev、ncurses-devel 或类似名称的软件包来获取头文件。我的 Mac OS X 开发系统上已安装这些文件;不过,它们可能是作为我安装的其他程序的依赖项而安装的。如果您在安装 ncurses 时遇到问题,可以通过仅指定要编译的目标来编译 gdisk 和/或 sgdisk,而不编译 cgdisk。
sgdisk 程序需要 popt 库及其开发文件(头文件)。大多数 Linux 发行版默认安装 popt,但您可能需要安装名为 popt-dev、popt-devel 或类似名称的软件包来获取头文件。Mac OS 用户可以从 DarwinPorts(http://popt.darwinports.com)或 Fink(http://www.finkproject.org)找到适用于 Mac OS 的 popt 版本;不过,您需要先安装 DarwinPorts 或 Fink(相关项目的页面有安装说明)。或者,您可以仅编译 gdisk 和/或 cgdisk,而不编译 sgdisk;gdisk 不需要 popt。
当所有必要的开发工具和库都安装完毕后,您可以解压本软件包,然后在生成的目录中键入 "make" 命令。(在 Mac OS X 上可能需要键入 "make -f Makefile.mac",在 FreeBSD 上键入 "make -f Makefile.freebsd",在 Solaris 上键入 "make -f Makefile.solaris",或使用 MinGW 为 Windows 编译时键入 "make -f Makefile.mingw"。)您可能还需要通过设置 CXXFLAGS 环境变量或编辑 Makefile 来添加头文件(包含)目录或库目录。结果应生成名为 gdisk、cgdisk、sgdisk 和 fixparts 的程序文件。键入 "make gdisk"、"make cgdisk"、"make sgdisk" 或 "make fixparts" 将仅编译所需的程序。您可以直接使用这些程序,或将其复制到合适的目录,例如 /usr/local/sbin。您可以将手册页(gdisk.8、cgdisk.8、sgdisk.8 和 fixparts.8)复制到 /usr/local/man/man8,以便使用。
本软件为测试版软件!如果它清空了您的硬盘或吃了您的猫,请别怪我!到目前为止,我已在多个 USB 闪存盘、物理硬盘以及 QEMU 和 VirtualBox 环境中的虚拟磁盘上测试了该软件。许多人也在他们的计算机上使用过该软件。我相信所有数据损坏的错误都已被修复,但我很清楚遗漏某些问题的可能性很高。对于大容量(超过 2 TiB)的驱动器尤其如此;我对此类磁盘的唯一直接测试是在虚拟 QEMU 和 VirtualBox 磁盘上进行的。不过,我收到了用户成功使用超过 2 TiB 的 RAID 阵列的报告。
我的主要开发平台是运行 64 位 Gentoo Linux 的系统。我还在其他几种 32 位和 64 位 Linux 发行版、基于 Intel 的 Mac OS X 10.5 和 10.6、64 位 FreeBSD 7.1 以及 Windows 7 上进行了测试。
本程序根据 GNU GPL 条款许可(参见文件 COPYING)。
本代码大部分是我自己的;不过,我使用了来自其他两个 GPL 程序的三个函数:
用于生成 CRC 的代码取自 Krzysztof Dabrowski 和 ElysiuM deeZine 的 efone 程序。(参见 crc32.h 和 crc32.cc 源代码文件。)
查找磁盘大小的函数取自 A. V. Le Blanc 的 Linux fdisk。此代码后来经过大量修改。
其他代码贡献者包括:
Yves Blusseau ([email protected])
David Hubbard ([email protected])
Justin Maggard ([email protected])
Dwight Schauer ([email protected])
Florian Zumbiehl ([email protected])
Guillaume Delacour (contributed the gdisk_test.sh script)