Go to main content

マニュアルページ セクション 7: 標準、環境、マクロ、文字セット、その他

印刷ビューの終了

更新: 2022年7月27日
 
 

smf_method(7)

名前

smf_method - サービス管理フレームワークのメソッド規約

説明

サービス管理フレームワーク smf(7) 内の svc.startd(8) によって管理されるサービスクラスは、単純な fork(2)-exec(2) モデルに適合するアプリケーションで構成されます。svc.startd(8) マスターデーモンやその他のリスタータは、fork(2)-exec(2) モデルを (場合によっては追加機能を使用して) サポートします。svc.startd(8) デーモンやその他のリスタータでは、サービスインスタンスをアクティブ化、操作、または検査するメソッドがこのマニュアルページで説明されている規約に従っている必要があります。

呼び出しの形式

メソッド呼び出しの形式は規約で規定されていません。メソッドの呼び出しは、デーモンまたはサービスを提供するほかの実行可能バイナリの直接呼び出しの場合もあります。実行可能スクリプトなどの間接実行可能ファイルを使用する場合は、規約では次の形式が推奨されています。

/path/to/method_executable abbr_method_name

この推奨形式の abbr_method_name は、startstop など、サポートされているメソッドです。リスタータでサポートされているメソッドセットについては、そのリスタータの関連ページで説明されています。svc.startd(8) デーモンは、startstop、および refresh メソッドをサポートしています。

リスタータには、このページで説明するメソッドのほかにも各種のメソッドが定義されていることがあります。そのような拡張も含めた規約はリスタータによって定義され、ここで説明する規約とは異なる場合があります。

環境変数

リスタータは、メソッド呼び出しのコンテキストを決定する 4 つの環境変数をメソッドに提供します。

SMF_FMRI

メソッド呼び出しの対象であるインスタンスのサービス障害管理リソース識別子 (FMRI)。

SMF_METHOD

呼び出されるメソッドの完全な名前。startstop など。

SMF_RESTARTER

メソッドを呼び出すリスタータのサービス FMRI。

SMF_ZONENAME

メソッドが実行されているゾーンの名前。これは zonename(1) コマンドでも取得できます。

SMF_EXIT_DEGRADED

メソッドは終了しますが、管理者が即時に介入する必要のない問題がサービスインスタンスに発生していることを検出します。この終了コードは、サービスインスタンスが正常に停止しなかったことを示すために stop メソッドで使用することもでき、その stop メソッドはあとで再試行する必要があります。

メソッドで永続的プロセスを呼び出す場合は、その前にこれらの変数を環境から削除するようにしてください。サービスの作成者が Bourne 互換のシェルスクリプトを使用して後述のインクルードファイルにサービスメソッドを合成できるように、簡易シェル関数 smf_clear_env が用意されています。

後述のとおり、メソッドコンテキストによってほかの環境変数が設定されることもあります。

メソッドの定義

メソッドは、method タイプのプロパティーグループの 3 つのプロパティーで最小限定義されます。

これらのプロパティーは次のとおりです。

exec (astring)

メソッドの実行可能ファイルの文字列。

timeout_seconds (count)

メソッドがタイムアウトするまでの秒数。詳細については、「タイムアウト」のセクションを参照してください。

type (astring)

メソッドのタイプ。現在は常に method に設定されます。

メソッドコンテキストを定義して、メソッドの実行環境をより詳細に指定することもできます。詳細については、「メソッドコンテキスト」のセクションを参照してください。

メソッドトークン

リスタータ svc.startd によってメソッドの exec 文字列に一連のトークンが定義されている場合は、それらが解析され、適切な値で展開されます。ほかのリスタータはメソッドトークンをサポートしていない場合があります。inet サービス inetd(8) の委任リスタータは、次のメソッド拡張をサポートしていません。

%%

%

%r

リスタータの名前。svc.startd など。

%m

呼び出されるメソッドの完全な名前。startstop など。

%s

サービスの名前

%i

インスタンスの名前

%f

インスタンスの FMRI

%{prop[:,]}

プロパティーの値。prop は、プロパティーの FMRI、プロパティーグループ名とプロパティー名を / で区切ったもの、または application プロパティーグループ内のプロパティー名です。これらの値のあとに , (コンマ) または : (コロン) が続く場合があります。ある場合、その区切り文字が複数の値を区切るために使用されます。ない場合は、スペースが使用されます。次に示すシェルのメタキャラクタが文字列値の中に見つかった場合は、\ (バックスラッシュ) でクォートされます。

; & ( ) | ^ < > newline space tab  \  " '

展開が正しくないとメソッドの失敗を招きます。

メソッドコマンドの代わりに、2 つの明示的なトークンを使用できます。

:kill [-signal]

指定されたシグナルをプライマリインスタンス契約のすべてのプロセスに送信します。デフォルトのシグナルは SIGTERM です。常に SMF_EXIT_OK を返します。このトークンは、一般的な pkill の呼び出しの代わりに使用するようにしてください。

:true

