find
filesystem

strictatime と find を使ってどのファイルがビルドに使われたかを調べる

やりたいこと

ビルド(など)の処理の際に実際にどのファイルが使われているか知りたいことがあります。

例えばこんなケースです。

  • 複数のビルドコンフィギュレーションがある大きなプロジェクトで、実際のプロダクトに使われているファイルを知りたい
    • プロダクトに関するコードメトリクス情報を収集するのに関係ないファイルは外したい、とか
  • もっと簡単に、古くなって既に使われていないファイルを削除したい、とか。

単純なやり方ですが、ファイルシステムの atime で調べられることがあります。

マウントオプションの変更

atime はパフォーマンスを悪化させるため、最近は relatimenoatime でマウントされていることが多いと思います。

手元の Ubuntu 16.04 LTS では

$ mount | grep sdb 
/dev/sdb1 on /mnt type ext4 (rw,relatime,data=ordered) 

のようになっていました。
atime を有効にするため、strictatime で remount します。

$ sudo mount -o strictatime,remount /mnt 
$ mount | grep sdb 
/dev/sdb1 on /mnt type ext4 (rw,data=ordered) 

これで有効になりました。
試してみます。 atime の確認には stat(1) コマンドを使うのがお手軽でしょう。

$ touch hello 
$ stat hello 
  File: 'hello' 
  Size: 0 Blocks: 0 IO Block: 4096 regular empty file 
Device: 801h/2049d  Inode: 256837 Links: 1 
Access: (0664/-rw-rw-r--) Uid: ( 1000/testuser) Gid: ( 1000/testgroup) 
Access: 2017-12-05 14:56:04.081279945 +0900 
Modify: 2017-12-05 14:56:04.081279945 +0900 
Change: 2017-12-05 14:56:04.081279945 +0900 
 Birth: - 
$ cat hello 
$ stat hello 
  File: 'hello' 
  Size: 0 Blocks: 0 IO Block: 4096 regular empty file 
Device: 801h/2049d  Inode: 256837 Links: 1 
Access: (0664/-rw-rw-r--) Uid: ( 1000/testuser) Gid: ( 1000/testgroup) 
Access: 2017-12-05 14:56:20.369457030 +0900 
Modify: 2017-12-05 14:56:04.081279945 +0900 
Change: 2017-12-05 14:56:04.081279945 +0900 
 Birth: - 

うまく atime が更新されているようです。

find

find には -anewer というオプションがあります。(GNU find 4.7.0 で確認)

      -anewer file
              File  was  last accessed more recently than file was modified.
              If file is a symbolic link and the -H option or the -L  option
              is  in  effect,  the  access  time of the file it points to is
              always used.

これを使います。ビルド処理であればこんな感じです。

  1. ソースコードを取得(更新)
  2. touch STARTTIME
  3. ビルド(など)
  4. $ find . -anewer STARTFILE -print などとしてビルドの過程で参照されたファイルのリストを取得

この方法が使えるかどうかはもちろんビルドシステム次第です。全てのファイルの内容を見に行ってしまうような仕組みだと使えません。

まとめ

atime と find を使って、ビルド(など)の処理の際に実際にどのファイルが使われているか調べる方法を紹介しました。

ごく単純な内容ですが、最近は atime が (毎回は) 更新されない環境が多いと思うのであえて書いてみました。