ソフトウェアの導入(1)

By takao - Last updated: 水曜日, 4月 1, 2009
すべてではありませんが、IBM系のソフトウェアはSMP/Eを使って導入するのが普通でしょう。これがまたわかりにくいソフトウェアなので習熟には時間がかかります。

それではどうしてメインフレームは導入にSMP/Eなんていうわけのわからんものを使っているのでしょうか?単純にコピーではいけないのでしょうか。理由は大別してふたつあります。

修正情報の履歴を明らかにすること

通常、モジュールをメンテナンスしていると複雑なモジュール関係が生じます。次の図で考え方を説明します。

smp_preプログラムのソースコードを何度か修正したとします。最初の修正がA(黄色)だったとします。次にB(赤)は、黄色の修正を前提として行われています。次に三度目にC部分(緑)を修正しました。この場合、赤は関係しているかも知れないし、していないかもしれません。機械的には決められません。
つまり、
どちらかが緑の修正情報の前提となります。このように、履歴がはっきりしていないと的確に修正情報を反映できません。Windowsなどではモジュールごと、ばさりと置き換えてしまうことが多いので、このような考慮は少ないかも知れません。このような管理をしている理由は、SMP/Eのもうひとつの目標に関係します。

修正情報をお客の環境にあわせて確実に適用する

モジュールをきちんとリンクエディット(連携編集、バインド)するのは、むつかしい作業です。モジュールの順序、与えるパラメータで再入可能とか、オーソライズドにするかなどが決まります。
さらに、ユーザーが出口ルーチンなどを利用している場合もあります。そのため、モジュールを単純に新しいものと置き換えると、カスタマイズした機能が消失する可能性があります。この多くのカストマイズを許しているところが、メインフレームの特徴のひとつでもあります。
それゆえ、修正情報を適用する場合には単純な置き換えでなく、システム部分のモジュールを置き換えて適切にリンクエディットしてロードモジュールを作り出します。

このふたつが大きな機能であるといえます。逆に、導入されていないプロダクトに関する修正情報を適用しようとしても、「ないよ」とはじかれることもSMP/Eの特徴です。
Filed in メインフレーム・ソフトウェア

10.REXX 他のOSでも動かす

By takao - Last updated: 火曜日, 3月 24, 2009
REXXの優れている点に、日本では知られていませんが、あらゆるOS上にポーティングされているという事実があります。(一昔前ですが、PC-DOSにまで搭載されていました。)しばらくWindows版が有償だったことは、普及の足かせだったと思います。
今はオープンソースでREXXの処理系はあります。まず、このOpen Object Rexxのサイトにアクセスしてください。左のメニューからDownloadを選んでいただくと、各プラットフォームごとのパッケージがあります。

Windows版をインストールすると、RXAPIというサービスが起動します。これのおかげでREXXを動かすことが、ずいぶん簡単になります。以下のようなファイルを作ってみます。

/* REXX */
SAY "Hello, World!";

適当なフォルダーにhelloworld.rexという名前で保管しましょう。
コマンドコンソールをあげて、適当なフォルダーをカレントフォルダーとして、helloworld.rexといきなりタイプインしてみてください。
Hello, World!
と表示されたはずです。上のサービスがサフィックス.rexを監視しているようです。

取り合えず動作を確認したところで、日本語マニュアルは以下にあります。
Object REXX for Windows リファレンス

Object REXX for Windowsプログラミングガイド
IBMのマニュアルは、リファレンスは辞書的に引くもの、ガイドは「?するには」的なものです。それゆえ、プログラミングガイドから見始めたほうがいいでしょう。

オブジェクト指向のREXXとはいえ、従来のREXXの機能(クラシックREXXなどといいます)はそのままです。オブジェクト指向を楽しみたくなってから始めてもいいでしょう。
なお、オープンソースとはいえ、このREXXはIBM REXXと100%コンパチだ、とウェブサイトには書いてありますので、プログラム自体はMVSにもっていっても動作するでしょう。同じ言語でプラットフォームを問わないというのは、Javaの普及を見てもわかるとおり便利なのです。もちろん、Windows固有の機能、MVS固有の機能を使う場合は無理ですけれども。

calcurator MVSのREXXと違って、GUIを作ることができます。サンプルは導入したパッケージ内のC:\Program Files\ooRexx\samples\oodialogなどにあります。calcurator.rexなどを動作させると、このように電卓のウィンドウが表示されます。

Filed in REXX入門

PCの中にメインフレーム?

By takao - Last updated: 金曜日, 3月 6, 2009
以下は、読まれている方からの貴重な投稿を加筆したものです。Kさん、ありがとうございます。
メインフレームはそのメインストリートとは別に奇異な機種をいくつか生み出しています。
ここで話題にするP/390は、まさにそのひとつであります。これは、OS/2(これももう死語ですが、IBM謹製のPC用OS)の動くパソコンにメインフレームのプロセッサーチップ(初期G4、後期G5用)を搭載したカードを乗っけたもので,1997年に発表されました。

当時は、I/O用のバス速度も現在と比べると鬼のように遅く、インストラクションの処理速度にI/Oがついていけない上に、SCSI系のトラブルも非常に多く、大変な苦労をしましたが、今となっては非常に懐かしく、かつ、貴重な思い出&経験でした。
その後、IBMが正規のサポート製品MP3000を1999年9月に発表するに至って、P/390の存在価値はどんどん薄れていきました。(P/390はエニコムなどが中心となりENI390といった名称で販売していた。MP3000は、100Vで動作し、中小企業のオフィスに置くことを想定した、「メインフレーム」でした)
しかし、あの頃、今のCPU、BUS、メモリー能力を持った、大容量HDDのPCがあったら、「ミニ・メインフレーム」はもっと脚光を浴びせられただろうなぁ、と今でも思っております。
廃棄処分となったPC390システムの390ボードを、現在のPCにさして動かしてみようかと計画中です。(発表当時はマイクロチャネル用だったが、後期にはPCI用があった)
もっとも、当時でもマザーボードのBIOSで相当苦労をしましたので、さしても認識すらされないかもしれませんが。
実験結果が出たら、またメールしますね。
どうか、サイトに訪れた、隠れMFオタクたちが、どんどんこのサイトを進化させて言ってくれる事を祈りつつ!今後とも宜しくお願い致します。



ここからはサイト主宰者追加です
某ISVにいたときに、ENI390使ってました。VMでVSEとOS/390の両方を動かしてました。開発部門で限られた人数でしか使わなかったせいもあるけど、会社のメインマシン(確かMultiprise 2000だったか)のOS/390より、はるかにさくさく動きました。Y2Kなんかもあって、結構な数の企業が導入したとも聞いてます。
ハードスペックだけ比べれば、現在のPCとHERCULESの組み合わせの方が格段に速い(?)のでしょうね。
Filed in メインフレーム・ハードウェア, メインフレーム情報

メインフレームはなぜなくならないか?

By takao - Last updated: 月曜日, 3月 2, 2009
多くの若者がこの疑問をもつ。
完全な答えじゃないけれども、オープン系も見てきた私から、理由をいくつかあげておく。

乗り換えコスト

2007年問題に代表されるように、初期のプログラムを設計、開発した人がほとんどいない。メインフレームシステムを移行しようとすると、その初期の設計からを完全に理解しないと、新しいアプリケーションを作るわけにはいかない。この莫大なコストをいまさら負担するだけの潤沢なキャッシュフローを持つ会社は少ないと思われる。

技術の素直さ

メインフレームの前身は、カード処理システムだったことをご存知の方もいるだろう。膨大なデータをプログラムで処理して出力する。「コンピュータ」出現前夜はすべてが手作業と算盤だった。それを素直に機械化したのが、現在のメインフレームである。基本の考えにはオブジェクト指向もなければ、RDBもない。なにより莫大にコードを費やすGUIはなかった。それゆえシンプルで圧倒的な速度を持つ。いまだにテープ搬送や大量印刷は性能、コスト面でオープン系は勝てない。
また、大規模プロジェクトにおいてプログラムの品質をそろえようとすると、相当に技術レベルとしては低めになる。大規模開発の場合は、オブジェクト指向にすぐれた人材をかき集めてテストするより、そこそこの人間を集めたほうが確実という面がある。

台数

オープン系サーバーがここ数年、大きく方針を変えたのが台数である。ブレード、VM、すべては筐体をひたすら減らしている。エネルギー問題もあるが、台数を減らすと確実に運用コストは減る。もともとメインフレームは一台でさまざまなプログラムを流すか、LPAR,VMなどでシステムをいくつももつ、といういずれのパターンにも対応できる。目先の導入コストが安くても、運用を考えメインフレームに戻したお客も少なくはない、と聞く。

運用の細やかさ

シンプルな動きであっても集積していくと、運用は煩雑になる。そのため、メインフレームは運用管理ソフトのレベルが非常に高い。都銀で多いところは一晩に1000本近いバッチジョブが走ることがあるが、それらをエラーをふくめて、きちんとコントロールできる。なんでもオンラインで済ませるという考え方もあるが、いろんな会社と仕事をしていく上でチェックポイントを儲けてデータを受け渡しし、バッチで処理していく、というほうがビジネス上は合理的な場合もよくあるのだ。

