Study Linux | bearsworld

bearsworld

for friendbear GitHub Pages.

Follow me on GitHub

Study Linux

01 Jan 2018 -

1.Linux


Linuxがsshが接続できるまでの起動からの流れ

カーネルに関係するデーモン ・keventd →モジュール化されたデバイスドライバを自動的にロードする割込を発生させるコントロールデーモン ・kapmd →パワーマネージメント関係のデーモン ・ksoftirq_CPU0 →ソフトIRQをCPU毎に順次処理するデーモン

  • kswapd →物理メモリが少なくなると必要に応じてディスク側のスワップ領域に読み書きしてコントロールするデーモン ・bdflushd →ディスクなどの記録媒体に書き込む機能を提供するデーモン ・kupdated →bdflushdの機能を定期的にスケジューリングして行うデーモン ・khubd →USB機器の抜き差しを監視するデーモン ・kjournald →ジャーナリング(データベースのようにデータを定期的に記録する構造)をサポートしたファイルシステムReiserFSやExt3 FSを使うときに必要なデーモン ・mdrecoveryd →RAID関係のコントロールデーモン ・ ログ管理デーモン(syslogd) ・ 定期的なジョブ実行デーモン(crond) ・ loginサービスデーモン ・ ネットワークデーモン

起動プロセス

linux起動01.jpg

/sbin/systemctl /etc/inittab あらかじめ決められた順番で起動していく仕組みのことをSysVinit Upstartで起動を並列高速化

fstabを元に / と swap をマウント

systemd

  • /usr/lib/systemd/system/ : システムデフォルト
  • /etc/systemd/system/ : 管理者がカスタマイズする場所

[Unit]
After=network.target auditd.service

[Service]
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
killMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
Alias=sshd.service

起動後のログの確認

  • /var/log/messages システム全般の情報
  • /var/log/boot.log   システム起動時の各プロセスが「OK」か「Failed」かを確認
  • /var/log/dmesg システム起動時のメッセージが出力

なぜ) /etc/init.d 配下にスクリプトがあるのか

Ref) 【Linux・CentOS7】 LVM によるディスクの管理について解説


tracerouteコマンドがいかに動作しているか詳細な説明

pingで相手ホストから正常な応答がなかった場合などに、ホスト自身や経路上のルーターのルーティング設定が正しいかどうかを確認するために用いられる。また、目的ホストまでのルーターのリストから、「設置場所が不明なホストのおおまかな場所を推測する」といった利用も行えるだろう。

 その他、各ルーターからのレスポンス時間などの統計値も表示されるので、経路上のボトルネックを探るなどの簡易的なネットワーク性能評価にも役立つ。

TTL(Time To Live)

IPパケットにおけるTTL(Time To Live) の仕組みをうまく利用しています。TTLとはIPパケットヘッダに指定可能な「生存時間」という意味だ。ただし時間ではなく、「ホップ数」を意味している。つまり、そのパケットが「生存」できるホップ数を指定するのがTTLなのである。

ルーターをホップする度に必ず1ずつ減らされる。そして0に達したパケットは発見したルーターが破棄することになっています。

パケットが単に破棄されたままでは送信元ホストは正しく相手のホストにパケットが届いたかどうか分からない。そこで、(ルーターの設定にもよるのだが)破棄したルーターはICMPのTime Exceededエラー(Type=11)を送信元ホストへ報告することになっている。この通知を受け取ることで、送信元ホストはルーティングなどに何らかの問題が発生していることを知ることができる

なぜUDPパケットでも調査に使用できるのか  LinuxやmacOSでは、tracerouteコマンドのためにICMPではなくUDPパケットを使用することもできる(Linuxでは逆にデフォルトがUDPとなっている)。  tracerouteなどのネットワーク経路の調査にはICMPの機能を利用すると理解している人からすると違和感があるかもしれないが、上記のようなtracerouteの動作原理が分かればそれほど不思議でもなくなるはずだ。  つまり、「調査の根拠となるのは往路ではなく復路のICMPパケット」ということである。例えば、tracerouteではICMP Time Exceededエラーを返答してくれればよいので、往路のパケットはICMPでもUDPでも関係がなく、IPパケットであればよい。これは、ICMPがIPネットワークにおけるエラーを通知するためのプロトコルであるからだ。「主役は復路のICMPパケットである」というICMPの特性をうまく活用したコマンドである。

なぜ) パケットモニタリングで確認


routeコマンドでルーティングテーブルを参照するためのオプション

route

