11.1カタログの探索とデータセット情報の取得(LOCATEとOBTAIN)
一般のデータセットへのアクセスだけでなく、カタログやDASDボリュームのVTOC(索引)にアクセスするためのサービスも提供されています。現在ではわざわざプログラムなどを作らなくても、ISPFやユーティリティ、ISVソフトウェア製品などを使えば事足りることが多いですが、どのようなサービスによって実現できるかを知っておくだけでもいいでしょう。
データセット名からカタログされているボリューム名を求める
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- : LOCATE CAMLST ISSUE LOCATE SVC LTR RF,RF SUCCESSFUL ? BNZ CATERROR NO, DSN NOT FOUND OR CATLG ERR : : CAMLST CAMLST NAME,DSN,,OUTAREA LOCATE SERVICE PLIST DSN DC CL44'TMP1.MULTIDS2' INPUT DSNAME DS 0D NEED DOUBLE WORD BOUNDARY OUTAREA DC XL265'00' 265BYTES OUTPUT AREA :
OUTAREAの形式 +---------------------+ +00 I H(ボリューム数) I +---------------------+ +02 I XL4(装置種別) I UCBの装置タイプバイト(UCBTBYT1からUCBTBYT4) +---------------------+ +06 I CL6(ボリューム名) I +---------------------+ +12 I H(順序番号) I +---------------------+ +14 I XL4(装置種別) I UCBの装置タイプバイト(UCBTBYT1からUCBTBYT4) +---------------------+ +18 I CL6(ボリューム名) I +---------------------+ +24 I H(順序番号) I +---------------------+ : : +---------------------+ +252I XL3(DSCB1-TTR) I 最初のボリュームのDSCBレコードTTR +---------------------+
データセット名からカタログされているボリューム名を求めるにはLOCATEマクロを使用します。LOCATEマクロはカタログ項目を読み取るためのサービスで、いくつかの機能がありますが、ここではDSNを入力にして、カタログされているボリューム名を求めています。ボリューム名は1つとは限らず、データセットは複数のボリュームに分散して作成されることもあるので、ボリューム・リストの形式で戻されます。HSMによってマイグレートされたデータセットの場合は、元のボリューム名ではなく「MIGRAT」という名前が返ります。
CAMLSTはLOCATEマクロの入力パラメーター・リストです。
カタログされているすべてのデータセットをリストアップするような場合は、CSI(カタログ検索インターフェース)を利用すればAMSのLISTCATのようなプログラムを作ることができます。MSPとVOS3にはありませんが、代わりにGENERIC LOCATEやカタログレコードを順次に読むためのインターフェースがあります。それらはMVSでも同じですが、現在ではCSIを使用する方がいいでしょう。MSPもVOS3もGENERIC LOCATEやカタログレコードの順次アクセスはマニュアルで公開していないため、必要ならメーカーに問い合わせて下さい。
データセット名とボリューム名からデータセットの属性情報を求める(非VSAMデータセット)
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- : OBTAIN CAMLST ISSUE OBTAIN SVC LTR RF,RF SUCCESSFUL ? BNZ VOLERROR NO, DSN NOT FOUND OR VOL IO ERR : : CAMLST CAMLST SEARCH,DSN,VOL,OUTAREA OBTAIN SERVICE PLIST DSN DC CL44'MY.JCL' INPUT DSNAME VOL DC CL6'ARTCED' INPUT VOLNAME OUTAREA DC XL140'00' 140BYTES DSCB READ AREA :
OUTAREAの形式 +-----------------------+ +00 I XL96(DSCB1データ部) I +-----------------------+ +96 I XL5(DSCBのCCHHR) I +-----------------------+
データセット名とボリューム名がすでにわかっている場合(あるいはLOCATEによってボリューム名を得た場合)、そのデータセットの各種の属性情報、例えば編成種別、レコード形式、レコード長、ブロック長、スペース量、作成日やアクセス日などを読み取ることができます。これらの情報はVTOC内のDSCBレコードに格納されており、OBTAINマクロによってDSCBレコードを読み取ることができます。編成種別やレコード形式、長さなどは、データセットをOPENすればDCBに返されますが、DSCBを読み取ればわざわざOPENしなくてもそれらを得ることができます。
OBTAINもLOCATE同様にCAMLSTマクロによって入力パラメーター・リストを作ります。ここではデータセット名を入力にして、対応するDSCBレコード(DSCB1)を読み取っています。返されるのはDSCBのデータ部(96バイト)とDSCBレコードのCCHHR(5バイトのボリューム内ディスクアドレス)です。
なお指定したDSNがVSAMのクラスター名の場合、返答域には最低限のフィールドが設定されたダミーのDSCBが作成され、DSCBのCCHHRには0が設定されます。
ボリューム内に格納されているデータセットをリストアップする
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- OPEN (SYSPRINT,OUTPUT) OPEN LIST DATASET SPACE , OBTAIN CAMLST1 ISSUE OBTAIN SVC LA R2,OUTAREA LOCATE TO DSCB4 DATA PART USING IECSDSL4,R2 ADDRESS IT SLR R0,R0 CLEAR WORKREG IC R0,DS4DEVDT LOAD NUM OF DSCBS PER TRACK STH R0,DSCBTRK SAVE IT MVC LASTTRK,DS4VTOCE+6 SET VTOC FINAL TRACK ADDRESS : DROP R2 FORGET DSCB4 MVC CCHHR,OUTAREA+96 SET DSCB4 CCHHR USING DDSCB,OUTAREA ADDRESS TO DSCB RECORD LOOP DS 0H BAS RE,SETCCHHR SET NEXT RECORD NUMBER OBTAIN CAMLST2 ISSUE OBTAIN SVC CLI DS1FMTID,C'1' RETURNED FORMAT1-DSCB ? BNE SKIP NO, IGNORE IT : MVC LISTREC+4(44),DS1DSNAM SET DSNAME PUT SYSPRINT,LISTREC PRINT IT : SKIP DS 0H CLC LASTTRK,CCHHR READ ALL DSCB IN LAST TRACK ? BNL LOOP NO, LOOP FOR NEXT DSCB SPACE , DONE DS 0H CLOSE (SYSPRINT) CLOSE LIST DATASET SLR RF,RF SET CC=0 SVC 3 EXIT TO DISPATCHER SPACE , SETCCHHR DS 0H SLR RF,RF CLEAR WORKREG IC RF,CCHHR+4 LOAD PREVIOUS RECORD NUMBER CH RF,DSCBTRK LAST RECORD IN TRACK ? BNL *+4+4+4+2 YES, CHANGE TRACK NUMBER LA RF,1(,RF) NO, INCREMENT RECORD NUMBER STC RF,CCHHR+4 SET IT BR RE RETURN TO CALLER SPACE , ICM RF,B'0011',CCHHR+2 LOAD PREVIOUS TRACK NUMBER CH RF,=H'14' LAST TRACK IN CYLINDER ? BNL *+4+4+4+4+2 YES, CHANGE TRACK NUMBER LA RF,1(,RF) NO, INCREMENT TRACK NUMBER STCM RF,B'0011',CCHHR+2 SET IT MVI CCHHR+4,1 SET RECORD NUMBER=1 BR RE RETURN TO CALLER SPACE , ICM RF,B'0011',CCHHR+0 LOAD PREVIOUS CYLINDER NUMBER LA RF,1(,RF) NO, INCREMENT CYLINDER NUMBER STCM RF,B'0011',CCHHR+0 SET IT XC CCHHR+2(2),CCHHR+2 SET TRACK NUMBER=0 MVI CCHHR+4,1 SET RECORD NUMBER=1 BR RE RETURN TO CALLER SPACE , CAMLST1 CAMLST SEARCH,VTOCDSN,VOL,OUTAREA OBTAIN SERVICE PLIST CAMLST2 CAMLST SEEK,CCHHR,VOL,OUTAREA OBTAIN SERVICE PLIST VTOCDSN DC 44X'04' VTOC DSNAME VOL DC CL6'WORKZ4' INPUT VOLNAME DSCBTRK DC H'0' NUM OF DSCBS PER TRACK LASTTRK DC XL4'00' VTOC FINAL TRACK ADDRESS CCHHR DC XL5'00' INPUT CCHHR OUTAREA DC XL140'00' 140BYTES DSCB READ AREA SPACE , LISTREC DC CL120'DSN=XXXXXXXX' SYSPRINT DCB DDNAME=SYSPRINT, LIST DATASET DCB + MACRF=PM,DSORG=PS, + RECFM=FB,LRECL=120 : : DDSCB DSECT , DSCB MAP IECSDSL1 (1) ORG DDSCB IECSDSL1 (3) ORG DDSCB+44 IECSDSL1 (4) ORG , :
OBTAINマクロを使い、VTOC内のDSCBを順次に読み取ることによって、DASDボリューム内のデータセットの一覧を作ることができます。ここではDSCBのCCHHR(ボリューム内ディスクアドレス)を入力にして、対応するDSCBレコード(DSCB1)を読み取っています。返されるのはDSCBのキー部(44バイト)とデータ部(96バイト)です。
VTOCの先頭にはDSCB4というVTOC自身を示すレコードがあります。このレコードのキーには44バイトのx04が設定されており、DSNに44バイトのx04を指定することで、DSCB4を読み取ることができます。返されたDSCB4のCCHHRを利用してDSCB4に続く残りのDSCBレコードを順次に読み取ることができます。
サンプルではDSCB4の読み取りにはOBTAIN/SEARCHを、以降のDSCBレコードの読み取りにはOBTAIN/SEEKを使っています。VTOCの終端はDSCB4に設定されているので、そこに示されたトラック内のDSCB4を全部読んだところで処理終了としています。読み込むべきDSCBのCCHHRは1トラック内に格納されるDSCBレコード数に基づいて計算します。この値もDSCB4に格納されています。1トラック分のDSCBを読んだら、トラックアドレスを1つ増やしてレコード番号は1に戻します。トラックアドレスが14になったら次は15ではなく、シリンダーアドレスを1つ増やしトラックアドレスは0に戻します。現在のディスク(3390など)は1シリンダー15トラック(0から14)なので、シリンダーあたりのトラック数を15と決めて処理していますが、本来はデバイスの特性に応じて変動してもいいようにロジックを作るべきです。例えばDEVTYPEマクロを使用すればシリンダーあたりのトラック数を求めることができます。
データセットを示すDSCB1以外はすべて読み捨てていますが、データセットが占めるスペース量などを正しく知る場合には、関連するDSCBも読む必要があります。またDSN以外はプリントしていませんが、実際には編成種別、レコード形式、レコード長その他の情報を編集して出力しなければ実用にはなりません。それらもDSCB1に格納されています。VTOCやDSCBレコードの詳細についてはマニュアル「z/OS DFSMSdfp 拡張サービス」に記載されています。
実践のプログラミングにおいて、VTOC内の複数のDSCBを読み取るような処理では、OBTAINで1つずつDSCBを読む代わりにCVAFという別のVTOCアクセスサービスを使うことが多いです。OBTAINはインデックスVTOCがサポートされるより前のMVSからある古典的なAPIですが、インデックスVTOCの場合はボリューム内の空きスペースを管理するDSCB5は事実上使われないので、OBTAINでは空きスペース量と場所などを知ることができませんが、CVAFを使うことでインデックスVTOCであってもそうでなくても処理することができます。しかしCVAFはOBTAINに比べると複雑なAPIなので、まずはOBTAINを使ってDSCBを読み取り、DSCBやVTOCの構造を理解してからCVAFを使う方がわかりやすいと思います。
なおOBTAINやLOCATEに関しては基本的な機能はMSPとVOS3でも互換があります。MSPではCVAFも一部を除き同様のAPIがサポートされています。
関連マニュアル: