web-dev-qa-db-ja.com

大きなパーティションを持つ小さなディスクイメージを作成するにはどうすればよいですか

組み込みシステム用のディスクイメージを作成しています(4GB SDカードに配置されます)。システムに2つのパーティションが必要です。 「ルート」(200Mb)、および「データ」パーティション(800Mb)。

Ddを使用して空の1GBファイルを作成します。次に、partedを使用してパーティションを設定します。それぞれをループデバイスにマウントしてからフォーマットします。 'ルート'のext2 'データ'のext4。ルートファイルシステムを「ルート」パーティションに追加し、「データ」を空のままにします。

ここに問題があります。私は今、1GBの画像に行き詰まり、その上に200MBのデータしかありません。理論的には、イメージを切り詰めて言う必要があります。201MBでもファイルシステムをマウントできますか?残念ながら、これが当てはまるとは思いませんでした。

私は過去に、4GBのSDカード全体を利用するためのパーティションを持つ、30Mbのイメージを作成するために使用されたFreescaleのビルド環境を使用したことを思い出しました。残念ながら、現時点では、彼らがそれをどのように行っていたかを見つけることができません。

Extファイルシステムのディスク上のフォーマットを読みましたが、最初のスーパーブロック(バックアップスーパーブロックと未使用のブロックテーブルを除く)を超えてデータがない場合は、そこで切り捨てることができると思いました。

残念ながら、これを行うと、マウントシステムがおかしくなります。その後、FSCKを実行し、スーパーブロックとブロックテーブルを復元して、問題なくマウントできます。それが必要だとは思いません。

おそらく別のファイルシステムが機能するでしょうか。何か案は?

ありがとう、

編集

ファイルシステムを読み取るようにパーティションを変更しました。パーティションはまだあり、変更されませんが、イメージを切り捨てた後、ファイルシステムは破壊されます。

編集

「データ」パーティションのスーパーブロックとiノード/ブロックテーブルの最初のセットよりも少し大きいサイズにファイルを切り捨てると、(データブロック範囲のどこかで)ファイルシステムが実行せずにマウント不能になる場合があります残りのスーパーブロックとブロック/ iノードテーブルを復元するためのfsck

7
AllenKll

まず、スパースイメージをディスクに書き込むと、ではなくそのイメージファイルのサイズ全体(穴とすべて)がディスクを覆ってしまいます。これは、スパースファイルの処理がファイルシステムの品質であるためです-そしてrawデバイス(イメージを書き込むデバイスなど)にはそのようなものがありませんまだ。スパースファイルは、格納されているが理解できるファイルシステムによって制御されているメディアに安全かつ安全に保存できますスパースファイル(ext4デバイスなど)書き出すとすぐに包まれますあなたがそれを意図しているすべて。そして、あなたがすべきことは次のいずれかです:

  1. 書き込みの準備ができるまで、スパースファイルを理解するfsに保存するだけです。

  2. 2層にして...

    • つまり、メインイメージをファイルに書き出し、スパースファイルを理解するfsを使用して別のイメージを作成してから、イメージをイメージにコピーして...

    • イメージを作成するときは、最初に親イメージを作成し、次にメインイメージを作成します。

