name: www-internals class: title, smokescreen, shelf, no-footer # WWWサーバを例にOSの動作イメージ <div class=footnote> <small> 知識編は、 基本情報処理試験 + 一部もうすこし難しい(応用情報処理試験)レベルの技術者としての常識を習得することが目的です。 このスライドでは、 WWWサーバを題材に第2回〜第7回に登場するキーワードを紹介します。 </small> </div> --- class: img-right,compact # ネットワークの全体像(復習、networkのスライド再掲) ![width640px](/images/network/end-to-end.png) - 右図: ホストとホストの通信 - ホスト = コンピュータ - END TO END (端〜端)通信 - 用語: 階層(Layer), 〜層 - 用語: プロトコル(取り決め,約束事) - TCP,IP,Ethernetなど - 用語: サーバ,クライアント - 右図: サーバ(左)とクライアント(右) - サーバ (写真の業務用PC) - サービスを提供する側 - WWWサーバ,メールサーバ - クライアント (右端のPC) - サービスを受ける側(お客様) - ブラウザやメールソフト - 人間が操作しているPC --- class: img-right,compact # サーバの全体像とキーワード ![width640px](images/server-internals.png) - 前頁のサーバ部分(図左端)を題材にして 第2回〜第7回のキーワードを紹介 - 右図はWWWサーバで、すでに3way handshakeが終わり、 クライアントから最初のリクエスト(GET / HTTP/1.0)が送られてきた時の挙動です - WWWサーバプログラムの例: apacheやnginx、thttpd - 次頁から各ステップを簡単に見ていきます (詳細は第2回〜第7回で取り上げます) - 用語 - カーネル(kernel) ... OS本体と言うべき**特権**プログラム --- class: img-right,compact # サーバの動作(1) ![width640px](images/server-internals.png) - サーバ宛のイーサネットフレームを**イーサネットカード**が受け取ります - フレームヘッダの宛先MACアドレスがカードのMACアドレスと一致すれば自分宛ということなので、 カードはフレームを受け取ります - 異なれば無視します - ブロードキャストも受け取ります (FF:FF:FF:FF:FF:FF) --- class: img-right,compact # サーバの動作(2) <div class=footnote> <small> (脚注)各デバイスにあるコントローラも小さなコンピュータです </small> </div> ![width640px](images/server-internals.png) - イーサネットカードのコントローラが、**ハードウエア割り込み**をかけます - OSが事前に設定した**割り込み**の設定表(**割り込みベクタ(interrupt vector)**)を検索し 該当する処理関数が呼ばれます - この**ハードウエア固有の**処理関数を**デバイスドライバ**と呼びます - ハードウエアそれぞれに専用の**デバイスドライバ**が必要です - カーネルに該当するデバイスドライバがない場合、 そのハードウエアは利用できません --- class: img-right,compact # サーバの動作(3) <div class=footnote> <small> (脚注)ここで出てくるXXX_input()はBSD Unixにある実際の関数名です </small> </div> ![width640px](images/server-internals.png) - 呼ばれたデバイスドライバは図のイーサネットカードの扱い方を知っています - 例: メモリ上の0170000から読む - カードからイーサネットの情報を取り出し(メイン)**メモリ**にコピーします - デバイスドライバは、この先の処理をイーサネットの処理関数 ether_input() にまかせます --- class: img-right,compact # サーバの動作(4) <div class=footnote> <small> (脚注)ここで出てくるXXX_input()はBSD Unixにある実際の関数名です </small> </div> ![width640px](images/server-internals.png) - ether_input() では必要があればフィルタリングの処理も行われます - イーサネットフレームのヘッダを見て、 フレームの中身がIPパケットだと分かるので、 IPパケットの処理関数 ip_input() を呼び出し、 先の処理をゆだねます --- class: img-right,compact # サーバの動作(5) <div class=footnote> <small> (脚注)ここで出てくるXXX_input()はBSD Unixにある実際の関数名です </small> </div> ![width640px](images/server-internals.png) - ip_input()はIPパケットの処理を行います - ルーティングやフィルタリングの処理も行われます - IPヘッダを見れば、ペイロード(運んでいるデータ)がTCPだと分かるので、 tcp_input()を呼び出します --- class: img-right,compact # サーバの動作(6) <div class=footnote> <small> (脚注)ここで出てくるXXX_input()はBSD Unixにある実際の関数名です </small> </div> ![width640px](images/server-internals.png) - tcp_input()はTCPパケットを処理します - フィルタリングの処理も行われます - 最終的にパケットのペイロード(データ)が取り出され、 WWWサーバ側でデータを待っている関数を呼び出します --- class: img-right,compact # サーバの動作(7) ![width640px](images/server-internals.png) - WWWサーバに順番が回ってきます - クライアントからのデータを待っている関数(例:recv())が、 メモリからデータ`GET / HTTP/1.0`をよみこみます - このあとWWWサーバ内の処理が続き - 上のGET ...をparseすれば `/`つまりサーバのトップページ(index.html)をリクエストしていることが分かります --- class: img-right,compact # サーバの動作(8) ![width640px](images/server-internals.png) - クライアントからのリクエスト`GET / HTTP/1.0`を解析して、 index.htmlファイルを読み込む必要があると分かりました - (図では略されていますが、まず) **ファイルシステム**上のファイルをopen**システムコール**で開き、 read**システムコール**でカーネルにファイルを読む処理を依頼します (システムコールも**割り込み**です) - HDDやSSDからファイルを読み出すのは、 そのHDD/SSDハードウエアの**デバイスドライバ**です。 カーネルが適切な**デバイスドライバ**を呼び出します - HDDやSSDは**ストレージ**と呼ばれます --- class: img-right,compact # サーバの動作(送信、詳細は省略) ![width640px](images/server-internals.png) - クライアントへの返事は逆順です - 送信するデータを用意し、send()などの関数(**システムコール**)を呼び出します - 逆順に tcp_output -> ip_output() -> ether_output() と進み、 最後はイーサネットの**デバイスドライバ**が呼ばれ、 イーサネットフレームが送信されるといった具合です --- class: img-right,compact # プロセス ![height480px](../process/images/memory_layout.png) - WWWサーバというプログラムが動いていますが、 コンパイルしたファイル(たとえばa.out)を、ただメモリに置けば動くわけではありません - プログラムが動く際には次のようなデータやハードウエアの設定が必要です - **メモリ**上に置かれたコード(プログラムの命令の実体,TEXTと呼ぶ) - **メモリ**上の変数や**スタック**領域 - **仮想記憶**システムの管理情報 - **レジスタ** - これらの総体を**プロセス**と呼んでいます この図では「WWWサーバのプロセス」が動いて(走って)います --- class: img-right,compact # スケジューラ、リソース制御 ![height240px](../../internal/device/images/interrupt_clock.png) ![height240px](../../internal/device/images/interrupt_hdd.png) - このスライドでは単に「XXX_input()を呼び出す」と説明していますが、 ソースコードが見たとおりに順番に実行されるわけではありません - **論理的にはコードのとおり**ですが**時間的には飛び飛びに**実行されています - プロセス群は**擬似並列処理**されます - GUI、ターミナル、ネットワーク、カーネル、みな別のプロセスです - カーネルが1/100秒ずつプロセスを切り替えて並行処理をするといった具合です。 どのプロセスに切り替えるか?を考えるのが**スケジューラ**です - 同じ関数を同時に(擬似並列に)実行するので**ロック**(一般には**リソース制御**)機能が必須です --- class: img-right,compact # キーボードやマウス ![width240px](../../internal/device/images/computer_keyboard_white.png) ![width240px](../../internal/device/images/computer_mouse_cord.png) ![width240px](../../internal/device/images/computer_harddisk.png) - (サーバには直接関係ありませんが) - キーボードやマウスからの入力も、 入力が発生するたびに対応するデバイスドライバが呼ばれます - こういった1バイトずつ転送するデバイスを**キャラクタデバイス**と呼びます。 逆にHDDやSSDなどのブロック単位(歴史的には512バイト、最近は4KBとか8KB) で読み書きするデバイスを**ブロックデバイス**と呼びます