web-dev-qa-db-ja.com

スパースファイル、dd、seek、inodeブロック構造につ​​いて

職場では、Oracle VMゲストディスクイメージ用の環境)の一部としてスパースファイルを使用しています。同僚からのいくつかの質問(回答済み)の後、スパースファイルに関する質問が残りました、そしておそらくより広くiノード構造について-stat(2)とstatfs(2)(FreeBSDの場合)のmanページを読むと、Cをもっと知っていればもっと簡単に理解できると思いますが、私のCの知識せいぜい最小限です...

これのいくつかはファイルシステムのタイプに依存していることを理解しています。私は主にFreeBSD/Solarisとext4のUFSに興味があります-ZFSはプラスになるでしょうが、私は希望を持ち続けるつもりはありません:)
Solaris 10、FreeBSD 10.3、CentOS6.7を定期的に使用しています。ここでのコマンドはCentOS 6.7 VMで実行されていますが、FreeBSDと相互参照されています。可能であれば、POSIXの観点から理解を深め、それが不可能な場合はLinuxよりもFreeBSDを優先することに興味があります。

次の一連のコマンドを検討してください。

printf "BIL" > /tmp/BIL

dd of=/tmp/sparse bs=1 count=0 seek=10
dd if=/tmp/BIL of=/tmp/sparse bs=1 count=3 seek=10

dd if=/tmp/BIL of=/tmp/sparse bs=1 count=3 seek=17

dd of=/tmp/sparse bs=1 count=0 seek=30
dd if=/tmp/BIL of=/tmp/sparse bs=1 count=3 seek=30

ファイル/tmp/BILの内容(16進数)は4942 004cである必要があるため、ファイル/tmp/sparsehexdumpすると、全体にこの組み合わせがわずかに表示されます。

%>hexdump sparse
0000000 0000 4942 004c 0000 0000 4942 004c 0000
0000010 4200 4c49 0000 0000 0000 0000 0000 4942
0000020 004c
0000021

%>cat sparse
BILBILBILBIL%

1。2番目の "BIL"が順不同で表示されるのはなぜですか?つまり、4200 4c49ではなく4942 004c?これは、3番目のddコマンドによって作成されました。

2。catおよび他のツールはどのようにして正しい順序で印刷することを知っていますか?

lsを使用すると、使用されたとされるスペースと割り当てられたブロックを確認できます。

%>ls -ls /tmp/sparse
8.0K -rw-r--r--. 1 bil bil 33 May 26 14:17 /tmp/sparse

申し立てられたサイズは33バイトですが、割り当てられたサイズは8キロバイトです(ファイルシステムのブロックサイズは4Kです)。

lsのようなプログラムは、「申し立てられた」サイズと割り当てられたサイズをどのように区別しますか?

割り当てられたサイズが直接ブロックと間接ブロックを歩くことによって計算されている間にinodeに格納された「疑わしい」数値かどうか疑問に思いましたが、歩くことによる計算には時間がかかり、lsなどのツールがすぐに戻るためこれは正しくありません、非常に大きなファイルの場合でも。

4。iノード情報の問い合わせに使用できるツールは?

statを知っていますが、iノード内のすべてのフィールドの値を出力していないようです...

5。直接ブロックと間接ブロックを歩くことができるツールはありますか?

ディスク上の各アドレスと、データがどのように格納されるかについてもう少し理解するための内容を見るのは興味深いでしょう

上記の他のコマンドの後に次のコマンドを実行すると、ファイル/tmp/sparseが切り捨てられます。

%>dd of=/tmp/sparse bs=1 count=0 seek=5
%>hexdump sparse
0000000 0000 4942 004c
0000005

6。ddがファイルを切り捨てて、ddまたは別のツールがファイルの途中に書き込むことができるのはなぜですか?

最後に、スパースファイルはスペースを事前に割り当てるための良いアイデアのように見えますが、コマンドがファイルを切り捨てたり、任意に大きくしたりしないというファイルシステムまたはオペレーティングシステムレベルの保証はないようです。

7。スパースファイルが縮小/拡大されるのを防ぐメカニズムはありますか?そうでない場合、なぜスパースファイルが役立つのですか?


上記の各質問は個別のSO質問である可能性がありますが、それらはすべて基礎となる理解に関連しているため、分析することはできません。

6
forquare