macは netstat -rn

  • 「Flags」は経路の種類を示している。「U」は有効、「H」はホスト、「G」はゲートウェイを意味している。そのほか、ダイナミックルーティングを行っている場合には、固有のフラグが追加されることもある。

  • 「Ref」は経路が参照された回数、「Use」は経路が実際に使用された(ルーティングされた)回数を表している。

$ netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            172.20.10.1        UGSc          131       18     en0
127                127.0.0.1          UCS             0        0     lo0
127.0.0.1          127.0.0.1          UH              1      152     lo0
169.254            link#8             UCS             0        0     en0      !
172.20.10/28       link#8             UCS            12        0     en0      !
172.20.10.1/32     link#8             UCS             2        0     en0      !
172.20.10.1        3a:53:9c:33:a2:64  UHLWIir        64      431     en0    248
172.20.10.2/32     link#8             UCS             1        0     en0      !
172.20.10.2        78:4f:43:63:7c:9   UHLWIi          1      336     lo0
172.20.10.3        link#8             UHLWI           0        2     en0      !
172.20.10.4        link#8             UHLWI           0        2     en0      !
172.20.10.5        link#8             UHLWI           0        2     en0      !
172.20.10.6        link#8             UHLWI           0        2     en0      !
172.20.10.7        link#8             UHLWI           0        2     en0      !
172.20.10.8        link#8             UHLWI           0        2     en0      !
172.20.10.9        link#8             UHLWI           0        2     en0      !
172.20.10.10       link#8             UHLWI           0        2     en0      !
172.20.10.11       link#8             UHLWI           0        2     en0      !
172.20.10.12       link#8             UHLWI           0        2     en0      !
172.20.10.13       link#8             UHLWI           0        2     en0      !
172.20.10.14       link#8             UHLWI           0        2     en0      !
224.0.0/4          link#8             UmCS            2        0     en0      !
224.0.0.251        1:0:5e:0:0:fb      UHmLWI          0        0     en0
239.255.255.250    1:0:5e:7f:ff:fa    UHmLWI          0      118     en0
255.255.255.255/32 link#8             UCS             0        0     en0      !

LISTEN状態にあるポートの一覧の確認方法

何もオプション引数を付けずにnetstatを実行すると、現在アクティブなTCPコネクションの状態が表示される(後述する「状態」が「LISTENING」ではないコネクションが表示される)。

$ netstat | head
Active Internet connections
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
tcp4       0      0  172.20.10.2.52823      ec2-13-115-96-25.http  ESTABLISHED
tcp4       0      0  172.20.10.2.52822      117.18.237.29.http     ESTABLISHED
tcp4       0      0  172.20.10.2.52821      ec2-18-179-194-1.https ESTABLISHED
tcp4      53      0  172.20.10.2.52819      52.119.165.138.https   CLOSE_WAIT
tcp6       0      0  2001:240:2408:26.52798 nrt20s08-in-x07..https ESTABLISHED
tcp6       0      0  2001:240:2408:26.52698 nrt12s17-in-x05..https ESTABLISHED
tcp4       0      0  172.20.10.2.51802      192.229.189.146.https  ESTABLISHED
tcp4       0      0  172.20.10.2.51681      104.244.42.1.https     ESTABLISHED

「プロトコル」欄は使用中のネットワークプロトコルの種類であり、次項で述べる「-a」オプションを付けていない場合は、常に「TCP」と表示されているはずである。UDPにはコネクションを確立するという概念がないので(UDPではデータを単発的に送るだけなので)、このコマンドではUDPの通信状態は表示されない

13d270d7.png

TCPの状態遷移図 TCPの規格書(RFC793)に記載の状態遷移図を簡略化して、分かりやすくしたものだ。四角の中に書かれているのがTCPの状態名。矢印は可能な遷移の経路。矢印のそばにある文字は「トリガ(アクション)」を表しており、ある「トリガ」となるイベントが発生すると指定された「アクション」を実行して、次の状態へ遷移する。TCPの主なステートは次の通りである。 パッシブオープン:TCPの接続要求を受け付ける側。いわゆるサーバ側は、このLISTEN状態でクライアントからの接続を待ち受けしている。例:Webサーバなど。 アクティブオープン:TCPの接続要求を送信する側。LISTEN状態のTCPのポートに対して、接続を試みる側。例:Webブラウザなど。 通信確立:TCPの接続が確立して、通信中の状態。双方からデータを送信可能な状態(通信路がアクティブな状態)。 アクティブクローズ:先に終了要求を送信する側。 パッシブクローズ:相手から終了要求を受け取って、自分自身も終了処理を実行する状態。

  • netstat -a -n