ハードとソフトの密接なかかわり

オープン系の人は実感しないだろうが、メインフレームのI/O処理にはCPUがほとんど介在しないため、ターンアラウンドタイムが早い。しかも接続されているデバイスの数は数百なんてのは当たり前にある。
intelが長年i/o専用プロセッサーの研究を続けていて、いまだに出せないのは、オープン系での適用は、それなりに困難さがあるのだと思われる。

また、初期のMVSからESAに変わった時、チャネルの設計は大きく変更され、OSのI/O関係のルーチンも書き直された。このようにハードとソフトを一体で作ることで、堅牢なシステムを作るという目的に焦点をあてることができる。

問題解決の確実さ

ブラックボックス、ホワイトボックスにも書いた問題である。オープン系は、専門家の集まり、水平分業の典型である。プロセッサはintel,メモリーはkingstone,HDDはHDS,ネットワークカードはどことも知れない。OSはオープンソース、言語環境はJavaでIBM,ミドルウェアはWebSphere, データベースはOracle。開発にはEclipseを使いました、なんてのは珍しくもなんともない。これらはお互いが接続点で規約を守る、というルールに基づいてできている。しかし、必ずしもそのルールどおりにならないこともある。JVMの微妙な動きはIBMのバージョンによってもSun Microによっても違うなんてこともある。

一方、メインフレームは基本が「純正」でできている。ハードウェアもOSもミドルウェアもすべて同じ会社が提供する垂直統合型である。そのため責任はきわめて明確である。問題を切り分けるところから、メインフレームベンダーに渡したって構わない。
サードパーティのハードウェアは、すべて純正のふりをしているから、動きも明確である。

ミッションクリティカルなシステムな場合、仕事の精度は常人じゃ驚くほどの精度で行われる。問題が起きて「わかりません」とか「相性の問題です」なんていうベスト・エフォートを根底とした発言はあり得ない。すべてのハードとコードに責任をもつ世界の重さというのは、オープン系の人間にはわからないと思う。

あらためて書いてみると、すべてではないけれども、メインフレームが頼りにされる場所があるのは当然か、という気がしている。
Filed in つぶやき・雑感

メインフレームの解説本、やっと出ます

By kamii - Last updated: 金曜日, 2月 27, 2009

このサイトを始めたばかりの昨年10月に、日本では久しぶりのメインフレーム・コンピュータに関する和書の発刊について紹介させてもらいました。一緒にこのサイトをやってくれている相方が「本が出ます」のページで宣伝してくれてますが、やっと発刊の運びとなりました。

「メインフレーム実践ハンドブック
(z/OS,MSP,VOS3のしくみと使い方)」
B5版、約580ページ、税込み価格9240円


3月下旬にリックテレコム社から刊行されます。メインフレームOS(z/OS、MSP、VOS3)の仕組みや機能に関しては文章だけでなく、図表も交えて解説してあるので、ビギナーの方にも理解しやすい内容で書き下ろしました。このサイトを訪れる方の多くが「JCL」「入門」と言ったキーワードで探し当てられているようです。JCLはMVSを使う上で、はずすことのできないものの一つですが、本の方でももちろん取り上げており、JCLだけで一つの章を割いています。書店に置いてあったらぜひ一度ご覧になってみてください。もちろんアマゾンでも取り扱われます。上に記した本のタイトルをクリックすると出版社からのパンフレットが開きます。本の目次が載ってますので、何について書いてあるかはご覧いただくことができます。

Filed in つぶやき・雑感

どうやって覚えればいいのか、何から始めればいいのか? -2-

By kamii - Last updated: 火曜日, 1月 13, 2009

前回はTSO/ISPFなどの対話型ツール、JCLとユーティリティから覚え始めるとよいのでは、と書きました。しかしユーティリティを使う上で避けて通れないものがあります。ユーティリティに限らずメインフレームを使う上で避けて通れないものでもあります。それがメインフレームにおけるファイル(データセット)の種類や構造に関する知識です。一般には「ファイルシステム」などと呼ばれているものです。


ファイルシステム

メインフレームでは一般に呼ばれる「ファイル」のことを「データセット」と呼びます。単に呼び方が違うだけではなく、使い分けられるものですが、ここでは説明しません。
データセットにはいくつかの種類と構造があり、用途によって使い分けられます。順次データセットや区分データセット、固定長レコードや可変長レコード、ブロックとレコードなどが関連するものです。これらはメインフレームのファイルシステムに特有のもので、他のプラットフォームを先に経験した人には、メインフレームをわかりにくくしている一つの要因かも知れません。しかしメインフレームでプログラムを作るだけでなく、使う上でも避けて通れないことです。
簡単な解説は「データセットの種類とアクセス法」に書いてあります。


OSの機能

メインフレームのOSは広範囲に渡る機能を持ちます。詳細を知る必要に迫られたときに頼りになるマニュアルなどもだいたい機能ごとに分類されています。どのような機能があって、それぞれの機能が何を行っているかの概要ぐらいはわかっていないと、なかなか先に進めません。代表的なOSであるz/OS(MSP,VOS3)に関して主な機能を取り上げ、概要を説明してみましたので参考にしてください。

記事一覧のページから、カテゴリー「 z/OS(MVS),MSP,VOS3のしくみ」をご覧下さい。

Filed in つぶやき・雑感

ホワイトボックスとブラックボックス

By takao - Last updated: 木曜日, 1月 8, 2009
オープン系とメインフレーム系で大きく違う文化が、これだと思います。
メインフレーム系は基本的に一社でハードウェア、オペレーティングシステム、ミドルウェアを提供し、システムとします。これはメーカーに相談すれば、わからないことはない、という文化を育成してきました。非常に高価な投資であったこともあり、ビジネスとしてみてもメーカー側も期待に答えざるを得ない面がありました。メインフレーム系の障害対応報告会などで、ミドルウェアの内部エラーの克明な説明をお聞きになられた方も多いでしょう。

一方、オープン系はその名のとおり、規格を基準として様々な会社が提供するパーツを組み合わせてシステムとします。それゆえ、中身がどうだという議論には至りにくく、規格どおりか、固有の動きから内部を類推する以上の議論には進めません。「相性」という言葉で済ませることもよくあります。
しかも、メインフレームに比べるとトレース、ログ機能が大幅に落ちることも障害分析を困難にしています。障害でも原因がはっきりしないままで終わらせるしかないものが少なくありません。

メインフレームの文化で育ってきたお客さんの中には、オープン系のアプローチがルーズに見える方もおられるようです。しかし、システムの金額や経済性などを考えると「そういうブラックボックスなのだ」と考えるしかないと思われます。汎用機やミニコンの時代はメーカーがハードウェアからOSまですべてを提供する方式でした。オープン系はおのおのの専業メーカーが競い合って出した製品を組み合わせることで提供されます。
過大な期待をオープン系システムに求めることは、たとえインテグレータが大丈夫と言ったとしても、無理なところがあります。

だからといって、最初から障害を解決する努力をほとんどせずに、なんでも「わからない、仕方ない」で済ませることも極端です。設定ミス、運用ミスであることもあるのですから。

筆者のようにオープン系、メインフレーム系の保守を経験してきた人間からすると、障害の解決(ソリューション)についてはオープン系のほうが、より大人の判断を求められることが多いように感じています。
Filed in つぶやき・雑感

メインフレーム技術者がなぜ育たないか?

By takao - Last updated: 火曜日, 12月 16, 2008
タイトルの記事を書くのですが、最初に理由から。オープン系に比べメインフレーム系の技術者が育つ(ここでは、より技術的に高度な仕事ができることを意味している)時間は遅いです。
その理由を明らかにすることで、メインフレームにたずさわっている人の将来と、穴に落ちてなかなか進まない状況を避けたい、さらにこのサイトでどうフォローすればいいのかも、できれば考えてみたいからです。

