Linuxシステムでは、ユーザースペースツールのみを使用してパーティションイメージ(おそらくext2ファイルシステムのみが含まれる)を作成および操作し、それらのパーティションイメージを使用してディスクイメージを作成することは可能ですか?
使うことができます genext2fs
ユーザースペースにext2ファイルシステムのイメージを生成しますが、ルートアクセスを必要とせずにディスクイメージを操作できるツール(パーティションテーブルの作成や既存のパーティションイメージからのディスクイメージの作成など)が見つかりません。現在、ディスクイメージ内のパーティションをマウントするためにkpartx
を使用していますが、これにはrootが必要なため、スクリプトに適していないため、ビルドスクリプトにエラーが発生した場合はそうではありません。トラップされた場合、マッパーデバイスは引き続き使用されます。
基本的に、3つのディレクトリがあり、各ディレクトリをディスクイメージ上のパーティションにしたいのですが、これをスクリプト化したいので、ルートアクセスを必要とするツールを使用したくありません(これには何もないようです)ルートアクセスが絶対に必要なプロセス)。
パーティションテーブルを作成するには、デバイスではなくファイルで一般的なツールを直接使用できます。 fdisk
やparted
など、ほとんどの標準ツールはこの使用法をサポートする必要があります。 parted
は、コマンドを引数として受け取ることができるため、スクリプトに統合するのに最適です。
parted -s testing.img mklabel gpt
parted -s -a none testing.img mkpart ESP fat32 0 4M
parted -s -a none testing.img mkpart linux ext4 4M 10M
仮想パーティションにファイルシステムをマウントまたは作成するためのクリーンなソリューションがありません。おそらく正しいことは、パーティションテーブル用のFuse
(ユーザースペースのファイルシステム)ドライバーを用意することです。しかし、私は現時点でそれを見つけていません。
ただし、mke2fs
は-E offset=1234
オプションを使用して、ファイル内の任意のオフセットにext2
、ext3
、またはext4
ファイルシステムを構築できます。あなたはそれにあなたのパーティションのオフセットを与えることができます。ただし、デフォルトの動作はバグがあるように見えるため、ファイルシステムのサイズも指定し、デフォルトで仮想ディスクのサイズでファイルシステムを作成し、必要に応じてファイルを拡張してください。
mke2fs -E offset=4000256 testing.img 6316k
残念ながら、すべてのmkfs
にそのようなオプションがあるわけではありません。 mkfs.vfat
はしません。したがって、別の解決策は、パーティションのサイズの別のファイルを作成し、そのファイルでmkfs
を使用してから、dd
を使用してコンテンツを完全な仮想ディスクにコピーすることです。
dd if=testing.img of=testing.fat32.img bs=512 skip=34 count=7779
mkfs -t vfat testing.fat32.img
dd if=testing.fat32.img of=testing.img bs=512 seek=34 count=7779 conv=notrunc
最もクリーンで最速のソリューションではありませんが、機能し、非常に一般的であり、root権限を必要としません。変換オプションsparse
を使用して、ゼロの長いシーケンスを書き込まないことで、処理を少し高速化することもできます。
ファイルシステムをサポートしている場合は、Fuse
を使用してファイルシステムをパーティションにマウントできます。 Fuse-ext2
という名前のext
ファイルシステムと、FAT
という名前のfusefat
の標準サポートがあります。残念ながら、現時点ではoffset
オプションを使用していません。したがって、mount
または以前と同じdd
トリックを使用する必要があると思います。
partx
またはkpartx
(またはmount
の-o offset
オプション)を使用する標準メソッドには、root権限が必要です。 dd
ソリューションは遅く、複雑で、エラープロンプトが表示されます。
次の組み合わせを使用してみてください。
そして:
例:
# Create 1GB sparse file
truncate -s 1G disk1.bin
# Create simple ms-dos partition table an a single partition with maximum free space
echo -e "o\nn\np\n1\n2048\n-1\np\nw\n" | /sbin/fdisk disk1.bin
Welcome to fdisk (util-linux 2.34).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x4643133c.
Command (m for help): Created a new DOS disklabel with disk identifier 0xff5d1f1e.
Command (m for help): Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): Partition number (1-4, default 1): First sector (2048-2097151, default 2048): Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-2097151, default 2097151):
Created a new partition 1 of type 'Linux' and of size 1023 MiB.
Command (m for help): Disk disk1.bin: 1 GiB, 1073741824 bytes, 2097152 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xff5d1f1e
Device Boot Start End Sectors Size Id Type
disk1.bin 1 2048 2097150 2095103 1023M 83 Linux
Command (m for help): The partition table has been altered.
Syncing disks.
# Check out the offset and size in bytes
$ parted disk1.bin
GNU Parted 3.3
Using /kvm/test2/disk1/disk1.bin
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit b
(parted) p
Model: (file)
Disk /kvm/test2/disk1/disk1.bin: 1073741824B
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1048576B 1073741311B 1072692736B primary fat32
(parted) q
# Create a placeholder file for fuseloop to use
touch disk1.bin.part1
# fuseloop - take a raw disk image and create a "loopback block device file" for a partition within the raw disk image file
# fuseloop -O OFFSET -S SIZE DISKFILE.RAW PARTITIONFILE.RAW
$ fuseloop -O 1048576 -S 1072692736 disk1.bin disk1.bin.part1
$ findmnt $(realpath disk1.bin.part1)
TARGET SOURCE FSTYPE OPTIONS
/kvm/test2/disk1/disk1.bin.part1 /dev/Fuse fuse rw,nosuid,nodev,relatime,user_id=0,group_id=0
# Create the filesystem
$ /sbin/mkfs.vfat -n DATA -v disk1.bin.part1
mkfs.fat 4.1 (2017-01-24)
Auto-selecting FAT32 for large filesystem
disk1.bin.part1 has 255 heads and 63 sectors per track,
hidden sectors 0x0000;
logical sector size is 512,
using 0xf8 media descriptor, with 2095103 sectors;
drive number 0x80;
filesystem has 2 32-bit FATs and 8 sectors per cluster.
FAT size is 2048 sectors, and provides 261371 clusters.
There are 32 reserved sectors.
Volume ID is c86be444, volume label DATA .
# Make a mountpoint dir (please don't use /tmp)
mkdir /tmp/mnt
# fusefat - take the "loopback block device file" and mount it (-o ro or -o rw required)
# fusefat -o MODE PARTITIONFILE.RAW /path/to/mountpoint/
$ fusefat -o ro disk1.bin.part1 /tmp/mnt/
fat type: FAT32. Fsi at 1
Fsioff: 512, size: 512
--- nxtfree --- :4
--- freecnt --- :261368
dataclusters :261371
first data byte : 2113536
1st fat off : 16384
2nd fat off : 1064960
fat_eoc_value: 268435448
fat_eoc_value is eoc?: 1
$ findmnt /tmp/mnt/
TARGET SOURCE FSTYPE OPTIONS
/tmp/mnt/ fusefat Fuse.fusefat ro,nosuid,nodev,relatime,user_id=0,group_id=0
# Unmount the filesystem (and verify)
$ fusermount -u /tmp/mnt/
$ findmnt /tmp/mnt/
# Unmount the "loopback block device file" (and verify)
$ fusermount -u disk1.bin.part1
$ findmnt $(realpath disk1.bin.part1)