nfs でマウントした NAS に対しては inotify は効かない

現在、ある病院の内視鏡画像管理システムを新規に構築しようとしていますが、イメージ的にはできると思ったことができずにちょっと足踏みをしてしまいました。

画像閲覧システムを図にすると、以下のようになります

左の図で linux mint にインストールされた dcm4chee と UNITEA を繋ぐと、直接に接続された NAS に dicom ファイルがどんどん保存されます。

新しい dicom ファイルが追加されたことを、内視鏡室のもう 1 台の linux mint からキャッチしたいと思いました。

それができれば、新たに追加された dicom ファイルを python で処理して必要な情報を ubuntu server の mysql に書き込んだり、dicom ファイルから jpg ファイルを作成して別の NAS に保存したりできます。

NFS では inotify が無効

内視鏡室の linux mint で PACS の NAS をマウントして、その NAS のあるディレクトリに何らかの変化があればそれをキャッチしたいと思ったのですが、シェルの inotifywait ではそもそもそれは無理のようです。

python の watchdog という便利なツールがあってそれはとてもいい感じなのですが、やはり NFS では簡単には動作しません。

何時間か試行錯誤して、自分の実力ではできないと判断し teratail に質問したところ、なかなかいい回答が書き込まれました。

PollingObserver を使う

python の watchdog で PollingObserver を使えば期待通りの動作をしてくれます。


import sys
import time
import logging
from watchdog.observers.polling import PollingObserver
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    path = sys.argv[1] if len(sys.argv) > 1 else '/mnt/nas/esDCM'
    event_handler = LoggingEventHandler()
    observer = PollingObserver()
    observer.schedule(event_handler, path, recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

このようにすると、「/mnt/nas/edDCM」に NAS 上でファイルを追加してもそれを検知できます。

NAS の python を使用する

私が teratail に質問した際に、「NAS上で検知して通知するというのが可能ならそっちの方が良いと思います。」というコメントを寄せて頂いた方がいて、ちょっと考えさせられました。

マウントということに対する理解が十分ではないのでハッキリ言えないのですが、例えば 500 GB 程度しかない linux mint に 4 TB の NAS をマウントするということはどういうことなんでしょう?

確かによくわからない状態ですよね。
マウントする方の容量を超えた NAS をマウントするということの意味がよくわからない。

なので、NAS 上に watchdog を設定できないかと考えました。

NAS は synology の DS 720+ なのですが、ssh ログインして python3 を確認すると python3.8 であることがわかりました。

でも、もちろん watchdog なんて使うことはできません。

それで、ローカルの site-packages にあった watchdog をフォルダごと NAS にアップして、NAS の site-packages にコピーしました。

そうすると NAS 上で watchdog が使えるようになりました。

さすがは python

watchdog は安定しない

いろいろ実験してみて達した結論です。

dcm4chee に dicom ファイルをインポートして、それを NAS の watchdog で捕捉して、それらのファイルを linux mint に ftp アップロードし、linux mint でそれらの dicom ファイルのタグ情報を読み取って、データを mysql に記録して、dicom ファイルから jpg ファイルを作成して、それらを別の NAS にアップロードする。

ということをすべてほぼリアルタイムに実行しようとしたのですが、まれにエラーが出ます。
ファイル変換ができないことがあるのです。

そもそもシステムが複雑すぎるような気がしたので、根本的に方法を変更しました。

watchdog じゃなくて、普通に cron で python を 5 分ごとに動かすことにしました。
こうするととても安定します。