kumagai@mbp ~/.d/.v/rc> netstat -a -n | head
Active Internet connections (including servers)
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
tcp4       0      0  172.20.10.2.52990      52.222.197.81.443      ESTABLISHED
tcp4       0      0  172.20.10.2.52988      13.115.96.251.443      ESTABLISHED
tcp4       0      0  172.20.10.2.52982      5.9.154.76.443         CLOSE_WAIT
tcp4      23      0  172.20.10.2.52981      5.9.154.76.443         CLOSE_WAIT
tcp4       0      0  172.20.10.2.52980      5.9.154.76.443         CLOSE_WAIT
tcp6     528      0  2001:240:2408:26.52978 2606:4700::6813:.443   ESTABLISHED
tcp4     289      0  172.20.10.2.52977      5.9.154.76.443         CLOSE_WAIT
tcp6       0      0  2001:240:2408:26.52933 2606:4700:20::68.443   ESTABLISHED

ext3とext4で可能になった変更箇所の説明

ext4(fourth extended file system)は、Linuxのファイルシステムで、ジャーナリングファイルシステムの一つである。ext3の後継のファイルシステムで、拡張機能を使っていない場合に限りext3としてマウントできる。

  • 1EiB(エクスビバイト)までのストレージをサポート
  • ファイルの断片化を防ぐextent file writingと呼ばれるシステム
  • ファイルのタイムスタンプナノ秒単位で西暦1901年から2514年までの範囲をサポート(ext3では秒単位で2038年まで) Linuxカーネル 2.6.19より開発版が利用が可能になり、2.6.28[1]より安定版のファイルシステムとなった

大きなボリュームサイズとファイルサイズ

ext4ファイルシステム

  • 最大1EiB(エクスビバイト)までのボリュームサイズ
  • 最大16TiB(テビバイト)までのファイルサイズ

エクステント

エクステントは、ext2およびext3で使われてきた伝統的なブロックマッピング方式を置き換える概念である。エクステントは連続した物理ブロックの集合であり、大きなファイルに対するパフォーマンスを改善し、フラグメンテーションの発生を減らすことができる。ext4におけるエクステントは、4KiBのブロックサイズで最大128MiBまでの連続した領域をマッピングすることができる。inodeごとに4つのエクステントを格納することができる。ひとつのファイルに5つ以上のエクステントがあるとき、残りのエクステントはHtreeで構造化される。

後方互換性

ext4ファイルシステムはext3およびext2に対する後方互換性を持つ。すなわち、ext3およびext2ファイルシステムをext4ファイルシステムとしてマウントすることができる。その場合でも、わずかにパフォーマンスの向上が見られる。なぜなら、ブロック確保アルゴリズムなどの新しい機能はext3やext2でも使用できるからである。 ext3ファイルシステムは部分的にext4に対する前方互換性を持つ。すなわち、ext4ファイルシステムをext3パーティションとしてマウントできる(マウントするときは「ext3」をファイルシステムタイプとして指定する)。しかし、もしext4パーティションがエクステント(ext4の重要な新機能である)を使用しているなら、ext3としてマウントすることはできなくなる。

永続的な事前確保

ext4ファイルシステムはファイルのためのディスク空き領域の事前確保を可能にする。ほとんどのファイルシステムにおけるこれまでの方法論では、ファイルが作成されたときに予約されたスペースを0で埋める形で書き込まれる。ext4においてはこの方法で要求されることはもはやない。そのかわり、新しくfallocate()システムコールがLinuxカーネルにファイルシステム用に追加され、ext4やXFSにおいて使われている。これにより互換性が維持されている。ファイルのために確保されたスペースはディスクフルによる書き込み失敗はしないことが保証され、連続していることが期待される。この機能はメディアストリーミングやデータベースで使われる。

遅延確保(理解が必要)

ext4ファイルシステムのパフォーマンス向上のテクニックとして、allocate-on-flushと呼ばれるものがある。これは遅延確保としても知られている。遅延したブロック確保はデータがディスクに書き込まれる いくつかの他のファイルシステムとは違って、必要なブロックをこの段階の前に確保するだろう。実際のファイルサイズに基づく形でブロック確保の決定する改良により、パフォーマンスは向上しフラグメンテーションは減少する。

サブディレクトリの32000個制限の撤廃