覚えることが多い
端的にいえばマニュアルの分厚さです。最近はDVDやWEBになったせいで、物量の把握が難しくなりました。推測ですが紙にすると、5メートル幅くらいのキャビネをドンと3段は占領するのではないでしょうか。
データセットで今使われているものにしても数種類、レコード形式の違いがそれぞれあり、扱うユーティリティも違います。さらにデータベースもやるとなるとIMSで数種類+DB2。
セキュリティのRACFもリソースごとに扱いが違い、言葉を覚えるだけでも一苦労。なんでもOSでやろうとするため、範囲が広い。Z/OSについてなんでも知っている、という無理をしないことが大事だと思います。基準はやはりLinuxエンジニアのような感じになるのでしょうか?そう絞っても覚えることは多いですが。
その場限りがむしろ例外
UNIXなどではコマンドをたたいて仕事して、その仕事のログと結果を保存しろなどとはいわれないと思います。メインフレームではTSOでいろんな仕事を済ませると「記録に残らない」とJCLでの仕事をうるさくいわれている人が多いと思います。少し大掛かりになると夜間バッチに回せ、といわれたりすらすることでしょう。対話的に仕事をするのと、定型的に仕事をするのでは「行動-フィードバック」のサイクルに大きな差が開き、それが学習効果にもたらす影響は大きいでしょう。
妙な徒弟制度
これは日本特有かも知れません。もともとメインフレームは研究所で最新の技術成果を投下した、いわゆるハイテク製品でした。そのころは扱う人もエンジニアだったのですが、自動化が進むにつれ、「定常業務については」誰もがコントロール可能なものになりました。このころから「どうしてこうするか?」ではなく、「こうしなくてはイケナイのだ。理由は聞くな。」という運用、オペレータの文化が育成されてきました。新人の「どうして?」という疑問に答えることもなく、形式主義となり長年勤めた人がエライ、という当初のコンピュータ運用とはかけ離れたものとなってしまいました。しかし、コンピュータはハイテク製品であるため、ある日突然、新技術により豹変します。形式主義では対応できないのです。また、「試す」という行為ができない現場では人は学習のしようがありません。
プログラミングの難しさ
このポータルでもプログラミングの解説を多く行っていますが、システムを触ろうとすると圧倒的にアセンブラーをつかわねばなりません。高水準言語でシステムと協調して動くプログラムを作ることのハードルがとても高いのです。これは、エンジニアに長時間の学習を強います。
コミュニティの乏しさ
メインフレームの世界には不思議なことにフリーウェアのポータルがありません。はっきりしませんが、アメリカではUS IBMが難癖をつけて潰す、と聞いたことがあります。ユーザーのスキルの低いことがビジネスチャンスであったことは間違いないのですが、今の時点でそれは正解でしょうか?
以上くらいを考えてみました。他にもあるかもしれません。ここから導き出されることは「自分用の環境をもち、すばやくテストする」「わからないことを人に聞ける、例がある」という点がLinuxなどと大きく違い、エンジニアが育たない原因かもしれません。
手前ミソになりますが、アルテシードでは前者をherculesで、後者をこのサイトでカバーしエンジニアの成長に貢献できたら、と思っています。
Filed in つぶやき・雑感

04.2オペレーター応答とコマンドを受け取る(WTORとQEDIT)

By kamii - Last updated: 金曜日, 12月 12, 2008

プログラムがコンソール・オペレーターと通信(会話)を行うには2つの方法があります。1つはメッセージを出力して、そのメッセージに対する応答を受け取る方法です。もう1つはメッセージとは無関係にオペレーターがMODIFYコマンドやSTOPコマンドによってプログラムに指示を与える方法です。
前者はプログラムでオペレーターの判断を必要とする何らかの事態が起きたときに利用されます。例えばデータセットを初期化することがパラメーターで指定された時に、本当にクリアーしてもいいのかを再確認するような機能を持たせる場合や、誤った入力データを見つけたような時に、処理不能で異常終了するのか、誤ったデータを無視して処理を続けるのか、などを選択させるような場合に、その旨のメッセージをコンソールに出して、この後どう動くかをオペレーターに判断してもらうようなプログラムを作ることができます。
後者はオペレーターの都合によってプログラムに特定の動作を行わせたり、動きを変える場合などに利用されます。バッチ処理のように入力データが終わったらプログラムの処理も終わるのではなく、一定時間あるいはオペレーターが指示するまで動き続ける常駐型のプログラムを作る際に必要となる機能です。MODIFYコマンドでプログラムの動作や機能を変更し、STOPコマンドでプログラムを終了させるのが一般的です。


メッセージに対するオペレーター応答を受け取る

WTORマクロはコンソールにメッセージを表示して、オペレーターからの応答を受け取ります。出力するメッセージの指定方法はWTOマクロと同じですが、オペレーターからの応答を受け取る領域とその長さ、および待ち受けのためのECBアドレスを追加で指定します。
WTORマクロの完了はオペレーターが応答を入力したときではありません。コンソールへのメッセージ出力がスケジュールされたら完了してプログラムに戻ってきます。この時返答領域にオペレーターからの応答が入力されているかはわかりません。WTORマクロで指定したECBでWAITマクロを発行して応答入力を待ち受けなければなりません。オペレーターが応答すればWAITマクロが完了します。
バッチ処理のプログラムではあまり必要ありませんが、WTORマクロの後ですぐにWAITを出さず、オペレーターが入力するまでの間も止まることなく別の処理を行うこともできます。またWTORもマクロ完了時にGR1にメッセージ識別番号が返ります。必要なら応答を待たずにメッセージを取り消すことも可能です。

最初の例は古典的なWTORマクロのコーディングです。MSPとVOS3もこの書き方になります。2番目はMVS(z/OS)で利用可能なメッセージ・テキストをマクロの外に記述する方法です。


オペレーター・コマンドを受け取る

アドレス空間に常駐してオペレーターが指示するまで一定の処理を行い続けるサーバー型のプログラムでは、「次に何を行うか?」と言ったことをオペレーターからのコマンドによって判定したい場合があります。このような場合にOSのMODIFYコマンドやSTOPコマンドでオペレーターの指示を受け取ることができます。このプログラムはMODIFYおよびSTOPコマンドを処理するサンプルです。WTORに比べるとロジックはやや複雑になりますが、STCタスクとして動かす常駐型のサーバープログラムでは必須となる機能です。

プログラムは起動時の初期設定として、EXTRACTマクロをサンプルのように発行してMVSのコマンドスケジューラーリスト(COMMAREA)のアドレスを得ます。STARTコマンドで起動されたSTCタスクの場合は、STARTコマンド用CIBがチェインされているのでそのアドレスを求めます。これはCOMMAREA内のCOMCIBPTフィールドにあります。バッチジョブなどSTARTコマンド以外の方法で起動された場合はチェインされていません。このアドレスを調べればSTARTコマンドで起動されたSTCタスクかそうでないかを判定できます。STC起動の場合はSTARTコマンド用CIBをBLOCK指定のQEDITマクロを発行してクリアーしておきます。(サンプルでは内部サブルーチンFREECIBで行っています)STARTコマンドでパラメーターを指定していなくてもCIBは作成されることを知っておいて下さい。

STARTコマンドでパラメーターを指定する場合はこのようにコマンドを入力します。例えば S MYSTC1,,,MODE=DEBUG とすれば MODE=DEBUG の文字列がSTARTコマンド用CIBで渡されます。CIBDATLNはパラメーターの長さ、CIBDATAがパラメーター文字列です。
次にMODIFYコマンド用のコマンドキューを作るため、CIBCTR指定のQEDITマクロを発行します。CIBCTRには同時に入力可能なコマンド数(最大255)を指定します。入力されたコマンドはいっぺんにプログラムに渡ってくるわけではありません。1つずつ順番に取り出し、1つずつ処理することができます。そのためCIBCTRは1でもかまいませんが、コマンド処理に時間が掛かるとオペレーターは次のコマンドを入力してもMVSにリジェクトされてしまいます。極端に多くする必要なありませんが、10個程度はあってもいいでしょう。CIBCTR=10は未処理のコマンドを10個分OS内でキューイングできることになります。ORIGINパラメーターにはCOMMAREAのCOMCIBPTフィールドを指定します。これでオペレーターコマンドを受け取る準備ができました。
EXTRACTを出した後QEDITも含めてOSのコントロールブロック(制御表)をプログラムで直接参照します。このためコントロールブロックをフィールド名でアクセスするためにコントロールブロックのマッピングマクロを使います。参照するコントロールブロックはCOMMAREAとCIBです。それぞれIEZCOMマクロとIEZCIBマクロでマッピングします。DSECT展開マクロでないためサンプルのように自分でDSECTを定義します。MSPではKDJCOMマクロとKDECIBマクロ、VOS3ではJDJCOMマクロとJDECOMIBマクロになります。このサンプルで参照しているものであればフィールド名は同じです。

プログラムはコマンドを受け取るタイミングになったら、COMMAREA内のCOMECBPTフィールドでポイントされているコマンド入力待ち合わせ用のECBを指定してWAITします。COMECBPTフィールドはECBそのものではなく、ECBアドレスが格納されたポインターフィールドです。
すでに何らかのコマンドが入力されていたり、新たなコマンドが入力された時点でWAITは解除されます。COMMAREA内のCOMCIBPTフィールドには次の処理すべきコマンドのCIBアドレスが入っています。ここが0ならすべてのCIBは処理済みなので再びWAITを発行してオペレーターコマンド入力待ちになります。CIBアドレスが入っていればそのCIBを調べることで入力されたコマンド文字列を求めることができます。CIBのCIBVERBフィールドは入力されたコマンド種類を示します。x44ならMODIFY、x40ならSTOPコマンドですが、サンプルのように必ずラベル名で参照します。CIBSTOPはSTOPコマンドを示すEQUラベルです。通常STOPコマンドはプログラムの終了を意味しますから、サンプルのように終了処理へ移ってしまってかまいません。MODIFYコマンドの場合は入力されたコマンド文字列と長さが必要なのでCIBから求めます。CIBDATLNはコマンド文字列の長さ、CIBDATAがコマンド文字列です。コマンドを入力したコンソールIDもわかります。MSPとVOS3ではCIBCONIDフィールド、z/OSではCIBX内のCIBXCNIDまたはCIBXCNNMフィールドを利用します。CIBXはCIBに連続して配置されている拡張CIBで、先頭アドレスはCIBアドレスにCIBXOFFフィールドの値を加えることで求められます。これによって特定のコンソールからのコマンド入力かどうかをチェックしたり、コマンド発行元コンソールを記録することなどもできます。
コマンド文字列が求められたら、対応するコマンド処理を行い、その後処理済みコマンドのCIBを解放します。(サンプルでは内部サブルーチンFREECIBで行っています)先にCIBを解放してもかまいませんが、その場合は入力されたコマンド文字列をプログラム側の領域に適宜コピーしておく必要があります。解放したCIB領域を後から参照してはなりません。このサンプルは入力されたコマンド文字列と長さを先頭の32バイト分コンソールにエコーしています。

