(57)【要約】【課題】仮想化環境において通信を行う際におけるサーバの負荷を軽減する。【解決手段】複数の仮想ＯＳ２が実行され、さらに、通信処理を管理するドライバＯＳ３が実行され、通信を行うための装置である通信装置５を有しているサーバ１における通信方法であって、共通メモリ４には、通信データが格納されるための通信バッファ４２と、通信バッファ４２のメモリアドレスを格納するための通信リングキュー４１が設定されており、ドライバＯＳ３は、通信リングキュー４１におけるメモリアドレスを管理し、仮想ＯＳ２および通信装置５は、通信リングキュー４１に格納されているメモリアドレスを参照して、通信バッファ４２に対し、通信データの読み書きを行うことを特徴とする。【選択図】図１
2012226471.tif 000002
【特許請求の範囲】
【請求項１】
複数の仮想ＯＳが実行され、さらに、通信処理を管理するドライバＯＳが実行されるための処理装置と、通信を行うための装置である通信装置と、記憶装置と、を有する通信サーバにおける通信方法であって、
前記記憶装置には、通信されるデータである通信データが格納されるための第１の記憶領域と、前記第１の記憶領域のメモリアドレスが格納されるための第２の記憶領域と、が設定されており、
前記ドライバＯＳは、
前記第２の記憶領域における前記メモリアドレスを管理し、
前記仮想ＯＳおよび前記通信装置は、
前記第２の記憶領域に格納されているメモリアドレスを参照して、前記第１の記憶領域に対し、前記通信データの読み書きを行う
ことを特徴とする通信方法。
【請求項２】
前記第２の記憶領域は、複数存在するとともに、巡回性を有しており、メモリアドレスが格納された前記第２の記憶領域には、前記通信データが格納されているか否かの情報である格納情報が付与され、
前記仮想ＯＳおよび前記通信装置は、
前記格納情報が付与された第２の記憶領域から、順々に前記メモリアドレスを参照する
ことを特徴とする請求項１に記載の通信方法。
【請求項３】
前記通信データの送信時において、
前記仮想ＯＳは、
前記通信データを送信するための通信関数を実行し、
前記前記通信データを、前記第１の記憶領域に格納し、
前記通信データを格納した第１の記憶領域のメモリアドレスを含む通信情報を生成し、
前記ドライバＯＳは、
前記通信情報のメモリアドレスを前記第２の記憶領域に格納し、
前記通信装置は、
前記第２の記憶領域に格納されたメモリアドレスが示す前記第１の記憶領域から前記通信データを取得し、
前記通信データを通信先装置へ送信する
ことを特徴とする請求項１または請求項２に記載の通信方法。
【請求項４】
前記通信データの送信時において、
前記ドライバＯＳは、
前記通信データを格納するための第１の記憶領域のメモリアドレスを取得し、
前記取得したメモリアドレスを前記仮想ＯＳへ通知し、
前記仮想ＯＳは、
前記通信データを送信するための通信関数を実行し、
前記前記通信データを、前記通知されたメモリアドレスが示す前記第１の記憶領域に格納し、
前記通信データを格納した第１の記憶領域のメモリアドレスを含む通信情報を生成し、
前記ドライバＯＳは、
前記通信情報のメモリアドレスを前記第２の記憶領域に格納し、
前記通信装置は、
前記第２の記憶領域に格納されたメモリアドレスが示す前記第１の記憶領域から前記通信データを取得し、
前記通信データを通信先装置へ送信する
ことを特徴とする請求項１または請求項２に記載の通信方法。
【請求項５】
前記通信データの送信時において、
前記ドライバＯＳは、予め前記第１の記憶領域のメモリアドレスを取得しており、
前記仮想ＯＳは、
前記通信データを送信するための通信関数を実行し、
前記前記通信データを、前記第１の記憶領域および第２の記憶領域とは異なる第３の記憶領域に格納し、
前記第３の記憶領域のメモリアドレスを含む通信情報を生成し、
前記ドライバＯＳは、
前記通信情報におけるメモリアドレスを基に、前記第３の記憶領域から通信データを取得すると、
前記予め取得していた前記第１の記憶領域のメモリアドレスを基に、前記第１の記憶領域へ前記取得した通信データをコピーし、
前記通信装置は、
前記第２の記憶領域に格納されたメモリアドレスが示す前記第１の記憶領域から前記通信データを取得し、
前記通信データを通信先装置へ送信する
ことを特徴とする請求項１または請求項２に記載の通信方法。
【請求項６】
前記通信データの受信時において、
前記仮想ＯＳは、
前記通信データを受信するため第１の記憶領域のメモリアドレスを引数とする前記通信関数を実行し、
前記通信関数の引数の前記メモリアドレスを含む通信情報を生成し、
前記ドライバＯＳは、
前記通信情報におけるメモリアドレスを、前記第２の記憶領域に格納し、
前記通信装置は、
通信先装置から前記通信データを受信し、
前記第２の記憶領域に格納されている前記メモリアドレスが示す前記第１の記憶領域に前記受信した通信データを格納し、
前記ドライバＯＳは、
前記第２の記憶領域に前記通信データが格納されたことを検知すると、
前記仮想ＯＳへ、前記第１の記憶領域に前記通信データが格納されたことを通知し、
前記通知を受けた仮想ＯＳは、
前記通信関数の引数における前記メモリアドレスが示す前記第１の記憶領域から、前記通信データを取得する
ことを特徴とする請求項１または請求項２に記載の通信方法。
【請求項７】
前記通信データの受信時において、
前記仮想ＯＳは、
前記通信データを格納するための前記第１の記憶領域のメモリアドレスを取得し、
前記取得したメモリアドレスが含まれる通信情報を生成し、
前記ドライバＯＳは、
前記通信情報のメモリアドレスを、前記第２の記憶領域に格納し、
前記通信装置は、
通信先装置から前記通信データを受信し、
前記第２の記憶領域に格納されている前記メモリアドレスが示す前記第１の記憶領域に前記受信した通信データを格納し、
前記ドライバＯＳは、
前記第２の記憶領域に前記通信データが格納されたことを検知すると、
前記仮想ＯＳへ、前記第１の記憶領域に前記通信データが格納されたことを通知し、
前記通知を受けた仮想ＯＳは、
前記取得したメモリアドレスが示す前記第１の記憶領域から、前記通信データを取得する
ことを特徴とする請求項１または請求項２に記載の通信方法。
【請求項８】
前記通信データの受信時において、
前記ドライバＯＳは、
予め前記第１の記憶領域のメモリアドレスを取得し、前記メモリアドレスを前記第２の記憶領域へ格納しており、
前記仮想ＯＳは、
前記前記通信データを、前記第１の記憶領域および前記第２の記憶領域とは異なる第３の記憶領域に格納し、
前記第３の記憶領域のメモリアドレスを引数とする前記通信関数を実行し、
前記通信関数の引数である第３の記憶領域のメモリアドレスを有する通信情報を生成し、
前記通信装置は、
通信先装置から前記通信データを受信し、
前記第２の記憶領域に格納されている前記メモリアドレスが示す前記第１の記憶領域に前記受信した通信データを格納し、
前記ドライバＯＳは、
前記第２の記憶領域に前記通信データが格納されたことを検知すると、
前記第２の記憶領域に格納されている前記メモリアドレスが示す前記第１の記憶領域から前記通信データを取得し、
前記通信情報における前記第３の記憶領域のメモリアドレスが示す記憶領域へ、前記取得した通信データをコピーし、
前記仮想ＯＳへ、前記第１の記憶領域に前記通信データが格納されたことを通知し、
前記通知を受けた仮想ＯＳは、
前記通信関数の引数である前記第３の記憶領域のメモリアドレスが示す記憶領域から、前記通信データを取得する
ことを特徴とする請求項１または請求項２に記載の通信方法。
【請求項９】
前記仮想ＯＳは、
前記第１の記憶領域および第２の記憶領域を介して通信データを処理する関数として登録されていない通信関数や、指定された通信コネクションを処理するためのプロトコルスタックを有している
ことを特徴とする請求項１から請求項８のいずれか一項に記載の通信方法。
【請求項１０】
複数の仮想ＯＳが実行され、さらに、通信処理を管理するドライバＯＳが実行されるための処理装置と、通信を行うための装置である通信装置と、記憶装置と、を有する通信サーバであって、
前記通信データが格納されるための第１の記憶領域と、前記第１の記憶領域のメモリアドレスを格納するための第２の記憶領域と、が設定されている記憶装置と、
前記ドライバＯＳは、
前記第２の記憶領域における前記メモリアドレスを管理し、
前記仮想ＯＳおよび前記通信装置は、
前記第２の記憶領域に格納されているメモリアドレスを参照して、前記第１の記憶領域に対し、前記通信データの読み書きを行う
ことを特徴とする通信サーバ。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、仮想化環境における通信方法および通信サーバの技術に関する。
【背景技術】
【０００２】
計算機の物理資源を複数の論理資源に見せかける仮想化ソフトウェアにより、１台の計算機上で複数の仮想的な計算機を同時に稼働させることが可能となる仮想化技術がある。
以下、複数の仮想計算機を動作させる物理計算機を単に「サーバ」と称し、物理計算機（サーバ）上で動作する仮想計算機を「ゲストＯＳ（Ｏｐｅｒａｔｉｎｇ  Ｓｙｓｔｅｍ）」と称することとする。
このような仮想化技術により、１台のサーバ上におけるプロセッサやメモリなどの物理資源（ハードウェア）を複数のゲストＯＳが共有して利用することができ、ＯＳ毎に複数のサーバを用意する場合に比べて、サーバの運用や管理にかかるコストを省くことができる。
【０００３】
仮想化環境では、ゲストＯＳとハードウェアのインタフェースにドライバＯＳを使用する方法が用いられる。ドライバＯＳとは、サーバ上で複数動作しているゲストＯＳの１つをデバイスドライバ管理専用のドライバＯＳとしたものである。各ゲストＯＳはこのドライバＯＳを通してハードウェアにアクセスする。
この方法を用いることにより、ゲストＯＳで実行されているドライバに不具合が起きたときにドライバを使用しない他のゲストＯＳを含むサーバ全体に影響が出ることや、仮想化ソフトウェアに複数のデバイスドライバを組み込むことで、仮想化のためのソフトウェアのサイズがそれに合わせて肥大化してしまう問題を解決している。
【０００４】
しかし、ドライバＯＳを導入する方法には、ドライバＯＳの負荷により、サーバ全体のシステム性能が制限されてしまうという問題がある。
例えば、ドライバＯＳに複数のゲストＯＳからのアクセスが集中し、ドライバＯＳが複数のゲストＯＳにハードウェアから入出力するたびに、データを振り分けたり、メモリコピーしたりするため、この振り分けや、コピーのためのプロセッサ負荷、メモリアクセス負荷が増大する。
特に、複数のゲストＯＳが１つのネットワークカードを使用して通信を行う際に、ドライバＯＳのプロセッサ負荷、メモリアクセス負荷により、通信速度が制限されてしまうことが問題となっている。
【０００５】
このような問題の対応策として、特許文献１ではサーバが通信データを受信したときに、ドライバＯＳにゲストＯＳのＩＤ（Ｉｄｅｎｔｉｆｉｃａｔｉｏｎ）をあらかじめ設定しておき、そのＩＤに基づいて分配先を決めて転送し、設定や転送ルートの簡素化することで、サーバのプロセッサ負荷とメモリ負荷を軽減する負荷分散機能を有した情報処理装置が開示されている。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特開２０１０−６６９３１号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
特許文献１に記載の技術によって、データ振り分けのためのテーブル検索に使用するプロセッサ負荷が軽減されるものの、ドライバＯＳが複数のゲストＯＳにハードウェアから入出力があるたびに、ハードウェア、ドライバＯＳ、ゲストＯＳ間で行われるメモリコピーが実行されなければならない。また、ＴＣＰ／ＩＰ（Ｔｒａｎｓｍｉｓｓｉｏｎ  Ｃｏｎｔｒｏｌ  Ｐｒｏｔｏｃｏｌ／Ｉｎｔｅｒｎｅｔ  Ｐｒｏｔｏｃｏｌ）のようにヘッダとペイロードを有するパケット構造を持つ通信プロトコルを用いる通信の場合、各ゲストＯＳは、それぞれゲストＯＳ上で実行されているドライバとは別に、通信アプリケーションを実行することによって、送受信パケットの送受信処理を行っている。この通信アプリケーションが送受信パケットを生成、解析する際のプロセッサ負荷、メモリアクセス負荷の存在も問題となっている。
【０００８】
通信の処理をゲストＯＳからオフロードし、専用ハードウェアによりこれを処理する方法もあるが、前記したゲストＯＳとハードウェア間の処理におけるプロセッサ負荷、メモリアクセス負荷の問題は解決されない。
【０００９】
このような背景に鑑みて本発明がなされたのであり、本発明は、仮想化環境において通信を行う際におけるサーバの負荷を軽減することを課題とする。
【課題を解決するための手段】
【００１０】
前記課題を解決するため、本発明は、複数の仮想ＯＳが実行され、さらに、通信処理を管理するドライバＯＳが実行されるための処理装置と、通信を行うための装置である通信装置と、記憶装置と、を有する通信サーバにおける通信方法であって、前記記憶装置には、通信されるデータである通信データが格納されるための第１の記憶領域と、前記第１の記憶領域のメモリアドレスが格納されるための第２の記憶領域と、が設定されており、前記ドライバＯＳは、前記第２の記憶領域における前記メモリアドレスを管理し、前記仮想ＯＳおよび前記通信装置は、前記第２の記憶領域に格納されているメモリアドレスを参照して、前記第１の記憶領域に対し、前記通信データの読み書きを行うことを特徴とする。
【発明の効果】
【００１１】
本発明によれば、仮想化環境において通信を行う際におけるサーバの負荷を軽減することが可能となる。
【図面の簡単な説明】
【００１２】
【図１】第１実施形態に係る仮想システムの構成例を示す図である。
【図２】サーバのハードウェア構成の一例を示す図である。
【図３】通信データが送受信される際に通る経路を示す図である。
【図４】通信関数を通信Ｉ／Ｆパケットへ変換する一例を示す図である。
【図５】第１実施形態に係るスイッチ変数管理テーブルの例を示す図である。
【図６】第１実施形態に係る通信Ｉ／Ｆパケット生成処理の手順を示すフローチャートである。
【図７】第１実施形態に係る通信リングキューの説明図である。
【図８】第１実施形態に係る通信リングキューの構成例を示す図である。
【図９】通信Ｉ／Ｆドライバの構成と、他の機能部との関係を示す図である。
【図１０】第１実施形態に係る通信Ｉ／Ｆパケット処理の手順を示すフローチャートである。
【図１１】第１実施形態に係るアクティブオープンの処理手順の一例を示すシーケンス図である（その１）。
【図１２】第１実施形態に係るアクティブオープンの処理手順の一例を示すシーケンス図である（その２）。
【図１３】第１実施形態に係るパッシブオープンの処理手順の一例を示すシーケンス図である（その１）。
【図１４】第１実施形態に係るパッシブオープンの処理手順の一例を示すシーケンス図である（その２）。
【図１５】第１実施形態に係るパッシブオープンの処理手順の一例を示すシーケンス図である（その３）。
【図１６】第１実施形態に係るデータ送信処理の処理手順の一例を示すシーケンス図である。
【図１７】第１実施形態に係るデータ受信処理の処理手順の一例を示すシーケンス図である。
【図１８】第１実施形態に係るアクティブクローズの処理手順の一例を示すシーケンス図である。
【図１９】第１実施形態に係るパッシブクローズの処理手順の一例を示すシーケンス図である。
【図２０】第２実施形態に係る仮想システムの構成例を示す図である。
【図２１】第２実施形態に係る通信Ｉ／Ｆパケット生成処理の手順を示すフローチャートである。
【発明を実施するための形態】
【００１３】
次に、本発明を実施するための形態（「実施形態」という）について、適宜図面を参照しながら詳細に説明する。
【００１４】
《第１実施形態》
まず、図１〜図１９を参照して、本発明の第１実施形態を説明する。
【００１５】
［システム構成］
図１は、第１実施形態に係る仮想システムの構成例を示す図である。
仮想システムＺは、物理的な計算機であるサーバ（通信サーバ）１と、通信先サーバ９とがネットワーク８を介して互いに接続している。
サーバ１には、ＰＣＩ（Ｐｅｒｉｐｈｅｒａｌ  Ｃｏｍｐｏｎｅｎｔ  ｉｎｔｅｒｆａｃｅ）Ｅｘｐｒｅｓｓ（登録商標）などのハードウェアＩ／Ｆ（Ｉｎｔｅｒｆａｃｅ）６を介して、通信処理の一部をＣＰＵ（Ｃｅｎｔｒａｌ  Ｐｒｏｃｅｓｓｉｎｇ  Ｕｎｉｔ）に代わって行う通信オフロードエンジン（通信装置）５が接続されている。そして、通信オフロードエンジン５は、ＮＩ（Ｎｅｔｗｏｒｋ  Ｉｎｔｅｒｆａｃｅ）となるＰＨＹ（Ｐｈｙｓｉｃａｌ  Ｌａｙｅｒ）などのハードウェアＩ／Ｆ７を介してネットワーク８に接続している。
【００１６】
サーバ１では、ハイパバイザ（処理装置）１０が実行されており、そのハイパバイザ１０が複数のゲストＯＳ２およびドライバＯＳ３を実行・管理している。
ハイパバイザ１０は、仮想化技術の１つであり、仮想化環境を実現する仮想化ソフトウェアである。ハイパバイザ１０はメインメモリ上で動作しており、ドライバＯＳ３、ゲストＯＳ２を含むすべてのＯＳはハイパバイザ１０上で動作する。なお、メインメモリ上でまず、図示しないホストＯＳが稼働し、その上でハイパバイザ１０が、そのホストＯＳのアプリケーションとして稼働し、さらに、ハイパバイザ１０がドライバＯＳ３やゲストＯＳ２を実行するケースもある。
【００１７】
ゲストＯＳ２は、サーバ１上で動作する仮想的なＯＳ（仮想計算機：仮想ＯＳ）である。ゲストＯＳ２は仮想化されていない計算機環境で動作するＯＳと同様の動作をする。仮想化環境下のサーバ１では、複数のゲストＯＳ２が動作可能であり、ゲストＯＳ２として様々な種類のＯＳを実行できる。
本実施形態では、ゲストＯＳ２は、通信アプリケーション２１と、通信Ｉ／Ｆライブラリ処理部２３とを実行しているが、これ以外のアプリケーションを実行することも可能である。
通信アプリケーション２１は、通信を行うための関数（以下、通信関数と称する）を実行し、ゲストＯＳ２上の通信処理を行う。
【００１８】
通信Ｉ／Ｆライブラリ処理部２３は、通信アプリケーション２１と通信Ｉ／Ｆドライバ３１のインタフェースである。
通信Ｉ／Ｆライブラリ処理部２３は、通信アプリケーション２１で実行された通信関数を、通信Ｉ／Ｆドライバ３１で実行可能な通信Ｉ／Ｆパケット（通信情報）へ変換することで、既存の通信アプリケーション２１を変更することなく、通信Ｉ／Ｆドライバ３１へ通信情報および通信データを渡すＩ／Ｆを提供する。
通信Ｉ／Ｆライブラリ処理部２３の詳細については、後記して説明する。
【００１９】
ドライバＯＳ３は、サーバ１上で動作する仮想ＯＳの１つである。ドライバＯＳ３が各種ハードウェアのドライバを管理することで、サーバ１における各種ハードウェアをゲストＯＳ２が使用できる。ドライバＯＳ３は、様々な種類のＯＳを使用することができるため、ハードウェアのドライバに合わせて使用するＯＳを変更することで、特定のＯＳでしか使えないドライバでも、対応することができる。
【００２０】
ドライバＯＳ３は、ドライバの１つとして、通信用のドライバである通信Ｉ／Ｆドライバ３１を実行している。通信Ｉ／Ｆドライバ３１は、通信Ｉ／Ｆライブラリ処理部２３より取得した通信Ｉ／Ｆパケットに基づいて、通信情報を通信リングキュー４１へ格納する。通信Ｉ／Ｆドライバ３１の詳細については、後記して説明する。
【００２１】
なお、通信アプリケーション２１と、通信Ｉ／Ｆライブラリ処理部２３との間には、ソフトウェアＩ／Ｆ２２が介在しており、通信Ｉ／Ｆライブラリ処理部２３と、通信Ｉ／Ｆドライバ３１間には、ソフトウェアＩ／Ｆ２４、３２が介在している。通信関数は、一般的な通信関数が使用可能である。たとえば、通信関数としては、ＴＣＰ／ＩＰ通信処理で広く使用されるソケット関数を使用する。
【００２２】
さらに、サーバ１は、後記して説明する通信リングキュー（第２の記憶領域）４１や、通信バッファ（第１の記憶領域）４２を保持している共通メモリ（記憶装置）４を有する。共通メモリ４には、仮想ＯＳ２や、通信Ｉ／Ｆドライバ３１や、通信オフロードエンジン５がアクセスすることができる。
【００２３】
通信オフロードエンジン５は、通信処理を行う専用ハードウェアである。通信オフロードエンジン５は、プロトコルスタックエンジン５１と、セッション管理テーブル５２を有している。
セッション管理テーブル５２は、通信のセッションに関する固有の状態情報などのセッション情報を管理するテーブルである。
プロトコルスタックエンジン５１は、ハードウェアＩ／Ｆ６を介して共通メモリ４にアクセスすることができ、セッション管理テーブル５２のセッション情報や、共通メモリ４の通信リングキュー４１の通信情報や、通信バッファ４２の通信データを基に、通信パケットの生成や解析をして通信先サーバ９と送受信をする。
【００２４】
［ハードウェア構成］
図２は、サーバのハードウェア構成の一例を示す図である。
図１のハイパバイザ１０、ゲストＯＳ２、ドライバＯＳ３、通信アプリケーション２１、通信Ｉ／Ｆライブラリ処理部２３、通信Ｉ／Ｆドライバ３１などは、ＲＯＭ（Ｒｅａｄ  Ｏｎｌｙ  Ｍｅｍｏｒｙ）２０３や、ＨＤＤ（Ｈａｒｄ  Ｄｉｓｋ  Ｄｒｉｖｅ）２０４に格納されたプログラムが、ＲＡＭ（Ｒａｎｄｏｍ  Ａｃｃｅｓｓ  Ｍｅｍｏｒｙ）２０２に展開され、ＣＰＵ２０１によって実行されることによって具現化する。
また、図１の共通メモリ４は、ＲＡＭ２０２あるいはＨＤＤ２０４上に保持され、通信データは、通信インタフェース２０５（図１の通信オフロードエンジン５およびハードウェアＩ／Ｆ７に相当）を介してネットワーク８へ送信される。
【００２５】
［通信経路］
図３は、通信データが送受信される際に通る経路を示す図である。
図３を参照して、通信アプリケーション２１から通信データが送受信される場合における経路の一例を説明する。各部２１、２３、３１における処理の詳細は後記して説明する。
【００２６】
図３に示すように、通信アプリケーション２１と、通信Ｉ／Ｆライブラリ処理部２３とはソフトウェアＩ／Ｆ２２を介して、通信のための情報の授受を行い、通信Ｉ／Ｆライブラリ処理部２３と、通信Ｉ／Ｆドライバ３１とはソフトウェアＩ／Ｆ２３、３２を介して通信のための情報の授受を行う。また、通信Ｉ／Ｆドライバ３１と、通信オフロードエンジン５は、ＰＣＩ  Ｅｘｐｒｅｓｓ（登録商標）などのハードウェアＩ／Ｆ６を介して、通信のための情報の授受を行う。さらに、通信オフロードエンジン５と、通信先サーバ９とは、ＮＩとなるＰＨＹなどのハードウェアＩ／Ｆ７およびネットワーク８を介して、通信を行う。
【００２７】
［通信Ｉ／Ｆライブラリ処理部］
次に、図４〜図６を参照して、通信Ｉ／Ｆライブラリ処理部２３について詳細に説明する。
（通信Ｉ／Ｆパケット）
図４は、通信関数を通信Ｉ／Ｆパケットへ変換する一例を示す図である。
図３の説明で示したように、通信Ｉ／Ｆライブラリ処理部２３は、通信アプリケーション２１で実行された既存の通信関数、例えばＴＣＰ／ＩＰで使用されるソケット関数から、通信情報および通信データを取得し、通信Ｉ／Ｆドライバ３１へ送信するための通信Ｉ／Ｆパケットを生成する。
図４では、一例として、送信に関する通信関数であるｓｅｎｄ関数４０１から通信Ｉ／Ｆパケット４０２への変換方法の例を示している。
ｓｅｎｄ関数４０１は、引数として、通信のコネクションを識別するソケット番号である「ｓｏｃｋｆｄ」、送信するデータを格納するメモリアドレスを示す「ｓｂｕｆ」、送信するデータの長さを示す「ｌｅｎ」、送信時における様々な機能について設定する「ｆｌａｇｓ」を有する。また、ｓｅｎｄ関数は、リターン値として送信できたデータのサイズを返す。
【００２８】
通信Ｉ／Ｆパケット４０２の先頭には、通信関数の種別を示すスイッチ変数４２１を設定する。図５で後記するように、スイッチ変数４２１は関数毎に設定されており、ｓｅｎｄ関数４０１に対応する通信Ｉ／Ｆパケット４０２のスイッチ変数４２１は５番（ｓｗｉｔｃｈ（５））として設定されている。スイッチ変数４２１に続いて、通信関数の引数をそれぞれ通信Ｉ／Ｆパケット４０２に設定することによって、通信Ｉ／Ｆライブラリ処理部２３は通信関数を通信Ｉ／Ｆパケット４０２に変換する。
なお、図４で示した通信Ｉ／Ｆパケット４０２の生成方法は一例であり、他の方法で通信Ｉ／Ｆパケット４０２を生成してもよいことは当然である。
【００２９】
（スイッチ変数管理テーブル５０１）
図５は、第１実施形態に係るスイッチ変数管理テーブルの例を示す図である。
スイッチ変数管理テーブル５０１は、例えばＨＤＤ２０４（図２）などに格納されており、通信Ｉ／Ｆライブラリ処理部２３は、このスイッチ変数管理テーブル５０１の情報に従って通信関数を通信Ｉ／Ｆパケットに変換する。
図５に示すように、スイッチ変数管理テーブル５０１では、各通信関数に対応するスイッチ変数と、その後に設定される変数（通信情報）が、通信Ｉ／Ｆパケットの後からのビット数で設定されている。つまり、通信関数と、通信Ｉ／Ｆパケットとのビット配列との関係が設定されている。
【００３０】
なお、通信Ｉ／Ｆパケットのサイズは、対応する通信関数に合わせて増減してもよい。
図５の例では、先頭のスイッチ変数（１３５〜１２８ビット）により、各種通信関数が識別され、スイッチ変数より後の各種変数は、それぞれの通信関数の引数と一致している。なお、通信関数の引数に該当する部分が通信情報となる。
【００３１】
（フローチャート）
図６は、第１実施形態に係る通信Ｉ／Ｆパケット生成処理の手順を示すフローチャートである。
一般的には、通信アプリケーション２１による通信が行われる際には、通信関数が使用され、ゲストＯＳ２上で動作している通信処理のためのソフトウェアであるプロトコルスタックにより、通信処理が行われる。
これに対し、本実施形態では、通信アプリケーション２１が実行した通信関数を、通信Ｉ／Ｆライブラリ処理部２３が通信Ｉ／Ｆドライバ３１による実行が可能な通信Ｉ／Ｆパケットへ変換する。
【００３２】
通信アプリケーション２１は、通信関数を実行する（Ｓ１０１）。
そして、通信Ｉ／Ｆライブラリ処理部２３は、通信関数から通信Ｉ／Ｆパケットを生成する（Ｓ１０２）。
通信Ｉ／Ｆライブラリ処理部２３による通信Ｉ／Ｆパケットの生成方法は、図４および図５を参照して説明した通りである。
【００３３】
そして、通信Ｉ／Ｆライブラリ処理部２３は通信Ｉ／Ｆドライバ３１へ通信Ｉ／Ｆパケットを送信する（Ｓ１０３）。
通信Ｉ／Ｆパケット受信した通信Ｉ／Ｆドライバ３１は、図７〜図１０で後記する処理を行うことによって通信Ｉ／Ｆパケットを処理し、リターン値を通信Ｉ／Ｆライブラリ処理部２３へ返し、通信Ｉ／Ｆライブラリ処理部２３は、通信Ｉ／Ｆドライバ３１から送信されたリターン値を取得する（Ｓ１０４）。
そして、通信Ｉ／Ｆライブラリ処理部２３は、取得したリターン値を通信関数のリターン値として通信アプリケーション２１へ送信し（Ｓ１０５）、通信Ｉ／Ｆパケット生成処理を完了する。
【００３４】
[通信リングキュー］
次に、図７〜図１０を参照して、通信リングキュー４１について詳細に説明する。
（通信リングキュー４１の説明図）
図７は、第１実施形態に係る通信リングキューの説明図である。
通信Ｉ／Ｆドライバ３１は、通信リングキュー４１を使用して、通信オフロードエンジン５と通信情報および通信データのやりとりを行う。
通信リングキュー４１は、送信リングキュー７０２と受信リングキュー７０１とを有する。送信リングキュー７０２および受信リングキュー７０１は、通信セッション毎に生成される。
送信リングキュー７０２には、送信される通信データを格納する送信バッファ７１１のメモリアドレスなどが格納されている。同様に、受信リングキュー７０１には、通信データ（通信データ）を格納する受信バッファ７１２のメモリアドレスが格納されている。なお、送信バッファ７１１および受信バッファ７１２は、通信バッファ４２を構成するものであり、実際に送受信するデータ本体（通信データ）が格納されている。
【００３５】
通信データの送信時において、通信Ｉ／Ｆドライバ３１は、送信リングキュー７０２に、通信データに関する各変数に関する通信情報（キューデータ）を格納し、通信オフロードエンジン５のプロトコルスタックエンジン５１は、格納されたキューデータを基に、送信バッファ７１１から通信データを取得する。キューデータについては、後記して説明する。
同様に、通信データの受信時において、通信オフロードエンジン５のプロトコルスタックエンジン５１が受信リングキュー７０１に、受信した通信データを格納している受信バッファ７１２のメモリアドレスなどをキューデータとして格納し、通信Ｉ／Ｆドライバ３１は格納されたキューデータを基に、受信バッファ７１２から通信データを取得する。
【００３６】
送信リングキュー７０２および受信リングキュー７０１は、複数のキュー（図７における１区画）で構成されており、このキューがリング状（巡回性）の構成を有しており、一方向へ順番に処理されるため、通信Ｉ／Ｆドライバ３１や、通信オフロードエンジン５のプロトコルスタックエンジン５１は送信リングキュー７０２および受信リングキュー７０１におけるキューが空いている限り、順番に連続してキューデータを設定・取得できる。送信リングキュー７０２および受信リングキュー７０１におけるキューが一杯になった場合は、キューが空くまで、通信Ｉ／Ｆドライバ３１や、通信オフロードエンジン５は待機状態となる。
【００３７】
（通信リングキューの構成）
図８は、第１実施形態に係る通信リングキューの構成例を示す図である。図８では、ＴＣＰ／ＩＰ通信を例に通信リングキュー４１（図７）の構成例を示している。また、図８では、通信リングキュー４１の１つのキュー（図７の通信リングキュー４１の１区画）の構成例を示している。
図８（ａ）は、送信リングキュー７０２の構成例を示す図である。
送信リングキュー７０２は、そのキューが有効であることを示すフラグ（格納情報）、ＴＣＰ／ＩＰ通信で使用する宛先ポート番号、拡張用の予約領域、宛先アドレス、送信データサイズ、通信データが格納されている送信バッファ７１１のメモリアドレスである送信バッファアドレスを有する。なお、送信リングキュー７０２の拡張時は、各キューのデータ内容を変更したり、各キューのデータを増設したりしてもよい。
ここで、図８（ａ）、図８（ｂ）とも、「アドレス」は、そのデータが入る共通メモリ４（図１）上のアドレスを示し、ビットは、アドレスの先頭からのビット数である。
【００３８】
受信リングキュー７０１は、送信リングキュー７０２と同様の構成を有しており、そのキューが有効であることを示すフラグ、ＴＣＰ／ＩＰ通信で使用する送信元ポート番号、拡張用の予約領域、送信元アドレス、受信データサイズ、通信データが格納されている受信バッファ７１２のメモリアドレスである受信バッファアドレスを有する。なお、受信リングキュー７０１の拡張時は、各キューのデータ内容を変更したり、各キューのデータを増設したりしてもよい。
【００３９】
［通信Ｉ／Ｆドライバ３１］
次に、図９および図１０を参照して、通信Ｉ／Ｆドライバ３１について詳細に説明する。
（構成図）
図９は、通信Ｉ／Ｆドライバの構成と、他の機能部との関係を示す図である。図９において、図１と同様の構成については、同一の符号を付して説明を省略する。また、図９において、通信Ｉ／Ｆライブラリ処理部２３、ソフトウェアＩ／Ｆ２２、２４、３２、ハードウェアＩ／Ｆ６は省略されている。
通信Ｉ／Ｆドライバ３１は、通信Ｉ／Ｆスイッチ処理部９０１、割込処理部９０２を有している。なお、通信Ｉ／Ｆドライバ３１は、ライン９２１を介して、直接通信オフロードエンジン５のプロトコルスタックエンジン５１における内部レジスタ（図示せず）およびメモリ（図示せず）に対して、読み書きすることも可能である。
通信Ｉ／Ｆスイッチ処理部９０１は、通信Ｉ／Ｆライブラリ処理部２３から渡される通信Ｉ／Ｆパケットのスイッチ番号に従って関数処理を行う。通信Ｉ／Ｆスイッチ処理部９０１の詳細については後記する。
割込処理部９０２は、通信オフロードエンジン５のプロトコルスタックエンジン５１における割込処理部９１１など、各種ハードウェアによる通信Ｉ／Ｆドライバ３１への割り込みを処理する。
【００４０】
共通メモリ４における通信リングキュー４１は、ゲストＯＳ２（＃１）に対応した通信リングキュー４１（＃１）や、ゲストＯＳ２（＃２）に対応した通信リングキュー４１（＃２）のようにゲストＯＳ２毎に生成される。さらに、通信リングキュー４１は、ゲストＯＳ２上で動作する通信アプリケーションプロセス９５１毎に生成される。図９の例では、ゲストＯＳ２（＃１）で実行されている通信アプリケーションプロセス９５１（＃１ａ）に対する通信リングキュー４１（＃１ａ）、ゲストＯＳ２（＃２）で実行されている通信アプリケーションプロセス９５１（＃２ａ）に対応する通信リングキュー４１（＃２ａ）、通信アプリケーションプロセス９５１（＃２ｂ）に対応する通信リングキュー４１（＃２ｂ）が生成されている。それぞれの通信リングキュー４１が送信リングキュー７０２および受信リングキュー７０１を有することは前記した通りである。ここで、通信アプリケーションプロセス９５１は、通信アプリケーション２１（図１）におけるプロセスである。
【００４１】
通信データを通信先サーバ９へ送信する場合、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、送信リングキュー７０２に各種通信情報を格納し、該当するキューのフラグ（図８参照）を「有効」にする。
送信が連続して実行される場合、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は送信リングキュー７０２の各キューに通信情報を次々と格納し、そのキューのフラグを「有効」にする。
【００４２】
通信オフロードエンジン５のプロトコルスタックエンジン５１は、送信リングキュー７０２のフラグを参照し、「有効」であればその送信リングキュー７０２の宛先ポート番号、宛先アドレスの情報（いずれも図８参照）を取得し、さらに、送信バッファアドレス（図８参照）から通信データが格納されている送信バッファ７１１のメモリアドレスを取得する。そして、通信オフロードエンジン５のプロトコルスタックエンジン５１は、送信リングキュー７０２の送信データサイズを参照し、取得した送信バッファアドレスから参照した送信データサイズ分の長さのデータを取得し、取得したデータを通信データとして宛先アドレス（通信先サーバ９）へ送信する。その後、通信オフロードエンジン５のプロトコルスタックエンジン５１は、送信リングキュー７０２のフラグを「無効」にし、次の送信リングキュー７０２を処理する。
【００４３】
通信データを通信先サーバ９から受信する場合、通信アプリケーション２１がｒｅｃｖ（ｒｅｃｅｉｖｅ）関数を実行する。ｒｅｃｖ関数には、受信バッファアドレスが引数として設定されており、通信Ｉ／Ｆパケットの通信情報として、この受信バッファアドレスを受け取った通信Ｉ／Ｆドライバ３１は、受信バッファアドレスを受信リングキュー７０１の受信バッファアドレスに格納する。
通信オフロードエンジン５のプロトコルスタックエンジン５１は、通信先サーバ９から通信データを受信すると、受信リングキュー７０１のうち、フラグが「無効」となっているキューの受信バッファアドレスを取得し、取得した受信バッファアドレスに該当する受信バッファ７１２に受信した通信データを格納する。そして、通信オフロードエンジン５のプロトコルスタックエンジン５１は、格納した通信データのサイズを、受信リングキュー７０１の受信データサイズ（図８参照）の部分に設定し、受信リングキュー７０１の処理対象フラグ（図８参照）を「有効」にする。通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、受信リングキュー７０１のフラグが「有効」であるキューの受信バッファアドレスと通信データサイズを参照し、通信Ｉ／Ｆライブラリ処理部２３へリターン値を返して、さらに、通信Ｉ／Ｆライブラリ処理部２３は通信アプリケーション２１へリターン値を送信する。
通信アプリケーション２１は、通信Ｉ／Ｆドライバ３１からリターン値を受信すると、実行したｒｅｃｖ関数の引数に設定されている受信バッファアドレスから、受信した通信データを取得する。
【００４４】
その後、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は受信リングキュー７０１の処理対象フラグを「無効」にする。
再度、通信アプリケーション２１がｒｅｃｖ関数を実行した場合、受信バッファアドレス、受信バッファサイズ等を設定し、受信リングキュー７０１のフラグを受信可能に設定する。
【００４５】
このようにすることで、送信時、受信時とも、各機能部間の通信データのやりとりは、通信バッファ４２のメモリアドレスで行うため、通信データのコピーに関するプロセッサ負荷を低減することができる。つまり、通信バッファ４２のメモリアドレス（例えば、Ｃ言語におけるポインタ）で通信データのやりとりが管理され、通信バッファ４２に格納されている通信データ本体は移動しないされない（コピー）こととなり、通信データのコピーに関するプロセッサ負荷や、メモリ負荷を低減することができる。
【００４６】
（通信Ｉ／Ｆパケット処理）
図１０は、第１実施形態に係る通信Ｉ／Ｆパケット処理の手順を示すフローチャートである。
まず、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、通信Ｉ／Ｆライブラリ処理部２３から通信Ｉ／Ｆパケット３０１を受信する（Ｓ２０１）。
そして、通信Ｉ／Ｆスイッチ処理部９０１は、受信した通信Ｉ／Ｆパケットの先頭のスイッチ変数（図４）を判定する（Ｓ２０２）。これにより、通信Ｉ／Ｆスイッチ処理部９０１は、受信した通信Ｉ／Ｆパケットが、どの通信関数に対応するかを判定する。通信Ｉ／Ｆスイッチ変数と、通信関数の種別との対応は、図５で前記したスイッチ変数管理テーブル５０１に準じる。
【００４７】
スイッチ変数が「０」であれば（Ｓ２０２→０）、通信Ｉ／Ｆスイッチ処理部９０１は通信関数名を「ｓｏｃｋｅｔ」と判定し、通信Ｉ／Ｆドライバ３１および通信オフロードエンジン５は図８におけるライン９２１を介して、通信で使用するソケットを生成し、共通メモリ４上に通信リングキュー４１を生成するｓｏｃｋｅｔ関数処理を行う（Ｓ２０３）。
スイッチ変数が「１」であれば（Ｓ２０２→１）、通信Ｉ／Ｆスイッチ処理部９０１は通信関数名を「ｂｉｎｄ」と判定し、図９におけるライン９２１を介して、生成したソケットに自己情報（アドレス、ポート番号）を割り当てるｂｉｎｄ関数処理を行う（Ｓ２０４）。
スイッチ変数が「２」であれば（Ｓ２０２→２）、通信Ｉ／Ｆスイッチ処理部９０１は通信関数名を「ｌｉｓｔｅｎ」と判定し、通信Ｉ／Ｆドライバ３１および通信オフロードエンジン５は図９におけるライン９２１を介して、自己情報を割り当てたソケットを待ち受けソケットとして登録するｌｉｓｔｅｎ関数処理を行う（Ｓ２０５）。
【００４８】
スイッチ変数が「３」であれば（Ｓ２０２→３）、通信Ｉ／Ｆスイッチ処理部９０１は通信関数名を「ａｃｃｅｐｔ」と判定し、通信Ｉ／Ｆドライバ３１および通信オフロードエンジン５は図９におけるライン９２１を介して、接続相手の待ち受けを行い、接続が確立した場合、新たにソケットを生成するａｃｃｅｐｔ関数処理を行う（Ｓ２０６）。
スイッチ変数が「４」であれば（Ｓ２０２→４）、通信Ｉ／Ｆスイッチ処理部９０１は通信関数名を「ｃｏｎｎｅｃｔ」と判定し、通信Ｉ／Ｆドライバ３１および通信オフロードエンジン５は図９におけるライン９２１を介して、指定したアドレスおよびポート番号に対して接続要求を発行するｃｏｎｎｅｃｔ関数処理を行う（Ｓ２０７）。
【００４９】
スイッチ変数が「５」であれば（Ｓ２０２→５）、通信Ｉ／Ｆスイッチ処理部９０１は通信関数名を「ｓｅｎｄ」と判定し、通信Ｉ／Ｆドライバ３１および通信オフロードエンジン５は通信データの送信を行うｓｅｎｄ関数処理を行う（Ｓ２０８）。
スイッチ変数が「６」であれば（Ｓ２０２→６）、通信Ｉ／Ｆスイッチ処理部９０１は通信関数名を「ｒｅｃｖ（ｒｅｃｅｉｖｅ）」と判定し、通信Ｉ／Ｆドライバ３１および通信オフロードエンジン５は通信データの受信を行うｒｅｃｖ関数処理を行う（Ｓ２０９）。
スイッチ変数が「７」であれば（Ｓ２０２→７）、通信Ｉ／Ｆスイッチ処理部９０１は通信関数名を「ｃｌｏｓｅ」と判定し、通信Ｉ／Ｆドライバ３１および通信オフロードエンジン５は図９におけるライン９２１を介して、ソケットを閉じるｃｌｏｓｅ関数処理を行う（Ｓ２１０）。
ステップＳ２０３〜Ｓ２１０の各処理の詳細は後記する。
なお、これら関数はアプリケーション処理のオフロード化に合わせて増減してもよい。
【００５０】
ステップＳ２０３〜Ｓ２１０の各処理を終了した後、通信Ｉ／Ｆスイッチ処理部９０１は、各通信関数が要求するリターン値を、通信Ｉ／Ｆライブラリへ送信し（Ｓ２１１）、通信Ｉ／Ｆパケット処理を終了する。
【００５１】
［ＴＣＰ／ＩＰ通信の例］
次に、図１、図７、図９を参照しつつ、図１１〜図１９に沿って、本実施形態の一例としてＴＣＰ／ＩＰ通信を行った時のシーケンスを説明する。
ＴＣＰ／ＩＰ通信では、送受信の通信に先立っての準備として接続確立シーケンスが必要となる。ＴＣＰ／ＩＰ通信では、シーケンス番号と呼ばれる番号を使用して、どこまで送信および受信したかを管理するが、このシーケンス番号の初期値を送信側、受信側で交換し合い、通信を開始する。
【００５２】
（アクティブオープン）
図１１および図１２は、第１実施形態に係るアクティブオープンの処理手順の一例を示すシーケンス図である。なお、アクティブオープンは、サーバ１の方から通信先サーバ９に対して先に接続確立の要求を送信するオープン処理である。
まず、ゲストＯＳ２の通信アプリケーション２１が、ｓｏｃｋｅｔ関数を実行し（Ｓ３０１）、通信用のソケットを生成する。
そして、通信Ｉ／Ｆライブラリ処理部２３が、実行されたｓｏｃｋｅｔ関数を基に、図６のステップＳ１０２における通信Ｉ／Ｆパケット生成処理を行って、ｓｏｃｋｅｔ関数に対応する通信Ｉ／Ｆパケットを生成し、生成した通信Ｉ／Ｆパケットを通信Ｉ／Ｆドライバ３１へ送信する（Ｓ３０２：図６のＳ１０３に相当）。
【００５３】
通信Ｉ／Ｆパケットを受信した通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、図１０のステップＳ２０２の処理を行い、受信した通信Ｉ／Ｆパケットがｓｏｃｋｅｔ関数に対応するものであると判定すると、共通メモリ４上に実行している通信アプリケーション２１に対応する通信リングキュー４１を生成する（Ｓ３０３）。さらに、通信Ｉ／Ｆスイッチ処理部９０１はセッション情報を生成し、通信オフロードエンジン５のセッション管理テーブル５２に、生成したセッション情報を格納する（Ｓ３０４）。ステップＳ３０３、Ｓ３０４の処理が図１０のステップＳ２０３に相当する処理（ｓｏｃｋｅｔ関数処理）である。
そして、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、通信Ｉ／Ｆライブラリ処理部２３へリターン値を送信し（Ｓ３０５：図１０のＳ２１１に相当）、さらに、通信Ｉ／Ｆライブラリ処理部２３は通信アプリケーション２１へリターン値（ソケットの識別子）を送信する（Ｓ３０６）。
【００５４】
続いて、通信アプリケーション２１は、ｃｏｎｎｅｃｔ関数を実行する（Ｓ３０７）。
通信Ｉ／Ｆライブラリ処理部２３は、実行されたｃｏｎｎｅｃｔ関数を基に、図６のステップＳ１０２の処理により、対応する通信Ｉ／Ｆパケットを生成し、通信Ｉ／Ｆドライバ３１へ送信する（Ｓ３０８：図６のＳ１０３に相当）。
この通信Ｉ／Ｆパケットを受信した通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、図１０のステップＳ２０２の処理を行い、受信した通信Ｉ／Ｆパケットがｃｏｎｎｅｃｔ関数に対応するものであると判定すると、通信先サーバ９の宛先アドレスなどのセッション情報を通信オフロードエンジン５のセッション管理テーブル５２へ格納し、接続確立を行う（Ｓ３０９）。
【００５５】
そして、通信オフロードエンジン５のプロトコルスタックエンジン５１は、ゲストＯＳ２に該当する通信リングキュー４１にアクセスし（Ｓ３１０）、送信リングキュー７０２および受信リングキュー７０１のキューデータを取得し（Ｓ３１１）、受信に対応できるようにする（受信対応準備完了）。以下、アクセスする受信リングキュー７０１は、処理対象となっているゲストＯＳ２に対応している受信リングキュー７０１である（図９参照）。なお、各キューデータには、対応する受信バッファ７１２のメモリアドレスがあらかじめ格納されており、その他の情報は空欄となっている。
そして、通信オフロードエンジン５のプロトコルスタックエンジン５１は、接続が確立された通信先サーバ９に対して、ネットワーク８を通して、ＳＹＮ（ＳＹＮｃｈｒｏｎｉｚｅ）フラグをセットしたＴＣＰ／ＩＰパケット（ＳＹＮパケット）を送信する（図１２のＳ３１２）。
【００５６】
ＳＹＮパケットを受信した通信先サーバ９は、受信したＴＣＰ／ＩＰパケットの応答として、ＳＹＮフラグとＡＣＫ（ＡＣＫｎｏｗｌｅｄｇｅｍｅｎｔ）フラグをセットしたＴＣＰ／ＩＰパケット（ＳＹＮ−ＡＣＫパケット）をサーバ１へ送信する（Ｓ３１３）。
通信先サーバ９からＳＹＮ−ＡＣＫパケットを受信した通信オフロードエンジン５のプロトコルスタックエンジン５１は、このＴＣＰ／ＩＰパケットを受信した旨を示すＡＣＫフラグをセットしたＴＣＰ／ＩＰパケット（ＡＣＫパケット）を送り通信先サーバ９へ送信する（Ｓ３１４）
【００５７】
。
そして、通信オフロードエンジン５の割込処理部９１１は通信Ｉ／Ｆドライバ３１の割込処理部９０２へ、接続確立完了割込を通知し（Ｓ３１５）、接続確立完了割込を受信した通信Ｉ／Ｆドライバ３１の割込処理部９０２は通信オフロードエンジン５の割込処理部９１１へ接続確立完了割込を受けたことを通知する割込クリアする（Ｓ３１６）ことにより接続確立完了割込の通知を受け取ったことを通信オフロードエンジン５へ通知する。なお、ステップＳ３０９〜Ｓ３１６の処理が図１０のステップＳ２０７の処理（ｃｏｎｎｅｃｔ関数処理）に該当する。
【００５８】
続いて、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、接続確立が完了したことを示すリターン値を通信Ｉ／Ｆライブラリ処理へ送信し（Ｓ３１７：図１０のＳ２１１に相当）、通信Ｉ／Ｆライブラリ処理部２３は通信アプリケーション２１へリターン値を送信する（Ｓ３１８：図６のＳ１０５に相当）ことにより、接続確立完了を通信アプリケーション２１へ通知する。
以上が、アクティブオープンのシーケンスである。仮想システムＺは、このシーケンスにより、通信データの送受信が可能となる。
【００５９】
（パッシブオープン）
図１３〜図１５は、第１実施形態に係るパッシブオープンの処理手順の一例を示すシーケンス図である。パッシブオープンは、相手が自分に対して先に接続確立の要求を送信するオープン処理である。
まず、ゲストＯＳ２の通信アプリケーション２１が、ｓｏｃｋｅｔ関数を実行する（Ｓ４０１）。
そして、通信Ｉ／Ｆライブラリ処理部２３が、生成されたｓｏｃｋｅｔ関数を基に、図６のステップＳ１０２における通信Ｉ／Ｆパケット生成処理を行って、ｓｏｃｋｅｔ関数に対応する通信Ｉ／Ｆパケットを生成し、生成した通信Ｉ／Ｆパケットを通信Ｉ／Ｆドライバ３１へ送信する（Ｓ４０２：図６のＳ１０３に相当）。
【００６０】
通信Ｉ／Ｆパケットを受信した通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、図１０のステップＳ２０２の処理を行い、受信した通信Ｉ／Ｆパケットがｓｏｃｋｅｔ関数に対応するものであると判定すると、共通メモリ４上に通信リングキュー４１を生成し（Ｓ４０３）、セッション情報を生成し、通信オフロードエンジン５のセッション管理テーブル５２に、生成したセッション情報を格納する（Ｓ４０４）。なお、ステップＳ４０３、４０４の処理が図１０のステップＳ２０３の処理（ｓｏｃｋｅｔ関数処理）に該当する。
そして、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、通信Ｉ／Ｆライブラリ処理部２３へリターン値（ソケットの識別子）を送信し（Ｓ４０５：図１０のＳ２１１に相当）、さらに通信Ｉ／Ｆライブラリ処理部２３は通信アプリケーション２１へリターン値を送信する（Ｓ４０６：図６のＳ１０５に相当）。
【００６１】
次に、通信アプリケーション２１は、ｂｉｎｄ関数を実行する（Ｓ４０７）。
通信Ｉ／Ｆライブラリ処理部２３は、実行されたｂｉｎｄ関数を、図６のステップＳ１０２の通信Ｉ／Ｆパケット生成処理により、対応する通信Ｉ／Ｆパケットを生成し、通信Ｉ／Ｆドライバ３１へ送信する（Ｓ４０８：：図６のＳ１０３に相当）。
この通信Ｉ／Ｆパケットを受信した通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、図１０のステップＳ２０２の処理を行い、受信した通信Ｉ／Ｆパケットがｂｉｎｄ関数に対応するものであると判定すると、セッション情報を生成し、生成したセッション情報をセッション管理テーブル５２に格納する（Ｓ４０９）。なお、ステップＳ４０９の処理が図１０のステップＳ２０４の処理（ｂｉｎｄ関数処理）に該当する。
続いて、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、リターン値を通信Ｉ／Ｆライブラリ処理部２３へ送信し（Ｓ４１０：図１０のＳ２１１に相当）、さらに、通信Ｉ／Ｆライブラリ処理部２３はリターン値を通信アプリケーション２１へ送信する（Ｓ４１１：図６のＳ１０５に相当）ことで、セッション情報の格納が完了したことを通信アプリケーション２１へ通知する。
【００６２】
続いて、通信アプリケーション２１はｌｉｓｔｅｎ関数を実行する（図１４のＳ４１２）。
通信Ｉ／Ｆライブラリ処理部２３は、実行されたｌｉｓｔｅｎ関数を、図６のステップＳ１０２の通信Ｉ／Ｆパケット生成処理を行うことによって、対応する通信Ｉ／Ｆパケットを生成し、通信Ｉ／Ｆドライバ３１へ送信する（Ｓ４１３：図６のＳ１０３に相当）。
この通信Ｉ／Ｆパケットを受信した通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、図１０のステップＳ２０２の処理を行い、受信した通信Ｉ／Ｆパケットがｌｉｓｔｅｎ関数に対応するものであると判定すると、通信オフロードエンジン５のセッション管理テーブル５２に対して受信確立フラグをセットする（Ｓ４１４）。これにより、通信オフロードエンジン５は、通信先サーバ９からの接続確立を受けることができる。
そして、通信オフロードエンジン５のプロトコルスタックエンジン５１は、通信リングキュー４１にアクセスし（Ｓ４１５）、送信リングキュー７０２および受信リングキュー７０１のキューデータを取得し（Ｓ４１６）、受信に対応できるようにする（受信対応準備完了）。なお、各キューデータには、対応する受信バッファ７１２のメモリアドレスがあらかじめ格納されており、その他の情報は空欄となっている。
【００６３】
ステップＳ４１６が終了すると、通信オフロードエンジン５の割込処理部９１１は、受信準備完了を通知するための受信準備完了割込を通信Ｉ／Ｆドライバ３１へ送信する（Ｓ４１７）。
受信対応準備完了の通知を受信した通信Ｉ／Ｆドライバ３１の割込処理部９０２は、割込クリアする（Ｓ４１８）ことにより受信対応準備完了の通知を受け取ったことを通信オフロードエンジン５へ通知する。なお、ステップＳ４１４〜Ｓ４１８の処理が図１０のステップＳ２０５（ｌｉｓｔｅｎ関数処理）の処理に該当する。
【００６４】
その後、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、ｌｉｓｔｅｎ関数処理が終了したことを示すリターン値を通信Ｉ／Ｆライブラリ処理部２３へ送信し（Ｓ４１９：図１０のＳ２１１に相当）、通信Ｉ／Ｆライブラリ処理部２３は通信アプリケーション２１へリターン値を送信する（Ｓ４２０：図６のＳ１０５に相当）ことで、受信対応準備完了を通信アプリケーション２１へ通知する。
【００６５】
ｌｉｓｔｅｎ関数処理のリターン値を受信することで、受信対応準備完了の通知を受信した通信アプリケーション２１はａｃｃｅｐｔ関数を実行する（Ｓ４２１）。
そして、通信Ｉ／Ｆライブラリ処理部２３が、生成されたａｃｃｅｐｔ関数を基に、図６のステップＳ１０２における通信Ｉ／Ｆパケット生成処理を行って、ａｃｃｅｐｔ関数に対応する通信Ｉ／Ｆパケットを生成し、生成した通信Ｉ／Ｆパケットを通信Ｉ／Ｆドライバ３１へ送信する（Ｓ４２２：図６のＳ１０３に相当）。
通信Ｉ／Ｆパケットを受信した通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、図１０のステップＳ２０２の処理を行い、受信した通信Ｉ／Ｆパケットがａｃｃｅｐｔ関数に対応するものであると判定すると、通信先サーバ９との接続確立待機状態となる（Ｓ４２３）。
【００６６】
通信先サーバ９が、サーバ１に対し、ＳＹＮフラグがセットされたＴＣＰ／ＩＰパケット（ＳＹＮパケット）をネットワーク８を介して送信し（図１５のＳ４２４）、通信オフロードエンジン５のプロトコルスタックエンジン５１が、このＳＹＮパケットを受信すると、通信オフロードエンジン５の割込処理部９１１は、接続確立を通知するための接続確立割込を通信Ｉ／Ｆドライバ３１へ送信する（Ｓ４２５）。
そして、通信Ｉ／Ｆドライバ３１の割込処理部９０２は、割込クリアする（Ｓ４２６）ことにより接続確立割込の通知を受け取ったことを通信オフロードエンジン５へ通知する。
【００６７】
続いて、通信オフロードエンジン５のプロトコルスタックエンジン５１は、通信先サーバ９へ接続確立を通知するＳＹＮフラグとＡＣＫフラグをセットしたＴＣＰ／ＩＰパケット（ＳＹＮ−ＡＣＫパケット）を通信先サーバ９へ送信する（Ｓ４２７）。
通信先サーバ９は、ＳＹＮ−ＡＣＫパケットを受信すると、このＴＣＰ／ＩＰパケットを受信したことを通知するためのＡＣＫフラグをセットしたＴＣＰ／ＩＰパケット（ＡＣＫパケット）を通信先サーバ９へ送信する（Ｓ４２８）。
【００６８】
ＡＣＫパケットを受信したサーバ１における通信オフロードエンジン５の割込処理部９１１は、通信Ｉ／Ｆドライバ３１へ接続確立成功割込を送信する（Ｓ４２９）。
通信Ｉ／Ｆドライバ３１の割込処理部９０２は、割込クリアする（Ｓ４３０）ことにより信確立成功割込の通知を受け取ったことを通信オフロードエンジン５へ通知する。
そして、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、新たに通信リングキュー４１を共通メモリ４上に生成する（Ｓ４３１）。
【００６９】
そして、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、通信用の通信リングキュー４１を共通メモリ４上に生成した旨を通信オフロードエンジン５に通知することでサーバ１と通信先サーバ９との間の通信用セッションを生成する（Ｓ４３２）。
続いて、通信オフロードエンジン５のプロトコルスタックエンジン５１は、ステップＳ４３１で生成された通信リングキュー４１にアクセスし（Ｓ４３３）、通信リングキュー４１からデータを取得する（Ｓ４３４）ことによって通信可能状態となる。なお、ステップＳ４２３〜Ｓ４３４の処理が図１０のステップＳ２０６の処理（ａｃｃｅｐｔ関数処理）に該当する。
【００７０】
そして、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、新たに生成したソケットの識別子をリターン値として通信Ｉ／Ｆライブラリ処理部２３へ送信し（Ｓ４３５）、さらに通信Ｉ／Ｆライブラリ処理部２３は、このリターン値を通信アプリケーション２１１へ送信し（Ｓ４３６）、パッシブオープン処理を終了する。
以上が、パッシブオープンのシーケンスである。仮想システムＺは、このシーケンスにより、通信データの送受信が可能となる。
【００７１】
（送信処理）
図１６は、第１実施形態に係るデータ送信処理の処理手順の一例を示すシーケンス図である。
前記したアクティブオープンあるいはパッシブオープンによる接続確立後に図１６の処理が実行される。
まず、送信処理に先立って、通信アプリケーション２１は送信する通信データを生成し、共通メモリ４（送信バッファ）上に通信データを格納するための領域を確保し、送信バッファ７１１に通信データを格納すると、格納した送信バッファ７１１のメモリアドレスを取得する。
そして、通信アプリケーション２１がｓｅｎｄ関数を実行する（Ｓ５０１）。このとき、ｓｅｎｄ関数の引数には、通信データを格納した送信バッファ７１１のメモリアドレスが設定される。
続いて、通信Ｉ／Ｆライブラリ処理部２３が、生成されたｓｅｎｄ関数を基に、図６のステップＳ１０２における通信Ｉ／Ｆパケット生成処理を行って、ｓｅｎｄ関数に対応する通信Ｉ／Ｆパケットを生成し、生成した通信Ｉ／Ｆパケットを通信Ｉ／Ｆドライバ３１へ送信する（Ｓ５０２：図６のＳ１０３に相当）。
【００７２】
通信Ｉ／Ｆパケットを受信した通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、図１０のステップＳ２０２の処理を行い、受信した通信Ｉ／Ｆパケットがｓｅｎｄ関数に対応するものであると判定すると、送信リングキュー７０２に送信する通信データのサイズ（送信データサイズ（図８））と、通信データが格納されている送信バッファ７１１のメモリアドレス（送信バッファアドレス（図８））を格納し（Ｓ５０３）、該当するキューのフラグを「有効」とする。なお、前記したように通信Ｉ／Ｆパケットには、通信関数の引数が設定されているので、送信バッファ７１１のアドレスや、通信データのサイズも通信Ｉ／Ｆパケットに設定されている。
【００７３】
その後、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は通信オフロードエンジン５へデータ送信要求を送信する（Ｓ５０４）。このとき、送信を連続して実行する場合は、その都度データ送信要求を通信オフロードエンジン５へ送信せずに、通信オフロードエンジン５が次々と送信リングキュー７０２のフラグを確認し、フラグが「有効」となっているキューに該当する送信バッファ７１１の通信データを通信先サーバ９へ送信するようにしてもよい。
【００７４】
データ送信要求を受信した通信オフロードエンジン５のプロトコルスタックエンジン５１は、送信リングキュー７０２にアクセスし（Ｓ５０５）、送信リングキュー７０２のデータを取得する（Ｓ５０６）。
そして、通信オフロードエンジン５のプロトコルスタックエンジン５１は、送信リングキュー７０２における送信バッファアドレス（図８）に該当する通信バッファ４２の送信バッファ７１１にアクセスし（Ｓ５０７）、送信リングキュー７０２における送信データサイズ（図８）分の通信データを取得する（Ｓ５０８）。
【００７５】
そして、通信オフロードエンジン５のプロトコルスタックエンジン５１は、取得した通信データから送信パケットを生成し（Ｓ５０９）、送信リングキュー７０２における宛先アドレス（図８）を基に、通信先サーバ９へ送信パケットを送信する（Ｓ５１０）。
そして、通信先サーバ９は、通信データ（すべての通信パケット）を受信すると、データを受信した旨をＡＣＫフラグをセットしたＴＣＰ／ＩＰパケット（ＡＣＫパケット）としてサーバ１へ送信する（Ｓ５１１）
【００７６】
ＡＣＫパケットを受信した通信オフロードエンジン５の割込処理部９１１は、送信完了を通知するための送信完了割込を通信Ｉ／Ｆドライバ３１へ通知する（Ｓ５１２）。
通信Ｉ／Ｆドライバ３１の割込処理部９０２は、割込クリアを通信オフロードエンジン５へ送信する（Ｓ５１３）ことにより、送信完了割込の通知を受け取ったことを通信オフロードエンジン５へ通知する。なお、ステップＳ５０３〜Ｓ５１３の処理が図１０のステップＳ２０８の処理（ｓｅｎｄ関数処理）に該当する。
その後、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は通信Ｉ／Ｆライブラリ処理部２３へ送信できた通信データのバイト数をリターン値として送信し（Ｓ５１４：図１０のＳ２１１に相当）、通信Ｉ／Ｆライブラリ処理部２３は通信アプリケーション２１へ送信できた通信データのサイズをリターン値として送信する（Ｓ５１５：図６のＳ１０５に相当）。
以上が、データ送信のシーケンスである。仮想システムＺは、このシーケンスにより、通信データを通信先サーバ９へ送信する。
【００７７】
（別の送信形態例１）
なお、本実施形態では、通信アプリケーション２１が通信データを格納するための共通メモリ４上の領域（つまり、送信バッファ７１１）を確保しているが、これに限らず、以下のような処理としてもよい。
すなわち、通信アプリケーション２１ではなく、通信Ｉ／Ｆドライバ３１が、予め共通メモリ４上に領域を確保しておき、そのメモリアドレスを通信アプリケーション２１へ送信する。通信アプリケーション２１は、ｓｅｎｄ関数を実行する際に、通信Ｉ／Ｆドライバ３１から取得したメモリアドレスを引数として実行するとともに、送信する通信データを通信Ｉ／Ｆドライバ３１から送信されたメモリアドレスへ格納する。以降は、図１６のステップＳ５０１〜Ｓ５１５の処理が行われるようにしてもよい。
【００７８】
（これまで用いられていた一般的な送信処理）
ここで、これまで用いられていた一般的な送信処理を説明する。
（ａ１）送信処理に先立って、通信アプリケーションは送信する通信データを生成し、メモリ上に通信データを格納するための領域を確保し、送信バッファに通信データを格納する。
（ａ２）通信アプリケーションが、通信データを格納したメモリのメモリアドレスを引数としたｓｅｎｄ関数を実行する。
（ａ３）ゲストＯＳで実行されているプロトコルスタックが、自身が予め確保してあるメモリ上の領域に、ｓｅｎｄ関数の引数として設定されているメモリアドレスに格納されている通信データをコピーする（１回目のデータコピー）。
（ａ４）プロトコルスタックは、コピーした通信データから通信パケットを生成する。
（ａ５）プロトコルスタックは、ドライバＯＳへ生成した通信パケットをコピーする（２回目のデータコピー）。
（ａ６）ドライバＯＳは、通信パケットをネットワークカードへ転送し、ネットワークカードが通信先サーバへ通信パケットを送信する。
【００７９】
このように、これまで用いられていた一般的な送信処理では、送信処理の際に２回のデータコピーが発生している。これに対し、本実施形態に係る送信処理では、送信リングキュー７０２の送信バッファアドレス（図８）に通信データが格納されている送信バッファ７１１のメモリアドレス（送信バッファアドレス）が格納され、通信Ｉ／Ｆドライバ３１、通信オフロードエンジン５は、この送信バッファアドレスを参照して通信データを読み込んで、送信する。このため、通信アプリケーション２１が送信バッファ７１１へ通信データを格納してから、通信オフロードエンジン５が通信データ（通信パケット）を送信するまで、通信データが他の場所へコピーされることはない。つまり、本実施形態に係る送信処理ではデータコピーは発生しない。
【００８０】
（別の送信形態例２）
また、仮想システムＺは本実施形態の送信処理において、以下のような処理をしてもよい。
（ｂ１）通信Ｉ／Ｆドライバ３１は、予め共通メモリ４上に通信データを格納するための領域（これが、送信バッファ７１１となる）を確保しておき、その領域のメモリアドレスを保持している。
（ｂ２）通信アプリケーション２１が送信する通信データを生成し、通信アプリケーション２１が確保している共通メモリ４上の領域（通信Ｉ／Ｆドライバ３１が確保している領域とは別）に通信データを格納する。
以下、図１６のステップＳ５０１、Ｓ５０２の処理が行われ、通信Ｉ／Ｆドライバ３１は、通信アプリケーション２１が通信データを格納したメモリアドレスを有している通信Ｉ／Ｆパケットを受信する。通信Ｉ／Ｆドライバ３１は、通信Ｉ／Ｆパケットにおけるメモリアドレスから、通信データを取得すると、自身が確保した領域（送信バッファ７１１）にコピーする（データコピー）。
そして、通信Ｉ／Ｆドライバ３１は、コピーした領域（送信バッファ７１１）のメモリアドレスを、送信バッファアドレスとして送信リングキュー７０２に格納する。
以下、図１６と同様にして、通信データが送信される。
【００８１】
この方法では、データコピーが１回発生しているが、２回のデータコピーが発生する一般的な送信処理よりも、データコピーの回数を少なくすることができる。
【００８２】
（受信処理）
図１７は、第１実施形態に係るデータ受信処理の処理手順の一例を示すシーケンス図である。図１７の処理は、図１１、図１２のアクティブオープンあるいは図１３〜図１５のパッシブオープンによる接続確立後に実行される。
受信処理に先立って、通信アプリケーション２１は、共通メモリ４上に通信データを格納するための領域を確保する。
まず、通信アプリケーション２１がｒｅｃｖ（ｒｅｃｅｉｖｅ）関数を実行する（Ｓ６０１）。このｒｅｃｖ関数には、受信した通信データが格納される受信バッファ７１２のメモリアドレスが設定されている。
続いて、通信Ｉ／Ｆライブラリ処理部２３が、実行されたｒｅｃｖ関数を基に、図６のステップＳ１０２における通信Ｉ／Ｆパケット生成処理を行って、ｒｅｃｖ関数に対応する通信Ｉ／Ｆパケットを生成し、生成した通信Ｉ／Ｆパケットを通信Ｉ／Ｆドライバ３１へ送信する（Ｓ６０２：図６のＳ１０３に相当）。この通信Ｉ／Ｆパケットには、ｒｅｃｖ関数に設定されている受信した通信データが格納される受信バッファ７１２のメモリアドレスが通信情報の１つとして設定される。
【００８３】
通信Ｉ／Ｆパケットを受信した通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、図１０のステップＳ２０２の処理を行い、受信した通信Ｉ／Ｆパケットがｒｅｃｖ関数に対応するものであると判定した後、通信Ｉ／Ｆパケットの通信情報を通信リングキュー４２の受信リングキュー７０２に格納し（Ｓ６０３）、受信待機状態となる（Ｓ６０４）。ステップＳ６０３の処理において、通信Ｉ／Ｆスイッチ処理部９０１は、通信Ｉ／Ｆパケットに設定されている受信バッファ７１２のメモリアドレスを、受信バッファアドレス（図８）として、受信リングキュー７０１に格納する。このとき、通信Ｉ／Ｆスイッチ処理部９０１は、格納したキューと対応しているｒｅｓｖ関数（通信アプリケーションプロセス９５１）を記憶しておく。
【００８４】
そして、通信先サーバ９がサーバ１へ通信データをＴＣＰ／ＩＰパケットとして送信し（Ｓ６０５）、通信オフロードエンジン５のプロトコルスタックエンジン５１が、この通信データを受信すると、「無効」となっている受信リングキュー７０１を参照し、そのキューの受信バッファアドレス（図８）が示す受信バッファ７１２に通信データを格納し（Ｓ６０６）、該当するキューのフラグを「有効」にする。このとき、プロトコルスタックエンジン５１は、受信した通信データのサイズを、受信リングキュー７０１の受信データサイズ（図８）に格納する。
通信データの格納が完了すると、通信オフロードエンジン５のプロトコルスタックエンジン５１は通信先サーバ１に対して、ＡＣＫフラグをセットしたＴＣＰ／ＩＰパケット（ＡＣＫパケット）を送信する（Ｓ６０７）。
【００８５】
ＡＣＫパケットの送信後、通信オフロードエンジン５の割込処理部９１１は受信完了を通知するための受信完了割込を通信Ｉ／Ｆドライバ３１へ送信する（Ｓ６０８）。なお、連続受信している場合、通信オフロードエンジン５のプロトコルスタックエンジン５１は、受信完了割込を受信のたびに送信しなくてもよく、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１が、一定時間毎に、受信リングキュー７０１のフラグを確認し、フラグが「有効」となっているキューが存在したら、割込処理部９１１は受信完了を通知するための受信完了割込を通信Ｉ／Ｆドライバ３１へ送信するようにしてもよい。
【００８６】
受信完了割込を受信した通信Ｉ／Ｆドライバ３１の割込処理部９０２は、割込クリアを通信オフロードエンジン５へ送信する（Ｓ６０９）ことにより受信完了割込の通知を受け取ったことを通信オフロードエンジン５へ通知する。
そして、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、受信リングキュー７０１へアクセスし（Ｓ６１０）、フラグが「有効」となっているキューがあると、そのキューのキューデータを取得して（Ｓ６１１）、受信データサイズに格納されている受信した通信データのサイズを取得する。そして、通信Ｉ／Ｆスイッチ処理部９０１は、このキューに対応するｒｅｃｖ関数（通信アプリケーションプロセス９５１）へ向け、通信Ｉ／Ｆライブラリ処理部２３へリターン値を送信し（Ｓ６１２：図１０のＳ２１１に相当）、通信Ｉ／Ｆライブラリ処理部２３は通信アプリケーション２１へリターン値を送信する（Ｓ６１３：図６のＳ１０５に相当）。このリターン値は、受信した通信データのサイズである。リターン値を受信した通信アプリケーション２１は、自身が実行したｒｅｃｖ関数の引数に設定されていたメモリアドレスから、リターン値として取得したサイズ分のデータ（通信データ）を取得する（Ｓ６１４）。
以上が、データ受信のシーケンスである。このシーケンスにより、通信データを受信する。
【００８７】
（別の受信形態例１）
また、本実施形態では、ｒｅｃｖ関数の実行にともなう通信Ｉ／Ｆパケットによって、通信Ｉ／Ｆドライバ３１に受信のための領域（受信バッファ７１２）のメモリアドレスが通知されるが、ｒｅｃｖ関数の実行前に、予め通信Ｉ／Ｆドライバ３１へ通信アプリケーション２１が確保した領域（受信バッファ７１２）のメモリアドレスが通知されてもよい。この通知の際には、通信Ｉ／Ｆライブラリ処理部２３によって生成された通信Ｉ／Ｆパケットに当該メモリアドレスが設定されることによって、通信Ｉ／Ｆドライバ３１への通知が行われる。
この場合、通信Ｉ／Ｆドライバ３１が通知されたメモリアドレスを、受信リングキュー７０１の受信バッファアドレス（図８）に格納した後に、通信アプリケーション２１がｒｅｃｖ関数を実行することとなる。このときのｒｅｃｖ関数は、通信Ｉ／Ｆドライバ３１へ通知されたメモリアドレスが引数として設定される。
なお、この例では、ｒｅｃｖ関数の実行前に、通信オフロードエンジン５が通信先サーバ９から通信データを受信し、受信バッファアドレスが示す受信バッファ７１２に通信データを格納することも可能である。
なお、この場合、図６および図１０の処理を行わなくてもよい。
【００８８】
（これまで用いられていた一般的な受信処理）
ここで、これまで用いられていた一般的な受信処理を説明する。
（ｃ１）通信アプリケーションがｒｅｃｖ関数を実行する。このｒｅｃｖ関数には受信バッファへのメモリアドレスが引数として設定されている。
（ｃ２）ネットワークカードが、通信先サーバからの通信データ（通信パケット）を受信すると、ネットワークカードはドライバＯＳへ通信データ（通信パケット）を転送する。なお、通信データの受信後に、通信アプリケーションがｒｅｃｖ関数を実行してもよい。
（ｃ３）ドライバＯＳは、転送された通信データ（通信パケット）をゲストＯＳのプロトコルスタックへコピーする（１回目のデータコピー）。
（ｃ４）プロトコルスタックは、コピーされた通信データ（通信パケット）をパケット処理すると、ｒｅｃｖ関数で引数として設定されているメモリアドレスへ、通信データをコピーする（２回目のデータコピー）。
（ｃ５）プロトコルスタックは、受信した通信データのサイズをリターン値として、通信アプリケーションへ送信する。
【００８９】
このように、これまで用いられていた一般的な受信処理では、受信処理の際に２回のデータコピーが発生している。これに対し、本実施形態に係る受信処理では、受信リングキュー７０１の受信バッファアドレス（図８）に、通信データが格納されている受信バッファ７１２のメモリアドレス（送信バッファアドレス）が格納され、通信オフロードエンジン５は、この受信バッファアドレスが示す受信バッファ７１２に受信した通信データを格納する。
そして、通信アプリケーション２１は、この受信バッファアドレスを基に、通信データを読み出す。
このため、通信オフロードエンジン５が受信バッファ７１２へ通信データを格納してから、通信アプリケーション２１が通信データ（通信パケット）を読み出すまで、通信データが他の場所へコピーされることはない。つまり、本実施形態に係る受信処理ではデータコピーは発生しない。
【００９０】
（受信形態例２）
また、仮想システムＺは本実施形態の受信処理において、以下のような処理をしてもよい。
（ｄ１）通信アプリケーション２１は、共通メモリ４上に通信データを格納するための領域を確保する。
（ｄ２）通信Ｉ／Ｆドライバ３１は、共通メモリ４上に通信データを格納するための領域を確保し、受信リングキュー７０１の受信バッファアドレス（図８）に、この領域のメモリアドレスを格納する。なお、通信Ｉ／Ｆドライバ３１が確保する領域は、通信アプリケーション２１が確保する領域とは異なるものである。通信Ｉ／Ｆドライバ３１が確保する領域が、受信バッファ７１２となる。なお、（１）、（２）の処理順番は逆でもよい。
（ｄ３）通信アプリケーション２１がｒｅｃｖ関数を実行する。ｒｅｃｖ関数の引数は、通信アプリケーション２１が確保した領域のメモリアドレスが設定される。
（ｄ４）通信Ｉ／Ｆライブラリ処理部２３は、ｒｅｃｖ関数の引数であるメモリアドレスを有する通信Ｉ／Ｆパケットを生成し、通信Ｉ／Ｆドライバ３１へ送信する。
【００９１】
（ｄ４）通信オフロードエンジン５が、通信先サーバ９から通信データを受信すると、図１７のＳ６０４〜Ｓ６０８と同様の処理が行われる。なお、（３）、（４）の処理順番は逆でもよい。
（ｄ５）通信Ｉ／Ｆドライバ３１は、「有効」となっている受信リングキュー７０１のキューがあれば、そのキューの受信バッファアドレスが示す受信バッファ７１２から通信データを取得し、その通信データを、受信した通信Ｉ／Ｆパケットの（つまり、ｒｅｃｖ関数の引数で示されている）メモリアドレスへコピーする（データコピー）。つまり、通信Ｉ／Ｆドライバ３１は、受信バッファ７１２から取得した通信データを、通信アプリケーション２１が確保した共通メモリ４上の領域へコピーする。また、処理対象となっているキューの受信データサイズから通信データのサイズを取得する。
（ｄ６）通信Ｉ／Ｆドライバ３１は、受信した通信データのサイズをリターン値として、通信Ｉ／Ｆライブラリ処理部２３を介して、通信アプリケーション２１へリターン値を送信する。
（ｄ７）通信アプリケーション２１は、ｒｅｃｖ関数の引数として設定したメモリアドレスから、リターン値として取得したサイズ分の通信データを取得する。
なお、この場合、図６および図１０の処理を行わなくてもよい。
【００９２】
この方法では、データコピーが１回発生しているが、２回のデータコピーが発生する一般的な受信処理よりも、データコピーの回数を少なくすることができる。
【００９３】
（アクティブクローズ）
ＴＣＰ／ＩＰの通信では、送受信の通信の終了処理として通信終了シーケンスが必要となるが、図１８および図１９を参照して、通信終了処理としてもクローズ処理を説明する。
図１８は、第１実施形態に係るアクティブクローズの処理手順の一例を示すシーケンス図である。アクティブクローズとは、サーバ１がクローズ処理を行う処理である。
まず、通信アプリケーション２１が、ｃｌｏｓｅ関数を実行する（Ｓ７０１）。
続いて、通信Ｉ／Ｆライブラリ処理部２３が、実行されたｃｌｏｓｅ関数を基に、図６のステップＳ１０２における通信Ｉ／Ｆパケット生成処理を行って、ｃｌｏｓｅ関数に対応する通信Ｉ／Ｆパケットを生成し、生成した通信Ｉ／Ｆパケットを通信Ｉ／Ｆドライバ３１へ送信する（Ｓ７０２：図６のＳ１０３に相当）。
通信Ｉ／Ｆパケットを受信した通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、図１０のステップＳ２０２の処理を行い、受信した通信Ｉ／Ｆパケットがｃｌｏｓｅ関数に対応するものであると判定すると、通信オフロードエンジン５へセッションのクローズを指示する（Ｓ７０３）。
【００９４】
クローズ処理を指示された通信オフロードエンジン５のプロトコルスタックエンジン５１は、ＦＩＮ（ＦＩＮｉｓｈ）フラグをセットしたＴＣＰ／ＩＰパケット（ＦＩＮパケット）を通信先サーバ９へ送信する（Ｓ７０４）。
ＦＩＮパケットを受信した通信先サーバ９は、ＦＩＮフラグと、ＡＣＫフラグをセットしたＴＣＰ／ＩＰパケット（ＦＩＮ−ＡＣＫパケット）をサーバ１へ送信する（Ｓ７０５）。
ＦＩＮ−ＡＣＫパケットを受信した通信オフロードエンジン５のプロトコルスタックエンジン５１は、該パケットを受信したことを通信先サーバ９へ伝えるため、ＡＣＫフラグをセットしたＴＣＰ／ＩＰパケット（ＡＣＫパケット）を通信先サーバ９へ送信する（Ｓ７０６）。
【００９５】
ＡＣＫパケットを送信した通信オフロードエンジン５の割込処理部９１１は、終了（クローズ）処理完了を通知するための終了処理完了割込を通信Ｉ／Ｆドライバ３１へ送信する（Ｓ７０７）。
通信Ｉ／Ｆドライバ３１の割込処理部９０２は、割込クリアをする（Ｓ７０８）ことにより終了処理完了割込の通知を受け取ったことを通信オフロードエンジン５へ通知する。
そして、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、共通メモリ４の通信リングキュー４１をクリアし（Ｓ７０９）、通信オフロードエンジン５のセッション管理テーブル５２をクリアする（Ｓ７１０）ことによりセッション情報をクリアする。なお、ステップＳ７０３〜Ｓ７１０の処理が図１０のステップＳ２１０の処理（ｃｌｏｓｅ関数処理）に該当する。
【００９６】
そして、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、通信終了処理の完了を示すリターン値を通信Ｉ／Ｆライブラリ処理部２３へ送信し（Ｓ７１１：図１０のＳ２１１に相当）、さらに、通信Ｉ／Ｆライブラリ処理部２３は、このリターン値を通信アプリケーション２１へ送信する（Ｓ７１２：図６のＳ１０５に相当）。
以上が、アクティブクローズのシーケンスである。仮想システムＺは、このシーケンスにより、通信のクローズが可能となる。
【００９７】
（パッシブクローズ処理）
図１９は、第１実施形態に係るパッシブクローズの処理手順の一例を示すシーケンス図である。パッシブクローズは、通信先サーバ９が先に通信終了を送信するクローズ処理である。
まず、通信先サーバ９が、ＦＩＮフラグをセットしたＴＣＰ／ＩＰパケット（ＦＩＮパケット）をサーバ１へ送信する（Ｓ８０１）。
ＦＩＮパケットを受信した通信オフロードエンジン５のプロトコルスタックエンジン５１は、ＡＣＫフラグをセットしたＴＣＰ／ＩＰパケット（ＡＣＫパケット）を通信先サーバ９へ送信する（Ｓ８０２）。
そして、通信オフロードエンジン５の割込処理部９１１は、ＦＩＮパケットを受信したことを通知するための終了通知受信割込を通信Ｉ／Ｆドライバ３１へ送信する（Ｓ８０３）。
割り込みを受信した通信Ｉ／Ｆドライバ３１の割込処理部９０２は、割込クリアする（Ｓ８０４）ことにより終了通知受信割込の通知を受け取ったことを通信オフロードエンジン５へ通知する。
【００９８】
その後、通信アプリケーション２１がｃｌｏｓｅ関数を実行する（Ｓ８０５）。
続いて、通信Ｉ／Ｆライブラリ処理部２３が、生成されたｃｌｏｓｅ関数を基に、図６のステップＳ１０２における通信Ｉ／Ｆパケット生成処理を行って、ｃｌｏｓｅ関数に対応する通信Ｉ／Ｆパケットを生成し、生成した通信Ｉ／Ｆパケットを通信Ｉ／Ｆドライバ３１へ送信する（Ｓ８０６：図６のＳ１０３に相当）。
通信Ｉ／Ｆパケットを受信した通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は図１０のステップＳ２０２の処理を行い、受信した通信Ｉ／Ｆパケットがｃｌｏｓｅ関数に対応するものであると判定すると、通信オフロードエンジン５へクローズ処理を指示する（Ｓ８０７）。
【００９９】
クローズ処理を指示された通信オフロードエンジン５のプロトコルスタックエンジン５１は、通信先サーバ９へＦＩＮフラグをセットしたＴＣＰ／ＩＰパケット（ＦＩＮパケット）を送信する（Ｓ８０８）。なお、ステップＳ８０２が省略されて、ステップＳ８０３〜Ｓ８０７が行われ、ステップＳ８０８の段階で、プロトコルスタックエンジン５１はステップＳ８０２におけるＡＣＫパケットと、ステップＳ８０８におけるＦＩＮパケットを合わせたＦＩＮ−ＡＣＫパケットを通信サーバ９へ送信するようにしてもよい。
【０１００】
ＦＩＮパケットを受信した通信先サーバ９は、ＡＣＫフラグをセットしたＴＣＰ／ＩＰパケット（ＡＣＫパケット）をサーバ１へ送信する（Ｓ８０９）ことによって、ＦＩＮパケットを受信したことをサーバ１へ通知する。
ＡＣＫパケットを受信した通信オフロードエンジン５の割込処理部９１１は、終了（クローズ）処理完了を通知するための終了処理完了割込を通信Ｉ／Ｆドライバ３１へ送信する（Ｓ８１０）。
そして、通信Ｉ／Ｆドライバ３１の割込処理部９０２は、通信オフロードエンジン５へ割込クリアする（Ｓ８１１）ことにより終了処理完了割込の通知を受け取ったことを通信オフロードエンジン５へ通知する。
【０１０１】
その後、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、通信リングキュー４１をクリアし（Ｓ８１２）、通信オフロードエンジン５のセッション管理テーブル５２をクリアする（Ｓ８１３）ことにより、セッション情報をクリアする。なお、ステップＳ８０７〜Ｓ８１３の処理が図１０のステップＳ２１０の処理（ｃｌｏｓｅ処理）に該当する。
そして、通信Ｉ／Ｆドライバ３１の通信Ｉ／Ｆスイッチ処理部９０１は、通信終了処理の完了を示すリターン値を通信Ｉ／Ｆライブラリ処理部２３へ送信し（Ｓ８１４：図１０のＳ２１１に相当）、さらに、通信Ｉ／Ｆライブラリ処理部２３は、このリターン値を通信アプリケーション２１へ返す（Ｓ８１５：図６のＳ１０５に相当）。
以上が、パッシブクローズのシーケンスである。このシーケンスにより、通信のクローズが可能となる。
【０１０２】
［まとめ］
第１実施形態によれば、通信バッファ４２のメモリアドレス（例えば、Ｃ言語におけるポインタ）で通信データのやりとりが管理され、通信バッファ４２に格納されている通信データ本体は移動しない（コピー）されないこととなり、通信データのコピーに関するプロセッサ負荷を低減することができる。すなわち、通信処理によるゲストＯＳ２やドライバＯＳ３のプロセッサ負荷やメモリアクセス負荷などの処理オーバヘッドを改善し、ゲストＯＳ２が動作するサーバ１全体の通信処理負荷の軽減と通信性能を向上させることができる。
【０１０３】
また、第１実施形態によれば、既存の通信関数（ソケット関数など）を通信Ｉ／Ｆライブラリ処理部２３で、通信Ｉ／Ｆパケットに変換して利用することで、ゲストＯＳ２上で動作する通信アプリケーション２１の変更や、使用する通信関数を新しくすることなしに、本実施形態に係る通信Ｉ／Ｆドライバ３１および通信オフロードエンジン５を導入することが可能となる。
そして、通信データのコピーに関するプロセッサ負荷の軽減に伴うサーバ１全体の処理負荷低減により、サーバ１へのゲストＯＳ２収容台数も増加させることができる。
【０１０４】
なお、本実施形態では、通信バッファ４２のサイズとメモリアドレスは、通信アプリケーション２１が管理していることを想定しているが、これに限らず、通信Ｉ／Ｆドライバ３１が管理してもよい。この場合、通信アプリケーション２１は通信バッファ４２を使用することができないので、通信アプリケーション２１が通信Ｉ／Ｆドライバ３１へ通信データをわたす必要がある。そのため、通信アプリケーション２１と、通信Ｉ／Ｆドライバ３１との間で通信データのデータコピーが発生することとなる。
【０１０５】
仮想化環境では、動作中のサーバ１上で動作するゲストＯＳ２を停止することなく、他の仮想化環境のサーバ１へ移すライブマイグレーションという技術がある。この技術により、さまざまなサービスを提供し続けながら、ゲストＯＳ２が動作するサーバ１を変更することができるので、サーバ１が高負荷時は、ゲストＯＳ２を他のサーバ１へ移すことで負荷分散を行うなど、より自由度の高い管理が可能となる。
【０１０６】
第１実施形態に係る通信Ｉ／Ｆライブラリ処理部２３、通信Ｉ／Ｆドライバ３１、通信オフロードエンジン５の環境で、ライブマイグレーションを実現する場合、通信Ｉ／Ｆドライバ３１の通信リングキュー４１、通信オフロードエンジン５内のセッション管理テーブル５２を異動先のサーバ１へ移すことで対応可能となる。移行先のサーバ１に通信オフロードエンジン５がない場合は、ゲストＯＳ２内の通信処理を行うプロトコルスタック２５の対応する部分へセッション管理テーブル５２の情報を格納し、通信リングキュー４１と、通信バッファ４２とを共通メモリ４へ格納することによりライブマイグレーションを実現することができる。
【０１０７】
《第２実施形態》
次に、図２０および図２１を参照して、本発明の第２実施形態について説明する。
［システム構成］
図２０は、第２実施形態に係る仮想システムの構成例を示す図である。図２０において、図１と同様の構成については同一の符号を付して説明を省略し、図１と異なる点について説明を行うこととする。
図２０の仮想システムＺａが図１の仮想システムＺと異なる点は、各ゲストＯＳ２ａがプロトコルスタック２５を有する点である。プロトコルスタック２５は、通信処理を行うための既存の技術である。
プロトコルスタック２５は、図２に示されているＲＯＭ２０３や、ＨＤＤ２０４に格納されたプログラムが、ＲＡＭ２０２に展開され、ＣＰＵ２０１によって実行されることによって具現化する。
【０１０８】
第２実施形態における通信Ｉ／Ｆライブラリ処理部２３は、例えば図５のスイッチ変数管理テーブル５０１に登録されていない通信関数が実行されている場合は既存のプロトコルスタック２５を介して通信処理を行う。つまり、通信Ｉ／Ｆライブラリ処理部２３は通信リングキュー４１や、通信バッファ４２を介して、通信データの送受信を行うための通信関数として、登録されていない通信関数が実行されている場合は既存のプロトコルスタック２５を介して通信処理を行う。
なお、これに限らず、プロトコルスタック２５で通信処理される通信関数は、ユーザによって任意に設定されてもよい。
なお、ドライバＯＳ３ａの通信Ｉ／Ｆドライバ３１ａは、通信Ｉ／Ｆパケットに対する通信処理および通信Ｉ／Ｆパケットに変換されていない通信関数を処理するＲＡＷモードを行うことができる。
【０１０９】
通信オフロードエンジン５がスイッチ変数管理テーブル５０１に登録されていない（非対応な）通信パケットを受信するときは、あらかじめ通信アプリケーション２１より、非対応通信であるモードをとることを通知されており、この場合、通信オフロードエンジン５は通常のネットワークカードとして振る舞う。そして、通信オフロードエンジン５は、この通信データを通信Ｉ／Ｆドライバ３１、または、図示しない既存のネットワーク８ドライバへ送信する。通信Ｉ／Ｆドライバ３１、または、既存ネットワークカードは、プロトコルスタック２５へ通信データを送信し、プロトコルスタック２５が既存の受信処理を行う。この後、通信Ｉ／Ｆライブラリ処理部２３、または、図示しない既存の通信関数Ｉ／Ｆを介して、通信アプリケーション２１１へ受信された通信データが送信される。
なお、スイッチ変数管理テーブル５０１に登録されている通信関数でも、図４に示す引数の通信のコネクション（通信コネクション）を識別するソケット番号などで判別し、該当するソケット番号のものは、プロトコルスタック２５で処理を行うようにしてもよい。通信コネクションは、例えば、ソケット番号などで指定されるが、これに限らず、ユーザなどによって指定されてもよい。
【０１１０】
《フローチャート》
（通信Ｉ／Ｆパケット）
図２１は、第２実施形態に係る通信Ｉ／Ｆパケット生成処理の手順を示すフローチャートである。
ステップＳ１０１（図６）の後、通信Ｉ／Ｆライブラリ処理部２３は、ステップＳ１０１で実行された通信関数が図５に示すスイッチ変数管理テーブル５０１に登録されているか否かを判定する（Ｓ１０１ａ）。
ステップＳ１０１ａの結果、実行された通信関数がスイッチ変数管理テーブル５０１に登録されている場合（Ｓ１０１ａ→Ｙｅｓ）、通信Ｉ／Ｆライブラリ処理部２３は図６のステップＳ１０２〜Ｓ１０５と同様の処理を行う。
ステップＳ１０１ａの結果、実行された通信関数がスイッチ変数管理テーブル５０１に登録されていない場合（Ｓ１０１ａ→Ｎｏ）、既存のプロトコルスタック２５が通信関数を処理する（Ｓ１０２ａ）。なお、通信関数がスイッチ変数管理テーブル５０１に登録されているか否かではなく、通信のコネクションを識別するソケット番号などを基に、既存のプロトコルスタック２５が、その通信関数を処理するか否かを判別するようにしてもよい。
【０１１１】
（第２実施形態のまとめ）
第２実施形態によれば、スイッチ関数管理テーブルに登録されていない、つまり、第１実施形態に係る技術に対し、非対応の通信関数や、非対応のプロトコルや、非対応のパケットで通信する時も通信を行なうことができる。なお、第２実施形態に係る仮想システムＺにおける通信時のマイグレーション（ライブマイグレーション）は、ゲストＯＳ２上のプロトコルスタック２５の情報も転送することで実現できる。
【０１１２】
また、第２実施形態によれば、非対応の通信関数や、非対応のプロトコルや、非対応のパケットや、指定した通信コネクションで通信する時に、既存のプロトコルスタック２５へ処理を切り替えることにより、ゲストＯＳ２上で動作する通信アプリケーション２１の変更や、新たな通信関数を使用することなしに、第１実施形態に係る通信Ｉ／Ｆライブラリ処理部２３、通信Ｉ／Ｆドライバ３１および通信オフロードエンジン５を用いて、通信を行うことができる。
【符号の説明】
【０１１３】
１、１ａ  サーバ（通信サーバ）
２、２ａ  ゲストＯＳ
３、３ａ  ドライバＯＳ
４      共通メモリ（記憶装置）
５      通信オフロードエンジン（通信装置）
６、７  ハードウェアＩ／Ｆ
８      ネットワーク
９      通信先サーバ（通信先装置）
１０    ハイパバイザ（処理装置）
２１    通信アプリケーション
２２、２４、３２  ソフトウェアＩ／Ｆ
２３    通信Ｉ／Ｆライブラリ処理部
２５    プロトコルスタック
３１、３１ａ  通信Ｉ／Ｆドライバ
４１    通信リングキュー（第２の記憶領域）
４２    通信バッファ（第１の記憶領域）
５１    プロトコルスタックエンジン
５２    セッション管理テーブル
４０１  ソケット関数
４０２  通信Ｉ／Ｆパケット（通信情報）
５０１  スイッチ変数管理テーブル
７０１  受信リングキュー
７０２  送信リングキュー
７１１  送信バッファ
７１２  受信バッファ
９０１  通信Ｉ／Ｆスイッチ処理部
９０２  割込処理部（通信Ｉ／Ｆドライバ）
９１１  割込処理部（通信オフロードエンジン）
Ｚ、Ｚａ  仮想システム
【図１】
2012226471.tif 000003
【図２】
2012226471.tif 000004
【図３】
2012226471.tif 000005
【図４】
2012226471.tif 000006
【図５】
2012226471.tif 000007
【図６】
2012226471.tif 000008
【図７】
2012226471.tif 000009
【図８】
2012226471.tif 000010
【図９】
2012226471.tif 000011
【図１０】
2012226471.tif 000012
【図１１】
2012226471.tif 000013
【図１２】
2012226471.tif 000014
【図１３】
2012226471.tif 000015
【図１４】
2012226471.tif 000016
【図１５】
2012226471.tif 000017
【図１６】
2012226471.tif 000018
【図１７】
2012226471.tif 000019
【図１８】
2012226471.tif 000020
【図１９】
2012226471.tif 000021
【図２０】
2012226471.tif 000022
【図２１】
2012226471.tif 000023