
chattr
Linux マシン ( )のマニュアルを読んでいたkali4-amd64
ところ、ファイル属性の定義リストに次の記述を見つけました。
A directory with the 'P' attribute set will enforce a hierarchical
structure for project id's. This means that files and directory created in
the directory will inherit the project id of the directory, rename
operations are constrained so when a file or directory is moved into
another directory, that the project id's much match. In addition, a hard
link to file can only be created when the project id for the file and the
destination directory match.
Linux/UNIX に関しては「プロジェクト ID」が何なのか個人的にはわかりませんし、グーグルで検索しても結果は得られないので、ここで誰かが助けてくれることを願っています。
答え1
あなたが尋ねているのは、プロジェクトクォータの概念の一部です。プロジェクトクォータは、管理する方法です。ディスククォータ特定のファイルシステムの種類は、プロジェクト ID をサポートする場合とサポートしない場合があります。ext4 に焦点を当てて、次のことから始めましょうman 8 tune2fs
。
-O [^]feature[,...]
ファイルシステム内の指定されたファイルシステム機能 (オプション) を設定またはクリアします。[…][…]
project
プロジェクト ID 追跡を有効にします。これは、プロジェクト クォータ追跡に使用されます。
quota
内部ファイルシステムのクォータ inode を有効にします。[…]
-Q quota-options
スーパーブロックに「クォータ」機能を設定し、指定されたクォータ タイプのクォータ ファイルで作業します。クォータ オプションは、次の 1 つ以上のオプションになります。
[^]usrquota
スーパーブロック内のユーザー クォータ inode を設定/クリアします。
[^]grpquota
スーパーブロック内のグループ クォータ inode を設定/クリアします。
[^]prjquota
スーパーブロック内のプロジェクト クォータ inode を設定/クリアします。
既存のファイルシステムでこれらのオプションを有効にすることができます。
tune2fs -O project,quota /your/device
(または、新しいファイルシステムを作成するときにそれらを指定しますmke2fs
)。次に、プロジェクト クォータを有効にします (必要に応じて、ユーザー クォータやグループ クォータも有効にできます)。
tune2fs -Q prjquota /your/device
マウントする:
mount /your/device /the/mountpoint
setquota
現在、やなどのツールを使用してクォータを管理できますquota
(ツールの古いバージョンには、-P
プロジェクト クォータを処理するオプションがない場合があります)。従来は、ユーザーまたはグループが使用できるディスク容量を制限していました。プロジェクト クォータを使用すると、参加するユーザーやグループに関係なく、「プロジェクト」に対してこれを実行できます。
動作は次のようになります。まずマウントポイントに移動し、いくつかのディレクトリを作成します。
cd /the/mountpoint
mkdir foo bar baz
プロジェクト階層を有効にします:
chattr +P foo bar baz
これらを 2 つの異なるプロジェクトに割り当てます。
chattr -p 123 foo # 123 is an arbitrary number, project id
chattr -p 5 bar baz # so is 5, the point is they are different
次の範囲内でファイルを作成します:
echo "lorem ipsum" > foo/file1
echo "lorem ipsum" > bar/file2
echo "lorem ipsum" > baz/file3
次に呼び出します:
lsattr -pR .
そして、次のような行が表示されます。
123 --------------e---P ./foo/file1
5 --------------e---P ./bar/file2
5 --------------e---P ./baz/file3
これは、idfile1
のプロジェクトに属し123
、id のプロジェクトに属していることを意味します。これらのプロジェクトにクォータを定義すると (つまり、プロジェクトが使用できるディスク容量を制限すると)、各ファイルはそれぞれのプロジェクトのクォータ消費に影響します。file2
file3
5
あなたが引用したものは、今や非常に意味を成しています:
ディレクトリ内に作成されたファイルとディレクトリは、ディレクトリのプロジェクトIDを継承します。
この例では、file1
はプロジェクト ID を から継承しますfoo
。 にさらにファイル/ディレクトリを作成すると、foo
それらも ID を継承します。これにより、あなた (および他のユーザー) は指定されたディレクトリでプロジェクトに取り組むことができ、作成したファイルは自動的にそれぞれのクォータにカウントされます。
ファイルへのハードリンクは、ファイルのプロジェクト ID と宛先ディレクトリが一致する場合にのみ作成できます。
ln ./baz/file3 ./foo/
失敗しますが (試してみてください)、ln ./baz/file3 ./bar/
成功します。OS では、あるプロジェクトに属するファイル (ソース パスがリンク解除されていないため、この状態のままにする必要があります) を別のプロジェクト ディレクトリに簡単に「埋め込む」ことはできません。プロジェクト内でファイルをリンクすることは許可されています。
ファイルまたはディレクトリを別のディレクトリに移動する場合、プロジェクトIDが一致している必要があります。
これは誤解を招くと思います。IDmv
が一致していなくても機能します。ポイントは、
mv baz/file3 foo/
ツールは最初にrename(2)
ファイルを新しいパスに移動しようとしますが、これは失敗します (ln
上記と同様)。通常、または同じプロジェクト内では成功し、元の名前は消えます。どうやら、この動作は「プロジェクト ID が一致する必要がある」ということのようです。
しかし、mv
まだ終了しません。ファイルシステム間の移動に似ています。mv
名前の変更に失敗すると、コピー+削除モードに戻ります。実際には、コピー(新しい inode 番号で) をターゲット ディレクトリにコピーします。この場合、コピーはfoo
(このディレクトリ内の他の新しいファイルと同様に) プロジェクト ID を継承するため、プロジェクトのクォータ消費に影響します123
。その後、元のパスのリンクが解除されます。これにより、プロジェクトのクォータ消費に影響が出る場合もあれば5
、出ない場合もあります。ハードリンクまたはオープン ファイル記述子により、元の inode とデータが残ります。
多少驚くべきことに、新しいファイルが作成され、古いハードリンク (存在する場合) は新しいファイルにリンクされず、古いファイルを指すファイル記述子は新しいファイルとは何の関係もありません。まるで、移動操作がファイルシステム間で実行されたかのようです。
コピー+削除の代わりに名前を変更する方法がありますmv
。元のファイルを手動でターゲットプロジェクトに割り当てると
chattr -p 123 baz/file3
すると、mv baz/file3 foo/
コピーせずに、ハードリンク (存在する場合) を壊さずに、実際に移動されます。ただし、プロジェクト番号は inode (パス、名前、ディレクトリ エントリではない) に属しているため、chattr -p
すべてのハードリンクに影響することに注意してください。
したがって、大きなファイル (つまり、多数のハードリンクの 1 つではなく、いくつかの inode の背後にあるデータ) を別のプロジェクトに移動する必要がある場合は、プロジェクトを変更してから移動することで、不要なコピーを省くことができます。