コマンド処理が終わりCIBを解放したら、次のコマンドをチェックします。再びCOMCIBPTフィールドを参照して次のCIBがセットされているかを調べます。COMCIBPTはCIBを解放するためのBLOCK指定のQEDITマクロによって内容が更新されます。次のCIBがなければWAITへ回ります。このようなサイクルでオペレーターコマンドの処理を行っていきます。MODIFYコマンドで独自のコマンド処理をする場合であってもプログラムはSTCタスクである必要はありません。バッチで起動されても同じロジックで処理できます。異なる点は初期設定時にSTARTコマンド用CIBがあるかないかです。もしSTARTコマンドではパラメーターを受け取らないなら、少し乱暴ですが初期設定時にSTCかどうかを判定せずにSTARTコマンド用CIBをQEDITで無条件にクリアーしてもかまいません。バッチの場合はQEDITがエラーになるだけでABENDするようなことにはなりません。


Filed in 中級編

どうやって覚えればいいのか、何から始めればいいのか? -1-

By kamii - Last updated: 木曜日, 12月 11, 2008

サイトに併設している掲示板に「1週間で覚えられることは?」という質問がありました。1週間という期間はともかくとしても、全く始めてメインフレーム・コンピューターの仕事に携わることになった人達には切実なことでしょう。コンピューターがまったく初めてなのか、他のプラットフォームは経験があるのか、などベースの知識や技術に違いがあってもメインフレーム・コンピューターそのものに携わったことがないのに、即戦力でないと困る、勉強は自分でやってね、みたいなツラい状況に置かれている人達に何かのアドバイスになればと考えます。


基本の対話ツールを使えるようにしましょう


JCLを書けるようにしましょう


ユーティリティ・プログラムを使ってみましょう


メインフレームは範囲が広い

マニュアルの数だけを見ても扱う範囲が広く、これさえ覚えれば後はどうとでもなる、と言う万能的なものもありません。やる仕事が決まっているのならターゲットを絞ることはできますが、それは中級レベル以上の知識でしょう。何をやるにせよ基本の部分をあまりに端折ると、結局中途半端なことになってあとで苦労します。とは言え基本の部分の範囲が広いのと、セルフスタディの材料が少ないのが最大のネックです。ここに挙げた3つで済むわけではありません。また昔は基本知識と言えば、OSコマンドがありましたが今はセキュリティの意味からも誰もがコンソールを使うことができません。こんなことも含めて基本知識や技術の習得に関してステップバイステップで考えてみようと思います。

この話題に関してはこれからメインフレームに携わる人達には切実です。ベテランの方々の幅広いご意見やお知恵があればぜひお聞かせ下さい。

Filed in つぶやき・雑感

IBMオフィシャルz/OS解説サイト

By kamii - Last updated: 月曜日, 12月 8, 2008
米国IBM社のWebサイトに、z/OSの基本スキルについて解説されているページを見つけました。

英文ではありますが、OSのしくみ、IMS、CICSとは何だ?プログラミング言語の紹介、JCLの解説からサンプルJCLなどなど広範囲に渡って、z/OSと関連する分野の基本スキルについて解説されています。
こういうのを見ると、やっぱIBM社はメインフレームに力入ってるじゃん!と改めて思います。メーカー自らの基本スキルの解説は、これからメインフレームに携わる人への大きな福音になります(残念ながら日本語版はありませんでした)。MSP,VOS3の利用者であってもOSとしての基本部分は同じですから参考になります。

「z/OS basic skills information center」


Filed in .z/OS(MVS),MSP,VOS3のしくみ, メインフレーム情報

01.2ストレージ・プールの作成(CPOOL)

By kamii - Last updated: 金曜日, 12月 5, 2008

リエントラントプログラムでは書き込みを行うレジスター保管域や作業域はプログラムの外に確保するため、GETMAIN/FREEMAINマクロを利用します。しかし頻繁に呼び出されるモジュールでは呼び出しの度にこれらの領域の獲得と解放を繰り返すのはパフォーマンスの点で劣ります。そこでこのような場合は作業に使用する領域をまとめて確保し、必要の都度そこから切り出して使う方法が行われます。まとめて確保した領域をプール(POOL)、切り出す領域をセル(CELL)と呼びます。セルは固定長と可変長の両方の構造がありますが、可変長セルはストレージの利用効率は上がりますが実現方法はむずかしいです。ここでは固定長のセルを使ったストレージ・プールの利用を解説します。


CPOOLマクロでストレージ・プールを作る

CPOOL BUILDマクロはセル・プールの作成を行い、CPOOL DELETEマクロはセル・プールの削除を行います。このサンプルでは1KBの固定長セル64個分のプールを16MB未満のリージョンに作成します。作成されたプールの識別子がGR0に返ります。この識別子(セル・プールID)は以降のGET,FREE,DELETEの各サービスで使用します。
64個以上のセルが要求された場合は8個単位でプールが拡張されます。(拡張されたプールが未使用となっても解放はなされません、より細かなセルとプールの制御が必要ならCSRPxxxルーチン(呼び出し可能セル・プール・サービス)も利用できます。)


CPOOLマクロでセルを切り出す

セル・プールはサブルーチンを呼び出す親プログラムがあらかじめ作成しておくものとします。サンプルでは親プログラムはサブルーチンを呼び出す時、GR0にセル・プールIDを、GR1にパラメーター・リストを設定しています。
呼び出されたサブルーチンはプログラムの先頭でCPOOL GETマクロを使ってプールからセルを切り出します。切り出されたセルの長さは親プログラムがプール作成時に定義します。レジスター保管域の目的なら72バイトあればいいのですが、リエントラントプログラムでは作業域も必要になりますからそれらの長さも考慮して適当な大きさのセルを定義する方がいいでしょう。サンプルではレジスター保管域の後ろにプログラム作業域をDSECTでマッピングしています。GETMAINの代わりにCPOOL GETを使うと考えればいいでしょう。
呼び出し元プログラムへ復帰する際に切り出したセルを返却します。セル・プールIDは入口点で保管したGR0を復元して指定しています。返却するセルのアドレスはGR2に設定しています。セル返却前に呼び出し元のレジスター保管域アドレスをGR13にロードしておきます。こちらもFREEMAINの代わりにCPOOL FREEを使うと考えればいいでしょう。

プールを各サブルーチンで作成する方法も考えられますが、プールIDをどこに保管するか?と言う問題がありますので、サンプルのように親プログラムでプールを作成する方が簡単です。なおサンプルのような使い方では影響ありませんが、GETはGR2?4が、FREEはGR2?3が破壊されます。REGS=SAVEパラメーターを指定すれば内容は保証されますが、GR13がレジスター保管域をポイントしていなければなりません。したがってサンプルのようにリエントラントプログラム用レジスター保管域のためのセルのGET/FREEであればREGS=SAVEパラメーターは利用できません。

CPOOLはz/OSでのみ利用できます。MSPには同等機能としてBLDCPOOL,GETCELL,FREECEEL,DELCPOOLの各マクロがありますが、プールの作成と削除はキー0・スーパーバイザーモードのプログラムでしか利用できず一般プログラムでの利用を想定していません。VOS3では同等機能が公開されていません。
マルチタスク構造のプログラムで各タスクが同じサブルーチンを頻繁に呼び出すならば、GETMAIN/FREEMAINよりCPOOLでセルを切り出す方がオーバーヘッドが少なくなります。

Filed in 中級編

COBOLから呼ばれるアセンブラールーチン

By kamii - Last updated: 金曜日, 12月 5, 2008

現在ではアセンブラー言語でメインのアプリケーションを作ることはほとんどないものの、COBOLなどで作成されたアプリケーションからサブルーチンとしてのアセンブラープログラムを呼び出すことはよく行われます。COBOLなどの高水準言語プログラムから呼び出されるアセンブラールーチンの作成はさほどむずかしいことではありません。リンケージ規約通りにプログラムを作ればいいのです
しかし逆はかなり面倒です。アセンブラールーチン側で言語処理プログラムの環境を作り上げねばなりません。現実的にアセンブラーでメインのアプリケーションを作り、サブルーチンをCOBOLで作るなどと言うことはまず行われませんからその方法はあえて解説もしません。必要ならコンパイラー(z/OSの場合ならLE)のマニュアルに解説されていますので参照してみてください。


