当我们想要改变Linux操作系统下已有分区的文件系统类型时,除了备份数据、重新格式化、恢复数据外,似乎别无它法。但fstransform的出现则给了我们一个选择。fstransform 允许操作系统在线、无损地将一种文件系统类型转换成另一种,比如从 jfs 变为 ext4。
截止本文发布时,fstransform最新版本是2012.03.28发布的0.9.3版本,该版本已经支持这些文件系统类型:ext2、ext3、ext4、reiserfs、minix、jfs、xfs
git地址:https://github.com/cosmos72/fstransform
下载fstransform命令,解压包,解压出目录为:fstransform-master进行编译安装
wget https://github.com/cosmos72/fstransform/archive/master.zip
unzip master.zip
./configure && make && make install
fstransform 命令的语法非常简单:fstransform <源设备> <目标文件系统>。请记住,它需要 root 权限才能运行,所以如果是普通用户不要忘记在开头添加 sudo。这是一个例子:
sudo fstransform /dev/sdb1 ext4
请注意,无法转换根文件系统,这是一种安全措施,请改用测试分区或实验性 USB 盘。
与此同时,Fstransform 会在控制台中有许多辅助输出。最有用的部分是预计完成时间,让你随时了解该过程需要多长时间。
Fstransform 存在一些警告和限制,因此强烈建议在尝试转换之前进行备份。此外,使用 Fstransform 时需要注意一些限制:
fstransform要有成功,有五个要求:
1.设备必须是卸载的,即“umount device”必须工作。特别是,如果某些正在运行的程序正在使用该设备,你必须先关闭或杀死他们。转换当前根目录不起作用。为此,你应该从其他安装(例如live CD、DVD或USB)启动。
2.设备必须有一点空闲空间,通常至少5%
警告:将几乎已满的设备转换为“xfs”文件系统这可能很棘手:
*你需要更多的自由空间,通常至少10%,
*或者你必须非常快地完成转换
当源或目标(或两者)文件系统几乎满时并在源设备或目标设备(或两者)上运行“xfs_fsr”
在恢复转换之前。未来的fstransform版本可能会自动执行此操作。
3.设备上的文件系统必须支持稀疏文件,即带有孔的文件
(例如,参见http://en.wikipedia.org/wiki/Sparse_file来解释它们是什么)
两个系统调用中至少有一个调用“ioctl(FS_IOC_FIEMAP)”或“ioctl(FIBMAP)”
(请参阅最近Linux内核中的文件Documentation/filesystems/fiemap.txt。)
获取解释,或在Internet上搜索同一文件)
ioctl(FIBMAP)受设计限制为2G-1块,通常转换为8TB-4kB。
要转换等于或大于8TB的文件系统,需要ioctl(FIEMAP)。
4.Linux内核必须支持初始和最终文件系统(即,它必须能够安装它们)通过工具“mkfs”和“fsck”(即,必须能够创建它们并检查它们是否存在错误)。理论上,通过FUSE(用户空间)驱动程序提供支持是可以接受的,但目前还没有经过测试的FUSE文件系统可以转换可靠的fstransform。
5.必须提供以下程序:
三个定制程序“fsmove”、“fsmount_内核”、“fsremap”(随脚本一起分发)和几个常见的Linux工具:其中expr,id,blockdev,losetup,mount,umount,mkdir,rmdir,rm,mkfifo,dd,sync,fsck,mkfs
1、将待转换文件系统的设备/分区以读写方式挂载。
mount {device} {device-mount-point} [your-options]
2、在设备/分区内部(待转换文件系统剩余空间(不少于5%))创建一个稀疏文件,映射成loop设备
dd if=/dev/zero of={device-mount-point}/{loop-file} bs=1 count=1 seek=$(( {device-size-in-bytes} - 1 ))
或者,如果有truncate
truncate -s {device-size-in-bytes} {device-mount-point}/{loop-file}
3、 使用新文件系统格式化循环设备loop-file
mkfs.[ext2,ext3,ext4,reiserfs,xfs,jfs...] {device-mount-point}/{loop-file}
如果创建ext2/ext3/ext4文件系统,选项“-m 0”将帮助您更精确地检测循环文件中的文件系统是否/何时变满
4、以读写方式挂载loop设备
mount {device-mount-point}/{loop-file} {loop-file-mount-point} -o loop {your-options}
这将找到一个空闲的/dev/loop{n},设置并挂载它。
5、从{device mount point}到{loop-file mount point},手动和递归地移动所有文件、目录、链接等。在{loop-file mount point}内复制{device mount point}中的原始树。有用到fsmove等工具。
6、初始设置几乎完成
现在,在{device mount point}中创建一个满0(不是稀疏)的文件
要帮助fsremap定位{device}内的任何可用磁盘空间,请执行以下操作:
dd if=/dev/zero of={device mount point}/{zero file}bs=512
第二个命令将退出,错误为“设备上没有剩余空间”,
但这是意料之中的,不是问题。
注意:如果您有fallocate并且{device}上的文件系统支持它,
你可以用fallocate代替dd,因为它速度更快。
7、以只读方式重新安装{device}以确保没有进程将在其中写入:
mount {device} -o remount,ro
8、选择一个有一些可用空间(不在{device}内)的文件夹,在那里fsremap可以编写备份数据和日志文件,并将其命名为{storage dir}。
如果跳过此步骤,fsremap将使用您的主目录作为默认值{storage dir}。
9、开启工具fsremap,运行:
{fsremap} -t {storage-dir} {device} {device-mount-point}/{loop-file} {device-mount-point}/{zero-file}
10、在分析阶段之后,fsremap将对{device}进行卸载:
umount {device}
11、fsremap现在将块从{loop-file}重新定位到{device},并将报告进展情况。
完成后,检查重新映射是否有效:
fsck -f {device}
mount {device} {device-mount-point} [your-options]
如果一切正常,则将删除{storage dir}