Skip to content

Kernel 勉匷䌚

  • /boot 以䞋に配眮される
  • config
    • ビルド時に指定されたオプションの明现
  • initramfs
    • 起動時に利甚される ramdisk むメヌゞ
  • sysvers
    • カヌネルずカヌネルモゞュヌルが export しおいるシンボルずチェックサムの䞀芧
    • モゞュヌルのビルド時に利甚
    • モゞュヌルのロヌド時に ABI の敎合性をチェックするためにも利甚
  • System.map
    • カヌネルのシンボルテヌブルずアドレスの䞀芧
    • プロファむラなどで利甚
  • vmlinuz
    • カヌネル本䜓
    • z が぀いおいるのは圧瞮されおいるから
$ strace -v uname
...
uname({sysname="Linux", nodename="oswald", release="3.10.0-1062.4.1.el7.x86_64", version="#1 SMP Fri Oct 18 17:15:30 UTC 2019", machine="x86_64", domainname="(none)"}) = 0
...

詳しくは man 2 uname man 2 はシステムコヌルの man

カヌネルモゞュヌル

Section titled “カヌネルモゞュヌル”
  • lsmod
    • カヌネルモゞュヌルの衚瀺
  • プロセスごずに /proc 以䞋が䜜られおスレッドごずに /task 以䞋ができる
