Solaris 動的トレースガイド

第 39 章 安定性

Sun では、しばしば開発者を対象に、新しいテクノロジのアーリーアクセス版や、ユーザー/カーネルソフトウェアの内部実装の詳細を確認するための各種監視ツールを提供しています。しかし、残念なことに、新しいテクノロジや内部実装の詳細は、よく変更されます。インタフェースや実装は、ソフトウェアの更新やパッチの発行を経て、発展し成熟するからです。Sun では、attributes(5) のマニュアルページに記載されているラベルを使って、アプリケーションやインタフェースの安定性のレベルを文書化しています。ユーザーは、この情報を基に、将来のリリースでどのような変更が加えられる可能性があるかを予想できます。

ある D プログラムからアクセス可能なさまざまな構成要素やサービスについて、どれか 1 つの安定性属性で説明できるものではありません。このため、DTrace と D コンパイラには、ユーザーが作成する D プログラムの安定性レベルを、動的に計算し記述する機能が用意されています。この章では、プログラムの安定性を決定する DTrace 機能について説明します。この機能は、安定した D プログラムを設計する上で役立ちます。DTrace の安定性機能を利用して、D プログラムの安定性属性を確認したり、プログラムのインタフェースに有害な依存関係が生じたとき、コンパイル時エラーを発行することもできます。

安定性レベル

DTrace は、組み込み変数、関数、プローブなどの構成要素に対して、2 種類の安定性属性を提供しています。 1 つは「安定性レベル」、もう 1 つはアーキテクチャの「依存クラス」です。DTrace の安定性レベルは、インタフェースや DTrace 構成要素が将来のリリースやパッチで変更される可能性を表しています。この情報は、DTrace ベースのスクリプトやツールを開発するときのリスク評価に役立ちます。DTrace の依存クラスは、あるインタフェースが、すべての Solaris プラットフォームおよびプロセッサに共通のインタフェースであるのか、あるいは特定のアーキテクチャ専用 (たとえば SPARC 専用) のインタフェースであるのかを示します。インタフェースの情報を提供するこの 2 種類の属性は、相互に依存することがありません。

以下では、DTrace で使用する安定性の値を、安定性の低いものから順に一覧します。比較的安定性の高いインタフェースは、すべての D プログラム、すべての階層化アプリケーションで使用できます。Sun では、これらのインタフェースが、将来のマイナーリリースでも引き続き動作するように開発を進めています。「安定」インタフェースだけに依存するアプリケーションは、将来のマイナーリリースでも正しく機能し、暫定パッチを適用しても問題は発生しません。比較的安定性の低いインタフェースは、現在のシステムでの計測、プロトタイピング、チューニング、およびデバッグには対応していますが、将来のマイナーリリースで、互換性の問題が発生したり、落とされたり、別のインタフェースに置き換えられたりする可能性があります。そのため、これらを使用するときは、注意が必要です。

DTrace の安定性の値は、DTrace インタフェースの安定性だけでなく、監視対象のソフトウェア構成要素の安定性を把握する上でも役立ちます。したがって、監視対象のソフトウェアスタックをアップグレードしたり変更したりするときに、D プログラムや階層化ツールの変更が必要になる可能性についても、DTrace の安定性の値から判断できます。

内部 (Internal)

DTrace 専用のインタフェースです。DTrace の実装の詳細を示します。「内部」インタフェースは、マイナーリリースやマイクロリリースで変更される可能性があります。

非公開 (Private)

Sun 専用のインタフェースです。Sun のほかの製品のために開発されたインタフェースで、まだ顧客や ISV 向けに正式に文書化されていません。「非公開」インタフェースは、マイナーリリースやマイクロリリースで変更される可能性があります。

廃止 (Obsolete)

現在のリリースではサポートされているが、将来的に削除される予定の (特にマイナーリリースで削除される可能性が高い) インタフェースです。Sun では、インタフェースのサポートを打ち切る場合には、なるべく事前に通知するようにしています。「廃止」インタフェースを使用しようとすると、D コンパイラから警告メッセージが出力されることがあります。