いくつかの簡単な答え:最初に、スパースファイルを作成しませんでした。これらの追加コマンドを試してください

dd if=/tmp/BIL of=/tmp/sparse seek=1000
ls -ls /tmp/sparse

サイズは512003バイトですが、必要なのは8ブロックだけです。 nullバイトはブロック全体を占める必要があり、ファイルシステム内でスパースになる可能性があるため、ブロック境界上にある必要があります。

  1. 「BIL」の2番目の出現が順不同であるのはなぜですか?

    リトルエンディアンシステムを使用していて、出力をショートパンツで書き込んでいるためです。 catのようにバイトを使用します。

  2. 猫や他のツールはどのようにして正しい順序で印刷することを知っていますか?

    それらはバイトで機能します。

  3. Lsのようなプログラムは、「割り当てられた」サイズと割り当てられたサイズをどのように区別しますか?

    lsなどは、次の2つの値を返すstat(2)システムコールを使用します。

    st_size;             /* total size, in bytes */ 
    blkcnt_t  st_blocks; /* number of 512B blocks allocated */
    
  4. Iノード情報を調べるためにどのツールを使用できますか?

    統計は良いです。

  5. 直接ブロックと間接ブロックを歩くことができるツールはありますか?

    Ext2/3/4では、hdparm --fibmapをファイル名とともに使用できます。

    $ Sudo hdparm --fibmap ~/sparse 
    filesystem blocksize 4096, begins at LBA 25167872; assuming 512 byte sectors.
    byte_offset  begin_LBA    end_LBA    sectors
         512000  226080744  226080751          8
    

    debugfsを使用することもできます。

    $ Sudo debugfs /dev/sda3
    debugfs:  stat <1040667>
    Inode: 1040667   Type: regular    Mode:  0644   Flags: 0x0
    Generation: 1161905167    Version: 0x00000000
    User:   127   Group:   500   Size: 335360
    File ACL: 0    Directory ACL: 0
    Links: 1   Blockcount: 664
    Fragment:  Address: 0    Number: 0    Size: 0
    ctime: 0x4dd61e6c -- Fri May 20 09:55:24 2011
    atime: 0x4dd61e29 -- Fri May 20 09:54:17 2011
    mtime: 0x4dd61e6c -- Fri May 20 09:55:24 2011
    Size of extra inode fields: 4
    BLOCKS:
    (0-11):4182714-4182725, (IND):4182726, (12-81):4182727-4182796
    TOTAL: 83
    
  6. Ddがファイルを切り捨てて、ddまたは別のツールがファイルの途中に書き込むことができるのはなぜですか?

    はい、ddは途中で書き込むことができます。 conv=notruncを追加します。

  7. スパースファイルが縮小/拡大されるのを防ぐメカニズムはありますか?そうでない場合、なぜスパースファイルが役立つのでしょうか。

    いいえ。スペースを取らないからです。

ファイルのまばらな側面は、プログラムに対して完全に透過的である必要があります。これは、プログラムがファイルを更新すると、まばらさが失われる場合があることを意味します。

一部のコピーユーティリティには、まばらさを維持するオプションがあります(例:tar --sparsersync --sparse)。

cp --sparse=alwaysを使用して、ファイル内の適切に配置されたゼロブロックをスパースネスに明示的に変換できます。逆に、cp --sparse=neverを使用して、スパーススペースを実際のゼロに変換できます。

8
meuh

Linuxでファイルレイアウトをダンプするためのより良いツールは、e2fsprogsパッケージに含まれているfilefragユーティリティです。これにより、ファイル内のすべてのエクステントが効率的かつコンパクトにダンプされます。

$ dd of=/var/tmp/sparse if=/dev/zero count=1
$ dd of=/var/tmp/sparse if=/dev/zero seek=1000 count=1
$ filefrag -v /var/tmp/sparse
Filesystem type is: ef53
File size of /var/tmp/sparse is 512512 (126 blocks of 4096 bytes)
ext:     logical_offset:        physical_offset: length:   expected: flags:
  0:        0..       0:    3441408..   3441408:      1: 
  1:      125..     125:    3441533..   3441533:      1:    3441409: last,eof
/var/tmp/sparse: 2 extents found

FIEMAP ioctlは、ほとんどの一般的なLinuxファイルシステム(ext4、XFS、Btrfsなど)で利用できますが、ZFSではまだ利用できません(開発中です)。

3
LustreOne