GNU/Linuxでハードリンクを削除する、とinodeの話

4 min read

こんにちは、無能です。
久しぶりにlnコマンドでリンクを作成しようとしたときに間違えて-sオプションを消し忘れてハードリンクが作成されてしまったので不要なハードリンクを削除します。

ハードリンクを作成する

オプションナシでlnコマンドを実行するとハードリンクが作成されます。

alleycat:[haturatu]:~/git/hardlink$ ls
alleycat:[haturatu]:~/git/hardlink$ touch hardlink1
alleycat:[haturatu]:~/git/hardlink$ echo "You are an idiot" >> hardlink1 
alleycat:[haturatu]:~/git/hardlink$ cat hardlink1 
You are an idiot
alleycat:[haturatu]:~/git/hardlink$ ls -la
合計 12
drwxr-xr-x   2 haturatu haturatu 4096  112 15:00 .
drwxr-xr-x 114 haturatu haturatu 4096  112 15:00 ..
-rw-r--r--   1 haturatu haturatu   17  112 15:01 hardlink1

上記の様にファイルを作成してみました。

alleycat:[haturatu]:~/git/hardlink$ ln hardlink1 hardlink2
alleycat:[haturatu]:~/git/hardlink$ ls -la
合計 16
drwxr-xr-x   2 haturatu haturatu 4096  112 15:02 .
drwxr-xr-x 114 haturatu haturatu 4096  112 15:00 ..
-rw-r--r--   2 haturatu haturatu   17  112 15:01 hardlink1
-rw-r--r--   2 haturatu haturatu   17  112 15:01 hardlink2

これでハードリンクが作成されました。
そして、以下の標準出力を見てみます。

-rw-r--r--   2 haturatu haturatu   17  112 15:01 hardlink1
-rw-r--r--   2 haturatu haturatu   17  112 15:01 hardlink2

この-rw-r--r-- 22がハードリンクされている数です。ハードリンクされる前と比較して、値が増えていることが確認出来るかと思います。
そして、あくまでこれはリンクされているだけなのでディスク容量自体の逼迫しません。単一のデータを格納しており、inode番号は同一となり同じファイルを示しています。
-iオプションでinode番号を確認します。

alleycat:[haturatu]:~/git/hardlink$ ls -lia
合計 16
13238408 drwxr-xr-x   2 haturatu haturatu 4096  112 15:02 .
11406555 drwxr-xr-x 114 haturatu haturatu 4096  112 15:00 ..
13265123 -rw-r--r--   2 haturatu haturatu   17  112 15:01 hardlink1
13265123 -rw-r--r--   2 haturatu haturatu   17  112 15:01 hardlink2

inodeって?

あくまでこれはファイルシステムに依存するので上記はGNU/Linux環境下でありBSD系のファイルシステムであるとvnodeだったり、ZFSだとznode等とちょっと変わっていますが歴史的に言えば元のUNIXファイルシステムを拡張したものだというイメージでよいのかなと思います。

そして、シンボリックリンクと違いハードリンクはhardlink1を消してもhardlink2は残りますし、hardlink2を消してもhardlink1は残ります。この点で言えばファイルシステムがそのファイル自体を管理しているから、という説明になりそうですがやはりちょっと難解ではありますよね。
しかし、こうみるとハードリンクは便利ですがシンボリックリンクは別のディスク上のファイルも参照できますがハードリンクの場合は別ディスク下には作成できません。
前述の説明も踏まえてシンプルに言えば、ファイルシステムは単一ディスクのinode基準での話なので別ディスクとなるとそのファイルシステムの管轄外、レイヤー構造的に参照できません。
なので、別ディスク上に存在するならばシンボリックリンクを張る必要性が出てきます。

そして、ファイルシステム的にはこれを身近に使っているのはディスクの復旧、リカバリ作業時に過去のinode情報から参照してどのinode番号のファイルが作られたか、削除されたかどうかを識別しています。
ここでトラップですが、ファイルの上書きされるとこのinode番号も更新されてしまいます。つまりはバックアップを取るスクリプト等のときはちゃんと上書き処理が入らないようなスクリプトを作る意識は必要かもしれません。(私は一度やらかしました)

同じinode番号のファイルを特定する

findコマンドで確認ができます。

alleycat:[haturatu]:~/git/hardlink$ find . -inum 13265123
./hardlink2
./hardlink1

じゃあ、これでhardlink1を削除してみます。

alleycat:[haturatu]:~/git/hardlink$ rm -i hardlink1
rm: 通常ファイル 'hardlink1' を削除しますか? y
alleycat:[haturatu]:~/git/hardlink$ ls -lai
合計 12
13238408 drwxr-xr-x   2 haturatu haturatu 4096  112 15:23 .
11406555 drwxr-xr-x 114 haturatu haturatu 4096  112 15:00 ..
13265123 -rw-r--r--   1 haturatu haturatu   17  112 15:01 hardlink2
alleycat:[haturatu]:~/git/hardlink$ cat hardlink2 
You are an idiot

これで、ハードリンクされている値も1となり、元々ln hardlink1 hardlink2hardlink1のリンクを作成して、hardlink1と同じ情報を持っているhardlink2が存在して同じデータを持っていることが確認出来ました。

活用的には

久しぶりに触りましたが、同じディスク内で大きなファイルをコピーさせたいけどディスク消耗は減らしたい場合はハードリンクしたほうがよさそうですね。
まあ、そんなに意識して使うものでもないかもしれませんがファイルシステムの構造がちょっとわかるようなものなので面白いものかなと思います。


それではまた。
よろしくおねがいします。

PGP --- Contact --- Machines