ext3ファイルシステムにおいては、1つのディレクトリに入れられるサブディレクトリ数が32,000個に制限されている。この制限がext4ファイルシステムでは64,000個まで引き上げられ、”dir_nlink”機能を使うとそれを超える事が可能となる(親ディレクトリのリンクカウント増加は止まるだろうが)。一つのディレクトリ内のファイル数が増えた場合における性能を上げる為、Htreeインデックス(B-treeの発展版)は、ext4でデフォルトでオンになった。この機能はLinux kernel 2.6.23 から導入されている。Htreeはext3でもdir_index機能が有効であれば利用可能であった。

ジャーナルのチェックサム

ext4は信頼性を向上のため、ジャーナルにチェックサムを使用する。 なぜならばジャーナルはディスクで最も使用されるファイルの一つだからである。この機能によってジャーナル過程の間ディスクI/Oの待機を安全に避ける事ができるという利点を持つ。これによりパフォーマンスが若干向上する。

オンラインのデフラグメンテーション

e4defrag により、マウント中(オンライン)でのデフラグが可能になった。ファイルシステムのフラグメンテーションを避けるための様々なテクニックによってフラグメントしにくくなっているが、それでもなお、長期間運用されたファイルシステムは時間経過によってフラグメントが発生する場合がある。

より高速なファイルシステムチェック

ext4において、確保されていないブロック群とi-nodeテーブル部は印をつけられる。 e2fsckの実行時に全体のチェックを不要にし、ファイルシステムのチェックにかかる時間を大きく減少させる。

マルチブロックの確保

ext3では、ファイルが追加される際にブロックアロケータをそれぞれのブロック個別に1回ずつ呼び出す。そのため、同時に複数書き込みを行う場合には、ディスク上でファイルのフラグメントは容易に発生する。しかし、ext4ではデータをバッファして複数のブロック群を一度に確保する遅延確保(理解不足)を利用する。これはアロケータは何を書き込むべきかについてより多くの情報を保持することを意味し、そしてディスク上のファイル領域確保のためより良い選択を行うことができるようになる。マルチブロックアロケータは遅延確保がファイルシステム上で有効になっているとき、もしくはファイルがO_DIRECTモードで開かれているときに使用される。この機能はディスクフォーマットには影響しない。

タイムスタンプの改良

コンピューターは全体的により高速になるにつれてLinuxはよりミッションクリティカルな用途で使用されるようになり、秒ベースの粒度のタイムスタンプでは不十分となってきている。この解決として、ext4ではタイムスタンプをナノ秒単位で提供している。付け加えて、2038年問題を引き伸ばすためにタイムスタンプの秒フィールドの上位に2ビットの拡張タイムスタンプフィールドが付け加えられている 結果として204年後まで先延ばしにしている。 ext4は日付によるタイムスタンプ(date-created timestamps)を追加でサポートする。

欠点

遅延アロケーションとデータ損失

遅延アロケーションは、すべてのデータをディスクに書き出す前にファイルシステムがクラッシュした際、データを損失する危険性を孕む。

このようなことが起こる典型的なシナリオは、fsyncでディスクに書き出すことをせずにファイルの内容を書き換えるようなプログラムを使用する時である。実際に書き出しをする前にシステムがクラッシュすると、問題が起こる可能性がある。このような状況では、ext3のユーザーは、クラッシュ後に変更前か変更後のどちらかのデータがディスクに残されているということを期待することができた。一方、Linuxカーネル2.6.28のext4では、クラッシュ前にファイルの内容を消去するが新しいデータを書き出さず、結果としてデータが損失するということがしばしば見られた。

この問題に対処するためにfsyncを頻繁に使用すると、data=orderedフラグ(多くのLinuxディストリビューションではデフォルト)でマウントされたext3ファイルシステムでは深刻なパフォーマンス低下が起こる恐れがある。どちらのファイルシステムもしばらくの間使用されるだろうということを考えると、これはエンドユーザーアプリケーション開発者にとって非常に厄介な問題となる。このため、セオドア・ツォーは、上記のような場合の遅延アロケーションを制限するext4のパッチを作成した。パフォーマンスは多少低下するが、これによってクラッシュ後にどちらかのバージョンのデータが残る可能性が著しく高まった。

関連) LVM


カーネルのメモリ回収処理 カーネルスレッド

カーネルスレッド

連続的ではなく定期的に実行するような処理はカーネルスレッドがバックグラウンドで実行する。 これによりユーザモードコンテキストの動作が妨げられない。

カーネルスレッドとそれ以外のプロセスの違い

  • 各カーネルスレッドは特定のカーネル関数を実行する。通常のプロセスはシステムコール経由でしか、カーネル関数を実行できない。
  • カーネルスレッドはカーネルモードでしか実行されないが、通常のプロセスはカーネルモードとユーザモードが交互に入れ替わる。
  • PAGE_OFFSET番地以降のリニアアドレスしか実行しない。通常のプロセスは4GB全体を利用する。