COBOLから呼ばれるサブルーチン例

COBOLから渡されるパラメーターはGR1が示すアドレス・パラメーターリストで受け取ることができます。
CALL文のUSINGで指定された順序でパラメーターが格納された領域アドレスが示されます。サンプルでは3つのパラメーターPARM1,PARM2,PARM3を格納した領域アドレスがGR1で示されるアドレス・パラメーターリストで渡されます。PARM3アドレスを示すワードの先頭ビットは最終パラメーターであることを示すため1にセットされます。PARM1からPARM3領域のアドレスをLM命令でGR2からGR4にそれぞれロードします。
PARM1およびPARM2で渡された値をPARM3領域にエコーバックするのがこのサンプルで行っている処理です。PARM1は8バイトの文字、PARM2はフルワードの整数値で、それぞれをPARM3領域の前半8バイトと後半8バイトに格納します。PARM2はバイナリー値を10進文字に変換して設定します。
もちろんどのパラメーターがどのような形式や長さ、意味を持つかはプログラム間のインタフェースとして予め取り決めておきます。
リンケージ規約やアドレス・パラメーターリストについてはリンケージ規約(サブルーチンを作る)も参照して下さい。


呼び出すCOBOL側のサンプル

呼び出されるアセンブラー・サブルーチンに対応した呼び出す側のCOBOLのサンプルです。
最初の例はアセンブラールーチンもリンケージエディターで静的に結合されたモジュールの呼び出し例で、2番目はリンケージエディターで結合されていない独立したロードモジュールの呼び出し例です。IBMのEnterprise COBOLによるコーディング例です。細かな構文はメーカーが提供するCOBOLコンパイラーによって多少の違いがあるので利用するコンパイラーのマニュアルも参照して下さい。


パラメーターの値渡し

IBMのEnterprise COBOLではパラメーターを値その物で渡すこともできます。CALL文のUSINGパラメーターに「BY VALUE」を指定することでパラメーター領域のアドレスではなく値が渡ります。渡せるパラメーター(値)は2進整数など4バイト以内で渡せるデータに限ります。

Filed in MVS実践アセンブラー・プログラミング

ハウスキーピングあれこれ

By kamii - Last updated: 水曜日, 12月 3, 2008

ハウスキーピング(プログラム冒頭での呼び出し元レジスター内容の保管やベースアドレスの設定処理)の処理はプログラマーによっていろいろな方法が行われるが基本は「リンケージ規約の遵守」です。決まり切った手順でもあるので一度スタイルを決めればずっと使い続けられます。
ここでは私自身が長年使ってきたコーディングのいくつかをサンプルとして紹介します。


オーソドックスなコード

レジスター保管域をハウスキーピングのコードの中に定義した例です。レジスター保管域のように実行中に参照することがないデータ領域にいちいち名前を付けるのも面倒なので私自身は好んで使っていました。
呼び出し元への復帰時にはGR15に復帰コードが設定されているものとしています。


モジュールの先頭にヘッダーを付ける

プログラムの冒頭にヘッダーを付けることはしばしば行われます。名前、アセンブル日付・時刻などはヘッダー情報の代表的なものです。複数のプログラムを結合して1つのロードモジュールにするような場合は各CSECTの名前も入れればダンプリストを見た際に識別しやすくなります。商用プログラムでは製品のバージョンやPTF用のパッチエリア、COPYRIGHT表示なども入れられます。
一般のプログラムは入口点のGR15にはプログラムの先頭アドレスが格納されていますから、ヘッダーの長さだけジャンプする無条件分岐命令を先頭に置いて、続いてヘッダーデータを書きます。GR15を基点にしてヘッダーの長さ+分岐命令の長さを指定してヘッダーを迂回します。
MSPとVOS3では&SYSDATCの代わりに&SYSDATEが使えます。


ヘッダー用マクロを作る

いちいちヘッダーを書くのが面倒、プログラムを分割して開発するがヘッダースタイルは統一したい、と言った場合はヘッダーを生成するマクロ命令を作ると便利です。MACROからMENDで囲まれた部分をMDHDRと言う名前のメンバーで作成します。プログラムではこのMDHDRマクロを書けばアセンブル時にマクロ内で定義したヘッダーデータが展開されます。
ヘッダーマクロのサンプルとそれを使ったサンプルを示します。


オーソドックスなコード(再入可能プログラム)

再入可能(リエントラント構造)プログラムは自分のプログラム内に書き込みデータを持つことができないので、レジスター保管域も定義できません。レジスター保管域をプログラムの外に確保するサンプルです。


GR13をベースレジスターに使う

再入可能である必要がないプログラムではレジスター保管域を示すGR13をベースアドレスにしたプログラムを作成することもできます。サイズが大きくなるプログラムでも、GR13,12,11とベースアドレスに使えるレジスターを1つでも多くすることができます。サンプルではレジスター保管域をプログラムの先頭に置き、GR13とGR12をベースレジスターにしています。
DC 17Fで68バイトしか定義していないのは間違いではありません。保管域の最初のワードはアセンブラー言語では未使用であることを応用しています。


一切のサブルーチンを呼ばないなら

あまりいいサンプルではありませんが、将来に渡っても絶対サブルーチンを呼ばないのならこのようにレジスター保管域を持たなくてもかまいません。OSのAPIはほとんどがSVC呼び出しなのでレジスター保管域を必要としませんが、データセットのアクセスに使うGET/PUTマクロなどAPIによってはGR13がレジスター保管域であることを要求するものもあるので注意します。


リンケージスタックを使う

リンケージスタックはESA/390から利用できる機能です。先頭のBAKR 14,0命令は現PSWの前半ワード内容とGR14の内容で後半ワードを生成した呼び出し元への復帰用PSW、および汎用レジスターとアクセスレジスターをスタックに保管します。最後のPR命令はスタックに保管されたPSWとレジスター2から14が復元されます。結果としてレジスターを復元して呼び出し元に戻ることになります。レジスター15,0,1はPR命令発行時の内容がそのまま渡ります。BAKRはスタックへのPUSH、PRはスタックからのPOPです。内部サブルーチンでもレジスターの保管を気にせずに済むので使うと便利な機能です。
MVSではリンケージスタックの利用は必須ではありませんし、使う使わないの選択は自由なので、自分が呼び出すサブルーチン(OSのAPIを含む)がリンケージスタックを使う保証はありません。そのためGR13には標準のレジスター保管域をポイントする方が間違いありません。この場合呼び出し元保管域のポインターにはアドレスの代わりに’F1SA’の4文字を設定する規約になっています。
現実的にはプログラムは最初に実行される時、OSが用意したレジスター保管域がGR13で渡されるため、GR13を他の目的で使わない限りわざわざ別に用意しなくても問題はおきないでしょう。(例えばQSAMのGET/PUTマクロの利用など)ただしプログラムがABENDした時のダンプには正しいSAトレースが出力されなくなります。自分は呼び出し元の保管域を使用しなくても、呼び出すプログラムのために標準通りの保管域を用意し、互いにチェインする代わりにF1SAを表示するのはレジスター保管域とリンケージスタックを混在させるためのMVSの決まり事なのです。テスト的に作成するプログラムでない限り規約通りに作成する方がいいでしょう。

リンケージスタックはMVS(z/OS)では当たり前に使える機能ですが、MSPとVOS3では注意が必要です。MSPではMAFと呼ばれる追加のハードウェア機構が必要で、VOS3ではIPLパラメーターにクロスメモリー機能を有効にするパラメーター(マニュアル記載なし?)が必要です。利用できない環境であれば、BAKR命令がS0DxのコードでABENDします。その場合はメーカーの担当SEに問い合わせてみて下さい。

Filed in MVS実践アセンブラー・プログラミング

ファイルシステム-1

By kamii - Last updated: 月曜日, 12月 1, 2008

MVSのファイルシステムの最も大きな特徴はファイル(データセット)は構造化されたレコードを持つ点です。WindowsやUnixのファイルシステムとはあらゆる点で異なります。ファイルそのものの構造について比べると、Windowsなどではファイル自体は可変長の大きさを持ち、ファイルの大きさはデータ量によって増減します。ファイルの中がどのような形式でフォーマットされているかはOSは関与しません。OSから見れば構造化されていない連続したストリーム・データの集合です。MVSで言えばRECFM=U・BLKSIZE=32760のデータセットが最も近いでしょう。
反面MVSではRECFM=U形式のデータセットはアプリケーション・データに使われることはほとんどありません。基本的にデータはレコードによってまとめられ、レコード単位にファイルが構成されます。データの集合がレコード、レコードの集合がブロック、ブロックの集合がデータセットです。ブロックはディスクやテープに記録される時の単位でもあることから物理レコードとも呼ばれます。

----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
<- Name           -><- Address                  -><- Phone ->

