歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> OpenWRT嵌入式Linux故障排除一例

OpenWRT嵌入式Linux故障排除一例

日期:2017/2/28 14:23:48   编辑:Linux教程

跟大數據沒關系,只是幫朋友忙排了個錯記錄一下。

以前關系很不錯的同事,目前在企業級wifi領域創業,采購了我們的大數據服務,正在給他做平台的搭建和調試。然後這幾天他這個CEO在調試路由器的時候遇到一些問題,在搞大數據的同時捎帶手解決了一下他這個問題。

OpenWRT,嵌入式Linux,主要用在MIPS或ARM設備上。路由器和wifi設備很多會采用這個系統,特點是輕巧。

Coova-Chilli,在openwrt下的接入訪問控制器,提供認證網關,可以使用radius或http來做接入計費等工作。

正常的話,在啟動chilli以後,會啟動四個tun虛擬隧道網卡,而故障是偶發性的,不定期的會有兩個IP地址一樣的tun設備。比如是這樣

tun0 10.1.0.1

tun1 10.1.0.1

tun2 10.2.0.1

tun3 10.3.0.1

tun4 10.4.0.1

正常的情況下是應該只有tun0-3的設備,但是每次啟動都會多出一兩個tun,而且還不固定,有時候是tun0-1 IP地址一樣,有時候tun2-3 IP地址一樣。而且OpenWRT默認是不記錄syslog的。很難排查。其實可以從logread裡面讀取syslog,但是syslog裡其實沒記錄任何東西。

那哥們以前也是寫代碼的,苦熬了三個通宵沒找到問題在哪,在chilli啟動腳本裡面設置了各種記log,wait,sleep,都沒用。下午過去討論完當前大數據平台的需求就沒事了,然後我閒的蛋疼就給他看了一下那個腳本,chilli腳本應該沒有太多的問題,然後他是按照官方部署文檔搭建的。一開始也沒看出問題在哪。chilli腳本默認是放在/etc/init.d目錄下的。按說不會有問題,後來快感來了,他告訴我他寫了一個命令在rc.local做啟動,我看了一下rc.local裡面,他寫了一個啟動腳本放到了/root下面。vi 那個在/root下的啟動腳本,裡面寫了一個/etc/init.d/chilli restart。我就問他這是干嘛用的,他說wrt官方讓這樣寫,說這樣寫保險。我嘗試注銷掉restart行,重啟10遍,tun隧道都毫無問題。20分鐘搞定。

問題分析

chilli原始腳本如下

#! /bin/sh
### BEGIN INIT INFO
# Provides: chilli
# Required-Start: $remote_fs $syslog $network
# Required-Stop: $remote_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start CoovaChilli daemon at boot time
# Description: Enable CoovaChilli service provided by daemon.
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/chilli
NAME=chilli
DESC=chilli
START_CHILLI=0
if [ -f /etc/default/chilli ] ; then
. /etc/default/chilli
fi
if [ "$START_CHILLI" != "1" ] ; then
echo "Chilli default off. Look at /etc/default/chilli"
exit 0
fi
test -f $DAEMON || exit 0
. /etc/chilli/functions
MULTI=$(ls /etc/chilli/*/chilli.conf 2>/dev/null)
[ -z "$DHCPIF" ] && [ -n "$MULTI" ] && {
for c in $MULTI;
do
echo "Found configuration $c"
DHCPIF=$(basename $(echo $c|sed 's#/chilli.conf##'))
export DHCPIF
echo "Running DHCPIF=$DHCPIF $0 $*"
sh $0 $*
done
exit
}
if [ -n "$DHCPIF" ]; then
CONFIG=/etc/chilli/$DHCPIF/chilli.conf
else
CONFIG=/etc/chilli.conf
fi
[ -f $CONFIG ] || {
echo "$CONFIG Not found"
exit 0
}
check_required
RETVAL=0
prog="chilli"
case "$1" in
start)
echo -n "Starting $DESC: "
/sbin/modprobe tun >/dev/null 2>&1
echo 1 > /proc/sys/net/ipv4/ip_forward
writeconfig
radiusconfig
test ${HS_ADMINTERVAL:-0} -gt 0 && {
(crontab -l 2>&- | grep -v $0
echo "*/$HS_ADMINTERVAL * * * * $0 radconfig"
) | crontab - 2>&-
}
ifconfig $HS_LANIF 0.0.0.0
start-stop-daemon --start --quiet --pidfile /var/run/$NAME.$HS_LANIF.pid \
--exec $DAEMON -- -c $CONFIG
RETVAL=$?
echo "$NAME."
;;
checkrunning)
check=`start-stop-daemon --start --exec $DAEMON --test`
if [ x"$check" != x"$DAEMON already running." ] ; then
$0 start
fi
;;
radconfig)
[ -e $MAIN_CONF ] || writeconfig
radiusconfig
;;
restart)
$0 stop
sleep 1
$0 start
RETVAL=$?
;;
stop)
echo -n "Stopping $DESC: "
crontab -l 2>&- | grep -v $0 | crontab -
start-stop-daemon --oknodo --stop --quiet --pidfile /var/run/$NAME.$HS_LANIF.pid \
--exec $DAEMON
echo "$NAME."
;;
reload)
echo "Reloading $DESC."
start-stop-daemon --stop --signal 1 --quiet --pidfile \
/var/run/$NAME.$HS_LANIF.pid --exec $DAEMON
;;
condrestart)
check=`start-stop-daemon --start --exec $DAEMON --test`
if [ x"$check" != x"$DAEMON already running." ] ; then
$0 restart
RETVAL=$?
fi
;;
status)
status chilli
RETVAL=$?
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|condrestart|status|reload|radconfig}" >&2
exit 1
;;
esac
exit 0

問題在於,他在調試的時候,在for c in $MULTI循環裡面,為了保證每個子進程都啟動成功,加了一個wait,後面在建立tun通道的時候為了調試又加了幾個sleep。照著官方文檔,他又加了個restart到rc.local裡面,這樣問題就來了,/etc/init.d裡面是自動執行chilli start命令的,而加上了wait和sleep。init.d的啟動腳本會等待,而這時候Linux在不同的tty又啟動了rc.local裡面的chilli restart命令,於是兩個或三個相同的tun IP地址就會共同存在。

反正問題解決了,鑒於他為這種破事熬了三個通宵,我就可以以先知的口吻教育這個親自調試程序的CEO:“盡信書不如無書”。開源系統的官方文檔往往滯後,可能新版本早就解決了需要restart的問題,但是文檔沒有及時更新,導致這種問題的發生。

總結,了解各種系統的工作原理是多麼重要。

OpenWrt下交叉編譯Node.js(HG255D) http://www.linuxidc.com/Linux/2014-06/102734.htm

OpenWRT上判斷客戶端在線個數 http://www.linuxidc.com/Linux/2014-06/102733.htm

Ubuntu親自手動編譯Openwrt (DreamBox): for njit....ipk http://www.linuxidc.com/Linux/2014-02/97217.htm

基於Tiny210v2編譯OpenWrt http://www.linuxidc.com/Linux/2013-07/87621.htm

Copyright © Linux教程網 All Rights Reserved