本文能學到?busybox為例粗略跟蹤軟件執行過程方法?如何判斷文件差異?cron 對任務計劃文件要求
1. 背景
無意中瞟一眼出廠產品的日志文件 /app/recode 大小居然有9MB,按照設計每10min執行任務檢查/app/recode文件大小,該文件不會超過4MB,超過此大小則壓縮處理,僅保留最近的日志內容。立馬著手檢查linux定時任務cron運行情況。
2. 初步排查
執 crontab -e 查看定時任務配置情況,其實是以root權限打開 var/spool/cron/crontabs/root 文件,第二行是本背景該執行的腳本,乍看一下沒有任何問題。檢查 /var/log/message 看是否有被執行的記錄,“cat /var/log/message | grep cron”,干干凈凈!!!的確沒被執行。
本來事情到此為止只算工程師一個平常無奇的日常,不過10min后再查看 /app/recode 居然從9MB變成4KB,/var/log/message也有執行記錄,發生了什么?
3. 分析
為了分析具體原因,準備一新燒錄的板卡作為排查對象。懷疑方向有三個,這三方面都是引起任務計劃不被執行的誘因:crontab file格式不正確
文件系統被改寫
crontab file所屬用戶不合法
3.1. x11 crontab file 格式不正確
crontab file文件位于 var/spool/cron/crontabs/root,當使用crontab -e命令打開該文件,不做任何修改并退出,cron任務計劃能被運行。懷疑var/spool/cron/crontabs/root文件里可能包含不合法字符或語法不正確,如:文件末尾有 、 、一行里有多個空格會影響cron解析該文件。于是執行如下步驟排查:1.備份配置文件cp var/spool/cron/crontabs/root var/spool/cron/crontabs/root.bak;
2.執行crontab -e;
3.cron任務計劃是否被執行,需查看記錄watch -n 1 cat /var/log/message。
4.計算兩文件md5是否一致md5sum var/spool/cron/crontabs/root var/spool/cron/crontabs/root.bak;
結果:文件一致。
證明:“crontab file 格式不正確”不是誘因。
3.2. x12 文件系統被改寫
crontab -e雖然沒有修改var/spool/cron/crontabs/root,但無法證明它有沒有改寫文件系統其他文件。于是在一塊重新燒錄鏡像的板卡執行如下步驟排查:獲取文件系統所有文件的MD5保存為/tmp/a.txt;
find arch bin etc home lib media opt root sbin tmp usr var -name “*” | xargs md5sum 》 /unuse/a.txt
執行crontab -e;
獲取文件系統所有文件的MD5保存為/tmp/b.txt;
find arch bin etc home lib media opt root sbin tmp usr var -name “*” | xargs md5sum 》 /unuse/b.txt比較a.txt和b.txt是否一致,從而證明crontab -e是否修改文件系統內容
結果:a.txt,b.txt文件一致。 證明:“x12 文件系統被改寫”不是誘因。
3.3. x13 crontab file所屬用戶不合法
產品的cron是busybox的組件,源碼面前無秘密。開始跟蹤crond執行過程。 在busybox源碼的miscutils/crond.c添加若干 “printf(”LINE %d“, __ LINE __);”跟蹤程序運行。cron在前臺運行,執行crond -f var/spool/cron/crontabs/root; 發現947行沒有被執行,且文件指針是0;推斷:var/spool/cron/crontabs/root沒有被讀取。
跟蹤文件讀取函數load_crontab發現438行的if第二個條件不滿足,DEAMON_UID是0,只有當sbuf.st_uid也等于0時才能執行文件讀取,實際返回1000。變量sbuf.st_uid表示文件所屬用戶的UID。
?修改crontab file文件的UID和GID都是0,chown 0:0 /var/spool/cron/crontabs/root;
?重新啟動crond:crond -f var/spool/cron/crontabs/
?10min后在/var/log/message里看到任務計劃執行痕跡
Jan 10 1200 (none) cron.info crond[854]: USER root pid 3506 cmd /usr/bin/compresslog.shJan 10 1200 (none) cron.info crond[854]: USER root pid 3508 cmd /usr/local/bin/recode_check.shJan 10 1200 (none) cron.info crond[854]: USER root pid 5007 cmd /usr/local/bin/recode_check.shJan 10 1200 (none) cron.info crond[854]: USER root pid 6506 cmd /usr/local/bin/recode_check.sh結果:修改“crontab file所屬用戶”有效,任務計劃可以正常運行。 證明:“crontab file所屬用戶不合法”是誘因
4. 推斷過程
看到這個1000我已經覺察到問題根本原因,看我娓娓道來。/etc/passwd記錄linux用戶所屬UID、GID。UID=0、GID=0屬于root用戶。passwd有若干ID號,普通預設的用戶的UID、GID在1~999,adduser創建的用戶ID從1000開始,啟動crond守護進程時會根據當前用名去/var/spool/cron/crontabs/目錄下尋找與用戶名同名的文件,順帶檢查該文件的所屬用戶UID,只有文件存在、UID相同才讀取該文件。按照設想,那么crontab -e執行后應該會修改用戶所屬ID,下面是實驗步驟。再修改用戶組為 1000 “chown 1000:root /var/spool/cron/crontabs/root”
觀察crontab -e執行前后文件所屬用戶是否改變
實踐和設想一致:crontab會修改文件所屬用戶。
5. 為什么測試階段沒發現問題
我的Linux系統開發環境普通用戶編碼從1000開始,為避免使用root用戶誤操作危害開發環境,一切文件均在普通用戶環境下編輯,為有編輯權限,曾執行過 chown up /var/spool/cron/crontabs/root(不理解cron設計者為什么要去檢查文件所屬UID,即使當前已經是root權限),這個up就是我的用戶名,up的UID=1000。之所以在軟件測試階段未發現問題,原因在于任務計劃默認10min才執行一次,為縮短測試時間而修改任務計劃執行頻率,提高測試效率,修改方法就是crontab -e編輯 /var/spool/cron/crontabs/root。 當初只注重recode_check.sh執行的正確性。
原文標題:揪出元兇:linux定時任務crontab居然沒執行
文章出處:【微信公眾號:嵌入式ARM】歡迎添加關注!文章轉載請注明出處。
責任編輯:haq
-
Linux
+關注
關注
87文章
11225瀏覽量
208917 -
代碼
+關注
關注
30文章
4744瀏覽量
68345
原文標題:揪出元兇:linux定時任務crontab居然沒執行
文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論