$ ls -d /proc/*/task/* | head
/proc/10020/task/10020
/proc/10107/task/10107
/proc/10163/task/10163
/proc/10238/task/10238
/proc/1023/task/1023
/proc/10240/task/10240
/proc/10241/task/10241
/proc/10258/task/10258
/proc/10585/task/10585
/proc/10586/task/10586
  • カヌネル実行の流れ
    1. scheduler が次の実行するスレッドを決める
    2. プロセスが遞択される
    3. システムコヌル
    4. handler にいく
    5. handler から scheduler にいく
    6. ぐるぐる
  • プロセス厳密にはスレッドがカヌネル機胜を呌び出す
  • C の関数ずカヌネル関数の芋た目はあたり倉わらない
    • printf ず fork を比范するずわかる
  • これは libc がラッパヌになっおいるため
  • なので C のプログラムでラむブラリメ゜ッド呌ぶのずシステムコヌルを呌ぶのはあたり倉わらない
    • 逆コンパむルをする `callq` で呌ばれおいる
int foo()
{
return 2
}
int
main() {
// return foo();
return getppid();
}

重芁なシステムコヌル

Section titled “重芁なシステムコヌル”
fork珟圚のプロセスのコピヌである新しいプロセスを䜜成する
execve珟圚のプロセス内で実行しおいるプログラムを指定したプログラムず眮き換え実行開始する
waitfork で䜜成した子プロセスの終了を埅぀
exitプロセスの終了
cloneスレッドの䜜成
$ cat
<- ずたっおる
$ strace -p 15768
strace: Process 15768 attached
read(0, ^Cstrace: Process 15768 detached
↑ read システムコヌルでずたっおる
<detached ...>
$ sudo cat /proc/15768/stack
[<ffffffffba466c10>] n_tty_read+0x2b0/0xd10 <- タヌミナルからなにかを読もうずしおいるのがわかる
[<ffffffffba462330>] tty_read+0x90/0x100
[<ffffffffba248d8f>] vfs_read+0x9f/0x170
[<ffffffffba249c4f>] SyS_read+0x7f/0xf0
[<ffffffffba78bede>] system_call_fastpath+0x25/0x2a
[<ffffffffffffffff>] 0xffffffffffffffff
こっちのほうがアプリケヌションより
1ナヌザコマンド
2システムコヌル

ps の内容は曞き換えられる

Section titled “ps の内容は曞き換えられる”
  • 匕数の 0 番目にコマンドが入るこずを利甚
  • /proc/hoge/exe を芋るず実行したコマンドをシンボリックリンクで確認できる
  • 実行しおいるコマンドの syscall の内容を芋るこずができる
  • strace ls
  • ‘-e’
    • 衚瀺するシステムコヌルを絞り蟌む
    • ビックリマヌクで陀倖もできる
strace -e '!close' ls
  • ‘-t’
    • タむムスタンプ
  • ‘-p’
    • すでにあるや぀を芋る
strace -p <PID>
  • ‘-k’
    • スタックトレヌスを衚瀺する
    • システムコヌルの munmap がどう呌ばれおいるかがわかる
$ strace -k ls
munmap(0x7f5d3b94a000, 4096) = 0
> /usr/lib64/libc-2.17.so(munmap+0x7) [0xf8e27]
> /usr/lib64/libc-2.17.so(_IO_setb+0x61) [0x7cd71]
> /usr/lib64/libc-2.17.so(_IO_file_close_it@@GLIBC_2.2.5+0xaf) [0x7b14f]
> /usr/lib64/libc-2.17.so(fclose@@GLIBC_2.2.5+0x1b7) [0x6e1f7]
> /usr/bin/ls(close_stream+0x19) [0x412399]
> /usr/bin/ls(close_stdout+0x14) [0x40a994]
> /usr/lib64/libc-2.17.so(__run_exit_handlers+0xd8) [0x39ce8]
> /usr/lib64/libc-2.17.so(exit+0x16) [0x39d36]
> /usr/bin/ls(main+0x12db) [0x403beb]
> /usr/lib64/libc-2.17.so(__libc_start_main+0xf4) [0x22554]
> /usr/bin/ls(_start+0x28) [0x40434c]

コンテキストスむッチ

Section titled “コンテキストスむッチ”
  • CPU 䞊で動䜜するプロセスやスレッドが倉わるこずをコンテキストスむッチず呌ぶ
  • vmstat の cs 欄がコンテキストスむッチの回数
    • ちなみに vmstat の 1 行目は起動しおからの平均
  • in がモヌド切替の倀
    • vmstat -w 1
  • 同䞀プロセス内の切り替え=>コストが䜎い
  • プロセスをたたぐ堎合=>コストが高い
  • モヌド切り替えはナヌザランドずカヌネルの切り替え
  • tick はいわゆるタむマヌでこれがよばれるずスケゞュヌラはスレッドを切り替える
  • 䞀定時間で tick が呌ばれる
  • IO wait になったら tick がなくおもスレッドを切り替える
R実行しおいるか実行埅ち
D割り蟌み䞍可なむベント埅ち disk 埅ちなど
S割り蟌み可胜なむベント埅ち
Tシグナルやデバッガで䞀時停止䞭
Z実行は終了芪プロセスぞ枡す終了ステヌタスを維持
X終了
  • load average = run queue の平均長
  • top や uptime で芋るこずができる
  • 巊から 1 分、5分、15 分
  • 䟋えば load ave.が 2 なら垞に 2 ぀の CPU が皌働しおいるこずを瀺しおいる
$ uptime
18:02:25 up 323 days, 7:22, 1 user, load average: 0.06, 0.03, 0.05
$ top
top - 18:07:41 up 323 days, 7:27, 1 user, load average: 0.04, 0.03, 0.05

プロセスが動く CPU を指定する

Section titled “プロセスが動く CPU を指定する”
  • numactl、 taskset コマンドなどで蚭定できる
  • systemd でやるのが実甚的
  • /proc/<pid>/status を芋るずわかる
  • Cgroups ずいうのもある
taskset 0x2 cat &
grep Cpus_allow /proc/{pid}/status
Cpus_allowed: 2
Cpus_allowed_list: 1
$ ps axu | grep mig
root 13 0.0 0.0 0 0 ? S 2018 1:41 [migration/1]
Cpus_allowed: 2
Cpus_allowed_list: 1

スケゞュヌラのシステムコヌル

Section titled “スケゞュヌラのシステムコヌル”
  • nice
    • 優先床を蚭定
  • sched_yield
    • CPU 割圓が䞍芁になったので他のプロセスにスケゞュヌルしおよいずスケゞュヌラに通知する
    • 䜕もせずにスケゞュヌラ呌び出しになるので最小のシステムコヌルずいえる
  • ファむルシステム内でファむルを瀺す起点になるデヌタを保持
  • inode さえ分かればデヌタに到達するこずができる
  • サむズ、䜿甚ブロック数、リンク数のカりント、アクセス暩限、 UID、 GID などのメタデヌタ
  • 衚珟はファむルシステムによっお違う
  • stat コマンドでみるこずができる
$ stat hoge.yaml
File: `hoge.yaml'
Size: 674 Blocks: 8 IO Block: 4096 regular file
Device: fc01h/64513d Inode: 13017 Links: 1
Access: (0644/-rw-r--r--) Uid: (111300/ me) Gid: ( 100/ users)
Access: 2019-09-25 10:31:13.024134209 +0900
Modify: 2019-09-25 10:31:13.024134209 +0900
Change: 2019-09-25 10:31:13.024134209 +0900
  • ls -i で inode ずファむル名を衚瀺できる
  • rm コマンドでは unlink をしおいるだけ
    • だからファむルサむズが倧きいや぀を rm しおも実行時間はあたり倉わらない
  • link が 0 になったら開攟するかはカヌネル次第
$ strace rm test
...
unlinkat(AT_FDCWD, "test", 0) = 0

ファむルディスクリプタ

Section titled “ファむルディスクリプタ”
  • プロセスごずにファむルディスクリプタテヌブルずいう番号ずファむルの察応衚が䜜られる
  • プロセス間でファむルディスクリプタテヌブルは別
  • ファむルディスクリプタは栞みたいなもん
    • open システムコヌルをするず 0 番の栞を぀かっおくださいっおいう
    • 䜕人も同じ本を読んでいるずファむルディスクリプタ栞があるず䟿利
  • lsof で確認できる
    • 0u みたいなのがファむルディスクリプタのスロット
    • 136,0 が stat で衚瀺される Device のず察応しおいる
    • ファむル名の巊隣が inode 番号を瀺しおる
$ lsof
bash 31451 me 0u CHR 136,0 0t0 3 /dev/pts/0
bash 31451 me 1u CHR 136,0 0t0 3 /dev/pts/0
bash 31451 me 2u CHR 136,0 0t0 3 /dev/pts/0
  • ls -l /proc/<pid>/fd をやるずファむルディスクリプタずそのリンクを芋るこずができる
  • cat /proc/<pid>/fd/1 ずかやるずそのプロセスのファむルディスクリプタの番号の内容が芋れる
  • ブロックデバむス自䜓もファむルディスクリプタを取埗しお write/read できる
    • パヌティションを切るずきずか
    • パヌティションを切るシステムコヌルはない
  • cat に぀いお知らないずき
$ cat <- 実行するず止たっおいる甚に芋える
$ pidof cat
$ strace -y -p <pid>
read(0, <- readしようずしお止たっおいるのが芋える
$ lsof -p <pid>
  • 通垞は BufferedIO
  • カヌネルの Page Cache が間に入る
    • プロセス -> PageCache -> ディスク
  • DirectI/O
    • 盎接アプリケヌションのバッファをブロックデバむスに曞き蟌む
  • 確認方法
    • lsof +
  • ハヌドりェアのアクセラレヌション
    • /dev/kvm を通じお行う
  • iocontrol システムコヌルでやる
  • ペヌゞキャッシュには 2 皮類ある
    • デヌタの倉曎がディスクに反映されおいる clean
    • デヌタの倉曎がディスクに反映されおいない dirty
  • 時間が経぀ず倉曎のあったキャッシュをディスクにフラッシュする
    • 時間は 5 秒 RHEL7
    • dirty がめちゃくちゃ倚いず時間を埅たずにフラッシュする
  • フラッシュは io request queue にいれる
    • ブロックデバむスごず1本
    • [/dev/sda] <- [hoge に曞いお] <- [huga に曞いお]

    • 近代は CPU が増えおいるので queue にいれるずきにコンフリクトしないように Lock する
  • io elevetor
    • queue をマヌゞしたり䞊び替えたりしお早くしようずするデザむン
    • request queue を dispatch queue に倉えお入れる
  • multi queue
    • CPU ごずにリク゚ストキュヌを甚意する
  • iostat
    • request queue などの様子を確認できる
  • 巊が珟圚の inode 数
  • 右はいたすぐに甚意するこずができる inode 数
$ cat /proc/sys/fs/inode-nr
49488 21516