常に SMF_EXIT_OK を返します。このトークンは、リスタータには必要であっても、特定のサービス実装には必要のないメソッドに使用するようにしてください。

終了と終了ステータス

start メソッドは、サービスインスタンスが要求に応答できる状態になるか、あるいは機能するまで、終了を遅らせる必要があります。

次の終了ステータスコードが <libscf.h> とシェルサポートファイルに定義されています。

SMF_EXIT_OK
0
メソッドは処理を正常に実行して終了しました。
SMF_EXIT_ERR_FATAL
95
メソッドで致命的な失敗が発生し、管理者の操作なしでは回復不可能です。
SMF_EXIT_ERR_CONFIG
96
回復不可能な構成エラー。一般に、この終了ステータスが返されるのは、有効になっているサービスインスタンスに必要な構成ファイルが見つからない場合です。
SMF_EXIT_ERR_NOSMF
99
メソッドは誤って smf(7) 機能の外部で呼び出されました。smf(7) の機能に依存しているサービスは、このステータス値で終了するようにしてください。
SMF_EXIT_ERR_PERM
100
メソッドには、ファイルのアクセス権、特権、承認、資格情報といった形式の特権が必要ですが、呼び出し時には使用できませんでした。
SMF_EXIT_ERR_OTHER
0 以外
メソッドから 0 以外の終了ステータスが返された場合、それは不明なエラーとして扱われます。一連の不明なエラーは、リスタータで、あるいはリスタータに代わって、障害として診断できます。

上で説明した終了コードに加えて、メソッドでは次の終了コードを、smf_method_exit(3SCF)smf_include.sh、および smf_include.py Python モジュールから使用可能な、smf_method_exit() と組み合わせて使用できます。

SMF_EXIT_TEMP_DISABLE
101
メソッドは正常に終了し、一時的な無効をリクエストします。
SMF_EXIT_TEMP_TRANSIENT
102
メソッドは正常に終了し、そのサービスモデルが「一時的」であるかのように処理されることをリクエストします。

正確な終了コードを使用することで、担当のリスタータでエラー応答を診断して、再起動が適切と考えられる断続的なエラーと、管理者の操作を必要とする永続的なエラーとに分類できます。

タイムアウト

メソッドごとに個別のタイムアウトを秒単位で指定できます。メソッドのタイムアウトは timeout_seconds プロパティーで指定されます。

タイムアウトは、メソッドがハングアップしているか、または進行していないことをサービスのリスタータが判断するための最後の手段として使用されます。タイムアウトが経過すると、多くのリスタータはそのサービスを保守状態にします。svc.startd(8) を参照してください。メソッドは進行しているが、メモリー、CPU、または I/O 負荷によってシステムの応答が一時的に非常に遅くなったときの早期エラーを避けるため、タイムアウトを指定する場合は誤差の範囲を大きくすることをお勧めします。

1 - 2 秒しかかからないと予想されるメソッドの場合、適切な開始値は 60 秒です。30 秒かかることが多いメソッドの場合は 300 秒 (5 分) が適切です。日常的に長い時間のかかるメソッドの場合は、必要に応じて値を大きくしてください。

管理者の介入を促すために早期エラーが必要な場合は、短いタイムアウトを使用できます。管理者の介入がサービスをクリアーしてメソッドを再度開始させるだけの可能性が高い場合は、長いタイムアウトを考慮します。

timeout_seconds0 に設定されている場合、そのサービスにはタイムアウトがありません。この設定は推奨されませんが、どうしてもそれを必要とするサービスには使用できます。-1 もタイムアウトがないことを指定するために受け入れられますが、非推奨です。

シェルプログラムのサポート

前述の終了ステータス値を定義する一連の環境変数が、/lib/svc/share/smf_include.sh ファイル内の簡易シェル関数で提供されます。このファイルは Bourne シェルスクリプトであり、任意の Bourne 互換シェルのソース演算子を介したインクルードに適しています。

SMF メソッドとして機能するスクリプトおよび /etc/init.d スクリプトの合成を容易にするために、smf_present() シェル関数が用意されています。smf(7) 機能を使用できない場合、smf_present() は 0 以外の終了ステータスを返します。

そのようなスクリプトの構造の例を次に示します。

if smf_present; then
      # Shell code to run application as managed service
      ....

      smf_clear_env
else
      # Shell code to run application as /etc/init.d script
      ....
fi

この例では、用意されている両方の簡易関数の使用方法が示されています。

Python プログラムのサポート

/lib/svc/share/smf_include.sh で提供されている終了ステータスと同じセットは、smf_include モジュールで使用できます。

メソッドコンテキスト

サービス管理機能は、fork(2)-exec(2) モデルサービスが実行されるコンテキストを設定するための共通のメカニズムを提供します。

必要なメソッドコンテキストはサービス開発者が指定するようにしてください。すべてのサービスインスタンスは、最低レベルの特権と、セキュリティー侵害を抑えるのに必要な最低の認可上限で実行するようにしてください。

メソッドコンテキストには次のプロパティーを含めることができます。

environment

メソッドの環境に挿入する環境変数を、いくつかの NAME=value 文字列で指定します。

