ファイルキャッシュクリアの謎      技術Bar#9   2012/12/4 光成滋生
cybozu.comで障害発生             ストレージ容量拡張操作の結果、Officeが動             いているLinuxマシンのページキャッシュが約             15分おきに破棄されるという未知の現象が発 ...
現象の詳細mdadmでLVMのパーティションを拡大する と15分毎にpage cacheがクリアされる                             メモリにキャッシュ MySQLなどのアプリ                    ...
調査のやりかた現象の再現方法の構築 頻度が低かったり環境によって起こらないと面倒原因を推測して絞り込み トライアンドエラー さまざまなツールを使う特定したら修正して確認 はずれていたらまた別の原因を推測              ...
現象の確認hazamaでの容量の変更は500GB→1TB バックグラウンドリサイズが長時間 数十MB程度では17分以内に終わってしまう手元の環境でディスクを用意して… 1時間待ったが発現しなかった  私の勘違い     キャッシュ...
犯人は誰か全然見当がつかない 普通ユーザラウンドで明示的に破棄なんてしない page cacheを破棄しそうなkernelの関数を列挙  flush_disk, invalidate_disk, invalidate_parition,...
ftraceの例ext4系関数が呼ばれたときのcall treeを表示// debugfsをmountmount -t debugfs debugfs /sys/kernel/debug// stack tracerを有効echo 1 > /...
あたりをつけるディスクを交換したり,resize開始直後に呼ば れる関数をセットして17分待つ 呼ばれない… 別の関数を試すことの繰り返し このあたりが結構辛い                       8 / 20
漸くヒット__invalidate_deviceが網にかかった!mdadm-900 [001] .... 75491.384221: __invalidate_device <-invalidate_partitionmdadm-900 [00...
犯人はmdadmのdaemon? __invalidate_deviceが網にかかった! mdadm-900 [001] .... 75491.384221: __invalidate_device <-invalidate_partition...
位置関係md daemon          monitor daemon       use space        kernel       ? md driver disk driver       invalidate_partiti...
mdadmのソースをで追いかけるまずこれで1000秒を30秒に短縮できる 調査効率が大幅に改善されるしかしやや戸惑いが monitorコマンドがクリアするとも思えない ファイルキャッシュがクリアされる関数が何か確認  しながらgdbで...
位置関係md daemon          monitor daemon       use space        kernel md driver         md_open                     ? disk d...
md_openを追いかけるcheck_disk_changeが呼ばれている これが怪しい?しかしこいつは犯人ではなかったもう一度call graphをみる __invalidate_deviceが網にかかった! mdadm-900 [0...
blk_devの中身このあたり  // こいつでmd_openが呼ばれる ret = disk->fops->open(bdev, mode); .. if (bdev->bd_invalidated) {    if (!ret)     ...
位置関係md daemon       monitor daemon       use space        kernel   blk_dev md driver                  bd_invalidated      ...
bd_invalidatedフラグを探すクリアしているのは初期化と二カ所rescan_partitions() {  .... disk->fops->revalidate_disk(disk); check_disk_size_change...
クリアし忘れ?しかし,revalidate_disk()の中では check_disk_size_change()を呼んだあとクリ アしていない revalidate_disk() {  ...     mutex_lock(&bdev->b...
動作確認クリアするようにしてkernelをビルド キャッシュクリア問題は起こらないてか,そもそもcheck_disk_size_change()の 中でクリアすればええんとちゃうか?                            ...
その後LinuxのMLに投げる 作法がいろいろある  patchの作り方  scripts/checkpatch.plでパッチフォーマットの検証  patchのMLへの投げかた     git send-emailを使う 題名のつ...
Upcoming SlideShare
Loading in...5
×

Kernel fcache-bug

1,716

Published on

how to find a bug in kernel/fs about wrong page cache flush in resizing MD device.

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,716
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
11
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Kernel fcache-bug

  1. 1. ファイルキャッシュクリアの謎 技術Bar#9 2012/12/4 光成滋生
  2. 2. cybozu.comで障害発生 ストレージ容量拡張操作の結果、Officeが動 いているLinuxマシンのページキャッシュが約 15分おきに破棄されるという未知の現象が発 生したためです 2 / 20
  3. 3. 現象の詳細mdadmでLVMのパーティションを拡大する と15分毎にpage cacheがクリアされる メモリにキャッシュ MySQLなどのアプリ これがクリアされて 激遅に ext3 ファイルシステム mdadm ソフトウェアRAID LVM パーティション管理 kernel/device driver 犯人はだれか? hard disk 3 / 20
  4. 4. 調査のやりかた現象の再現方法の構築 頻度が低かったり環境によって起こらないと面倒原因を推測して絞り込み トライアンドエラー さまざまなツールを使う特定したら修正して確認 はずれていたらまた別の原因を推測 4 / 20
  5. 5. 現象の確認hazamaでの容量の変更は500GB→1TB バックグラウンドリサイズが長時間 数十MB程度では17分以内に終わってしまう手元の環境でディスクを用意して… 1時間待ったが発現しなかった 私の勘違い  キャッシュがクリアされるのはそのディスクに構築し たファイルシステム上のもののみ 再度テスト クリアされることを確認 約17分=>概ね1000秒であることも判明 5 / 20
  6. 6. 犯人は誰か全然見当がつかない 普通ユーザラウンドで明示的に破棄なんてしない page cacheを破棄しそうなkernelの関数を列挙 flush_disk, invalidate_disk, invalidate_parition, ... これらの関数を呼び出すやつを探そうftraceを使って探す ubuntuでは標準搭載 呼ばれた関数,stacktrace,eventなどがわかる /sys/kernel/debug/tracingに様々な値を書き込 むことでパラメータを設定する 結構複雑で慣れるまで難しかった 6 / 20
  7. 7. ftraceの例ext4系関数が呼ばれたときのcall treeを表示// debugfsをmountmount -t debugfs debugfs /sys/kernel/debug// stack tracerを有効echo 1 > /proc/sys/kernel/stack_tracer_enabledcd /sys/kernel/debug/tracing// ext4で始まる関数名をターゲットにecho "ext4*" > set_ftrace_filter// 関数トレーサーをセットecho function > current_tracerecho 0 > trace cat trace_pipeext4のファイルシステムをmoutすると関連関 数のlogが表示される 7 / 20
  8. 8. あたりをつけるディスクを交換したり,resize開始直後に呼ば れる関数をセットして17分待つ 呼ばれない… 別の関数を試すことの繰り返し このあたりが結構辛い 8 / 20
  9. 9. 漸くヒット__invalidate_deviceが網にかかった!mdadm-900 [001] .... 75491.384221: __invalidate_device <-invalidate_partitionmdadm-900 [001] .... 75491.384235: <stack trace>=> ftrace_call=> invalidate_partition=> rescan_partitions=> __blkdev_get 下の関数が上の関数=> blkdev_get=> blkdev_open を呼び出している=> do_dentry_open=> nameidata_to_filp=> do_last=> path_openat=> do_filp_open=> do_sys_open=> sys_open ここから下はユーザ空間=> system_call_fastpathここには重要な情報が… 9 / 20
  10. 10. 犯人はmdadmのdaemon? __invalidate_deviceが網にかかった! mdadm-900 [001] .... 75491.384221: __invalidate_device <-invalidate_partition mdadm-900 [001] .... 75491.384235: <stack trace> => ftrace_call ...ユーザ空間側なのでgdbでひっかけられるsudo gdb –p <processId>でatach backtraceしてみる gdb) bt #0 0x00007f85b1ebf103 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:82 #1 0x000000000040de66 in mdstat_wait (seconds=1000) at mdstat.c:317 #2 0x000000000042dea1 in Monitor (devlist=0x0, mailaddr=0x1a7b020 "root",時間の間隔も正確に1000秒なのがわかる 10 / 20
  11. 11. 位置関係md daemon monitor daemon use space kernel ? md driver disk driver invalidate_partition hard disk clear page cache 11 / 20
  12. 12. mdadmのソースをで追いかけるまずこれで1000秒を30秒に短縮できる 調査効率が大幅に改善されるしかしやや戸惑いが monitorコマンドがクリアするとも思えない ファイルキャッシュがクリアされる関数が何か確認 しながらgdbでstep実行 daemon内部で/dev/mdをopenするだけでクリ アされることが判明 fd = open("dev/md/test..", O_RDONLY); mdのdevice driverの問題? 12 / 20
  13. 13. 位置関係md daemon monitor daemon use space kernel md driver md_open ? disk driver invalidate_partition hard disk clear page cache 13 / 20
  14. 14. md_openを追いかけるcheck_disk_changeが呼ばれている これが怪しい?しかしこいつは犯人ではなかったもう一度call graphをみる __invalidate_deviceが網にかかった! mdadm-900 [001] .... 75491.384221: __invalidate_device <-invalidate_partition mdadm-900 [001] .... 75491.384235: <stack trace> => ftrace_call => invalidate_partition => rescan_partitions => __blkdev_get => blkdev_get => blkdev_openblkdev_getのあたりから分岐してそう 14 / 20
  15. 15. blk_devの中身このあたり // こいつでmd_openが呼ばれる ret = disk->fops->open(bdev, mode); .. if (bdev->bd_invalidated) { if (!ret) rescan_partitions(disk, bdev); else if (ret == -ENOMEDIUM) // この中で__invalidate_paritionが呼ばれる invalidate_partitions(disk, bdev);bd_invalidatedフラグが怪しい 15 / 20
  16. 16. 位置関係md daemon monitor daemon use space kernel blk_dev md driver bd_invalidated md_open disk driver invalidate_partition hard disk clear page cache 16 / 20
  17. 17. bd_invalidatedフラグを探すクリアしているのは初期化と二カ所rescan_partitions() { .... disk->fops->revalidate_disk(disk); check_disk_size_change(disk, bdev); bdev->bd_invalidated = 0;invalidate_partitions() { ... set_capacity(disk, 0); check_disk_size_change(disk, bdev); bdev->bd_invalidated = 0; どちらもcheck_disk_size_change()を呼んで からbd_invalidatedを0クリア 17 / 20
  18. 18. クリアし忘れ?しかし,revalidate_disk()の中では check_disk_size_change()を呼んだあとクリ アしていない revalidate_disk() { ... mutex_lock(&bdev->bd_mutex); check_disk_size_change(disk, bdev); // bdev->bd_invalidated = 0; がない mutex_unlock(&bdev->bd_mutex); このせいでopenするたびに毎回キャッシュクリア 結局LVMでもmdadmでもなくkernel/fsが原因 18 / 20
  19. 19. 動作確認クリアするようにしてkernelをビルド キャッシュクリア問題は起こらないてか,そもそもcheck_disk_size_change()の 中でクリアすればええんとちゃうか? 19 / 20
  20. 20. その後LinuxのMLに投げる 作法がいろいろある patchの作り方 scripts/checkpatch.plでパッチフォーマットの検証 patchのMLへの投げかた  git send-emailを使う 題名のつけかたと投げる場所が不適切だったかも MLに投げたが黙殺 再度別のMLに挑戦 山本さんによる英語メールの推敲(という名の書き直し)  結局パッチを手動で張り付けたものがaccept...  http://git.kernel.org/?p=linux/kernel/git/next/lin ux-next.git;a=commit;h=9b4b0d9f9f9ad2 20 / 20
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×