10.1 データセットを割り振る(DYNALLOC)

MVSではプログラムがアクセスするデータセットは、ジョブを実行するJCLのDDステートメントで予め定義しておくのが一般的です。バッチ処理においては、殆どのジョブがDDステートメントによる事前の定義を行っています。
しかしながら、オンライン処理、特にTSOなどの対話型処理では、事前に使用するデータセットを決めることができません。例えば、エディターがそうです。編集するデータセットは、エディターを起動した後にパネルにそのDSNを指定します。つまり、エディターというプログラムでは、起動してみなければどのデータセットをアクセスするか決められません。バッチ処理であっても、プログラムの処理中にアクセスするデータセットを決めるということはありえないことではありません。

このような場合、データセットの割り振りはJCLのDDステートメントではなく、プログラムからMVSのAPIを呼び出してデータセットを割り振ります。これがダイナミック・アロケーション(動的割り振り)と呼ばれるものです。ダイナミック・アロケーションは、DYNALLOCマクロによってSVC99を発行することで行われます。

カタログ済みの既存データセットをアロケーションする

既存のデータセットをアロケーションする例です。わかりやすくするために、アロケーションとアン・アロケーションのテキスト・ユニットのポインター領域を分けていますが、実際のプログラムでは共用可能です。

DYNALLOCは、MVSのAPIの中では呼び出し手順が複雑なものです。覚えるまでは難しく見えますが、慣れの問題です。

必要なパラメーターは、大きく4種類に分かれます。1つ目がRBポインター・フィールドです。サンプルでは、ラベルDALRBPの箇所です。フルワード領域に、DYNALLOCのRBアドレスを格納して先頭ビットをONにします。
2つ目がRBです。DYNALLOCのパラメーター・リストで、要求する機能、復帰時のエラーコード、テキスト・ユニット・ポインター・リストのアドレス、オプション・フラグなどで構成されています。
3つ目がテキスト・ユニット・ポインター・リストです。各テキスト・ユニットのアドレスを格納したポインター・リストです。リストの最終エントリーの先頭ビットをONにします。
4つ目がテキスト・ユニットです。テキスト・ユニットは、JCL DDステートメントの各パラメーターに相当します。DDステートメントの各パラメーターに対応してテキスト・ユニットを用意します。

パラメーター領域を準備して初期設定したら、GR1にRBポインター・フィールドのアドレスを入れてDYNALLOCマクロを発行します。DYNALLOCマクロ自身にはパラメーターは無く、単にSVC 99命令を発行するだけのものです。直接SVC命令を書いても大差ありませんが、マクロを使用して呼び出せばそこでDYNALLOCしていることがはっきりしますから、後で保守する人にはわかりやすいでしょう。DYNALLOCが完了すると、GR15に復帰コードが返ります。0以外なら何らかの誤りが起きていますから、RBに設定されているエラー・コードと情報コードを参照して必要なエラー処理を行います。0で完了しても状況によっては情報コードでエラーが通知される場合もあります(特にアン・アロケーション時)。例えば、DISP=(NEW,KEEP)の指定をしてアロケーションしたデータセットに対して、後処理をCATLGに変更してアン・アロケーションした時、既に同名データセットがカタログされていたような場合です。このアン・アロケーション自体は成功していますが、データセットのカタログには失敗しています(NOT CATLGD 2と同じ)。同名DSNがカタログ済みの場合、アロケーション時にDISP=(NEW,CATLG)が指定されていると、アロケーション時に失敗しエラーで通知されます。この場合、データセットも作成されていません。

アン・アロケーションは必ずしも必要ではありません。アロケーションした後、OPENして入出力を行いその後にCLOSEを行う場合、CLOSE時にデータセットを自動的にアン・アロケーションさせるオプションも指定できます(アロケーション時にキーx001Cのテキスト・ユニットを指定する)。CLOSE後に再OPENしないのであれば、この機能を使うと便利です。

新しいデータセットを作成する

新規のデータセットをDYNALLOCで割り振るサンプルです。DYNALLOC自体の出し方は、既存のデータセットと変わりません。指定するテキスト・ユニットが増えるだけです。DCB属性に関するテキスト・ユニットは指定していませんが、アロケーション後にOUTPUTオープンすればDCBに指定したRECFMやLRECLなどで設定されます。

最初のサンプルでは、DYNALLOCのパラメーターを直接コーディングしましたが、こちらのサンプルではOSが提供するDYNALLOCのパラメーター・リストのDSECTを使って、OS標準のフィールド名でアクセスしています。簡単なプログラムではDSECTを使う方が逆に面倒になりますが、きちんとした正式なプログラムや商用プログラムの場合、提供されているのならOSのマッピング・マクロを使うのがオーソドックスな作り方です。
さらに、RBエクステンションも指定して、DYNALLOCがエラーになった時にコンソールにメッセージが出力されるようにしています。この機能を使えば、エラー・コードを解析しなくても診断情報を簡単に得ることができます。編集されたメッセージをプログラムで処理できるように、そのメッセージが格納されたアドレスなどを通知してもらうこともできます。RBエクステンションで指定すれば、メッセージの作成と出力はDYNALLOCサービスの中で自動的に行ってくれます。

SYSOUTデータセットをアロケーションする

SYSOUTデータセットをDYNALLOCで割り振るサンプルです。SYSOUTの場合、パラメーターでSYSOUTクラスを指定します。その他、ライタープログラム名、フォーム名、出力ライン数リミットなども追加のテキスト・ユニットを定義することで指定できます。SYSOUT=*と同じことを行うには、DALSYSOUキーでパラメーター数を0にします。クラス値として’*’を指定してはなりません。パラメーター・エラーでDYNALLOCは失敗します。勘違いしやすいので注意します。

DYNALLOCは、一般のデータセットやSYSOUTデータセットのアロケーションでも利用しますが、その他にもJCLのDDステートメントではアロケーションできない特殊なデータセットにアクセスする場合などにも用います。例えば、JES2スプール内の書き込み済みSYSOUTデータセットがそうです。SDSFのように、他のジョブによってすでに書き込まれたSYSOUTデータセットを読み込んでその内容を表示するような場合です。