Systemtap 用法

<meta charset="utf-8">

霸爺博客,干貨滿滿岗仑。有兩篇文章現(xiàn)在還記得聚请,《Linux下如何知道文件被哪個(gè)進(jìn)程寫》《巧用Systemtap注入延遲模擬IO設(shè)備抖動(dòng)》,周末突然想起來炸卑,發(fā)現(xiàn)能看懂了:)

什么是 systemtap

Systemtap is a tool that allows developers and administrators to write and reuse simple scripts to deeply examine the activities of a live Linux system. Data may be extracted, filtered, and summarized quickly and safely, to enable diagnoses of complex performance or functional problems.

我們一般調(diào)試程序盖文,業(yè)務(wù)程序加日志蚯姆,打 log, 基本能滿足需求洒敏。再不濟(jì)返帕,使用 strace荆萤、lsof铣卡、perf 足夠看到性能瓶勁,可以參考我 go gc 的文章敞峭。但是系統(tǒng)編程蝉仇,就不能狂打日志轿衔,而且很多調(diào)用棧都處于 kernel space,那么普通的調(diào)試手段就顯得捉襟見肘了害驹。

此時(shí) systemtap 就能派上用場宛官,他會在內(nèi)核函數(shù)加 probe 探針,對 kernel space 函數(shù)調(diào)用進(jìn)行統(tǒng)計(jì)匯總腋么,甚至可以對其進(jìn)行干預(yù)亥揖。但是對 user space 調(diào)試支持不是很好徐块。

安裝

本機(jī)環(huán)境:DELL R720, Ubuntu 14.04 3.19.0-25-generic x86_64

apt-get  install systemtap systemtap-client systemtap-common systemtap-runtime systemtap-server -y

對于 centos 系統(tǒng)也一樣,yum install 即可扳剿。此時(shí)還要使用執(zhí)行 stap-prep 安裝缺失的內(nèi)核鏡像調(diào)試包昼激。比如我的就是

linux-image-3.19.0-25-generic-dbgsym_3.19.0-25.26~14.04.1_amd64.ddeb

遇到缺什么包直接安裝锡搜,或是從網(wǎng)上下載耕餐。systemtap 最好不要用源碼安裝辟狈,涉及內(nèi)核的包都很惡心,版本必須匹配明未,可以用 uname -r 查看壹蔓。

1. Linux下如何知道文件被哪個(gè)進(jìn)程寫

有個(gè)文件佣蓉,不定期的被修改,如果只是瞬間的寫入行疏,lsof 也沒有辦法套像,就算定期執(zhí)行,也可能有缺失贞让。那么此時(shí) systemtap 就該大顯身手了柳譬,先上代碼:

#!/usr/bin/env stap

probe vfs.write, vfs.read
{
  if (@defined($file->f_path->dentry)) {
    dev_nr=$file->f_path->dentry->d_inode->i_sb->s_dev
    inode_nr = $file->f_path->dentry->d_inode->i_ino
    } else {
    dev_nr=$file->f_dentry->d_inode->i_sb->s_dev
    inode_nr = $file->f_dentry->d_inode->i_ino
    }
  # dev and ino are defined by vfs.write and vfs.read
  if (dev_nr == MKDEV($1,$2) && inode_nr==$3){
    printf ("%s(%d) %s 0x%x/%u\n",execname(), pid(), ppfunc(), dev_nr, inode_nr)
   }
}

probe timer.ms(10) {
    exit()
}

語法類似 awk 代碼很簡單美澳,probe 定義探針,后面緊跟著探測點(diǎn)舅桩,可以是具體的函數(shù)名雨膨,支持 * 匹配聊记,大括號定義探針觸發(fā)動(dòng)作恢暖。

file 是函數(shù) vfs.read, vfs.write 的參數(shù)狰右,dev_nr,inode_nr 根據(jù) file 結(jié)構(gòu)體獲取設(shè)備號和 inode棋蚌,探測點(diǎn)是針對內(nèi)核函數(shù)的,所以可以獲取函數(shù)所有參數(shù)脱拼。

