web-dev-qa-db-ja.com

パーティションおよびディスクイメージのユーザースペース操作

Linuxシステムでは、ユーザースペースツールのみを使用してパーティションイメージ(おそらくext2ファイルシステムのみが含まれる)を作成および操作し、それらのパーティションイメージを使用してディスクイメージを作成することは可能ですか?

使うことができます genext2fsユーザースペースにext2ファイルシステムのイメージを生成しますが、ルートアクセスを必要とせずにディスクイメージを操作できるツール(パーティションテーブルの作成や既存のパーティションイメージからのディスクイメージの作成など)が見つかりません。現在、ディスクイメージ内のパーティションをマウントするためにkpartxを使用していますが、これにはrootが必要なため、スクリプトに適していないため、ビルドスクリプトにエラーが発生した場合はそうではありません。トラップされた場合、マッパーデバイスは引き続き使用されます。

基本的に、3つのディレクトリがあり、各ディレクトリをディスクイメージ上のパーティションにしたいのですが、これをスクリプト化したいので、ルートアクセスを必要とするツールを使用したくありません(これには何もないようです)ルートアクセスが絶対に必要なプロセス)。

4
dreamlax

パーティションの作成

パーティションテーブルを作成するには、デバイスではなくファイルで一般的なツールを直接使用できます。 fdiskpartedなど、ほとんどの標準ツールはこの使用法をサポートする必要があります。 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オプションを使用して、ファイル内の任意のオフセットにext2ext3、または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ソリューションは遅く、複雑で、エラープロンプトが表示されます。

4
Celelibi

次の組み合わせを使用してみてください。

そして:

例:

# 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)
1
Jeremy Smith