web-dev-qa-db-ja.com

ext2またはext3またはext4を検出する信頼できる方法は?

ファイルシステムスーパーブロックを使用して、C/C++プログラムからファイルシステムタイプを検出する必要があります。ただし、ext2とext4のスーパーブロックの間に大きな違いは見られません。 s_rev_levelフィールドは同じ(= 1)、s_minor_rev_levelは同じ(= 0)です。

s_feature_compat(およびその他の機能フィールド)からいくつかの機能をチェックして、ext2でサポートされていない機能を見つけようとすることができました。しかし、パーティションをフォーマットしている人は、意図的に一部の機能を無効にする可能性があります。したがって、このメソッドはext4を検出できますが、ext2とext4固有の機能が無効になっているext4を区別することはできません。

だから、それを行う方法は?

7
HEKTO

さまざまなユーティリティのコードとカーネルコードをしばらく見てみると、 @ Haukeが提案 は正しいようです-ファイルシステムがext2/ext3/ext4であるかどうかは、純粋に次のオプションによって定義されます。有効になっています。

ウィキペディアのページ からext4

下位互換性

ext4はext3およびext2と下位互換性があり、ext3およびext2をext4としてマウントすることができます。これにより、パフォーマンスがわずかに向上します。これは、新しいブロック割り当てアルゴリズムなど、ext4の特定の新機能をext3およびext2でも使用できるためです。

ext3はext4と部分的に上位互換性があります。つまり、ext4はext3としてマウントできます(マウント時にファイルシステムタイプとして「ext3」を使用)。ただし、ext4パーティションがエクステント(ext4の主要な新機能)を使用している場合、ext3としてマウントする機能は失われます。

おそらくすでに知っているように、ext2ext3の間には同様の互換性があります。

blkidが異なるextファイルシステムを区別するために使用するコード を見た後、ext4ファイルシステムをext3として認識されるものに(そしてそこからext2に)変えることができました。 )。これを次のように繰り返すことができるはずです:

truncate -s 100M testfs
mkfs.ext4 -O ^64bit,^extent,^flex_bg testfs <<<y
blkid testfs
tune2fs -O ^huge_file,^dir_nlink,^extra_isize,^mmp testfs
e2fsck testfs
tune2fs -O metadata_csum testfs
tune2fs -O ^metadata_csum testfs
blkid testfs
./e2fsprogs/misc/tune2fs -O ^has_journal testfs
blkid testfs

最初のblkid出力は次のとおりです。

testfs: UUID="78f4475b-060a-445c-a5d2-0f45688cc954" SEC_TYPE="ext2" TYPE="ext4"

2番目は:

testfs: UUID="78f4475b-060a-445c-a5d2-0f45688cc954" SEC_TYPE="ext2" TYPE="ext3"

そして最後のもの:

testfs: UUID="78f4475b-060a-445c-a5d2-0f45688cc954" TYPE="ext2"

e2fsprogsフラグを取得するには、ディストリビューションで使用可能なものよりも新しいバージョンのmetadata_csumを使用する必要があることに注意してください。設定してからこれをクリアする理由は、基になるEXT4_FEATURE_RO_COMPAT_GDT_CSUMフラグに影響を与える他の方法が見つからなかったためです。 metadata_csumEXT4_FEATURE_RO_COMPAT_METADATA_CSUM)とEXT4_FEATURE_RO_COMPAT_GDT_CSUMの基になるフラグは相互に排他的です。 metadata_csumを設定するとEXT4_FEATURE_RO_COMPAT_GDT_CSUMが無効になりますが、metadata_csumを設定解除しても後者は再度有効になりません。

結論

ファイルシステムの内部に関する深い知識が不足しているため、次のいずれかのように思われます。

  1. ジャーナルチェックサムは、ext4として作成されたファイルシステムの定義機能であり、実際には無効にする必要はありません。これを管理したという事実は、実際にはe2fsprogsのバグです。または、

  2. すべてのext4機能は常に無効になるように設計されており、それらを無効にすると、ファイルシステムはすべての目的でext3ファイルシステムになります。

いずれにせよ、ファイルシステム間の高レベルの互換性が明らかに設計目標です。これを、Reiser4が完全に再設計されたReiserFSおよびReiser4と比較してください。本当に重要なのは、存在する機能がシステムのマウントに使用されるドライバーによってサポートされているかどうかです。ウィキペディアの記事に記載されているように、ext4ドライバーはext3およびext2でも使用できます(実際、常にext4ドライバーを使用して他のドライバーを捨てるカーネルオプションがあります)。機能を無効にすると、以前のドライバーはファイルシステムに問題がないため、ファイルシステムのマウントを停止する理由はありません。

推奨事項

Cプログラム内の異なるextファイルシステムを区別するには、libblkidを使用するのが最適なようです。これはutil-linuxの一部であり、これはmountコマンドがファイルシステムタイプを判別するために使用するものです。 APIドキュメントは ここ です。

チェックを独自に実装する必要がある場合は、 libblkidと同じフラグをテストする が正しい方法のようです。特にリンクされているファイルには、実際にテストされているように見えるEXT4_FEATURE_RO_COMPAT_METADATA_CSUMフラグについての言及がありません。

本当にやりたいのであれば、ジャーナルのチェックサムを探すことは、これらのフラグのないファイルシステムが(またはおそらくだったext4であるかどうかを見つける確実な方法かもしれません。

更新

実際には、反対方向に進んでext2ファイルシステムをext4に昇格させる方がやや簡単です。

truncate -s 100M test
mkfs.ext2 test
blkid test
tune2fs -O has_journal test
blkid test
tune2fs -O huge_file test
blkid test

3つのblkid出力:

test: UUID="59dce6f5-96ed-4307-9b39-6da2ff73cb04" TYPE="ext2"
test: UUID="59dce6f5-96ed-4307-9b39-6da2ff73cb04" SEC_TYPE="ext2" TYPE="ext3"
test: UUID="59dce6f5-96ed-4307-9b39-6da2ff73cb04" SEC_TYPE="ext2" TYPE="ext4"

ext3/ext4機能は、ext2として開始されたファイルシステムで有効にすることで非常に簡単にできるという事実は、ファイルシステムタイプが実際に機能によって定義されていることを示す最良のデモンストレーションです。

6
Graeme