(57)【特許請求の範囲】
【請求項１】
記憶媒体へのアクセスをサービスとして実行するサーバと、
前記サービスを必要とするプロセスを有するクライアントと、
前記サーバと前記クライアントとの間でソケットを用いて通信を行うための仮想デバイスと、
前記クライアント内のプロセスが前記仮想デバイスをオープンするとき、前記仮想デバイスが既にオープンされているかどうかを判定する判定手段と、
前記仮想デバイスが既にオープンされている場合、前記プロセスのプロセス表において未使用の番号のファイルディスクリプタを探し出し、前記プロセス表に、前記ファイルディスクリプタと、前記カーネルファイル表にて前記仮想デバイスを既にオープンしているプロセスが参照する前記ソケットのデータ構造体へのインデックスが登録されたエントリへのインデックスとを結び付けて登録することで、前記ソケットを参照する前記プロセス用のファイルディスクリプタを再生成する再生成手段と
を具備する記録装置。
【請求項２】
請求項１に記載の記録装置であって、
前記仮想デバイスを既にオープンしているプロセスが、前記仮想デバイスをオープンしようとしているプロセスと同じプロセスまたは別のプロセスである記録装置。
【請求項３】
サービスを実行するサーバと、前記サービスを必要とするプロセスを有するクライアントとの間でソケットを用いて通信を行う仮想デバイスを、前記クライアント内のプロセスがオープンするとき、前記仮想デバイスが既にオープンされているかどうかを、前記クライアントに備えられた判定手段により判定し、
前記仮想デバイスが既にオープンされている場合、前記プロセスのプロセス表において未使用の番号のファイルディスクリプタを探し出し、前記プロセス表に、前記ファイルディスクリプタと、前記カーネルファイル表にて前記仮想デバイスを既にオープンしているプロセスが参照する前記ソケットのデータ構造体へのインデックスが登録されたエントリへのインデックスとを結び付けて登録することで、前記ソケットを参照する前記プロセス用のファイルディスクリプタを、前記クライアントに備えられた再生成手段により再生成する
ファイルディスクリプタ生成方法。
【請求項４】
記憶媒体へのアクセスをサービスとして実行するサーバと、前記サービスを必要とするプロセスを有するクライアントとの間でソケットを用いて通信を行うための仮想デバイスを、前記クライアント内のプロセスがオープンするとき、前記仮想デバイスが既にオープンされているかどうかを判定する判定手段と、
前記仮想デバイスが既にオープンされている場合、前記プロセスのプロセス表において未使用の番号のファイルディスクリプタを探し出し、前記プロセス表に、前記ファイルディスクリプタと、前記カーネルファイル表にて前記仮想デバイスを既にオープンしているプロセスが参照する前記ソケットのデータ構造体へのインデックスが登録されたエントリへのインデックスとを結び付けて登録することで、前記ソケットを参照する前記プロセス用のファイルディスクリプタを再生成する再生成手段と
としてコンピュータを動作させるプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、記録装置、ファイルディスクリプタ生成方法、プログラムに関するものである。
【背景技術】
【０００２】
ＵＮＩＸ（登録商標）、ＬＩＮＵＸ（登録商標）などのカーネルにおいては、プロセスやスレッドがファイルやソケットなどのオブジェクトを操作するための機構としてファイルディスクリプタを採用している。ファイルディスクリプタは、プロセス毎のプロセス表で管理され、その実体はカーネルによって順番に割り当てられた単なる番号である。プロセス表には、そのファイルディスクリプタと対応付けて、カーネルファイル表のエントリへのインデックスが登録されている。カーネルファイル表の各インデックスに対応するエントリには、ファイル、ソケットなどのオブジェクトのデータ構造体へのインデックスがそれぞれ登録されている。
【０００３】
特許文献１には、ファイルディスクリプタを利用したクライアントとサーバとの間の通信処理が記載されている。サーバ側のプロセスは、socketシステムコールにより作成したソケットに、bindシステムコールを使用してファイルディスクリプタを割り当てた後、listenシステムコールを実行して接続準備状態を設定する。一方、クライアント側のプロセスは、socketシステムコールでソケットを作成し、connectシステムコールを使用してサーバ側ソケットとの通信路を確立する。サーバ側のプロセスは、acceptシステムコールを実行し、クライアント側のプロセスからの要求を受け入れる。接続完了後に、ソケット対応のファイルディスクリプタに対する書き込み処理としてのwriteシステムコールと、読み取り処理としてのreadシステムコールを利用して、メッセージ送受信を実現する。
【特許文献１】特開２００６−１２７４６１（段落００８４）
【発明の開示】
【発明が解決しようとする課題】
【０００４】
クライアントの複数のプロセスやスレッドからサーバに対して頻繁にサービスを要求する場合、要求ごとに新たにソケットを生成せずに，仮想的な１つの双方向ＦＩＦＯ通信路(ストリーム指向ソケット，TCPソケットなど)を共有できるようにしたい場合がある．そのため従来はプロセス間でファイルディスクリプタの受け渡しを行っていた。しかしながら、プロセス間でファイルディスクリプタを受け渡すには、受け渡しのためのソケット通信路を確立して，sendmsgシステムコールやrecvmsgシステムコールを利用してファイルディスクリプタそのものを送受信するなど、煩雑な手順が必要であった。
【０００５】
また、クライアントの複数のプロセスやスレッドからサーバに対してサービスを要求し、サーバは各プロセスからの要求に対するサービスを順次実行するという運用においては、複数のプロセスから同時に要求が発生した場合に、一方のプロセスからの要求に対するサーバ側の処理が終了してから別のプロセスからの要求を処理するといった相互排除が必要である。そのため，従来は，サーバ側において，相互排除を行う必要があった。
【０００６】
本発明は、かかる実情に鑑み、プロセス間でファイルディスクリプタを受け渡すことなく、クライアント内の複数のプロセスやスレッドが１つのソケットを共有してサーバと通信を行うことのできる記録装置、ファイルディスクリプタ生成方法、プログラムを提供しようとするものである。
【課題を解決するための手段】
【０００７】
上記の課題を解決するために、本発明の記録装置は、記憶媒体へのアクセスをサービスとして実行するサーバと、前記サービスを必要とするプロセスを有するクライアントと、前記サーバと前記クライアントとの間でソケットを用いて通信を行うための仮想デバイスと、前記クライアント内のプロセスが前記仮想デバイスをオープンするとき、前記仮想デバイスが既にオープンされているかどうかを判定する判定手段と、前記仮想デバイスが既にオープンされている場合、前記プロセスのプロセス表において未使用の番号のファイルディスクリプタを探し出し、前記プロセス表に、前記ファイルディスクリプタと、前記カーネルファイル表にて前記仮想デバイスを既にオープンしているプロセスが参照する前記ソケットのデータ構造体へのインデックスが登録されたエントリへのインデックスとを結び付けて登録することで、前記ソケットを参照する前記プロセス用のファイルディスクリプタを再生成する再生成手段とを具備する。
【０００９】
本発明の記録装置は、前記プロセスが前記仮想デバイスをオープンするとき、カーネルのセマフォを操作して、他のプロセスからの前記仮想デバイスのオープンの許可制限を設定する手段をさらに具備するものであってよい。
【００１０】
仮想デバイスを既にオープンしているプロセスとは、仮想デバイスをオープンしようとしているプロセスと同じプロセスまたは別のプロセスである。
【００１１】
本発明の別の観点に基づくファイルディスクリプタ生成方法は、サービスを実行するサーバと、前記サービスを必要とするプロセスを有するクライアントとの間でソケットを用いて通信を行う仮想デバイスを、前記クライアント内のプロセスがオープンするとき、前記仮想デバイスが既にオープンされているかどうかを、前記クライアントに備えられた判定手段により判定し、前記仮想デバイスが既にオープンされている場合、前記プロセスのプロセス表において未使用の番号のファイルディスクリプタを探し出し、前記プロセス表に、前記ファイルディスクリプタと、前記カーネルファイル表にて前記仮想デバイスを既にオープンしているプロセスが参照する前記ソケットのデータ構造体へのインデックスが登録されたエントリへのインデックスとを結び付けて登録することで、前記ソケットを参照する前記プロセス用のファイルディスクリプタを、前記クライアントに備えられた再生成手段により再生成する。
【００１２】
本発明の別の観点に基づくプログラムは、記憶媒体へのアクセスをサービスとして実行するサーバと、前記サービスを必要とするプロセスを有するクライアントとの間でソケットを用いて通信を行うための仮想デバイスを、前記クライアント内のプロセスがオープンするとき、前記仮想デバイスが既にオープンされているかどうかを判定する判定手段と、前記仮想デバイスが既にオープンされている場合、前記プロセスのプロセス表において未使用の番号のファイルディスクリプタを探し出し、前記プロセス表に、前記ファイルディスクリプタと、前記カーネルファイル表にて前記仮想デバイスを既にオープンしているプロセスが参照する前記ソケットのデータ構造体へのインデックスが登録されたエントリへのインデックスとを結び付けて登録することで、前記ソケットを参照する前記プロセス用のファイルディスクリプタを再生成する再生成手段としてコンピュータを動作させる。
【発明の効果】
【００１３】
本発明によれば、プロセス間でファイルディスクリプタを受け渡すことなく、クライアントの複数のプロセスが１つのソケットを共有してサーバとの通信を行うことができる。
【発明を実施するための最良の形態】
【００１４】
以下、本発明の実施形態を図面を参照して説明する。
【００１５】
図１は本発明を採用した実施形態である記録装置のハードウェアの構成を示す図である。
【００１６】
同図に示すように、ＣＰＵ（Ｃｅｎｔｒａｌ Ｐｒｏｃｅｓｓｉｎｇ Ｕｎｉｔ）１０１には、システムバス１０２を介して、ＲＯＭ（Ｒｅａｄ Ｏｎｌｙ Ｍｅｍｏｒｙ）１０３と、ＲＡＭ（Ｒａｎｄｏｍ Ａｃｃｅｓｓ Ｍｅｍｏｒｙ）１０４と、入力操作部１０５と、ＡＶインタフェース１０６と、ＨＤＤ（Ｈａｒｄ Ｄｉｓｋ Ｄｒｉｖｅ）１０７と、ディスクドライブ１０８と、ネットワークインタフェース１０９が接続されている。
【００１７】
ＣＰＵ１０１は、ＲＯＭ１０３に格納されたプログラムやデータなどのソフトウェアに基づいて演算処理を実行する。ＲＯＭ１０３には、記録装置１００を動作させるために必要なＯＳ（オペレーティングシステム）、このＯＳ上で動作するアプリケーションなどのプログラムやデータなどのソフトウェアが格納されている。ＲＡＭ１０４は、ＣＰＵ１０１の作業領域や各種の情報の保持領域などとして用いられる。
【００１８】
入力操作部１０５は、各種のキーなどを備え、ユーザからの各種の指令の入力を処理する。入力操作部１０５より入力された指令はシステムバス１０２を通じてＣＰＵ１０１に供給される。
【００１９】
ＡＶインタフェース１０６は、テレビジョンなどの外部ＡＶ機器４とのインタフェースをとるものである。
【００２０】
ＨＤＤ１０７は、コンテンツや、このコンテンツのメタデータなどのユーザデータやその他のデータを保存する記憶媒体である。
【００２１】
ディスクドライブ１０８は、記憶媒体であるブルーレイディスク、ＤＶＤ（Ｄｉｇｉｔａｌ Ｖｅｒｓａｔｉｌｅ Ｄｉｓｋ）などのリムーバブルメディア２の装着が可能とされ、このリムーバブルメディア２に対するデータの書き込み、読み出しを行う。
【００２２】
ネットワークインタフェース１０９は、例えば家庭内のＬＡＮ（Ｌｏｃａｌ Ａｒｅａ Ｎｅｔｗｏｒｋ）などのネットワーク１との接続をとる。本記録装置１００には、ネットワーク１を通じて、コンテンツ受信ＳＴＢ（Ｓｅｔ ｔｏｐ ｂｏｘ）３、リモートユーザインタフェース５などの外部機器が接続可能とされている。
【００２３】
コンテンツ受信ＳＴＢ３は、例えば、地上アナログテレビジョン放送、地上デジタルテレビジョン放送、ＣＳデジタル放送、ＢＳデジタル放送などの放送波に乗って送信される放送コンテンツ、さらには、インターネットなどのネットワークを通じて配信されるネット配信コンテンツなどを受信し、記録装置１００にネットワーク１を通じて送信することが可能な機器である。
【００２４】
リモートユーザインタフェース５は、本記録装置１００をネットワーク１を介して遠隔で操作することのできる機器であり、例えば、携帯電話、ＰＣなどである。
【００２５】
次に、図２を用いて記録装置１００のソフトウェアの構成を説明する。
【００２６】
記録装置１００のソフトウェアは、ＮＦＥ（Network Front End）２１０、ＩＯＰ(Input Output Processor)２２０、ＡＶＤＥＣ（Audio Visual DECorder）２３０に大別される。
【００２７】
ＮＦＥ２１０は、主にネットワークに関する機能を担う。ＩＯＰ２２０は、ＨＤＤ１０７およびディスクドライブ１０８に装着されたリムーバブルメディア２などの記憶媒体に対する書き込みおよび読み出しなどのアクセス、メタデータの管理などを行う。ＣＰＵ１０１の処理負荷を適正に分散させるために、ＮＦＥ２１０とＩＯＰ２２０はethernet（登録商標）などの高速リンクにより粗結合している。ＮＦＥ２１０とＩＯＰ２２０にはそれぞれ、仮想デバイス２１２，２１２，２１３，２２２，２２３，２２４を導入するカーネルモード・ドライバモジュール２１１，２２１がローダブルモジュールとしてインストールされている。ローダブルモジュールとは、オペレーティングシステムの基本コンポーネントであるカーネルそのものには変更を加えずに機能を追加するためのモジュールである。
【００２８】
カーネルモード・ドライバモジュールによって提供される仮想デバイス２１２，２１２，２１３，２２２，２２３，２２４はソケットを用いてＮＦＥ２１０とＩＯＰ２２０との間で通信を行うためのデバイスである。ここでは３つの仮想デバイス、すなわち、ＮＦＥ２１０をクライアントとし、ＩＯＰ２２０をサーバとして通信を行う第１の仮想デバイス２１２，２２２と、並列通信を行う第２の仮想デバイス２１３，２２３と、ＮＦＥ２１０をサーバとし、ＩＯＰ２２０をクライアントとして通信を行う第３の仮想デバイス２１４，２２４とが導入されている。以下、ＮＦＥ２１０がクライアントとなり、ＩＯＰ２２０がサーバとなる第１の仮想デバイス２１２，２２２に絞って説明を進めることとする。
【００２９】
ＮＦＥ２１０（クライアント）にはＩＯＰ２２０（サーバ）が提供するサービスを必要とする複数のプロセス（スレッドを含む）Ｐ１−Ｐｎが存在し、ＩＯＰ２２０（サーバ）にはＮＦＥ２１０（クライアント）の複数のプロセス（スレッドを含む）Ｐ１−Ｐｎからの要求により順次的にサービスを処理するプロセスＳ１が存在する。したがって、クライアントとサーバとの間での通信はＮ：１となる。なお、ＩＯＰ２２０（サーバ）には、プロセスＳ１以外のプロセスＳ２が存在してもよい。
【００３０】
ＮＦＥ２１０（クライアント）とＩＯＰ２２０（サーバ）はそれぞれ、ソケットを用いた通信に先立ち、仮想デバイス２１２，２２２をオープンして通信路を確保する。通信に先立つタイミングとしては、例えば記録装置１００の起動時などが挙げられる。通信に先立つタイミングであれば、起動時以後の任意のタイミングでもよい。
【００３１】
次に、ＮＦＥ２１０（クライアント）とＩＯＰ２２０（サーバ）の仮想デバイス２１２，２２２をオープンする処理について説明する。
【００３２】
（クライアントの仮想デバイスのオープン処理）
【００３３】
図３はクライアントの仮想デバイスのオープン処理に関するフローチャートである。
【００３４】
ＮＦＥ２１０は、ＩＯＰ２２０（サーバ）のサービスを必要とするプロセス（仮に「プロセスＰ１」とする。）を生成し、起動する。プロセスＰ１はソケットを用いて通信を行うために仮想デバイス２１２のオープンを要求する。ＮＦＥ２１０は、プロセスＰ１からの仮想デバイス２１２のオープンの要求が発生すると、システムコールによってカーネルの(down(&sem_0))関数を呼び出し、セマフォに対するdown操作を行うことで、セマフォの値を"０"にする（ステップＳ１０１）。これにより、後から仮想デバイス２１２をオープンしようとする別のプロセスは、セマフォの値が"０"であることによってスリーブ状態になる。
【００３５】
次に、ＮＦＥ２１０は、仮想デバイス２１２に対応付けられたオープンカウント(open count)をインクリメントする（ステップＳ１０２）。オープンカウント(open count)とは、仮想デバイス毎にオープンインスタンス数を管理する変数であり、初期値は"０"である。オープンカウント(open count)は仮想デバイス２１２がリリースされる毎にデクリメントされる。オープンとリリースの対応関係はカーネルによって管理される。
【００３６】
次に、ＮＦＥ２１０は、システムコールによりvmalloc()関数を実行して、プロセスＰ１の仮想アドレス空間内にメモリを確保する（ステップＳ１０３）。
【００３７】
次に、ＮＦＥ２１０は、オープンカウントの値が"１"であるかどうかを判定する（ステップＳ１０４）。当該仮想デバイス２１２が最初にオープンされたときにはオープンカウントの値は"１"であり、オープンカウントの値が"２"以上であれば当該仮想デバイス２１２が既にいずれかのプロセスやスレッドによってオープンされていることを示す。ここで、いずれかのプロセスとは、仮想デバイス２１２をオープンしようとしているプロセスと同じプロセスまたは別のプロセスである。
【００３８】
ここではまず、仮想デバイス２１２が最初にオープンされた場合を想定し、オープンカウントの値が"１"である場合の動作から説明する。
【００３９】
ＮＦＥ２１０は、システムコールによりsocket()関数を実行し、その返り値としてファイルディスクリプタ（psockfd)を得る（ステップＳ１０５）。これに伴い、ＮＦＥ２１０は、カーネルファイル表にソケット構造体（sock）へのインデックスを登録する。さらに、ＮＦＥ２１０は、当該プロセスＰ１のプロセス表に、当該ファイルディスクリプタ（psockfd)と、カーネルファイル表のソケット構造体（sock）へのインデックスが登録されたエントリへのインデックスとを結び付けて登録する。
【００４０】
続いて、ＮＦＥ２１０は、システムコールにより、ファイルディスクリプタ（psockfd)を引き数としてconnect()関数を実行することによって、サーバ側の仮想デバイス２２２のポートとのコネクションを確立する（ステップＳ１０６）。
【００４１】
次に、ＮＦＥ２１０は、システムコールによりファイルディスクリプタ（psockfd)を引き数としてsockfd lookup()関数を実行することによってソケット構造体（sock）を変数p_socketの値として得て、カーネル内の仮想メモリに保存する（ステップＳ１０７）。このソケット構造体（sock）の変数p_socketは、後で説明するsock_remap_fd()関数を実行する際の引き数として用いられる。
【００４２】
続いて、ＮＦＥ２１０は、仮想デバイスのオープンインスタンスごとのプライベート変数であるfile->private_dataにファイルディスクリプタ（psockfd)を代入する。これにより以後、カーネルは、プロセスＰ１からのリード（read）、ライト（write）などの要求が発生したとき、file->private_dataとして格納されたファイルディスクリプタ（psockfd)を用いてソケット構造体の操作を行うことができる。
【００４３】
最後に、ＮＦＥ２１０は、システムコールにより(up(&sem_0))関数を呼び出し、セマフォに対するup操作を行うことで、セマフォの値を"１"に戻す。これによりセマフォによるオープン処理の許可制限が解除される（ステップＳ１０９）。
【００４４】
ここで、ファイルディスクリプタ、プロセス表、カーネルファイル表、ソケット構造体の関係について説明を行う。
【００４５】
ファイルディスクリプタは、ソケット、デバイス、ファイルなどのオブジェクトがプロセスからオープンされることによって、そのオブジェクトに対してカーネルから所定の値から順番に割り当てられる番号である。プロセス表は、プロセス毎にオープンしたオブジェクトを参照するファイルディスクリプタを管理するための表である。プロセス表には、ファイルディスクリプタと、プロセスが参照するオブジェクトへのインデックスが登録されたカーネルファイル表のエントリへのインデックスとが結び付けて登録される。カーネルファイル表には、オープンしているオブジェクトの実体を管理するデータ構造体へのインデックスが登録される。
【００４６】
図７はプロセス、ファイルディスクリプタ、プロセス表、カーネルファイル表、ソケット構造体の関係の例を示す図である。この例では、プロセスＰ１にのプロセス表ＰＴ１にファイルディスクリプタとして１から３の番号が登録されている。それぞれのファイルディスクリプタには、プロセスＰ１が参照するソケット構造体などのオブジェクトへのインデックスが登録されたカーネルファイル表１２のエントリへのインデックスが結び付けて登録されている。一方、プロセスＰ２のプロセス表ＰＴ２にはファイルディスクリプタとして１から４の番号が格納され、それぞれのファイルディスクリプタには、プロセスＰ２が参照するソケット構造体などのオブジェクトへのインデックスが登録されたカーネルファイル表１２のエントリへのインデックスとが結び付けて登録される。ここで、プロセスＰ１のプロセス表ＰＴ１のファイルディスクリプタ（＝１）とプロセスＰ２のプロセス表ＰＴ２のファイルディスクリプタ（＝３）はそれぞれ、カーネルファイル表１２の同じエントリと結び付けられ、共通のソケット構造体１３を参照する。
【００４７】
次に、ステップＳ１０４の判定で、オープンカウントの値が"１"以外つまり"２"以上である場合の以後の動作を説明する。オープンカウントの値が"２"以上であるなら、既に仮想デバイス２１２が、いずれかのプロセスやスレッドによって既にオープンされていることを示している。したがって、そのプロセスのプロセス表には、既に、ファイルディスクリプタ（psockfd)とソケット構造体へのインデックスが登録されたカーネルファイル表のエントリへのインデックスとが結び付けて登録されている。
【００４８】
この場合、ＮＦＥ２１０は、プロセスＰ１用のファイルディスクリプタ（psockfd)を既存のカーネルファイル表をもとに再生成するsock_remap_fd()関数をソケット構造体（sock）の変数p_socketの値を引き数として実行する（ステップＳ１１０）。
【００４９】
図４はsock_remap_fd()関数のフローチャートである。
【００５０】
ＮＦＥ２１０は、まず、変数p_socketの値であるソケット構造体（sock）がカーネル内に存在するかどうかの確認を行う（ステップＳ１１１）。該当するソケット構造体（sock）が何らの障害によりカーネル内に存在しない場合にはエラーとして終了する（ステップＳ１１２）。
【００５１】
該当するソケット構造体（sock）が存在することを確認した場合、次にＮＦＥ２１０は、そのソケット構造体（sock）へのインデックスを登録したカーネルファイル表のエントリ（sock->file）が存在するかどうかの確認を行う（ステップＳ１１３）。カーネルファイル表に該当するエントリ（sock->file）が何らかの障害等により存在しない場合には、システムコールによりソケット構造体（sock）を引き数としてsock_map_fd()関数を実行する。これにより、ソケット構造体（sock）を参照するファイルディスクリプタ（psockfd)が生成される（ステップＳ１１４）。これに伴いＮＦＥ２１０は、カーネルファイル表にソケット構造体（sock）へのインデックスを登録する。さらに、ＮＦＥ２１０は、プロセスＰ１のプロセス表に、当該ファイルディスクリプタ（psockfd)と、カーネルファイル表のソケット構造体（sock）へのインデックスが登録されたエントリへのインデックスとを結び付けて登録する。この後、ファイルディスクリプタ（psockfd)がsock_remap_fd()関数の返り値として出力される（ステップＳ１１７）。
【００５２】
図３に戻って、この後、ＮＦＥ２１０は、仮想デバイスのオープンインスタンスごとのプライベート変数であるfile->private_dataにファイルディスクリプタ（psockfd)を代入する。これにより以後、カーネルは、プロセスＰ１からのリード（read）、ライト（write）などの要求が発生したとき、file->private_dataとして格納されたファイルディスクリプタ（psockfd)を用いてソケット構造体の操作を行うことができる。
【００５３】
最後に、ＮＦＥ２１０は、システムコールにより(up(&sem_0))関数を呼び出し、セマフォに対するup操作を行うことで、セマフォの値を"１"に戻す。これによりセマフォによるオープン処理の許可制限が解除される（ステップＳ１０９）。
【００５４】
また、図４のステップＳ１１３の判定で、該当するカーネルファイル表のエントリ（sock->file）が存在することが判定された場合、ＮＦＥ２１０は、プロセスＰ１のプロセス表から未使用の番号のファイルディスクリプタ（psockfd)を探し出す（ステップＳ１１５）。続いて、ＮＦＥ２１０は、プロセスＰ１のプロセス表に、そのファイルディスクリプタ（psockfd)と、カーネルファイル表のソケット構造体（sock）へのインデックスが登録されたエントリへのインデックスとを結び付けて登録する（ステップＳ１１６）。この後、ＮＦＥ２１０は、当該ファイルディスクリプタ（psockfd)をsock_remap_fd()関数の返り値として出力する（ステップＳ１１７）。
【００５５】
図３に戻って、この後、ＮＦＥ２１０は、上記と同様に、仮想デバイスのオープンインスタンスごとのプライベート変数であるfile->private_dataにsock_remap_fd()関数の返り値として得られたファイルディスクリプタ（psockfd)を代入する。これにより以後、カーネルは、プロセスＰ１からのリード（read）、ライト（write）などの要求が発生したとき、file->private_dataとして格納されたファイルディスクリプタ（psockfd)を用いてソケット構造体の操作を行うことができる。
【００５６】
上記のsock_remap_fd()関数はサーバの仮想デバイスのオープン処理に採用してもよい。
【００５７】
（サーバの仮想デバイスのオープン処理）
【００５８】
図５はサーバの仮想デバイスのオープン処理にsock_remap_fd()関数を採用した場合のフローチャートである。
【００５９】
ＩＯＰ２２０は、サービスを処理するためのプロセス（仮に「プロセスＳ１」とする。）を生成し、起動する。プロセスＳ１はソケットを用いて通信を行うために仮想デバイス２２２のオープンを要求する。ＩＯＰ２２０は、プロセスＳ１からの仮想デバイス２２２のオープンの要求が発生すると、システムコールによりカーネルの(down(&sem_0))関数を呼び出し、セマフォに対するdown操作を行うことで、セマフォの値を"０"にする（ステップＳ２１０）。これにより、後から仮想デバイス２２２をオープンしようとする別のプロセスは、そのセマフォの値が"０"であることによってスリーブ状態になる。
【００６０】
次に、ＩＯＰ２２０は、仮想デバイスに対応付けられたオープンカウント(open count)をインクリメントする（ステップＳ２２０）。このオープンカウント(open count)の初期値は"０"である。このオープンカウント(open count)は仮想デバイス２２２がリリースされる毎にデクリメントされる。オープンとリリースの対応関係はカーネルによって管理される。
【００６１】
次に、ＩＯＰ２２０は、システムコールによりvmalloc()関数を実行して、プロセスＳ１の仮想アドレス空間内にメモリを確保する（ステップＳ２０３）。
【００６２】
次に、ＩＯＰ２２０は、オープンカウントの値が"１"であるかどうかを判定する（ステップＳ２０４）。当該仮想デバイス２２２が最初にオープンされたときにはオープンカウントの値は"１"であり、オープンカウントの値が"２"以上であれば当該仮想デバイス２２２が既にいずれかのプロセスやスレッドによってオープンされていることを示す。ここで、いずれかのプロセスとは、仮想デバイス２２２をオープンしようとしているプロセスと同じプロセスまたは別のプロセスである。
【００６３】
ここではまず、仮想デバイス２２２が最初にオープンされた場合を想定し、オープンカウントの値が"１"である場合の動作から説明する。
【００６４】
ＩＯＰ２２０は、システムコールによりsocket()関数を実行し、その返り値としてファイルディスクリプタ（listenfd)を得る（ステップＳ２０５）。
【００６５】
次に、ＩＯＰ２２０は、システムコールによりsetsockopt()関数を実行して、ソケットのオプションを設定する（ステップＳ２０６）。ソケットのオプションには、サーバ側が一旦使用したListenポート用アドレスが完全に開放されなくてもすぐに再利用できるようにすることを指定するSO_REUSEADDR、バッファサイズの設定であるSO_RCVBUF SO_SNDBUFなどがある。
【００６６】
次に、ＩＯＰ２２０は、システムコールによりbind()関数を実行して、「socket()関数により作成したソケット」と「自分のＩＰアドレスとポート番号」を対応づける。続いてＩＯＰ２２０は、システムコールによりlisten()関数を実行して、クライアントからソケットへの接続に待機することをカーネルを指示する（ステップＳ２０７）。
【００６７】
次に、ＩＯＰ２２０は、システムコールによりaccept()関数を実行する（ステップＳ２０８）。これにより、ＩＯＰ２２０は、クライアントからソケットへの接続要求を受けた時、当該プロセスＳ１のプロセス表に新たなファイルディスクリプタ（psockfd)を登録し、ファイルディスクリプタ（listenfd)と結び付けて登録されているカーネルファイル表へのインデックスを、上記の新たなファイルディスクリプタ（psockfd)と結び付けてプロセス表に登録する。
【００６８】
次に、ＩＯＰ２２０は、システムコールによりファイルディスクリプタ（listenfd)を引き数としてshutdown()関数を実行することにより、ファイルディスクリプタ（listenfd)が割り当てられたソケットとクライアントとの接続を無効にする（ステップＳ２０９）。これにより、ファイルディスクリプタ（listenfd)をつかってクライアントの仮想デバイス２１２からの次の接続要求は拒否される。
【００６９】
次に、ＩＯＰ２２０は、システムコールによりファイルディスクリプタ（psockfd)を引き数としてsockfd lookup()関数を実行して、ソケット構造体を変数p_socketの値として得て、カーネル内の仮想メモリに保存する（ステップＳ２１０）。
【００７０】
続いて、ＩＯＰ２２０は、仮想デバイスのオープンインスタンスごとのプライベート変数であるfile->private_dataにファイルディスクリプタ（psockfd)を代入する（ステップＳ２１１）。これにより以後、カーネルは、プロセスＳ１からの次の要求が発生したとき、file->private_dataとして格納されたファイルディスクリプタ（psockfd)を用いてソケット構造体の操作を行うことができる。
【００７１】
最後に、ＩＯＰ２２０は、システムコールによりカーネルの(up(&sem_0))関数を呼び出し、セマフォに対するup操作を行うことで、セマフォの値を"１"に戻す。これによりセマフォによるオープン処理の許可制限が解除される（ステップＳ２１２）。
【００７２】
次に、ステップＳ２０４の判定で、オープンカウントの値が"１"以外つまり"２"以上である場合の以後の動作を説明する。オープンカウントの値が"２"以上であるなら、既にサーバの仮想デバイス２２２が、いずれかのプロセスまたはスレッドによって既にオープンされていることを示している。先にオープンしたプロセスのプロセス表には、既に、ファイルディスクリプタ（psockfd)と、ソケット構造体へのインデックスが登録されたカーネルファイル表のエントリへのインデックスとが結び付けて登録されている。
【００７３】
この場合、ＩＯＰ２２０は、プロセスＳ１用のファイルディスクリプタ（psockfd)を既存のカーネルファイル表をもとに再生成するsock_remap_fd()関数を変数p_socketの値を引き数として実行する（ステップＳ２１３）。sock_remap_fd()関数のフローは、前述のクライアントに対応する仮想デバイスのオープン処理時のそれと同じであるので、ここでの重複する説明は省く。
【００７４】
sock_remap_fd()関数の実行により、プロセスＳ１用のファイルディスクリプタ（psockfd)が得られた後、ＩＯＰ２２０は、仮想デバイスのオープンインスタンスごとのプライベート変数であるfile->private_dataにそのファイルディスクリプタ（psockfd)を代入する（ステップＳ２１１）。これにより以後、カーネルは、プロセスＳ１からの次の要求が発生したとき、file->private_dataとして格納されたファイルディスクリプタ（psockfd)を用いてソケット操作を行うことができる。
【００７５】
最後に、ＩＯＰ２２０は、 システムコールにより(up(&sem_0))関数を呼び出し、セマフォに対するup操作を行うことで、セマフォの値を"１"に戻す。これによりセマフォによるオープン処理の許可制限が解除される（ステップＳ２１２）。
【００７６】
（仮想デバイスのクローズ処理）
【００７７】
次に、クライアントの仮想デバイスのクローズ処理について説明するが、このクローズ処理はサーバの仮想デバイスをクローズする場合も同様である。
【００７８】
図６はこの仮想デバイスのクローズ処理に関するフローチャートである。
【００７９】
ＮＦＥ２１０は、システムコールによりカーネルの(down(&sem_0))関数を呼び出し、セマフォに対するdown操作を行うことで、セマフォの値を"０"にする（ステップＳ３０１）。
【００８０】
次に、ＮＦＥ２１０は、システムコール元がユーザであるかユーザ以外であるかを判定する（ステップＳ３０２）。システムコール元がユーザである場合、ＮＦＥ２１０は、仮想メモリにプロセスＰ１のプライベートデータとして保存されているファイルディスクリプタ（psockfd)を取り出す（ステップＳ３０３）。
【００８１】
次に、ＮＦＥ２１０は、オープンカウントの値が"１"であるかどうかを判定する（ステップＳ３０４）。オープンカウントの値が"１"の場合は、ファイルディスクリプタ（psockfd)が参照するソケットを利用しているプロセスの数（正確にはオープンインスタンス数）は１つであり、このソケットを用いた通信を無効にしても他のプロセスへの影響はない。したがって、この場合、ＮＦＥ２１０は、システムコールによりファイルディスクリプタ（psockfd)を引き数としてshutdown()関数を実行することによって、そのファイルディスクリプタ（psockfd)が参照するソケットを利用した通信を無効にする（ステップＳ３０５）。
【００８２】
次に、ＮＦＥ２１０は、システムコールによりソケット構造体(p_socket)を引き数としてsockfd_put()関数を実行することによって、ソケット構造体の参照数をデクリメントする（ステップＳ３０６）。
【００８３】
この後、ＮＦＥ２１０は、システムコールによりファイルディスクリプタ（psockfd)を引き数としてclose()関数を実行することにより、ファイルディスクリプタ（psockfd)が参照するソケットを利用しているプロセスＰ１のプロセス表からそのファイルディスクリプタ（psockfd)のエントリを削除する（ステップＳ３０７）。
【００８４】
一方、オープンカウントの値が"２以上"の場合、ファイルディスクリプタ（psockfd)が参照するソケットを利用しているプロセスが２以上であるから、ソケットを用いた通信を無効にすることはできない。この場合、ＮＦＥ２１０は、shutdown()関数の実行、sockfd_put()関数の実行をそれぞれスキップしてシステムコールによりclose()関数を実行する（ステップＳ３０７）。これにより、そのファイルディスクリプタ（psockfd)が参照するソケットを利用した通信を有効のまま、プロセスＰ１のプロセス表のエントリとして保存されているファイルディスクリプタ（psockfd)を削除する。
【００８５】
この後、ＮＦＥ２１０は、システムコールによりオープンインスタンスごとのプライベートデータを引き数としてvfree関数を実行することによって、オープンインスタンスごとのプライベートデータを保存するために割り当てられた仮想メモリ内の空間を解放する（ステップＳ３０８）。続いて、ＮＦＥ２１０は、オープンカウントの値をデクリメントする（ステップＳ３０９）。最後にＮＦＥ２１０は、 システムコールにより(up(&sem_0))関数を呼び出し、セマフォに対するup操作を行うことで、セマフォの値を"１"に戻す。これによりセマフォによる許可制限が解除される（ステップＳ３１０）。
【００８６】
また、ステップＳ３０２で、システムコール元がユーザ以外、例えば、遅延release処理，シグナル処理ルーチン，異常終了処理ルーチンなどのカーネルルーチンであることが判定された場合、ＮＦＥ２１０は、オープンカウントの値が"１"であるかどうかを判定する（ステップＳ３１１）。オープンカウントの値が"１"ならば、ＮＦＥ２１０は、システムコールによりp_socket->ops->shutdown()関数を実行することにより、当該プロセスＰ１のプロセス表のファイルディスクリプタ（psockfd)を使わずにソケットを利用した通信を無効にする（ステップＳ３１２）。この後、ＮＦＥ２１０は、前述のステップＳ３０８以降を実行する。オープンカウントの値が"２"以上の場合には、ソケットを用いた通信を無効にできないのでステップＳをスキップしてステップＳ３０８以降を実行する。
【００８７】
以上説明したように、本実施形態では、クライアントの仮想デバイスがいずれかのプロセスまたはスレッドによって既にオープンされているときに、任意のプロセスまたはスレッドからその仮想デバイスをオープンする場合に、sock_remap_fd()関数を実行し、そのプロセスのファイルディスクリプタを再生成することが行われる。これにより、プロセス間でファイルディスクリプタを受け渡すことなく、クライアントの複数のプロセスが１つの仮想デバイスおよび仮想デバイスが使用するソケットを共有してサーバとの通信を行うことができる。
【００８８】
一般的には、プロセス間でファイルディスクリプタを介して同じオブジェクトを指定できるようにするには、ファイルディスクリプタをプロセス間で受け渡していた。そのためには、ファイルディスクリプタの受け渡しのためのソケット通信路を確立してから、sendmsgシステムコールやrecvmsgシステムコールなどを利用してファイルディスクリプタの記述子そのものを送受信していた。これに対して本実施形態によれば、ファイルディスクリプタの受け渡しのためのソケット通信路を確立する必要がないため、リソースの利用効率が改善される。
【００８９】
また、本実施形態によれば、クライアントの複数のプロセスからサーバに対してサービスを要求し、サーバは各プロセスからの要求に対するサービスを順次実行するという運用において、複数のプロセスから同時に要求が発生した場合の相互排除を、オープン処理の最初にカーネルがもつ(down(&sem_0))関数を用いて実現している。このため、相互排除のための機能を新たに追加することなくクライアント側での相互排除を実現することができる。
【００９０】
さらに、本実施形態において採用されたカーネルモード・ドライバモジュール２１１，２２１は、カーネルそのものを変更せずに、カーネルの関数をシステムコールにより呼び出すことによって特定の機能をカーネルに追加するローダブルモジュールとしてインストールされたものである。このため、ＧＰＬ（GNU Public License）によるカーネル保護の規約に違反しない。
【００９１】
以上はプロセスがファイルディスクリプタを指定してソケットに対する操作を行う場合について説明したが、ファイルディスクリプタを指定して、ファイルなど、ソケット以外のオブジェクトに対する操作を行う場合にも本発明は同様に適用できる。
【００９２】
その他、本発明は、上述の実施形態にのみ限定されるものではなく、本発明の要旨を逸脱しない範囲内において種々更新を加え得ることは勿論である。
【図面の簡単な説明】
【００９３】
【図１】本発明の実施形態である記録装置のハードウェアの構成を示す図である。
【図２】図１の記録装置のソフトウェアの構成を示す図である。
【図３】クライアントの仮想デバイスのオープン処理に関するフローチャートである。
【図４】sock_remap_fd()関数のフローチャートである。
【図５】サーバの仮想デバイスのオープン処理に関するフローチャートである。
【図６】仮想デバイスのクローズ処理に関するフローチャートである。
【図７】プロセス、ファイルディスクリプタ、プロセス表、カーネルファイル表、ソケット構造体の関係の例を示す図である。
【符号の説明】
【００９４】
Ｐ１，Ｓ１…プロセス
ＰＴ１，ＰＴ２…プロセス表
１…ネットワーク
２…リムーバブルメディア
３…コンテンツ受信ＳＴＢ
４…外部ＡＶ機器
５…リモートユーザインタフェース
１２…カーネルファイル表
１３…ソケット構造体
１００…記録装置
１０１…ＣＰＵ
１０２…システムバス
１０３…ＲＯＭ
１０４…ＲＡＭ
１０５…入力操作部
１０６…ＡＶインタフェース
１０７…ＨＤＤ
１０８…ディスクドライブ
１０９…ネットワークインタフェース
２１０…ＮＦＥ
２２０…ＩＯＰ
２１１，２２１…カーネルモード・ドライバモジュール
２１２，２２２…第１の仮想デバイス
２１３．２２３…第２の仮想デバイス
２１４．２２４…第３の仮想デバイス
２３０…ＡＶＤＥＣ
【図１】
0004518177.tif 000002
【図２】
0004518177.tif 000003
【図３】
0004518177.tif 000004
【図４】
0004518177.tif 000005
【図５】
0004518177.tif 000006
【図６】
0004518177.tif 000007
【図７】
0004518177.tif 000008