Sun Cluster ソフトウェアをお使いであれば、プロキシファイルシステム (Proxy File System、PxFS) の使用をお勧めします。PxFS はグローバルデバイスを可能にします。グローバルデバイスとは、クラスタのデバイス管理の中核をなすものです。ソースが公開されるようになったこともあり、PxFS の利点を説明できる環境は整っています。PxFS アーキテクチャーの概要について、ソースを参照しながら説明したいと思います。ほかのいくつかのブログエントリも参照したいと思います。このエントリでは、PxFS の紹介とグローバルマウントの説明をいたします。
PxFS は、POSIX に準拠し、高可用性を保ちながら、クラスタノード間にディスクベースのファイルシステムを配置するプロトコルレイヤーです。アプリケーションにファイルレベルのロックを要求しなくても、POSIX に準拠したうえで、複数のノードから同時にアクセスすることができます。グローバルマウントを行う際に管理者に求められる作業は、すべてのクラスタノード上にマウントポイントが存在していることの確認だけです。確認後、マウントコマンドに "-g" を付けると、マウントがグローバルになります。次のブログエントリで用語について解説しています。
最初に、専用の物理デバイスを使用しなくても UFS ファイルシステムの作成とグローバルマウントを簡単に行えることを示したいと思います。では、lofi デバイスを作成し、そのデバイスを UFS でフォーマットし、グローバルマウントしてみましょう。
注意: この操作は Solaris 9 では行わないでください。このバージョンにはシステムパニックを発生させる可能性のある lofs バグが含まれているためです。
# mkfile 100m /var/tmp/100m
# LOFIDEV=`lofiadm -a /var/tmp/100m`
# yes | newfs ${LOFIDEV}
では、この lofi デバイスをクラスタ全体にマウントします (すべてのノード上にターゲットディレクトリが存在することを確認してください)。
# mount -g ${LOFIDEV} /mnt
完了です。これでクラスタのどのノードでも /mnt にアクセスでき、node1 上の lofi デバイスの UFS ファイルシステムに透過的にアクセスできます。
では、グローバルマウントについて詳しく見ていきましょう。ここでは、共有ストレージにファイルシステムをグローバルマウントする方法を例に話を進めます。3 つのノードで構成されるクラスタがあります。そして、node2 および node3 は共有ストレージに直接接続されていると想定します。"/dev/md/mydg/dsk/d42" という svm メタデバイスを、node1 のディレクトリ "/global/answer" にグローバルマウントすることにします。
コードについては、PxFS サービスの起動を参照してください。
マウントサブシステムは HA サービスです。クラスタ用語である HA サービスというのは、フェイルオーバー機能を持つことを意味します。HA サービスには、1 つのプライマリおよび 1 つまたは複数のセカンダリが備わっています。現在のプライマリがダウンすると、どのセカンダリでもプライマリになれます。セカンダリからプライマリへの昇格は、アプリケーションに対し透過的に行われます。
どのクラスタ セットアップにおいても、マウントサービスプライマリは常に 1 つのみです。ほかのすべてのノードにはマウントサービスセカンダリが含まれています。各クラスタノードには、グローバルマウントがノードで最初に有効化されたときに作成されたマウントクライアントもあります。
マウントプライマリおよびマウントセカンダリは、ノードのクラスタ参加時に作成される、二面のマウントレプリカオブジェクトです。このコードは、マウントレプリカサーバーを作成するものです。レプリカフレームワークにより、一度に 1 つのみのプライマリが存在し、必要に応じてセカンダリからプライマリへの昇格が確実に行われるようになっています。
では、グローバルマウントを行う際の一連の処理について説明します。下の図をご覧ください。グローバルマウントの各手順が、順番に示されています。番号にマウスをポイントすると、各手順のツールヒントが対応コードのリンクとともに表示されます。

ここからは、上の図の手順をわかりやすく説明していきます。
- グローバルマウントコマンド mount -g は、どのクラスタノードからでも発行できます。このコマンドがカーネルに入ると、汎用マウントがこの呼び出しを PxFS にリダイレクトします。この時点で、マウントされるディレクトリがロックされます。
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/syscall/mount.c#125 http://src.opensolaris.org/source/xref/ohac/ohac/usr/src/common/cl/pxfs/client/pxvfs.cc#594
- PxFS クライアントは、マウントサーバーにこのグローバルマウント要求を自分のノード上のマウントクライアントを介して通知します。マウントクライアントはサーバー参照を持つようになります。
http://src.opensolaris.org/source/xref/ohac/ohac/usr/src/common/cl/pxfs/client/pxvfs.cc#999
- マウントサーバーは元のノード (この例では node1) 以外の各クライアントに、マウントポイントをロックするように要求します。
http://src.opensolaris.org/source/xref/ohac/ohac/usr/src/common/cl/pxfs/mount/mount_server_impl.cc#1204
- 共有デバイスでは、マウントサーバーは PxFS プライマリおよび PxFS セカンダリを作成します。プライマリデバイスが存在するノードが PxFS プライマリになります。ローカルデバイスでは、マウントは HA ではなく、レプリケートされていない PxFS サーバーが作成されます。上の例での lofi デバイスでは、node1 に作成される PxFS サーバーはレプリケートされていないものになります。
PxFS サーバーはデバイスの非表示マウントを行います。マウントの詳細情報は PxFS サーバーオブジェクトに含まれています。
http://src.opensolaris.org/source/xref/ohac/ohac/usr/src/common/cl/pxfs/mount/mount_server_impl.cc#1237 http://src.opensolaris.org/source/xref/ohac/ohac/usr/src/common/cl/pxfs/server/repl_pxfs_server.cc#125
- マウントサーバーは新たに作成されたサーバーへの参照をすべてのマウントクライアントに渡し、ユーザーに見えるかたちで PxFS マウントを行うようマウントクライアントに要求します。
http://src.opensolaris.org/source/xref/ohac/ohac/usr/src/common/cl/pxfs/mount/mount_server_impl.cc#1438 http://src.opensolaris.org/source/xref/ohac/ohac/usr/src/common/cl/pxfs/mount/mount_server_impl.cc#1684
- マウントクライアントは、基盤のファイルシステムと同種類の vfs_t エントリを作成し、これを追加します。
http://src.opensolaris.org/source/xref/ohac/ohac/usr/src/common/cl/pxfs/mount/mount_client_impl.cc#1804 http://src.opensolaris.org/source/xref/ohac/ohac/usr/src/common/cl/pxfs/mount/mount_client_impl.cc#1817
これですべてのクライアント上でマウントが表示されるようになりました。マウントサブシステムが提供する優れた機能はほかにもあります。たとえば、ノードがクラスタに参加するときに fs レプリカを起動したり、ストレージに接続されたノードがクラスタに参加するときに新たに PxFS セカンダリやプライマリを作成したりします。次回は PxFS での通常のファイルアクセスの動作についてお話しします。
Walter Zorn 氏の javascript ライブラリを利用させていただき、わかりやすいツールヒントを作成することができました。ここにお礼を申し上げます。
Binu Philip
Solaris Cluster エンジニアリング