外部 (External)

このインタフェースは Sun 以外によって管理されています。Sun は、これらのインタフェースの更新版 (ただし以前のものと互換性がない可能性がある) を管理元から入手できる場合には、独自の裁量で、これをリリースの一部に追加して配布できます。異なるリリース間での「外部」インタフェースのソースまたはバイナリ互換性については、Sun は一切関与しません。これらのインタフェースに基づくアプリケーション (「外部」インタフェースが含まれているパッチも含む) は、将来のリリースでは動作しない可能性があります。

変更の可能性あり (Unstable)

新しい (頻繁に変更される) テクノロジや、システム動作の監視やデバッグに必要な実装アーティファクトへの、開発者向けアーリーアクセス用に提供されているインタフェースです。将来的により安定したソリューションが提供される予定です。「変更の可能性あり」インタフェースのマイナーリリース間でのソースまたはバイナリ互換性については、Sun は一切関与しません。

発展中 (Evolving)

将来的に「標準」インタフェースまたは「安定」インタフェースになる可能性があるが、まだ過渡期にあるインタフェースです。Sun は、発展後も以前のリリースと互換性が保たれるよう、適切な努力をします。上位互換性のない変更が必要な場合は、マイナーリリースとメジャーリリースで行われます。こうした変更は、マイクロリリースではできるかぎり回避されます。こうした変更の必要が生じた場合、影響を受けるリリースのリリースノートにその旨が文書化されます。可能なかぎり、Sun は、バイナリ互換性の実現と D プログラム開発続行のために、移行支援ツールを提供します。

安定 (Stable)

Sun の管理下にある完成したインタフェースです。Sun は、これらのインタフェースに対する上位互換性のない変更をできるかぎり回避します。特に、マイナーリリースとマイクロリリースでの変更を回避します。「安定」インタフェースのサポートを打ち切る場合、Sun はその旨を通知し、安定性レベルを「廃止」に変更します。

標準 (Standard)

業界標準に準拠したインタフェースです。このインタフェースの文書には、準拠する標準の説明が記載されています。標準は、通常、標準開発団体によって管理されています。この標準の変更が認可された場合、それに沿って「標準」インタフェースが変更されることがあります。この安定性レベルは、業界の慣例により、正規標準なしで採用されたインタフェースにも当てはまります。指定されたバージョンの標準のみがサポート対象になります。以降のバージョンがサポートされるかどうかは保証されていません。「標準」インタフェースについて、上位互換性のない変更が標準開発団体によって認可され、この変更をサポートすることを Sun が決定した場合には、Sun は互換性と移行方法を通知します。

依存クラス

Solaris と DTrace では、さまざまなオペレーティングプラットフォームとプロセッサがサポートされています。このため、DTrace では、インタフェースを「依存クラス」に分類して、すべての Solaris プラットフォームとプロセッサに共通のインタフェースであるのか、特定のシステムアーキテクチャ専用のインタフェースであるのかを区別しています。依存クラスは、上で説明した安定性レベルとは別の観点からの分類です。たとえば、安定しているが SPARC マイクロプロセッサでしかサポートされない DTrace インタフェースもあれば、変更の可能性はあるがすべての Solaris システムに共通の DTrace インタフェースもあります。以下では、DTrace の依存クラスについて、共通性の低いものから順に説明します。もっとも共通性が低いクラスは、特定のアーキテクチャに固有のクラスです。もっとも共通性が高いクラスは、すべてのアーキテクチャに共通のクラスです。

不明 (Unknown)

アーキテクチャの依存関係が不明なインタフェースです。DTrace は、すべての構成要素 (オペレーティングシステム実装内で定義されたデータ型など) について、アーキテクチャの依存関係を認識できるとは限りません。通常、「不明」に分類されるのは、依存関係を計算できない、安定性の非常に低いインタフェースです。現在使用中のアーキテクチャ以外で DTrace を使用するときには、このインタフェースが使用できない可能性があります。

