VOS について思うところ2010年07月11日 04時59分35秒

前職では VOS を主体として開発していた。運よく次の仕事も見付かり、なんとか順調にやっている。恐らく、VOS にお目にかかることも当分はないだろう。

何だかんだ言っても所詮は計算機。目的に沿った API を正しく使えば正確に動く。問題は API が POSIX では無いこと。ここ十年来は OpenVOS として POSIX 準拠の API も力が入っていたが、所詮は付け焼き刃。性能を引き出す上では専用 API にはまったく及ばない。しかし、色々と癖があり、慣れてくるまでにそれなりに時間がかかる。

開発環境としては、スクリプト言語なども含めて貧相でかなり手間のかかる環境だった。OpenVOS で bash スクリプトが使えるようになるまでは、VOS コマンドマクロという、bourne シェルにすら大きく劣るスクリプト言語しかなかった。長い間、変数と if、else、goto が主な武器で、ブロックの do が出てくるのは二十 一世紀に入ってからだ。その為、長い間 if の後は goto がほぼ定型になっていた。

この VOS を専門にする人達は VOS について様々なことをよく知っている。UNIX には無い、システムや各種サブシステムを検査、実験するツールがたくさん存在する。これらを上手に使うことが VOS 上で未経験の部分の開発に大きい影響を与える。これらのツールの中には、コマンドラインから直接全てのシステムコールを叩ける物まである。逆にこのシステム以外の事を知らないのが欠点だ。

普通にお目にかかる機会のない事もあり、個人的には色々と楽しむことも出来た。元々は UNIX 使いだが、この変わったシステムも色々と使い込んだ。特に OpenVOS が出てきてからは UNIX と VOS の合わせ技で、前職では開発陣と開発環境を色々といじって楽しんだものだ。

VOS debug で条件式を使う2010年06月14日 15時30分21秒

VOS debug にて条件式を使う方法。別に、VOS だけでなく、gdb 等の他のデバッガにもあるのだが、文法が違うためすぐに忘れてしまう。既に VOS から離れてしまっているので忘れる前に。

デバッガを起動し、break の後に条件式を入れる。なお、以下のコードは PL/1 に対する式なので、id 部分は VOS C 言語の char_varying 相当になる。C 言語内で文字列を比較するのには各文字毎を比較する必要がある。


db? break 59 (if employee.id = 'uyota' then (display employee.id; continue) else (continue))

59 行目停止し、employee 構造体の id が uyota だったら、内容を表示して続行。それ以外だと、そのまま続行になる。表示以外でも、値を設定することも出来る。

デバッガで値を自由かつ効率的に変えられると、障害の再現や、修正の有効性などが、コードを変更したり、コンパイルしたりしなくても手軽に検証できる。

特にコードを変更する前から、既に変更後の正しい結果を出せる様になるので、事後処理の書類と修正結果の書類を提出して、対応の書類を別途進めて貰っている間に、実際のコードの変更とテストなど開発側の準備を並列して進めるなどといった事が出来るようになる。

Stratus 社 の Virtual Operating System2010年06月10日 16時49分58秒

VOS は Stratus Virtual Operating System の略。Multics をモデルに開発された。 Stratus Technologies 社がそのハードウェアと共に提供している。

いわゆる無停止システムで、平均稼働率は五桁の 99.999% を誇る。この確率だと、年間の平均停止時間は五分十六秒となる。この九の後も結構良い数字が並んでいるので、実質的にはもっと短い。

動作中にディスクが壊れたのは何度か目にしたし、CPU が故障したのも見たことがある。が、システムは停止しない。安全を取って CPU のボードを交換していた。

ハードウェアの障害を検知するのも、コンソールの前にはりついているオペレータの人達よりも先に Stratus のサポートの人達が連絡を入れてくる位早い。

安全性という見方では随一なのだが、もちろんそれに伴う不利益もある。最高の性能を引き出すには専用のシステムコールを使わないといけないし、そうなると技術者なども限られて来る。物にもよるが一台ずつの値段も数千万円単位になり、サポート契約も必要になる。

VOS/Stratus のシステムコールを乗っ取る2010年04月28日 12時36分37秒

VOS のシステムコールは実はユーザプログラムから乗っ取ることが出来る。相応のオブジェクトモジュールを作り、プログラムモジュールにバインドする。

まず、制御を得たいシステムコールと同じ引数を普通の関数を作るように書く。つまり、そのまま関数書いた関数の名前がシステムコールと一緒なのだ。その関数でやりたいことを自由に書く。もし、本来のシステムコールをこの自前のシステムコールから呼び出したい場合は、システムコールを大文字で記す。それで、本来のシステムコールを呼べる。

この技術を用いることで、システムコールにかかる統計を取ったり、あるシステムコールを意図的に別のシステムコールに入れ換えるなど、かなりきわどい事が出来る。

cvs on VOS2009年02月04日 03時16分29秒

GNU tools は VOS では異色な存在だ。そのため、変わったところに置かれる。

例えば、cvs-1.11.22 を見ると、cvs は >system>ported>bin>cvs.pm に置くように指示している。fileutils や binutils などの関係は、 (master_disk)>system>ported>bin に行くようだが。

ただ、ファイルに目を通すと、あちらこちら置く場所の指示が微妙に違ったりするので、まだまだ作業中な故かもしれない。いまの環境だと、(master_disk)>system>ported>cvs>cvs.pm になっている。インストール自体は、既に五年ぐらい前に遡るであろうか。この間、久しぶりに使おうと思ったら、パスが分からなくて困ってしまった。

VOS の batch コマンドの癖2009年01月30日 00時24分13秒

