テスト環境の作成
テストパーティションを作成してマウントして、以降のテストを行うユーザで書き込み可能にしておく。
# dd if=/dev/zero of=./vdz0 bs=1024 count=10K # dd if=/dev/zero of=./vdz1 bs=1024 count=10K # mkfs.ext4 ./vdz0 # mkfs.ext4 ./vdz1 # mkdir -p /mnt/hardlink_test/vdz0 # mkdir -p /mnt/hardlink_test/vdz1 # mount ./vdz0 /mnt/hardlink_test/vdz0 # mount ./vdz1 /mnt/hardlink_test/vdz1 # chown ****:**** /mnt/hardlink_test/vdz0 # chown ****:**** /mnt/hardlink_test/vdz1
テストを実行するユーザでテストファイルを作成。以下のファイルを作成。相対ファイルパスにcon0が含まれるファイルの内容は同じ。ino0が含まれるファイルのinodeは同じ。
$ find /mnt/hardlink_test/vdz0/hardlink_test_dir /mnt/hardlink_test/vdz1/hardlink_test_dir -type f -printf '%D %i %n %P\n' | sort -k1,1n -k4,4 1792 13 2 con0/dev0/ino0/name0 1792 13 2 con0/dev0/ino0/name1 1792 15 2 con0/dev0/ino2/name0 1792 15 2 con0/dev0/ino2/name1 1792 14 2 con1/dev0/ino1/name0 1792 14 2 con1/dev0/ino1/name1 1792 16 2 con1/dev0/ino3/name0 1792 16 2 con1/dev0/ino3/name1 1793 13 2 con0/dev1/ino0/name0 1793 13 2 con0/dev1/ino0/name1 1793 15 2 con0/dev1/ino2/name0 1793 15 2 con0/dev1/ino2/name1 1793 14 2 con1/dev1/ino1/name0 1793 14 2 con1/dev1/ino1/name1 1793 16 2 con1/dev1/ino3/name0 1793 16 2 con1/dev1/ino3/name1
hardlink
hardlink を使うと期待通りの結果が得られる。すなわち、同じデバイスに含まれる同一内容を持つファイルは全て一つのiノード番号を持つようになった。
$ find /mnt/hardlink_test/vdz0/hardlink_test_dir /mnt/hardlink_test/vdz1/hardlink_test_dir -type f -printf '%D %i %n %P\n' | sort -k1,1n -k4,4 1792 13 2 con0/dev0/ino0/name0 1792 13 2 con0/dev0/ino0/name1 1792 15 2 con0/dev0/ino2/name0 1792 15 2 con0/dev0/ino2/name1 1792 14 2 con1/dev0/ino1/name0 1792 14 2 con1/dev0/ino1/name1 1792 16 2 con1/dev0/ino3/name0 1792 16 2 con1/dev0/ino3/name1 1793 13 2 con0/dev1/ino0/name0 1793 13 2 con0/dev1/ino0/name1 1793 15 2 con0/dev1/ino2/name0 1793 15 2 con0/dev1/ino2/name1 1793 14 2 con1/dev1/ino1/name0 1793 14 2 con1/dev1/ino1/name1 1793 16 2 con1/dev1/ino3/name0 1793 16 2 con1/dev1/ino3/name1 $ hardlink --ignore-time /mnt/hardlink_test Mode: real Files: 16 Linked: 8 files Compared: 0 xattrs Compared: 8 files Saved: 20 bytes Duration: 0.00 seconds $ echo $? 0 $ find /mnt/hardlink_test/vdz0/hardlink_test_dir /mnt/hardlink_test/vdz1/hardlink_test_dir -type f -printf '%D %i %n %P\n' | sort -k1,1n -k4,4 1792 13 4 con0/dev0/ino0/name0 1792 13 4 con0/dev0/ino0/name1 1792 13 4 con0/dev0/ino2/name0 1792 13 4 con0/dev0/ino2/name1 1792 14 4 con1/dev0/ino1/name0 1792 14 4 con1/dev0/ino1/name1 1792 14 4 con1/dev0/ino3/name0 1792 14 4 con1/dev0/ino3/name1 1793 13 4 con0/dev1/ino0/name0 1793 13 4 con0/dev1/ino0/name1 1793 13 4 con0/dev1/ino2/name0 1793 13 4 con0/dev1/ino2/name1 1793 14 4 con1/dev1/ino1/name0 1793 14 4 con1/dev1/ino1/name1 1793 14 4 con1/dev1/ino3/name0 1793 14 4 con1/dev1/ino3/name1
rdfind
rdfind を使うと期待通りの結果が得られない。rdfind の出力はハードリンクの作成に失敗したことを伝えているが、戻り値はゼロで失敗を判断しづらい。また、ハードリンクの作成に失敗したファイルは結果的に削除される事になる。さらに、rdfind の出力には現れないものの、同一の内容を持つファイルがハードリンクになっていない場合がある。
$ find /mnt/hardlink_test/vdz0/hardlink_test_dir /mnt/hardlink_test/vdz1/hardlink_test_dir -type f -printf '%D %i %n %P\n' | sort -k1,1n -k4,4 1792 13 2 con0/dev0/ino0/name0 1792 13 2 con0/dev0/ino0/name1 1792 15 2 con0/dev0/ino2/name0 1792 15 2 con0/dev0/ino2/name1 1792 14 2 con1/dev0/ino1/name0 1792 14 2 con1/dev0/ino1/name1 1792 16 2 con1/dev0/ino3/name0 1792 16 2 con1/dev0/ino3/name1 1793 13 2 con0/dev1/ino0/name0 1793 13 2 con0/dev1/ino0/name1 1793 15 2 con0/dev1/ino2/name0 1793 15 2 con0/dev1/ino2/name1 1793 14 2 con1/dev1/ino1/name0 1793 14 2 con1/dev1/ino1/name1 1793 16 2 con1/dev1/ino3/name0 1793 16 2 con1/dev1/ino3/name1 $ rdfind -makehardlinks true /mnt/hardlink_test Now scanning "/mnt/hardlink_test", found 16 files. Now have 16 files in total. Removed 8 files due to nonunique device and inode. Now removing files with zero size from list...removed 0 files Total size is 40 bytes or 40 b Now sorting on size:removed 0 files due to unique sizes from list.8 files left. Now eliminating candidates based on first bytes:removed 0 files from list.8 files left. Now eliminating candidates based on last bytes:removed 0 files from list.8 files left. Now eliminating candidates based on md5 checksum:removed 0 files from list.8 files left. It seems like you have 8 files that are not unique Totally, 30 b can be reduced. Now making results file results.txt Now making hard links. failed to make hardlink /mnt/hardlink_test/vdz1/hardlink_test_dir/con0/dev1/ino2/name0 to /mnt/hardlink_test/vdz0/hardlink_test_dir/con0/dev0/ino2/name0 Rdutil.cc: Failed to apply function f on it. failed to make hardlink /mnt/hardlink_test/vdz1/hardlink_test_dir/con0/dev1/ino0/name0 to /mnt/hardlink_test/vdz0/hardlink_test_dir/con0/dev0/ino2/name0 Rdutil.cc: Failed to apply function f on it. failed to make hardlink /mnt/hardlink_test/vdz1/hardlink_test_dir/con1/dev1/ino3/name0 to /mnt/hardlink_test/vdz0/hardlink_test_dir/con1/dev0/ino3/name0 Rdutil.cc: Failed to apply function f on it. failed to make hardlink /mnt/hardlink_test/vdz1/hardlink_test_dir/con1/dev1/ino1/name0 to /mnt/hardlink_test/vdz0/hardlink_test_dir/con1/dev0/ino3/name0 Rdutil.cc: Failed to apply function f on it. Making 2 links. + echo $? 0 $ find /mnt/hardlink_test/vdz0/hardlink_test_dir /mnt/hardlink_test/vdz1/hardlink_test_dir -type f -printf '%D %i %n %P\n' | sort -k1,1n -k4,4 1792 15 3 con0/dev0/ino0/name0 1792 13 1 con0/dev0/ino0/name1 1792 15 3 con0/dev0/ino2/name0 1792 15 3 con0/dev0/ino2/name1 1792 16 3 con1/dev0/ino1/name0 1792 14 1 con1/dev0/ino1/name1 1792 16 3 con1/dev0/ino3/name0 1792 16 3 con1/dev0/ino3/name1 1793 13 1 con0/dev1/ino0/name1 1793 15 1 con0/dev1/ino2/name1 1793 14 1 con1/dev1/ino1/name1 1793 16 1 con1/dev1/ino3/name1