CPU

現在のシステムの CPU モデル固有のインタフェースです。現在の CPU モデルと実装名を表示するには、psrinfo(1M) ユーティリティーの -v オプションを使用します。CPU モデル依存インタフェースは、その他の CPU 実装では使用できない可能性があります。同じ命令セットアーキテクチャ (ISA) をエクスポートする CPU でも同様です。たとえば、UltraSPARC-III+ と UltraSPARC-II は、どちらも SPARC 命令セットをサポートします。しかし、UltraSPARC-III+ マイクロプロセッサ上の CPU 依存インタフェースは、UltraSPARC-II マイクロプロセッサでは使用できない可能性があります。

プラットフォーム (Platform)

現在のシステムのハードウェアプラットフォーム固有のインタフェースです。通常、プラットフォームは、システムコンポーネントとアーキテクチャの特性のセット (たとえばサポート対象の CPU モデルのセット) に、「SUNW,Ultra-Enterprise-10000」のようなシステム名を関連付けています。現在のプラットフォーム名を表示するには、uname(1) -i オプションを使用します。このインタフェースは、ほかのハードウェアプラットフォームでは使用できない可能性があります。

グループ (Group)

現在のシステムのハードウェアプラットフォームグループ固有のインタフェースです。通常、プラットフォームグループは、プラットフォームのセットと関連する特性を、「sun4u」のような 1 つの名前で関連付けています。現在のプラットフォームグループ名を表示するには、uname(1) -m オプションを使用します。このインタフェースは、現在のプラットフォームグループ内のその他のプラットフォーム上では使用可能ですが、このグループのメンバーでないハードウェアプラットフォーム上では使用できない可能性があります。

ISA

このシステム上のマイクロプロセッサがサポートする命令セットアーキテクチャ (ISA) 固有のインタフェースです。ISA は、マイクロプロセッサ上で実行可能なソフトウェアの仕様 (アセンブリ言語命令、レジスタなどの詳細情報を含む) について説明したものです。システムがサポートするネイティブの命令セットを表示するには、isainfo(1) ユーティリティーを使用します。このインタフェースは、同じ命令セットをエクスポートしないシステム上ではサポートされない可能性があります。たとえば、Solaris SPARC システム上の ISA 依存インタフェースは、Solaris x86 システム上ではサポートされない可能性があります。

共通

配下のハードウェアとは関係なく、すべての Solaris システムに共通のインタフェースです。「共通」インタフェースだけに依存する DTrace プログラムと階層化アプリケーションは、Solaris と DTrace のリビジョンが共通しているその他の Solaris システムに配備し、実行できます。大部分の DTrace インタフェースは「共通」インタフェースです。したがって、Solaris を使用する場合いつでも使用できます。

インタフェース属性

DTrace は、インタフェースについて説明するとき、2 つの安定性レベルと 1 つの依存クラスからなる三つ組の属性を使用します。慣習上、インタフェース属性は次の順序で記述します。各属性は、スラッシュで区切ります。

name-stability / data-stability / dependency-class

インタフェースの「名前の安定性 (name-stability)」は、D プログラム内または dtrace(1M) コマンド行に表示されるインタフェース名の安定性レベルです。たとえば、D 変数名 execname は、安定しています。 Sun は、この識別子が、「安定」インタフェースの規則 (上記参照) に従って、D プログラム内で引き続きサポートされることを保証します。

インタフェースの「データの安定性 (data-stability)」は、名前の安定性とは別のものです。この安定性レベルは、インタフェースや関連データセマンティクスで使用されるデータ書式を保持する Sun の責任について説明するものです。たとえば、D 変数 pid は、「安定」インタフェースです。 プロセス ID は、Solaris で使用される安定した概念です。Sun は、pid 変数が pid_t 型であり、「安定」インタフェースの規則に従って、プローブを起動したスレッドのプロセス ID に設定されるというセマンティクスを持つことを保証します。