レコードにはこんな感じでデータが並べられます。メインフレーム・コンピューターの原点がパンチカード・システムあったことから、アプリケーション・データは古くからこのように業務処理で使うデータが1つのレコードに並べられ、それを複数集めて処理データを構成するファイル(データセット)を作りました。パンチカードの名残ではデータセットはRECFM=F,BLKSIZE=LRECL=80の1形式しかありませんが、現在のMVSではRECFM=F[B]|V[B]|U,BLKSIZE|LRECL=1?32760の範囲で、さまざまな組み合わせによって構成されます。

----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
Block-1
<- Record-1       -><-                          -><-       ->
<- Record-2       -><-                          -><-       ->
<- Record-3       -><-                          -><-       ->
<- Record-4       -><-                          -><-       ->
<- Record-5       -><-                          -><-       ->
<- Record-6       -><-                          -><-       ->
<- Record-7       -><-                          -><-       ->
<- Record-8       -><-                          -><-       ->
<- Record-9       -><-                          -><-       ->
<- Record-10      -><-                          -><-       ->

Block-2
<- Record-11      -><-                          -><-       ->
<- Record-12      -><-                          -><-       ->
<- Record-13      -><-                          -><-       ->
<- Record-14      -><-                          -><-       ->
<- Record-15      -><-                          -><-       ->
<- Record-16      -><-                          -><-       ->
<- Record-17      -><-                          -><-       ->
<- Record-18      -><-                          -><-       ->
<- Record-19      -><-                          -><-       ->
<- Record-20      -><-                          -><-       ->
   :
   :
レコードをいくつかまとめたものがブロック。
この例では10レコードをまとめてブロックにしている。
レコード長を72バイトとした場合、BLKSIZE=720,LRECL=72となる。
ディスクやテープには720バイト単位でデータが記録される。

レコード形式(RECFM)、ブロック長(BLKSIZE)およびレコード長(LRECL)はデータセットの物理的な構造を示した属性ですが、レコードの配列の種類を示すデータセット編成(DSORG)と呼ばれるものが別にあります。代表的なものが順次編成(PS)と区分編成(PDS,PO)およびVSAMです。他にも直接編成(DA)、索引順次編成(IS)データセットもありますが、現在ではVSAMまたはデータベース・システムに取って代わられ、互換目的以外で使われることはありません。新たに学ぶ必要もないでしょう。
データセットをアクセスするためのAPIはアクセス法と呼ばれ、データセット編成毎に用意されます。MVSが標準で提供するもの以外にもデータベース・システム(DB2,IMS/DB,AIM/DB,ADABASなど)やライブラリー管理システム(CA-LIBRARIAN,CA-PANVALETなど)がメーカーだけでなくISVからもソフウェア製品が提供されています。
しかしどのような編成のデータセットやデータベース・システムであっても、ディスク上はいずれかのRECFMとBLKSIZE,LRECLを持つブロックの集合体です。レコード形式やデータセット編成については「データセットの種類とアクセス法」に解説があります。

MVSのファイルシステムではOSもデータセットのレコード形式や長さを意識してアクセスの制御を行います。データのアクセス単位がデータの構造によって変わるためです。アクセス法によってレコード単位、ブロック単位など何種類かに分かれます。このあたりが他のプラットフォームに慣れた人には複雑に見える点でしょう。元々の発想点が1行80文字の紙カードから来ていて、文字単位ではなくカード単位での(何文字読んだ?ではなく何枚読んだ?)処理が原点だからです。


編成(アクセス法)別に見たデータセットの特徴

上段ほど新しいアクセス法です。最も下段にあるEXCPはチャネルプログラムを直接使う方法ですが、アプリケーションがこれを使うことはまずありません。さらに下段(BIOSコール)もありますがここでは省きます。下段に行くほどデータセットの物理的な構造と、ハードウェア特性がわかっていないとアクセスできません。EXCPの場合はデータセットの物理構造だけでなく、ディスクやテープ装置自体のデータ記録方法も知っている必要があります。
QSAMあたりにくると論理レコード単位のアクセスができるようになり、物理的な構造からかなり解放されます。COBOLやPL/I言語でのファイルアクセスもQSAMあるいはVSAMを通じて行われます。VSAMからはデータセットの物理的な構造とプログラムが扱うデータ構造は1対1に対応しなくなってきます。VSAMはその名の通りデバイスに依存しない仮想のファイルを実現するものです。VSAMをさらに発展させたものがデータベースです。データベースの物理的な器であるMVSデータセットはVSAMあるいは順次編成データセットがよく使われます。プログラムが扱うレコードはデータベース・システムが提供する機能に基づきメモリー内にマッピングされ、物理的な構造にはまったく関わる必要がありません。
PDSEはMVSが提供する拡張区分編成データセットですが、その物理的な実体は4096バイト固定長レコードの順次データセットです。プログラム上は従来の区分データセット同様にRECFM,BLKSIZE,LRECLを持ちますがあくまでも仮想のもので従来と同じアクセス法(BPAM,QSAM)でアクセスできる互換性があります。もちろんプログラムは物理的構造である4KB固定長レコードを意識する必要はまったくありません。

難易度についてはアセンブラー言語によるプログラミングが必要かどうか、よりハードウェア寄りの知識がいるかどうかで付けてみました。同じ構造のデータなら一般的には高水準なアクセス法(より抽象的、仮想的)ほどプログラミングもやさしくなります。ただし高水準なアクセス法ほど機能も豊富になりますので、それらも含めて使いこなそうとすればやさしいプログラミングだけでは済みませんし、データ設計もきちんと行わなければなりません。そう言う意味では難易度の幅は広くなります。

Filed in .z/OS(MVS),MSP,VOS3のしくみ

シンプルISPFメニューとクイック起動

By kamii - Last updated: 金曜日, 11月 28, 2008
(このトピックはz/OS限定です)

デフォルトで導入されたISPFをそのまま利用してもいいのですが、普段からよく利用するツールなので使いやすいようにメニューパネルをカスタマイズすることもできます。
デフォルトで導入されたISPF起動CLISTでISPFを起動したとき、ISPFメニューの前にISMF、IPCS、RACF、DITTO、SMP/Eなどのアドミニストレーターのシステム保守用ツールも起動できる「CUSTOMPAC MASTER APPLICATION MENU」パネルが表示されるようになっていると、PDFやSDSFはそのパネルから改めて選択し直すことになります。普段使うのがISPF/PDFとSDSFなら直接PDFメニューパネルを表示して、SDSFもそこから選択できると便利です。

アドミニストレーター用のシステム保守ツールも使える「CUSTOMPAC MASTER APPLICATION MENU」は、PDFとSDSFの起動に必要なデータセットだけでなく、数多くのプロダクトのデータセットをCLIST内で割り当てるため、起動に時間が掛かります。
普段の作業に必要なければ、使うツールに限定したCLISTやパネルを使えば資源の節約やセキュリティー面でも有益です。


ISPF起動用CLISTの作成

ISPFのデフォルトPOM(Primary Option Menu)パネルである、ISR@PRIMを使用し、最低限必要なISPFデータセットを割り振り、ISPFを起動するCLISTサンプルです。
MY.CLISTおよびMY.PANELはユーザー専用のCLIST、PANEL定義体を格納するデータセットです。必要に応じてデータセットを追加するか、不要であれば削除します。
このCLISTではISPFプロファイルは、新規データセットをダイナミックにアロケートしないで、すでに作成済みである、としています。SET &PROFDSN = ISPF.&SYSUID..ISPPROF の箇所で自分のISPFプロファイル・データセット名がセットされるように修正します。


カスタマイズしたパネルでISPFを起動する

作成したCLISTをデータセットMY.CLISTに、メンバー名MYPDFで入れたものとします。
TSOに再ログオンして、READYプロンプトから「EX ‘MY.CLIST(MYPDF)’」で修正したパネルを使ったISPFが起動します。z/OSでは、デフォルトのISPFメニューパネル(ISR@PRIM)にはSDSFが「S」で追加されているので、PDFの各パネルから=SでSDSFを直接起動できます。ISPFを終了してREADYプロンプトへ戻った後、再度ISPFを起動する時は単に「MYPDF」と打てばISPFを起動できます。MYPDF内でSYSPROCにMY.CLISTを追加して再アロケーションしているからです。

初回のEXコマンドが面倒なら、TSOのログオンプロシージャのSYSPROC DD文に、「MY.CLIST」を追加します。




英語パネルのISPF

筆者の好みではありますが、日本語パネルは字が大きく、どうもごちゃごちゃした感じですっきりしません。覚えてしまえば、パネル上の決まり切ったガイダンスなど日本語である必要はないので、パネルのみ英語版を使うのもいいと思います。英語パネルはすっきりした感じに見えますが、どうでしょうか?
英語パネルを使っても、端末エミュレーターが日本語をサポートしていれば、エディターやブラウザーで日本語を表示・入力することは可能です。

英語パネルを使う場合は、前述のサンプルCLISTでデータセットの最後3文字がJPNになっているところをENUに変更します。

ISPFプライマリーメニューパネルの修正

POMパネルにSDSFが組み込まれていなければ、パネル定義体を修正して追加します。

