特定のデバイスのUCBを求める
特定のデバイスのUCBを求める
QSAMなどのアクセス法を使わずCCWを自分で組み立て実行させるような場合でも、アクセスするデバイスをJCLのDD文で定義してOPENマクロで予めオープンしてからアクセスするのであればUCBを求める必要はない。デバイスをオープンしないでチャネルプログラムを投げたり、オフライン・デバイスにI/Oを行うような特殊なユーティリティーなどでは、ターゲットのデバイスを直接指し示す必要があるためUCBを求めることになる。
その他、デバイスへのI/Oではなく、システムに接続されているデバイスをリストアップするためにUCBをルックアップすることもある。複数のデバイスのUCBを探す方法は記事を改めるが、ここでは特定の1つのデバイスのUCBアドレスを求める方法の違いについて記してみたい。
なお、UCBアドレスの求め方は必ずしも唯一ではなく、ここで紹介するのは筆者が過去に実践で使用したもので、ここに紹介していない方法が使われることもある。
MVS(z/OS)
ボリューム名や装置番号などをキーにして特定のデバイスのUCBアドレスを求めるなら、UCBLOOKマクロが利用できる。
: UCBLOOK UCBPTR=AUCB, GET UCB ADDRESS + VOLSER==CL6'VOL123', + NOPIN,DYNAMIC=YES,RANGE=ALL,LOC=ANY : AUCB DC A(0) UCB ADDRESS :
なお、UCBLOOKマクロはスーパーバイザー・モード(もしくはPSWキー0から7)での発行が必須なのでAPF許可プログラムである必要がある。
MSP
マニュアルで公開された方法としては、IOSLOOKマクロが利用できる。ただし求めたいデバイスのキーに指定できるのは装置番号だけで、ボリューム名をキーにすることはできない。
: L R6,=A(X'000002A0') LOAD DEVICE NUMBER = 02A0 IOSLOOK UCB=AUCB, GET UCB ADDRESS + DEV=(6) : AUCB DC A(0) UCB ADDRESS :
公開された方法でボリューム名からUCBアドレスを求めるには、UCBスキャンサービスルーチンを呼び出し、通知されたUCB内のUCBVOLIフィールドを求めたいボリューム名と比較して、一致するまでUCBスキャンサービスを繰り返し呼び出す方法がある。ループを繰り返すのでデバイス数が多いと効率は落ちるがCPU処理だけである。
なお、KDJSYSRQマクロを利用すれば、ボリューム名からUCBアドレスを求めることができるが、これは一般に公開されていない方法である。必要であれば富士通に問い合わせる。マクロ自体はSYS1.MACLIBまたはSYS1.MODGENデータセットに格納されている。
VOS3
MVSのUCBLOOKに相当するのがGETUCBADマクロになる。ただし一般に公開されていない方法である。必要であれば日立に問い合わせる。マクロ命令はSYS1.MACLIBまたはSYS1.VMODMACに格納されるが、標準で配布されているかどうかは定かでない。
上記の3つは、OS毎にUCBアドレスを求めるAPIを使用したものである。APIについてはMVS、MSPおよびVOS3間での互換はない。実は、UCBアドレスを返すようなAPIは当初のMVSから実装されていたわけではなかった。初期のMVSではUCB領域はニュークリアスの一部であって、CVTからポイントされるUCBルックアップテーブルをサーチすることで目的デバイスのUCBを容易に見つけることができた。しかしMVS/XA以降、3桁の装置番号が4桁に拡大されたり、UCB自体の位置が16MBラインの上に展開できたり、デバイスの構成を動的に変更できたりとデバイス管理に関連するOS機能はエンハンスされてきた。それに伴いUCB領域もIOSによって管理され、個々のデバイスのUCBもAPIを通じてそのアドレスや内容のコピーを求めることができるように変わってきた。MVS/XA以降のデバイス管理の機能については必ずしも互換が取られるわけではなくなったため、UCB関連のAPIも3つのOSでそれぞれ異なるものである。ちなみにMVSのUCBLOOKはESA V4より提供されたもので、それ以前のMVS/XA、ESA V3ではMSPと同じIOSLOOKマクロであった。MSPのIOSLOOKやUCBスキャンサービスは、元々MVS/XAとの互換機能である。
DDステートメント定義からUCBアドレスを求める
APIによるUCBアドレスの取得方法は、3つのOSに互換がないが、ターゲットのボリューム(あるいはデータセット)がJCLのDDステートメントで定義されるか、もしくはダイナミック・アロケーションされるのであれば、APIではなくDDステートメントの管理テーブルであるTIOTから求めることもできる。この方法はMVS、MSPおよびVOS3間で互換がある。EXTRACTマクロもTIOTの構造もこのサンプルで参照しているパラメーターやフィールドに関しては互換があるので、実行モジュール・レベルで互換がある。
: EXTRACT ATIOT,'S',FIELDS=TIOT EXTRACT OUR TIOT ADDRESS L R6,ATIOT LOAD TIOT ADDRESS LA R6,TIOENTRY-TIOT1(,R6) LOCATE TO 1ST DD ENTRY USING TIOENTRY,R6 ADDRESS IT SLR RF,RF CLEAR WORKREG CLC TIOEDDNM,=CL8'SYSUT1' IS HERE SYSUT1 DD ENTRY ? BE *+4+4+4+4 YES, FOUND IT IC RF,TIOELNGH ADD CURRENT ENTRY LENGTH LA R6,0(RF,R6) LOCATE TO NEXT ENTRY B *-4-4-4-6 FIND OUR DD STATEMENT SLR R1,R1 CLEAR WORKREG ICM R1,B'0111',TIOEFSRT LOAD UCB(CAPTURED) ADDRESS + GR1 --> CONTAIN UCB ADDRESS DROP R6 FORGET TIOT : ATIOT DC A(0) TIOT ADDRESS AUCB DC A(0) UCB ADDRESS : DSECT IEFTIOT1 , TIOT :
MVSでは、UCBが16MBラインより上の31ビット領域の拡張SQAに展開されている場合、24ビット領域にキャプチャーされたUCBのアドレスとなる。このUCBはデバイスの実UCBではないが、このUCBを参照してI/Oを発行することができる。
TIOTのマッピングマクロであるIEFTIOT1は、MSPとVOS3ではそれぞれKDJTIOT1とJDJTIOT1であるがIEFTIOT1の別名マクロも格納されている。