以下がその方法です。

  • 1GBのスパースファイルを作成...

    dd bs=1kx1k seek=1k of=img </dev/null
    
  • 2つのext4パーティションをそのパーティションテーブルに書き込みます:1 200MB、2 800MB .. ..

    printf '%b\n\n\n\n' n '+200M\nn\n' 'w\n\c' | fdisk img
    
  • ext4artitionedループデバイス上に2つの-Pファイルシステムを作成し、最初のループデバイスに2番目のコピーを配置します。

    Sudo sh -c '
        for p in "$(losetup --show -Pf img)p"*        ### the for loop will iterate
        do    mkfs.ext4 "$p"                          ### over fdisks two partitions
              mkdir -p ./mnt/"${p##*/}"               ### and mkfs, then mount each
              mount "$p" ./mnt/"${p##*/}"             ### on dirs created for them
        done; sync; cd ./mnt/*/                       ### next we cp a sparse image
        cp --sparse=always "$p" ./part2               ### of part2 onto part1
        dd bs=1kx1k count=175 </dev/zero >./zero_fill ### fill out part1 w/ zeroes
        sync; cd ..; ls -Rhls .                       ### sync, and list contents
        umount */; losetup -d "${p%p*}"               ### last umount, destroy
        rm -rf loop*p[12]/ '                          ### loop devs and mount dirs
    

    mke2fs 1.42.12 (29-Aug-2014)
    Discarding device blocks: done
    Creating filesystem with 204800 1k blocks and 51200 inodes
    Filesystem UUID: 2f8ae02f-4422-4456-9a8b-8056a40fab32
    Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729
    
    Allocating group tables: done
    Writing inode tables: done
    Creating journal (4096 blocks): done
    Writing superblocks and filesystem accounting information: done
    
    mke2fs 1.42.12 (29-Aug-2014)
    Discarding device blocks: done
    Creating filesystem with 210688 4k blocks and 52752 inodes
    Filesystem UUID: fa14171c-f591-4067-a39a-e5d0dac1b806
    Superblock backups stored on blocks:
        32768, 98304, 163840
    
    Allocating group tables: done
    Writing inode tables: done
    Creating journal (4096 blocks): done
    Writing superblocks and filesystem accounting information: done
    
    175+0 records in
    175+0 records out
    183500800 bytes (184 MB) copied, 0.365576 s, 502 MB/s
    ./:
    total 1.0K
    1.0K drwxr-xr-x 3 root root 1.0K Jul 16 20:49 loop0p1
       0 drwxr-xr-x 2 root root   40 Jul 16 20:42 loop0p2
    
    ./loop0p1:
    total 176M
     12K drwx------ 2 root root  12K Jul 16 20:49 lost+found
     79K -rw-r----- 1 root root 823M Jul 16 20:49 part2
    176M -rw-r--r-- 1 root root 175M Jul 16 20:49 zero_fill
    
    ./loop0p1/lost+found:
    total 0
    
    ./loop0p2:
    total 0
    
  • これで多くの出力が得られます(主にmkfs.ext4から)が、特に下部のlsビットに注意してください。 ls -sは、ディスク上のファイルの実際の-sizeを表示し、常に最初の列に表示されます。

  • これで、基本的にイメージを最初のパーティションのみに縮小できます...

    fdisk -l img
    

    Disk img: 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: 0xc455ed35
    
    Device Boot  Start     End Sectors  Size Id Type
    img1          2048  411647  409600  200M 83 Linux
    img2        411648 2097151 1685504  823M 83 Linux
    
  • そこにfdiskは、img..の最初のパーティションに411647 + 1512バイトのセクターがあることを示しています。

    dd seek=411648 of=img </dev/null
    
  • これにより、imgファイルが最初のパーティションのみに切り捨てられます。見る?

    ls -hls img
    

    181M -rw-r--r-- 1 mikeserv mikeserv 201M Jul 16 21:37 img
    
  • ...しかし、そのパーティションをマウントすることはできます...

    Sudo mount "$(Sudo losetup -Pf --show img)p"*1 ./mnt
    
  • ...そしてここにその内容があります...

    ls -hls ./mnt
    

    total 176M
     12K drwx------ 2 root root  12K Jul 16 21:34 lost+found
     79K -rw-r----- 1 root root 823M Jul 16 21:34 part2
    176M -rw-r--r-- 1 root root 175M Jul 16 21:34 zero_fill
    
  • そして 2番目のパーティションの保存されたイメージを最初のパーティションに追加できます...

    Sudo sh -c '
        dd seek=411648 if=./mnt/part2 of=img
        umount ./mnt; losetup -D
        mount "$(losetup -Pf --show img)p"*2 ./mnt
        ls ./mnt; umount ./mnt; losetup -D'
    

    1685504+0 records in
    1685504+0 records out
    862978048 bytes (863 MB) copied, 1.96805 s, 438 MB/s
    lost+found
    
  • これで、imgファイルが大きくなりました。スパースではなくなりました...

    ls -hls img
    

    1004M -rw-r--r-- 1 mikeserv mikeserv 1.0G Jul 16 21:58 img
    
  • ...しかし、それを削除するのは、もちろん、最初と同じくらい簡単です...

    dd seek=411648 of=img </dev/null
    ls -hls img
    

    181M -rw-r--r-- 1 mikeserv mikeserv 201M Jul 16 22:01 img
    
4
mikeserv

これを行う最も簡単な方法は、バッキングファイルをスパースファイルとして作成することです。つまり、truncate -s 1G disk.img(またはその他)の代わりにdd if=/dev/zero bs=1048576 count=1024 of=disk.imgを使用して1GBにします。素敵なことに、truncateもはるかに高速です。

ファイルにls -lを実行すると、1GBと表示されますが、それは見かけのサイズにすぎません。 du disk.imgは実際のサイズを示します。

(注-スパースファイルをサポートするファイルシステムにイメージを配置する必要があります。一般的なUnixのものはすべてサポートします。Ext2/ 3/4はすべてサポートします。FAT32はサポートしません。HFS+もサポートしません。)

注:スパースファイルは、論理的にはフルサイズのままです。書き込まれたことのないセクションだけが物理的にディスクに保存されません。ほとんどの場合、実際には保存されていない部分はプログラムから隠されています。ただし、いくつかのユーティリティはそれをサポートしています。 (例:dd conv=sparsecp --sparse=auto/alwaysなど)。実際のUSBスティックできません疎です。また、dd conv=sparseを使用して書き込むと、おそらくはるかに高速になりますが、予想されるNUL(0x00)でいっぱいのブロックではなく、以前にあったデータをすべて残します。 (空き領域として)正常に動作するはずですが、USBスティックに古いデータが残るため、おそらくセキュリティ上の懸念があります。

6
derobert

このイメージを800MBのスペースで作成して、sdカードにコピーできるようにしますか。しかし、画像を保存するときにスペースを無駄にしたくない。もしそうなら、bzipなどの圧縮をお勧めします。ただし、未使用のブロックがゼロに初期化されるかどうかに依存します。

0
ctrl-alt-delor