英語版のデフォルトPOMパネルは、ISP.SISPPENUのISR@PRIMです。これを任意のデータセットにコピーして上記のように修正します。サンプルのCLISTであれば、「MY.PANEL」にコピーして、そちらを修正します。この修正はPOMパネルからSDSFを起動できるようにするためのものです。「<=== ADD for SDSF」で示した行を追加します。最初の追加部分は新たな行を挿入するのではなく、6 Command または 7 Dialog Test の行をリピートして修正するようにします。これはその行に表示・入力できないバイナリーデータが使われているためです。
普段使わない機能はメニューからはずせばよりシンプルになりますが、速さの面ではほとんど関係ありません。他のISV製品などのツール類も含めて1メニューパネルに収めたいような時は、使わなくてもかまわない機能をはずすのもいいでしょう。サンプルではSDSFに「SD」を割り当てましたが、日本語パネルと同じ「S」でももちろんかまいません。
ISV製品のプログラムやパネルも、同様の方法で追加できます。

Filed in CLIST(コマンドプロシージャ)とISPFダイアログ, ISPFとSDSFのちょっと得する使い方

09.1プログラムをスーパーバイザー・モードに切り替える(MODESET)

By kamii - Last updated: 水曜日, 11月 26, 2008

一般のアプリケーション・プログラムではほとんど必要ありませんが、システム・プログラムでは処理によっては監視プログラム(スーパーバイザー)モードに切り替える必要が生じます。例えば監視プログラム状態を要求するAPIの使用(MGCRなど)、特権命令の使用などです。
このような場合、プログラムはAPIによって自分自身の走行モードを問題プログラム状態から監視プログラム状態に変更することができます。

スーパーバイザー・モードとAPF許可を混同しないで下さい。スーパーバイザー・モードは特権命令が利用できるCPU上の特別な実行モードですが、APF許可はMVSにシステム・プログラム用機能の利用が許可されたプログラムであって、PSWの走行モードとは関係ありません。APF許可プログラムであっても特別な設定(PPT登録)がされない限り、MVSは問題プログラム状態でプログラムを実行します。なおシステム・プログラミング用機能であってもほとんどのAPIはAPF許可さえあれば良く、監視プログラム状態を要求するものはごく1部です。マニュアルをよく読んで不必要なモードチェンジをしないようにします。


プログラムを監視プログラムモード(スーパーバイザーモード)に切り替える

MODESETマクロはプログラムの走行モードを切り替えます。当然APF許可されたプログラムでなければ使用できません。MODEパラメーターで走行モードを、KEYパラメーターでPSWキーを変更できます。MODE=SUPは監視プログラム・モードへ切り替え、MODE=PROBで元の問題プログラム・モードに戻します。同時にPSWキーを変更する時は、KEY=ZEROでPSWキーを0に、KEY=NZEROでPSWキーを元のキーに戻します。キーを変更する必要がなければモードのみを変更しましょう。スーパーバイザーモードだからキーも0にする、と理解しているプログラマーもいますが、それは正しいことではありません。元のPSWキーのままで問題ないロジックは無用にキーを変えてはなりません。


PSWの記憶保護キーを変更する

OSの出口ルーチンなどではその多くが監視プログラム状態のまま呼び出されます。このようなプログラムでは特権命令を使わないからと言ってわざわざ問題プログラム状態に変える必要はありません。むしろモードの不用意な変更は致命的なエラーを引き起こします。ただし処理によってはPSWキーを変更する場合もあり得ます。このような時KEYパラメーターを指定したMODESETマクロを使ってはなりません。最初から監視プログラム状態で動くプログラムの場合はSPKA命令を使用してPSWキーを変更します。
オペランドに新しいキーを即値またはキー値を格納したレジスターで指定し、サンプルのようにコーディングします。出口ルーチンなどでは最初に制御が渡されたときのキーはマニュアルに明記されていますから、その値に戻してもいいですし、IPK命令で現在のPSWキー値を保存してもいいでしょう。IPK命令は無条件にGR2の下位バイトにキーの値をセットしてしまいます。そのレジスターを使ってSPKA命令を出せば元のキーに戻せます。GR0でなければGR2以外のレジスターにコピーして使ってもかまいません。

Filed in 中級編

08.1TSO端末との通信(TPUTとTGET)

By kamii - Last updated: 水曜日, 11月 26, 2008

MVSにおけるアプリケーション・プログラムの基本はバッチ処理ですが、端末と直接会話できるオンライン処理もポピュラーな利用方法です。基幹業務システムに使うプログラムはCICSやIMSなどを使って動かしますが、簡単な処理や非定型なものはTSOが便利です。ここではTSO端末への簡単なI/O方法(送受信処理)を紹介します。MSPとVOS3にも共通な方法です。


QSAMによるTSO端末I/Oプログラム