◆カーネルスレッドの生成 kernel_thread()

◆プロセス0 swapperプロセス, start_kernel()関数によりLinuxの初期化時に生成されるカーネルスレッド。

start_kernel()関数 | |カーネルが必要とするすべてのデータ構造の初期化 |割り込みの許可 ↓プロセス1の生成 cpu_idle()関数の実行

Raspberry Pi2(Linux Kernel)のブートシーケンスを読む(その4) start_kernel()始めからカナリアコードまで - Qiita

◆プロセス1 初期化の続きをしたのちに、execvシステムコールを発行して実行可能プログラムinitを読み込む。

◆その他のカーネルスレッド keventd - qt_contextタスクキューのタスクを実行(ボトムハーフ) kapm - APM( Advanced Power Management ) kswapd - メモリの回収

  • 空きメモリが少なくなってくると、ディスクキャッシュ等のページを解放して空きメモリを増やす。
  • キャッシュの解放は主にshrink_*の関数で行われる
  • 空きメモリが少なくなりkswapd()がWakeupされると(kswapdはカーネルスレッド)、balance_pgdat()を呼び出してshrink処理を開始する。

kflushd - ダーティなメモリをディスクへ書き出す。 kupdate - ダーティなバッファをディスクに戻す ksofirqd - タスクレット

kswapd

物理メモリが少なくなると、Linux のメモリ管理サブシステムは、物理ページを 解放するよう努力しなければならない。このタスクは、カーネルスワップデーモン (kernel swap daemon)(kswapd)の仕事である。 カーネルスワップデーモンは、カーネルスレッド(kernel thread)という特別な プロセスである。 カーネルスレッドは仮想メモリを持たず、そのかわり物理アドレス空間内において カーネルモードで実行される。このカーネルスワップデーモンは、その役割が 単にページをシステムのスワップファイルに書き出すだけでないことからすると、 やや命名に難があるといえる。その役割は、システム内で充分な空ページを確保して、メモリ管理システムの操作効率を維持することである。

カーネルスワップデーモン(kswapd)は、起動時にカーネル初期化プロセ スにより起動され、カーネルスワップタイマーが定期的に時間切れになるのを待って いる。 [see: kswapd(), in mm/vmscan.c]

タイマーが時間切れになると、スワップデーモンはシステムの空ページの数が減りす ぎていないかどうかを確認する。kswapdは、 free_pages_high と free_pages_low のふたつの変数を使ってページを解放するかどうかを判断 する。 システム内の空ページの数が free_pages_high よりも多い限り、カーネル スワップデーモンは何もしない。タイマーが切れるまで再び休憩する。このチェックに 際して、カーネルスワップデーモンは、スワップファイルに現在書き出されている ページ数を考慮に入れる。カーネルスワップデーモンは、その数を、nr_async_pages に保持している。この数は、スワップファイルに書き出される ためにページがキューに入れられたときに増加し、スワップデバイスへの書き込みが 完了したときに減少する。free_pages_high と free_page_low と は、システム起動時にセットされ、システム内の物理ページの数と関連付けられる。 システム内の空ページの数が free_page_high 以下になるか、free_pages_low 以下にまで落ち込んでしまった場合には、カーネルスワップ デーモンは、3 つの方法を使ってシステムで使用されている物理ページの数を減ら そうとする。

  • バッファとページキャッシュのサイズを減らす。
  • System V 共有メモリページをスワップアウトさせる。
  • ページをスワップアウトさせて、破棄する。

システムの空ページの数が free_pages_low 以下になっている場合、 カーネルスワップデーモンは、次の実行時までに 6 つのページを解放する。でなけれ ば、3 つのページを解放する。上記の方法は、充分なページが解放されるまで順番に 繰り返される。カーネルスワップデーモンは、物理メモリを解放するとき最後に 使った方法を覚えている。実行の際はいつも、前回の最後に成功した方法を使用して ページを解放しようとし始める。

充分な空ページが出来たら、スワップデーモンは、タイマーが切れるまで再び休憩 に入る。カーネルスワップデーモンがページを解放した理由が、システム内の空ページ の数が free_pages_low を下回ったからであった場合は、その休憩時間は、 通常の半分に短縮される。空ページの数が free_pages_low の数を超えて しまえば、カーネルスワップデーモンは通常のタイマー間隔での休憩に戻る。

追加で学ぶ) カーネルスレッド

Ref)

[root@vmlinux01 linux]# ps -aef | grep k