IMSのプログラム作成Exitを使ってみる

プログラム作成ユーザーExit(Program Creation user exit routine)は、BMP実行時にランタイムの制御ブロックを自動的に生成するユーザーExitです。
ランタイム制御ブロックは通常、APPLCTNマクロを書いてIMS生成を行うことによってMODBLKSに作成し、プログラム実行時に読み込まれるものです。このユーザーExitを使うと、マクロからの生成を行わずともその場でランタイム制御ブロックを生成してBMPを実行できるようになります。

アセンブラーのサンプルコードがIMS.SDFSSMPL(DFSPGCX0)にあるので、これを使います。
作成される制御ブロックの属性(APPLCTNマクロ記述に相当)はExitルーチン内へコーディングすることになります。

今回はこのようなAPPLCTNマクロを想定します。
```
APPLCTN GPSB=EXTTSTB,LANG=ASSEM,PGMTYPE=BATCH
```
各指定に対応してどこにフラグを立てれば良いかマニュアルに載っているので、これを見ながらコーディングしていきます。
[PGMCREAT user exit routine type (IMS公式マニュアル)](https://www.ibm.com/docs/en/ims/15.1.0?topic=routines-pgmcreat-user-exit-routine-type#ims_pgmcreat_procreatexit__communicate)

こんな感じ。
```text:DFSPGCX0コーディング例
DFSPGCX0 CSECT                                                        
DFSPGCX0 AMODE 31                                                     
DFSPGCX0 RMODE ANY                                                    
         STM   R14,R12,12(R13)                                        
         LR    R12,R15             Set Base Register                  
         USING DFSPGCX0,R12                                           
         LR    R2,R1               GET A(STANDARD USER EXIT PARM LIST)
         USING SXPL,R2                                                
         L     R4,SXPLFSPL         GET A(DFSPGMCR Parm List)          
         USING DFSPGMCR,R4                                            
         OI    PGMCR_FLGC,PGMCR_FC_CREATEPGM                           
         OI    PGMCR_PFLG1,PGMCR_PF1_GPSBY                             
         OI    PGMCR_PLANG,PGMCR_ASSEM                                 
         OI    PGMCR_PTYPE,PGMCR_BMP                                   

PGCXEXIT DS    0H                                                      
         L     R14,12(R13)                                             
         LM    R0,R12,20(R13)                                          
         BR    R14                                                     
         LTORG                                                         
         REQUATE                                                       
         DFSSXPL                                                       
         DFSPGMCR                                                      
         END                                                           
```
これを連係編集。
そして作ったExitルーチンをPROCLIBメンバーDFSDFxxxの中でUSER_EXITSセクションに指定します。
```text:DFSDFxxx指定例: EXITS=でモジュール名を指定
<SECTION=USER_EXITS>                    
EXITDEF=(TYPE=PGMCREAT,EXITS=(DFSPGCX0))
```
プログラム作成ユーザーExitはDRD(動的リソース定義)の活動化が前提となるため、最後にDFSDFxxxで`MODBLKS=DYN`となっていることを確認します。
```
<SECTION=COMMON_SERVICE_LAYER>                                        
(中略)
MODBLKS=DYN,
```
IMS(とCSL環境)を立上げます。
まずプログラム定義(今回は`EXTTSTB`というPSBを使います)が存在していないことを確認。
```
/DIS PGM EXTTSTB                                                       
DFS4445I CMD FROM MCS/E-MCS CONSOLE USERID=IMS005: DIS PGM EXTTSTB I15A
DFS4444I DISPLAY FROM ID=I15A 563                                      
     PROGRAM    TRAN      TYPE                                         
     EXTTSTB  IS INVALID                                               
     *2022202/100320*                                                  
```
ここでおもむろにBMPを実行。
すると制御ブロックが存在していないにもかかわらずちゃんと稼働します。制御ブロックの動的生成に成功したようです。
その後再度同様のプログラム定義を確認してみると、ちゃんとTYPE: BMPで存在しています。
```
/DIS PGM EXTTSTB                                                       
DFS4445I CMD FROM MCS/E-MCS CONSOLE USERID=IMS005: DIS PGM EXTTSTB I15A
DFS4444I DISPLAY FROM ID=I15A 963                                      
     PROGRAM    TRAN      TYPE                                         
     EXTTSTB              BMP                                          
     *2022202/102812*                                                  
```

## おまけ1. 自動生成した定義の持ち越し

こうして作成された制御ブロックはIMSのコールド・リスタートを挟むと消えてしまいます。
その場限りのプログラム定義が残り続けることなく使い捨てにできるというのはそれはそれで便利なのですが、このExitで作成した定義がエクスポートされて次回コールド・リスタート時にインポートされるようにすることもできます。
Exitで`PGMCR_FLGC`に`PGMCR_FC_EXPORT`フラグを立ててあげると、Exitによって作成された資源がエクスポート対象に含まれるようになります。
```text:DFSPGCX0コーディング例
         OI    PGMCR_FLGC,PGMCR_FC_EXPORT
```
エクスポートおよびインポートの設定はDFSDFxxxでの環境設定に依存します。自動エクスポートの設定がない場合もType-2コマンド`EXPORT DEFN`によってエクスポートすることができます。
```text:RDDSへの自動インポート/エクスポートが指定されている例
<SECTION=DYNAMIC_RESOURCES>                                           
AUTOIMPORT=AUTO,                 /* AUTO IMPORT RESOURCES FR RDDS   */
AUTOEXPORT=AUTO,                 /* AUTO EXPORT RESOURCES TO RDDS   */
RDDSDSN=(IMSV15.I15A.RDDS1,IMSV15.I15A.RDDS2,IMSV15.I15A.RDDS3)       
```

## おまけ2. Exitの動的差し替え

制御ブロックの属性をExitにハードコーディングする必要があるため、属性を変えたい場合はExitそのものを差し替える必要があります。
IMSを動かしたままExitを差し替えるには、DFSDFxxxメンバー中`EXITDEF=(TYPE=PGMCREAT,EXITS=(exitname))`記述のexitname部分を書換え、Type-2コマンド`REFRESH USEREXIT TYPE(PGMCREAT) MEMBER(xxx)`を発行します。xxxにはDFSDFxxxのサフィックスを指定します。
```text:REFRESH USEREXITコマンド実行結果イメージ
Response for: REFRESH USEREXIT TYPE(PGMCREAT) MEMBER(5A2)
ExitType ModName  MbrName   CC                           
-------- -------- ------- ----                           
PGMCREAT DFSPGCX0 I15A       0                           
```