背景
路由器在使用過程中,偶像啟動挂載檔案系統異常,檢視列印後發現挂載overlay異常,列印錯誤代碼-39,跟蹤代碼發現由于work目錄非空導緻清除失敗,接下來分析原因。
overlay原理
通過overlay挂載,可保護lower分區使其隻讀,對lower分區需改檔案放在upper目錄,workdir目錄用于檔案的原子性保證。
錯誤列印overlayfs: cleanup of 'work/work' failed (-39)
Unable to handle kernel NULL pointer dereference at virtual address 00000030
pgd = ffffffc034282000
[00000030] *pgd=00000000343ca003, *pud=00000000343ca003, *pmd=000000003e1c6003, *pte=0000000000000000
Internal error: Oops: 96000007 [#1] PREEMPT SMP
Modules linked in:
CPU: 1 PID: 910 Comm: rm Not tainted 4.1.27 #1
Hardware name: Broadcom-v8A (DT)
task: ffffffc03e103100 ti: ffffffc033c7c000 task.ti: ffffffc033c7c000
PC is at ovl_do_remove+0x158/0x394
LR is at ovl_do_remove+0x150/0x394
pc : [] lr : [] pstate: 20000145
sp : ffffffc033c7fcd0
x29: ffffffc033c7fcd0 x28: ffffffc033c7c000
x27: 0000000000000000 x26: 00000000ffffffec
x25: 00000000ffffffeb x24: 0000000000000000
x23: ffffffc03e5817d0 x22: ffffffc03423a7c0
x21: ffffffc03e581728 x20: 00000000fffffff4
x19: ffffffc03e57f0d8 x18: 0000000000000000
x17: 0000000000000000 x16: ffffffc00014541c
x15: 0000000000000000 x14: 0000003fffffffff
x13: 0000003fffffffff x12: 0000000000000000
x11: 0000000000000000 x10: 0000000000000000
x9 : 0000000000000000 x8 : 0000000000000000
x7 : ffffffc0007f7678 x6 : ffffffc03423a838
x5 : 0000000000000000 x4 : 0000000000000000
x3 : 0000000000000000 x2 : ffffffc03e1035c8
x1 : ffffffc03ea9f9c0 x0 : ffffffc03e55cd98
解決思路
1、最簡單的方式在啟動腳本種檢查work非空就删除檔案并重新開機進行恢複,方法簡單但是有副作用導緻二次重新開機;dir="/xxx/work/work"
is_empty_dir(){
return `/bin/ls -A $1|wc -w`
}
if [ -d $dir ]; then
/bin/echo "$dir is dir"
if is_empty_dir $dir
then
/bin/echo "$dir is empty"
else
/bin/echo "$dir is not empty, cleanup!"
/bin/rm -rf $dir/*
reboot
fi
else
echo "$dir is NULL!"
fi
2、在啟動挂載overlay時,發現work目錄非空也強制進行删除,work目錄下存放的時中間檔案,可以直接删除的;
解決
網上搜尋發現有網友遇到此問題,并通過核心更新檔解決此問題,這個問題應該算是overlay的bug,在後面高版本的核心已經解決了此問題,是以問題很簡單了,找到更新檔或者對比高版本核心,合入清除work代碼;
總結
需要對overlay檔案系統工作方式熟悉,并跟蹤代碼發現問題和解決問題。