execname 執(zhí)行 vfs.write 或 vfs.read 程序名

pid 執(zhí)行 vfs.write 或 vfs.read 進(jìn)程號

ppfunc 是控測點(diǎn)函數(shù)名坷备,這個(gè)內(nèi)置函數(shù)在不同版本可能不一樣省撑,比如霸爺文章里是 probefuc

1.1 開終端執(zhí)行 dd

打開終端執(zhí)行 dd 不斷的寫入數(shù)據(jù)俯在,并查看文件 inode 號

dd if=/dev/zero of=test.dat

stat -c "%i" /disk1/test.dat
ls -al /dev/sdb1

這里 /dev/sdb1 是掛載在 /disk1 目錄下的設(shè)備

1.2 執(zhí)行 stap 探測

stap -v inodewatch.stp 8 17 15
Pass 1: parsed user script and 95 library script(s) using 84976virt/30204res/5152shr/25852data kb, in 200usr/0sys/456real ms.
Pass 2: analyzed script: 3 probe(s), 7 function(s), 5 embed(s), 0 global(s) using 610884virt/195324res/12432shr/180716data kb, in 1810usr/290sys/3605real ms.
Pass 3: translated to C into "/tmp/stapJEOYcQ/stap_20c430109956cd1ffc28c7ceaf0aa2f1_6899_src.c" using 599240virt/188844res/8908shr/180712data kb, in 0usr/0sys/73real ms.
Pass 4: compiled C into "stap_20c430109956cd1ffc28c7ceaf0aa2f1_6899.ko" in 1840usr/320sys/4180real ms.
Pass 5: starting run.
dd(25763) vfs_write 0x800011/15
dd(25763) vfs_write 0x800011/15
dd(25763) vfs_write 0x800011/15
dd(25763) vfs_write 0x800011/15
dd(25763) vfs_write 0x800011/15
Pass 5: run completed in 0usr/40sys/724real ms.

stap 執(zhí)行腳本需要 5 個(gè)步驟肥败,解析腳本愕提,分析,生成 c 代碼纽谒,編繹成內(nèi)核模塊 ko 文件如输。最后執(zhí)行模塊不见,可以看到 dd 任務(wù)在寫文件,調(diào)用 vfs_write

2. 巧用Systemtap注入延遲模擬IO設(shè)備抖動(dòng)

霸爺?shù)倪@篇例子很有意思稳吮,systemtap 模擬磁盤 IO 抖動(dòng)盖高,對于一些存儲系統(tǒng)眼虱,壓測時(shí)可以試一下捏悬。原理還是很簡單的润梯,在 vfs_write, vfs_read 時(shí) sleep 一小段時(shí)間即可,時(shí)間可以隨機(jī)寇钉。先上代碼

cat inject_ka.stp
global inject, ka_cnt

probe procfs("cnt").read {
  $value = sprintf("%d\n", ka_cnt);
}
probe procfs("inject").write {
  inject= $value;
  printf("inject count %d, ka %s", ka_cnt, inject);
}

probe vfs.read.return,
      vfs.write.return {
  if (@defined($file->f_path->dentry)) {
    dev_nr=$file->f_path->dentry->d_inode->i_sb->s_dev
    inode_nr = $file->f_path->dentry->d_inode->i_ino
    } else {
    dev_nr=$file->f_dentry->d_inode->i_sb->s_dev
    inode_nr = $file->f_dentry->d_inode->i_ino
    }

  if ($return &&
      dev_nr == MKDEV($1,$2) &&
      inject == "on\n")
  {
#   printf("dev %x func: %s\n", dev_nr, ppfunc())
    ka_cnt++;
    udelay($3);
  }
}

probe begin{
  println("ik module begin:)");
}

代碼有些略長扫倡,先看探針 probe vfs.read.return, vfs.write.return 表示在退出前執(zhí)行探針代碼竟纳,判斷 dev_nr 是不是目標(biāo)設(shè)備锥累,并且打開了 ineject, 如果打開缘挑,那么 udelay 一小段時(shí)間。