インタフェースの「依存クラス (dependency-class)」は、名前やデータの安定性とは別のものです。依存クラスは、このインタフェースが現在のオペレーティングプラットフォームやマイクロプロセッサに固有であるかどうかを示します。

DTrace と D コンパイラは、プロバイダ、プローブ記述、D 変数、D 関数、型、プログラム文自体を含む、DTrace インタフェースの全構成要素の安定性属性を追跡します。この 3 つの値は、互いに異なることがあります。たとえば、D 変数 curthread は、「Stable/Private/Common」という属性を持っています。 これは、変数名が「安定」していて、すべての Solaris オペレーティングプラットフォームに「共通」であるが、この変数は、Solaris カーネルの実装アーティファクトである「非公開」のデータ書式へのアクセスを提供するという意味です。ほとんどの D 変数はユーザー定義の変数なので、「Stable/Stable/Common」の属性を持っています。

安定性の計算と報告

D コンパイラは、D プログラム内の個々のプローブ記述とアクション文に対して、安定性の計算を行います。プログラムの安定性のレポートを表示するには、dtrace -v オプションを使用します。以下の例では、コマンド行に記述されたプログラムを使用します。


# dtrace -v -n dtrace:::BEGIN'{exit(0);}'
dtrace: description 'dtrace:::BEGIN' matched 1 probe
Stability data for description dtrace:::BEGIN:
        Minimum probe description attributes
                Identifier Names: Evolving
                Data Semantics:   Evolving
                Dependency Class: Common
        Minimum probe statement attributes
                Identifier Names: Stable
                Data Semantics:   Stable
                Dependency Class: Common
CPU     ID                    FUNCTION:NAME
  0      1                           :BEGIN

プローブを有効にせず、プログラムも実行しないで、プログラムの安定性を判定したい場合は、dtrace -v オプションと -e オプションを組み合わせて使用します。この場合、dtrace は、D プログラムを実行せず、コンパイルだけを行います。以下に、別の安定性レポートの例を示します。


# dtrace -ev -n dtrace:::BEGIN'{trace(curthread->t_procp);}'
Stability data for description dtrace:::BEGIN:
        Minimum probe description attributes
                Identifier Names: Evolving
                Data Semantics:   Evolving
                Dependency Class: Common
        Minimum probe statement attributes
                Identifier Names: Stable
                Data Semantics:   Private
                Dependency Class: Common
#

新しいプログラムでは、D 変数 curthread を参照しています。この D 変数は、安定した名前と非公開のデータセマンティクスを持っています。非公開のデータセマンティクスを持っているということは、この変数について調べるとき、カーネルの非公開の実装の詳細にアクセスするということです。プログラムの安定性レポートには、現在、この状態が反映されています。プログラムレポート内の安定性属性は、インタフェース属性の三つ組の対応する値から最小の安定性レベルとクラスを選択することで計算されます。

プローブ記述の安定性属性は、プロバイダによって発行された属性に従って、指定されたすべてのプローブ記述フィールドの最小の安定性属性をとることによって計算されます。使用可能な DTrace プロバイダの属性については、各プロバイダの章を参照してください。DTrace プロバイダは、自身が公開しているすべてのプローブの 4 つの記述フィールドの 1 つ 1 つに対して、安定性属性の三つ組をエクスポートします。このため、プロバイダの名前のほうが、このプロバイダがエクスポートする個々のプローブよりも安定性が高い場合があります。たとえば、次のようなプローブ記述があるとします。

fbt:::

このプローブ記述は、すべてのカーネル関数の開始 (entry) と終了 (return) をトレースするように指示するもので、次のプローブ記述より高い安定性を備えています。

fbt:foo:bar:entry