profile

RBAC (役割に基づくアクセス制御) プロファイルの名前。メソッドの実行可能ファイルとの組み合わせで、exec_attr(5) 内のエントリを識別します。

user

数値またはテキスト形式のオプションのユーザー ID。

group

数値またはテキスト形式のオプションのグループ ID。

supp_groups

補助グループメンバーシップを数値またはテキスト形式の ID で指定する、省略可能な文字列。

privileges

privileges(7) で定義されている特権セットを指定する、省略可能な文字列。拡張ポリシーはここで指定できます。

limit_privileges

privileges(7) で定義されている制限特権セットを指定する、省略可能な文字列。

working_directory

メソッドを起動するホームディレクトリ。トークンとして :home を使用すると、メソッドの起動に使用された uid に該当するユーザーのホームディレクトリを指定できます。このプロパティーが設定されていない場合は、:home が使用されます。

project

数値またはテキスト形式のプロジェクト ID。トークンとして :default を使用すると、メソッドの起動に使用された uid に該当するユーザーの、getdefaultproj(3PROJECT) で識別されるプロジェクトを指定できます。

resource_pool

メソッドを起動するリソースプールの名前。トークンとして :default を使用すると、上記の project 属性で示された project(5) エントリに指定されているプールを指定できます。

clearance

labels(7) に指定されているように、プロセスの認可上限を指定するオプションの文字列。この文字列は、ADMIN_LOWADMIN_HIGH、または atohexlabel(8) によって生成された 16 進文字列のいずれかである可能性があります。これを指定しない場合は、policy.conf(5) に指定されている認可上限でメソッドが開始されます。デフォルト値は ADMIN_HIGH です。

trusted_path

このサービスをトラステッドパス上で実行するかどうかを指定するオプションの文字列。詳細は、tpd(7) のマニュアルページを参照してください。デフォルトは false です。トラステッドパス上で実行されているサービスは、MWAC ポリシーから除外されます。詳細については、mwac(7) のマニュアルページを参照してください。

priv_debug

An optional boolean that specifies whether this service runs with the PPRIV_DEBUG process flag. Setting this true will result in details of any file access errors or missing required privileges being printed to the system messages file. These messages will describe the missing privilege and for file access, name the file to which access was denied.

サービスまたはインスタンスの method_context プロパティーグループを指定することにより、サービスインスタンス全体のメソッドコンテキストを設定できます。メソッドプロパティーグループのメソッドコンテキストプロパティーを指定することで、メソッドがインスタンスのメソッドコンテキストをオーバーライドする場合もあります。

メソッドコンテキストの設定が正しくないと、メソッドは常に失敗しますが、環境変数が無効な場合は警告が発行されます。

上記で定義されるコンテキストに加え、fork(2)-exec(2) モデルのリスタータは、実行可能ファイルをメソッドとして呼び出すときに次の規約も使用します。

引数配列

argv[] 内の引数は、exec 文字列の /bin/sh -c の結果と一致するように設定されます。

ファイル記述子

ファイル記述子 0/dev/null です。ファイル記述子 12 は、サービスごとのログファイルに推奨されます。

ファイル

/lib/svc/share/smf_include.sh
/lib/svc/share/smf_exit_codes.sh
/usr/lib/python-version/vendor-packages/smf_include.py

終了ステータス値の定義。

/usr/include/libscf.h

終了ステータスコードの定義。

使用例 1 サービスログでサービス固有の構成エラーメッセージを報告します。

start メソッドでは、サービスログでサービス固有の構成エラーメッセージを報告するために smf_method_exit() を使用することもできます。

if [ ! -s "$my_config_file" ]; then
   smf_method_exit $SMF_EXIT_ERR_CONFIG \
       missing_or_empty_config_file \
       "$my_config_file is missing or empty"
fi

使用例 2 非大域ゾーンで起動されたときに大域ゾーンでのみ実行されるべきサービスを無効にします。

大域ゾーンでのみ実行されるべきサービスは、非大域ゾーンで起動されたときに、自身を無効にすることもできます。

if smf_is_nonglobalzone; then
    smf_method_exit $SMF_EXIT_TEMP_DISABLE global_zone_only \
    "$SMF_FMRI is not supported in a local zone" SUNW_OST_OSCMD
fi

関連項目

zonename(1)exec(2)fork(2)getdefaultproj(3PROJECT)smf_method_exit(3SCF)exec_attr(5)project(5)service_bundle(5)attributes(7)mwac(7)labels(7)privileges(7)rbac(7)smf(7)smf_bootstrap(7)tpd(7)zones(7)atohexlabel(8)coreadm(8)inetd(8)svc.startd(8)svccfg(8)

smf(7) の現在のバージョンでは、複数のリポジトリはサポートされていません。

サービスが limit_privileges とは異なる特権で root ユーザーとして起動するように構成されている場合、結果として得られるプロセスは特権に対応したものになります。これは、seteuid(<non-zero UID>) によって特権が basic 以下に下がると考えている開発者には予期しないことです。