至于另外兩個(gè)探針桶略,procfs("cnt"), procfs("inject") 讀取 /proc/systemtap 時(shí)觸發(fā)语淘,修改全局變量 inject 來決定是否打開 IO 注入。

2.1 執(zhí)行代碼

這個(gè)腳本執(zhí)行可能會遇到 vfs_lookup_path 報(bào)錯(cuò)际歼,很惡心惶翻,我把 procfs.c 升級了一個(gè)版本,并注釋掉 vfs_lookup_path 部份才解決 ...

stap -DMAXSKIPPED=9999 -m ik -g inject_ka.stp 8 17 400
ik module begin:)

8蹬挺,17 表示磁盤設(shè)備號维贺,400表示 udelay 時(shí)間,此時(shí)腳本阻塞在這里巴帮,并沒有開始執(zhí)行 IO 注入溯泣。打開另一個(gè)終端執(zhí)行注入榕茧,持續(xù) 30 秒垃沦。

echo on| tee /proc/systemtap/ik/inject  && sleep 30 && echo off| tee /proc/systemtap/ik/inject

此時(shí)可以看到 stap 有輸出。

2.2 測試磁盤性能

簡單的使用 dd 來測試 IO 延遲對順序?qū)懙挠绊?/p>

注入前

dd if=/dev/zero of=test.dat  bs=8k count=1000000
1000000+0 records in
1000000+0 records out
8192000000 bytes (8.2 GB) copied, 34.8372 s, 235 MB/s

注入后

dd if=/dev/zero of=test.dat  bs=8k count=1000000
1000000+0 records in
1000000+0 records out
8192000000 bytes (8.2 GB) copied, 79.5475 s, 103 MB/s

可以看到 dd 性能下降很大用押,通過調(diào)整 udelay 時(shí)間可以模擬不同延遲下的性能肢簿。如果是隨機(jī)的,或是符合正態(tài)分布的可能更好。

小結(jié)

官網(wǎng) 有很多 systemtap 使用例子和介紹池充,還可以抓網(wǎng)絡(luò)協(xié)義棧桩引,性能很強(qiáng)大。同時(shí)需要有一定的內(nèi)核功底收夸,至少要知道探針埋在哪里坑匠,openresty 大量使用 systemtap 進(jìn)行調(diào)試,可以參考學(xué)習(xí)卧惜。

另外厘灼,安裝是個(gè)很大問題,一定要注意版本咽瓷,太新也不可以设凹,ubuntu 系統(tǒng) apt 源是 2.3,嘗試過源碼安裝高版本茅姜,各種報(bào)錯(cuò)闪朱。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市匈睁,隨后出現(xiàn)的幾起案子监透,更是在濱河造成了極大的恐慌桶错,老刑警劉巖航唆,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異院刁,居然都是意外死亡糯钙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門退腥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來任岸,“玉大人,你說我怎么就攤上這事狡刘∠砬保” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵嗅蔬,是天一觀的道長剑按。 經(jīng)常有香客問我,道長澜术,這世上最難降的妖魔是什么艺蝴? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮鸟废,結(jié)果婚禮上猜敢,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好缩擂,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布鼠冕。 她就那樣靜靜地躺著,像睡著了一般胯盯。 火紅的嫁衣襯著肌膚如雪供鸠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天陨闹,我揣著相機(jī)與錄音楞捂,去河邊找鬼。 笑死趋厉,一個(gè)胖子當(dāng)著我的面吹牛寨闹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播君账,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼繁堡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乡数?” 一聲冷哼從身側(cè)響起椭蹄,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎净赴,沒想到半個(gè)月后绳矩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玖翅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年翼馆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片金度。...
    茶點(diǎn)故事閱讀 40,505評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡应媚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出猜极,到底是詐尸還是另有隱情中姜,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布跟伏,位于F島的核電站丢胚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏酬姆。R本人自食惡果不足惜嗜桌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辞色。 院中可真熱鬧骨宠,春花似錦浮定、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至匿又,卻和暖如春方灾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背碌更。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工裕偿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人痛单。 一個(gè)月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓嘿棘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親旭绒。 傳聞我的和親對象是個(gè)殘疾皇子鸟妙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容