VOS にも所定の時刻がきたら、自動的にプログラムを起動する batch コマンドがある。-defer_until で起動時刻を指定できる。

例えば、


batch -defer_until 10:00:00

で 10 時にプログラムが始まるわけだ。

しかし、VOS の batch がどうも癖がある。ここでの、10:00 とはその日の 10:00 と指定していることになる。例えば、11:00 にこの書式で batch 登録をすると、即座に起動することになる。なぜなら、既に 10:00 を越えたからだ。

翌日の 10:00 を指定したいのなら、コマンドラインから明日の日付けも含めて登録しなければならない。


batch -defer_until (date_time coming 10:00:00)

とやることで、明日の 10:00 を指定できる。

VOS のコマンドには英語的解釈からずれたコマンドが時折見かけられる。英語では、this Sunday が前回の日曜日も次回の日曜日を指すこともある。これは文脈次第だ。I watched a movie this Sunday なら、過去の事なので前回の日曜日だ。I will watch a movie this Sunday なら、上と同じ日に言ったとしても、この日曜日は次のを指す。defer until と言ったのなら、次に来る時刻と思うのが普通だろう。

s$parse_command を複数回呼ぶ2009年01月20日 11時21分30秒

s$parse_command は UNIX で言う getopt + argc/argv の様な物だ。プログラムへの引数を処理する。getopt と違うのは、s$parse_command が form と言う対話的なユーザインターフェースを司り、より細かい入力制限などが出来ることだろう。

s$parse_command をプログラム中に何回でも呼ぶことも出来る。"end,form" と form を指定することで、強制的に対話的インターフェースを起動する事により、活用する。

例えば、電話帳や住所録のようなプログラムを考えてみよう。edit_addressbook は最初に一つの引数をとる。編集する人の名前だ。edit_addressbook uyota と起動するとしよう。一度、電話番号や住所などを取得してから、それらを編集するために、二度目の form をあげる事が出来る。

実は、s$parse_command を単純に呼ぶだけのやり方だと、全ての呼び出しにて、プログラム起動時に渡された引数を受け取る。その為、プログラムが取得したデータを表示しようとした場合に、予期せずに書き換えられてしまうことがある。例えば、最初の s$parse_command では、最初の引数はユーザ名で、二度目の s$parse_command での最初の引数が電話番号だった場合、表示しようとしている電話番号がユーザ名に上書きされてしまうのである。

完全な形の対話プログラムを作る時には s$monitor を使ってここら辺の処理をするのだが、物によってはそこまでするのは大がかり過ぎる。その様な時には、全ての s$parse_command で共通の引数を作ることで、回避できる。二回目の s$parse_command では、最初にユーザ名を表示して、それ以降に電話番号を表示することで、業とユーザ名を引き受ける場所を作る。


...
    s$parse_command( &(char_varying(32)) "modify_addressbook", &ret_code,  
        &(char_varying(256)) "index:string,length(14),disable_input,value",
            &user.account,       
        &(char_varying(256)) "end");              

...

    s$parse_command( &(char_varying(32)) "modify_phone", &ret_code,  
        &(char_varying(256)) "index:string,length(14),disable_input,value",
            &user.account,                     
        &(char_varying(256)) "phone:string,value"      
            &user.phone,
        &(char_varying(256)) "end,form");

...

    s$parse_command( &(char_varying(32)) "modify_address", &ret_code,
        &(char_varying(256)) "index:string,length(14),disable_input,value",
            &user.account,
        &(char_varying(256)) "address:string,value"
            &user.address,
        &(char_varying(256)) "zipcode:string,value"
            &user.zipcode,
        &(char_varying(256)) "end,form");

s$monitor を使うと色々と大がかりになるので、小さいプログラムの時は、この様な特徴を抑えつつ、s$parse_command だけで仕上げたい。

「printf(buffer) の危険性」を読み返してみたら2008年12月15日 14時22分16秒

printf(buffer)の危険性をふと読み返してみた。今から読み返してみると、解りづらい文章だった。

ここで指摘している問題は、printf(path) となっていること。VOS のパス名には printf が特別扱いをする % が含まれる。その為に、プロセスが core を起こしてしまうのが問題だった。

VOS C return v.s. exit2008年02月16日 18時16分59秒


!display_line (command_status)

で最後に実行したプログラムの返り値を調べることが出来る。

UNIX 環境では、この返り値は main 関数の return の値でも exit 関数に渡した値でも、どちらでも $? で調べられる。どうも、VOS では exit 関数でしか、受渡しが出来ないようだ。

return 1 でも return 2 でも、(command_status) が 0 のままなので、おかしいと思ったら return が使われているところだった。exit に変えたら、期待通りの値に変わった。

VOS C entry v.s. argc/argv2008年02月13日 11時07分43秒

VOS の C 言語では、プログラムの開始関数は、main に縛られてはいない。bind 時に任意に指定することも出来る。bind 時に entry が指定されていないで、main 関数が一つの時にはそちらが、entry として扱われる。

VOS 本来のコマンドオプションの引き取り方は、s$parse_command() による物だが、一般的な、UNIX 系の C 言語の様に argc/argv を用いることも出来る。

しかし、この argc/argv は entry が暗示的に main で指定されている時には使えない様だ。bind の entry が指定されると、bind が失敗し実行形式プログラムが作れない。entry が指定されると、以下の様なエラーがでる。


bind: Warning: The main entrypoint "display_stdin" of object module
     "echo" has arguments.

何処にも記述されていないので、何故 display_stdin(int argc, char *argv[]) がいけないのか理解するのに時間を喰ってしまった。