Мне нужно сгенерировать несколько образов ext2. Очевидный способ сделать это — создать образ, смонтировать его и скопировать содержимое. Но для этого дважды требуются права root (для chown файлов и для монтирования образа). Также я нашел два инструмента для генерации образов: e2fsimage и genext2fs.
genext2fs помещает изображение в оперативную память во время генерации, но размер одного из моих изображений составляет ~30 ГБ.
e2fsimage аварийно завершает работу при некоторых значениях размера изображения.
Так как же мне генерировать свои изображения? Было бы неплохо, если бы инструмент сам рассчитывал размер изображения.
решение1
mke2fs -d
минимальный работоспособный пример безsudo
mke2fs
является частью пакета e2fsprogs. Он написан известным разработчиком файловой системы ядра Linux Теодором Цо, который работает в Google с 2018 года, а исходный код upstream находится на 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
Поэтому он работает в Ubuntu 18.04 «из коробки», в которой установлен e2fsprogs 1.44.1-1, но не в Ubuntu 16.04, в которой установлен e2fsprogs 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
говорит, что если вы используете вызов if с такой символической ссылкой, то -t
подразумевается.
Как я об этом узнал и как решить возможные проблемы в будущем:Buildrootсоздает образы ext2 без sudoкак показано здесь, поэтому я просто запустил сборку V=1
и извлек команды из части генерации изображения, которая идет в самом конце. Старый добрый копипаст никогда меня не подводил.
TODO: опишите, как решить следующие проблемы:
- создать файлы, принадлежащие sudo, в образе. Buildroot делает это.
- автоматически вычислить минимальный требуемый размер. Первоначальная оценка с
du
размером файла иfind . | wc
структурой каталогов, минимум 32 Мб (меньше не срабатывает), затем удваивать, пока команда не сработает, вероятно, очень приличный подход. Buildroot раньше делал это, но по какой-то причине перестал, но легко реализовать самим. - удобно извлечь все файлы из раздела:
Несколько разделов в одном файле образа
решение2
Разобрался, почему e2fsimage
происходит сбой. Это вызвано переполнением int32, когда размер образа больше 4GiB. Поэтому решение заключается в подсчете требуемых блоков и инодов, создании файла цикла ( 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