我需要生成几个 ext2 映像。最明显的方法是创建一个映像,挂载它并复制内容。但它需要两次 root 权限(更改文件和挂载映像)。我还发现了两个用于生成映像的工具:e2fsimage 和 genext2fs。
genext2fs 在生成时将图像放在 RAM 中,但其中一个图像的大小约为 30GiB。
e2fsimage 因某些图像大小值而崩溃。
那么我该如何生成图像呢?如果该工具可以自行计算图像大小就好了。
答案1
mke2fs -d
最小可运行示例,无需sudo
mke2fs
是 e2fsprogs 软件包的一部分。它由著名的 Linux 内核文件系统开发人员 Theodore Ts'o(2018 年加入 Google)编写,源代码上游位于 kernel.org 下:https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs因此,该存储库可以被视为 ext 文件系统操作的参考用户空间实现:
#!/usr/bin/env bash
set -eu
root_dir=root
img_file=img.ext2
# Create a test directory to convert to ext2.
mkdir -p "$root_dir"
echo asdf > "${root_dir}/qwer"
# Create a 32M ext2 without sudo.
# If 32M is not enough for the contents of the directory,
# it will fail.
rm -f "$img_file"
mke2fs \
-L '' \
-N 0 \
-O ^64bit \
-d "$root_dir" \
-m 5 \
-r 1 \
-t ext2 \
"$img_file" \
32M \
;
# Test the ext2 by mounting it with sudo.
# sudo is only used for testing.
mountpoint=mnt
mkdir -p "$mountpoint"
sudo mount "$img_file" "$mountpoint"
sudo ls -l "$mountpoint"
sudo cmp "${mountpoint}/qwer" "${root_dir}/qwer"
sudo umount "$mountpoint"
关键选项是-d
,选择用于图像的目录,它是提交中 v1.43 的一个相对较新的添加0d4deba22e2aa95ad958b44972dc933fd0ebbc59
因此,它可以在具有 e2fsprogs 1.44.1-1 的 Ubuntu 18.04 上开箱即用,但不能在 Ubuntu 16.04 上运行,后者的版本为 1.42.13。
但是,我们可以像 Buildroot 那样在 Ubuntu 16.04 上轻松地从源代码进行编译:
git clone git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
cd e2fsprogs
git checkout v1.44.4
./configure
make -j`nproc`
./misc/mke2fs -h
如果mke2fs
失败:
__populate_fs: Operation not supported while setting xattrs for "qwer"
mke2fs: Operation not supported while populating file system
添加选项时:
-E no_copy_xattrs
例如,当根目录位于 NFS 中或tmpfs
不是 extX 之类的文件系统时,这是必需的似乎没有扩展属性。
mke2fs
通常是符号链接到的mkfs.extX
,并且man mke2fs
表示如果您使用带有此类符号链接的调用,则-t
暗示。
我如何发现这一点以及如何解决任何未来的问题:构建根无需 sudo 即可生成 ext2 映像如图所示,所以我只是用 运行构建V=1
并从最后出现的图像生成部分中提取命令。 好用的复制粘贴从未让我失望过。
TODO:描述如何解决以下问题:
- 在镜像中创建 sudo 拥有的文件。Buildroot 会做这件事。
- 自动计算所需的最小大小。初步估计
du
文件大小和find . | wc
目录结构,将其最小设置为 32Mb(更小则失败),然后将其翻倍直到命令有效,这可能是一个非常不错的方法。Buildroot 曾经这样做过,但由于某种原因停止了,但我们自己很容易实现。 - 方便地从分区中提取所有文件:
一个映像文件中有多个分区
答案2
弄清楚了e2fsimage
崩溃的原因。这是由于当图像大小大于 4GiB 时 int32 溢出引起的。因此,解决方案是计算所需的块和 inode,创建循环文件(truncate
& mke2fs
),然后使用e2fsimage
参数-n
(因此它不会创建循环文件,而是使用已创建的文件)
答案3
创建镜像不需要 root 权限。下面是创建 ext2 镜像的示例:
dd if=/dev/zero of=./MyDisk.ext2 bs=512 count=20480
mkfs.ext2 ./MyDisk.ext2
但挂载设备需要 root 权限:
mkdir MyDisk
sudo mount ./MyDisk.ext2 MyDisk