このプローブ記述は、カーネルモジュール foo() 内の内部関数 bar を指定しています。簡便性のため、ほとんどのプロバイダは、公開する値 module:function:name 全部に、単一の属性セットを使用します。プロバイダは、args[] 配列の属性を指定します。これは、プローブ引数の安定性がプロバイダごとに異なるからです。

プローブ記述のプロバイダフィールドが未指定の場合、この記述には安定性属性 Unstable/Unstable/Common が割り当てられます。これは、この記述が将来の Solaris バージョンで使用されたとき、現在まだ存在しないプロバイダのプローブと照合されてしまう可能性があるからです。このため、Sun は、このプログラムの将来の安定性と動作について保証できません。D プログラム節を作成するときは、プロバイダを常に明示的に指定する必要があります。また、パターンマッチング文字 (第 4 章D プログラムの構造を参照) や $ 15 のようなマクロ変数 (第 15 章スクリプトの作成を参照) を含むプローブ記述フィールドは、未指定として扱われます。これは、これらの記述パターンを展開すると、将来の DTrace や Solaris OS で、Sun によってリリースされたプロバイダまたはプローブと照合されてしまう可能性があるからです。

ほとんどの D 言語の文で、安定性属性は、その文の構成要素の最小の安定性とクラスをとることで計算されます。たとえば、次の D 言語構成要素は、次の属性を持っています。

構成要素 

属性 

D 組み込み変数 curthread

Stable/Private/Common 

D ユーザー定義変数 x

安定/安定/共通 

次の D プログラム文を作成するとします。

x += curthread->t_pri;

この文の属性は、「Stable/Private/Common」になります。これは、オペランド curthreadx の最小属性です。式の安定性は、各オペランドの最小属性をとることで計算されます。

プログラム内に定義した D 変数には、属性「Stable/Stable/Common」が自動的に割り当てられます。D 言語の文法や D 演算子には、「Stable/Stable/Common」の属性が暗黙的に割り当てられます。逆引用符演算子 (`) によるカーネルシンボルの参照には、常に「Private/Private/Unknown」の属性が割り当てられます。これは、これらが実装アーティファクトを反映しているからです。D プログラムソースコード内で定義した型、具体的に言うと、C 型やD 型の名前空間に関連付けられた型には、「Stable/Stable/Common」の属性が割り当てられます。オペレーティングシステム実装内に定義され、ほかの型の名前空間から提供された型には、「Private/Private/Unknown」の属性が割り当てられます。D 型キャスト演算子が生成する式には、入力式の安定性属性とキャスト出力型の安定性属性との最小値が割り当てられます。

C プリプロセッサを使って C システムヘッダーファイルをインクルードする場合、これらの型には、C 型名前空間が関連付けられ、属性「Stable/Stable/Common」が割り当てられます。これは、D コンパイラが、ユーザーがこれらの宣言に責任を持つと仮定せざるをえないからです。このため、C プリプロセッサを使って実装アーティファクトを含むヘッダーファイルをインクルードする場合、プログラムの安定性を誤る可能性があります。正しい安定性レベルを判断するには、インクルードするヘッダーファイルの文書を常に参照する必要があります。

安定性の強制

DTrace スクリプトや階層化ツールを開発するとき、安定性の問題の原因を特定したり、プログラムの安定性属性のセットが適切であることを確認したりできます。属性の計算結果として、コマンド行に指定した最小値未満の三つ組が得られた場合に、D コンパイラに強制的にエラーを返させるには、dtrace -x amin=attributes オプションを使用します。以下では、D プログラムソースの抜粋を使って、-x amin の使用例を紹介します。属性は、通常の順番で、スラッシュ (/) で区切った形式で指定されています。


# dtrace -x amin=Evolving/Evolving/Common \
    -ev -n dtrace:::BEGIN'{trace(curthread->t_procp);}'
dtrace: invalid probe specifier dtrace:::BEGIN{trace(curthread->t_procp);}: \
    in action list: attributes for scalar curthread (Stable/Private/Common) \
    are less than predefined minimum
#