別のカテゴリー「TSOで動作する簡単なコマンドライン版プログラムの作り方」でも紹介したQSAMによる方法です。SYSPRINTが端末への出力、SYSINが端末からの入力になります。MVSとMSPではこのDD名でLOGONプロシージャーに割り当てられていますからDD名を合わせればそのまま使えます。
サンプルのようにSYSPRINTとSYSINをそれぞれOUTPUTモード、INPUTモードでOPENします。端末へメッセージを送信するにはPUTマクロを、端末からデータを受信するにはGETマクロを発行します。PUTマクロはメッセージの送信がキューイングされれば完了するので、実際にはすぐに戻ってきます。GETマクロは端末でキー入力が行われるまで待ち状態になります。端末で「/*」の2文字が入力されるとEODと見なされ、DCBで指定したEODADルーチンが実行されます。EODADを使わず任意の文字列を入力終了の判定に使ってもかまいません。処理が終了したらSYSPRINTとSYSINをCLOSEします。
サンプルでは簡単にするために固定長レコードを使っていますが、メッセージ領域を節約するならRECFM=VBで可変長レコード形式にしてもかまいません。


TSOプログラミングAPIによるTSO端末I/Oプログラム?

最初のサンプルと同じことをQSAMではなくTSOのプログラミングAPIであるTPUTマクロとTGETマクロに置換えたものです。TSOでのみ動かすプログラムならTPUT,TGETの方がすっきりしますが、QSAMを使えばバッチ、TSO両方でも実行できるメリットがあります。
TPUT/TGETではメッセージ領域のアドレスと長さを指定します。TGETでは実際にメッセージ領域に格納されたデータ長がGR1に返されます。サンプルでは省略していますがTPUTもTGETも復帰コードを返しますので本来ならば正しくチェックすべきです。QSAMと違って/*入力でのEOD処理はされませんから自分で入力データを判定して同様のことを行っています。TPUT/TGETは可変長データの取り扱いになりますが、RECFM=VB指定のQSAMアクセスと異なりRDWを必要としません。


TSOプログラミングAPIによるTSO端末I/Oプログラム?

少しだけ込み入った処理を加えます。プロンプトの「COMMAND READY >>」の直後にデータを入力できるようにして、入力に使ったキーの種類(アテンションID)をエコーするようにしたものです。TPUTマクロでのASISオプションはメッセージを自動改行しないようにします。TGETマクロでのASISオプションは端末からの入力データを制御コード付きのままプログラムに渡します。

TPUTでコマンドプロンプト・メッセージを送った後、ASIS指定のTGETで入力を待ち合わせます。1バイトのみ読み込んでいるのはどのキーでデータを入力したのかを得るためです。ENTERキーであればx7D、PF1?PF9キーであればxF1?xF9、PF10?PF12キーであればx7A?x7Cとなります。次のTGETで入力された文字列を読み込んでいます。エコーするメッセージの先頭には入力に使われたAID文字を表示するようにしています。
/*の入力またはPF3キー押下であれば処理を終了します。CLRの入力またはPF12キー押下であれば画面をクリアーします。画面のクリアーは端末画面(3270)のデータストリーム・制御コードを直接定義して行っています。データストリームの解説はここでは行いませんが、CLRDATAに定義したコードが画面消去用のデータです。(先頭のx27を除く)これをFULLSCRオプションのTPUTで送信します。FULLSCRオプションを使う時はデータストリームの先頭にx27を付加する決まり事になっています。

TPUTおよびTGETはMVSのAPIではなくTSOのAPIです。
マクロの詳細はTSOのプログラミング・マニュアルを参照して下さい。

Filed in .基礎編

07.1非同期事象の待ち合わせと通知(WAITとPOST)

By kamii - Last updated: 火曜日, 11月 25, 2008

システムプログラムでは「いつ来るかわからない」「いつ終わるかわからない」と言った事象(イベント)を待ち合わせることは多々あります。メインフレームでもイベントが発生・終了するまで、来たか?来たか?、終わったか?終わったか?、とループしてタイミングを合わせる方法がありますが、一般のプログラムでは使いません。OSであってもループによるタイミング合わせは本当に必要な所だけに限定して使っています。
MVSはイベントの完了の待ち合わせにWAIT、イベントの完了の通知にはPOSTと言うサービスを提供しています。プログラムはこのサービスを使うことで、ループなどしなくても、必要なイベントの発生や終了のタイミングを合わせることができます。

上に挙げたこれらの例も、いつ発生するかわからない事柄です。インターバルタイマーに関しては例えば10秒後と言う時間はわかっていても、いつが10秒後なのかわかりません。人間は時計を見ながら10秒後を知ることができますが、これはループと同じです。オペレーターコマンドや端末の受信データはわかりやすいでしょう。いつコマンドが入力されるか、いつ実行(エンター)キーが押されるかは人間様次第です。I/O動作の完了やJCLのサブミットの待ち合わせはOSに取っての待ち合わせ事象の1つです。チャネルで実行されたI/Oはいつ完了するかわかりません。JCLは人間がコマンドやパネルでサブミット操作を行いますが、OSにしてみれば、それがいつ行われるかまったく予測できません。
これらのようにいつ起きるかわからない事を非同期事象(asynchronous event)と呼びます。バッチ処理用のアプリケーション・プログラムを作るだけではなかなかわかりにくいのですが、MVSは基本的にイベント駆動型のソフトウェアです。さまざまな非同期事象の発生を待ち受け、それに応じた処理をディスパッチします。このサイクルを延々と繰り返して行くわけです。


タイマーによるインターバル時間の経過を待ち合わせる(WAIT)

WAITマクロはイベントの完了を待ち合わせます。WAITマクロではどのイベントかを識別するため、ECBと言う1ワードの領域を使用します。ECBの先頭のビット0をWAITビット、ビット1をPOSTビットと呼びます。WAITマクロを発行するためにはECBを用意し、ビット0をクリアーしておかなければなりません。サンプルではビット0のクリアーではなくMVIでバイト毎クリアーしていますが、これも一般的な方法で非同期事象の開始前であることがはっきりしている時は、その時点ではこのECBにPOSTするプログラムは存在しないためPOSTビットも含めて0クリアーしてかまいません。XC命令でワード毎クリアーしてもかまいません。
イベントの識別と言ってもややこしい規約があるわけではなく、単に待ちになる側と、完了を伝える側でどこにECBがあるかがわかっていればいいのです。複数のイベントを並行して取り扱うような場合、それぞれのイベントをどのECBを使って待ち合わせるかを取り決める、と言うことです。一般的にはWAITする前にECBのアドレスを、実際に非同期事象を実行する側のプログラム(POSTする側)に何らかの手段で伝えます。

WAITマクロを発行するとプログラム(タスク)は指定したECBにPOSTがなされるまで、スーパーバイザー(WAITルーチン)の中で待ち状態となります。ECBのWAITビットは1にされ、WAIT中プログラムを識別するトークン(RBアドレス)が下位3バイトに格納されます。

ECBをどこでクリアーするかは重要なことです。待ち合わせる事象が開始する前にクリアーするのが原則です。タイマーならSTIMER発行前、オペレータ応答の受け取りならWTOR発行前、データの受信ならRECEIVE要求の前です。イベントを開始させてしまってからクリアーするとタイミングによってはイベントをロストさせてしまいます。
イベントによってはWAITしようとする時点で既にPOSTされている場合もあり得ます。すでにPOST済みのECBを指定してWAITマクロを発行しても問題ありません。実際にWAITせずにすぐに発行元プログラムに戻ってきます。しかしWAITビットが1になっているECB(WAIT中ECB)を指定するとプログラムはABENDさせられます。

これは誤ったECBクリアーの例です。STIMETRマクロで指定する時刻や間隔時間にもよりますが、99%は正しく動くでしょう。しかし指定した時刻が15:00丁度である時、STIMETRマクロが15時に限りなく近い15時前での発行であった場合、STIMERマクロから復帰した時点でWKUPECBにはすでにPOSTがなされているかも知れません。指定した間隔時間が1/10秒などと言う極端に短い時間である時も、STIMERマクロから復帰した時点で実時間で1/10秒は過ぎてしまっているかも知れません。
ロジックでは無条件にECBをクリアーしていますから、その場合永遠にPOSTされないWAITに入ってしまいます。これがイベントのロストです。WAIT発行前にPOSTビットをテストして1であればWAITを迂回するロジックもありですが、この例に関して言えばそんなことをするよりはECBのクリアーをSTIMETRマクロの発行前に行えばよいのです。非同期事象はその名の通り非同期ですから指定したイベントがいつ完了するかは予測できませんが、この例では自分がSTIMERを出さない限り時間計測と言う非同期イベントは起き得ないのでPOSTされることもありません。そのきっかけとなるSTIMERマクロの前でECBをクリアーできます。


タイマーによるインターバル時間の経過を通知する(POST)

POSTマクロはWAITの逆でイベントの完了を通知します。指定したECBにPOSTビットを設定し、WAIT中のプログラムがあれば待ち状態を解きます。この時ECBのビット2?31に任意のPOSTコードを設定することもできます。省略すればビット2?31は0にクリアーされます。POSTする側は相手がWAITしているかどうかを考える必要はありません。
このサンプルはSTIMERマクロによるインターバル時間の経過の待ち合わせと通知の例です。STIMERマクロを出した後のWAITマクロによってプログラムのタスクは待ち状態になります。10秒経過するとTIMREXITルーチンが実行されます。タスクが止まっている状態でも割り込んで実行されます。このようなプログラムを非同期出口ルーチンと言います。MVSでは長時間掛かるサービスやいつ完了するか予測できないサービスの完了を通知するために非同期出口ルーチンが使われるものがいくつかあります。

WAIT/POSTはマルチタスクのプログラムで使うもの、と言うイメージがありますが、シングルタスクのプログラムでも使用するAPIによってはWAIT/POSTによる待ち合わせと通知の処理が必要になります。


複数のイベントを待ち合わせる(ECBLIST)

複数の非同期イベントを取り扱うプログラムでは、いずれかのイベントが完了したら通知してもらうようにすることもできます。サンプルでは複数のECBの内、どれか1つが完了したら通知してもらう例です。これはマルチイベント・シングルウェイトです。複数個のECBが完了したら通知してもらうようにすることも(マルチイベント・マルチウェイト)、すべてのECBが完了したら通知してもらうようにすることも(マルチイベント・オールウェイト)できます。ただしマルチウェイトの場合どのECBから完了したかはわかりません。シングルウェイトであってもWAITが解けた後に別のECBにもPOSTされることがあり得ます。同様にどのECBから終わったかはわかりません。どちらの場合であってもどのECBのイベントが終わったかは、プログラムが自分でPOSTビットの立っているECBを探す必要があります。
なおマルチイベントではWAITから復帰した後、POSTビットとPOSTコードはPOSTされたECBにのみ設定されています。POSTされたECBを含めすべてのECBのWAITビットは0になっていますが、POSTされなかったECBのPOSTコード部にはRBアドレスが設定されたままになっていることに注意してください。MVS側はECBにRBアドレスが設定されたままで再びWAITが出されても支障ありませんが、POSTされなかったECBはECBワード自体が0(あるいはWAIT発行時の内容)になっているものと期待してロジックを作ると正しく動きません。

Filed in .基礎編

09.REXX 組み込み関数

By takao - Last updated: 火曜日, 11月 25, 2008
REXXは大量の組み込み関数で、プログラマーの負担を減らそうとしています。関数ライブラリーはREXXでも作れますし、多くのプロダクトが提供していたりもします。
ここでは、個々の関数について、マニュアルのような解説はしません(できません)。適当に分類してみたので、「あー、こんな関数があるのね」と頭に留めておいて、必要な都度、マニュアルを調べてください。

文字列
* ABBREV (Abbreviation)
* CENTER/CENTRE
* COMPARE
* COPIES
* DBxx (Double-Byte Character Set Functions)
* DELSTR (Delete String)
* DELWORD (Delete Word)
* FORMAT
* INSERT
* LASTPOS (Last Position)
* LEFT
* LENGTH
* OVERLAY
* POS (Position)
* REVERSE
* RIGHT
* SPACE
* STRIP
* SUBSTR (Substring)
* SUBWORD
* TRANSLATE
* TRUNC (Truncate)
* WORD
* WORDINDEX
* WORDLENGTH
* WORDPOS (Word Position)
* WORDS
* VERIFY
* XRANGE (Hexadecimal Range)
制御
* ADDRESS
* ARG (Argument)
* CHARIN (Character Input)
* CHAROUT (Character Output)
* DIGITS
* LINEIN (Line Input)
* LINEOUT (Line Output)
演算
* ABS (Absolute Value)
* BITAND (Bit by Bit AND)
* BITOR (Bit by Bit OR)
* BITXOR (Bit by Bit Exclusive OR)
* B2X (Binary to Hexadecimal)
* C2D (Character to Decimal)
* C2X (Character to Hexadecimal)
* D2C (Decimal to Character)
* D2X (Decimal to Hexadecimal)
* MAX (Maximum)
* MIN (Minimum)
* RANDOM
* X2B (Hexadecimal to Binary)
* X2C (Hexadecimal to Character)
* X2D (Hexadecimal to Decimal)

検査
* CHARS (Characters Remaining)
* CONDITION
* DATATYPE
* DATE
* ERRORTEXT
* FORM
* FUZZ
* LINES (Lines Remaining)
* QUEUED
* SIGN
* SOURCELINE
* STREAM
* SYMBOL
* TIME
* TRACE
* VALUE
Filed in REXX入門