由于tailscale占用内存较大,AX6000中的可用内存非常有限,所以需要对AX6000的内存使用进行优化:
1.减小tmpfs内存占用的大小:
#从150M -> 90M,由于tailscale下载安装包是27M作用, 解压后50M左右,所以预留90M够用了
mount -o remount,size=90m /tmp
2.使用cron来执行脚本,而不是通过while循环创建守护进程
crontab -e
*/10 * * * * /etc/tailscale/tailscaleMonitor.sh >/dev/null 2>&1
/etc/init.d/cron restart
3.创建脚本,检查/etc/config/xiaoqiang中uci的led配置状态来控制是否启动tailscale
#!/bin/sh
#crontab -e
#*/10 * * * * /etc/tailscale/tailscaleMonitor.sh >/dev/null 2>&1
#/etc/init.d/cron restart
# Define Tailscale related paths
TAILSCALED_PATH="/tmp/tailscale/tailscale_1.80.3_arm/tailscaled"
TAILSCALE_PATH="/tmp/tailscale/tailscale_1.80.3_arm/tailscale"
LOG_DIR="/etc/tailscale"
LOG_FILE="$LOG_DIR/tailscale.log"
LED_CONFIG="/etc/config/xiaoqiang"
MAX_LOG_SIZE=1048576 # 1MB in bytes
LAST_LED_STATUS_FILE="$LOG_DIR/last_led_status" # File to store last ledstatus state
# Create log directory
mkdir -p "$LOG_DIR"
# Function: Log messages with log rotation
log() {
# Check log file size
if [ -f "$LOG_FILE" ] && [ $(stat -c%s "$LOG_FILE" 2>/dev/null || stat -f%z "$LOG_FILE") -gt $MAX_LOG_SIZE ]; then
# Rotate log - keep only last 20% of the file
KEEP_LINES=$(wc -l < "$LOG_FILE" | awk '{print int($1 * 0.2)}')
if [ $KEEP_LINES -gt 0 ]; then
tail -n $KEEP_LINES "$LOG_FILE" > "$LOG_FILE.tmp"
mv "$LOG_FILE.tmp" "$LOG_FILE"
else
# If calculation fails, just truncate the file
echo "" > "$LOG_FILE"
fi
fi
echo "$1"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
# Function: Check ledstatus option in xiaoqiang config
check_ledstatus() {
if [ -f "$LED_CONFIG" ]; then
LED_STATUS=$(grep -o "option BLUE_LED '[01]'" "$LED_CONFIG" | grep -o "[01]")
# Get last LED_STATUS state
LAST_LED_STATUS=""
if [ -f "$LAST_LED_STATUS_FILE" ]; then
LAST_LED_STATUS=$(cat "$LAST_LED_STATUS_FILE")
fi
# Log only when LED_STATUS state changes
if [ "$LED_STATUS" != "$LAST_LED_STATUS" ]; then
if [ "$LED_STATUS" = "1" ]; then
log "LED_STATUS state changed to enabled (1), Tailscale should run."
else
log "LED_STATUS state changed to disabled (0), Tailscale should not run."
fi
# Save new state
echo "$LED_STATUS" > "$LAST_LED_STATUS_FILE"
fi
if [ "$LED_STATUS" = "1" ]; then
return 0
else
return 1
fi
else
# Check if we've already logged this error
if [ -f "$LAST_LED_STATUS_FILE" ] && [ "$(cat "$LAST_LED_STATUS_FILE")" != "error" ]; then
log "xiaoqiang config file not found at $LED_CONFIG"
echo "error" > "$LAST_LED_STATUS_FILE"
fi
return 1
fi
}
# Function: Kill Tailscale processes
kill_tailscale() {
# Find process IDs for tailscale processes
TAILSCALED_PIDS=$(ps | grep "$TAILSCALED_PATH" | grep -v grep | awk '{print $1}')
TAILSCALE_PIDS=$(ps | grep "$TAILSCALE_PATH" | grep -v grep | awk '{print $1}')
# Check if any processes were found before trying to kill
if [ -n "$TAILSCALED_PIDS" ] || [ -n "$TAILSCALE_PIDS" ]; then
log "Stopping Tailscale processes..."
# Kill tailscale processes
for PID in $TAILSCALE_PIDS; do
kill $PID 2>/dev/null
done
# Kill tailscaled processes
for PID in $TAILSCALED_PIDS; do
kill $PID 2>/dev/null
done
# Give processes a moment to terminate
sleep 1
# Verify processes were terminated
REMAINING_TAILSCALED=$(ps | grep "$TAILSCALED_PATH" | grep -v grep)
REMAINING_TAILSCALE=$(ps | grep "$TAILSCALE_PATH" | grep -v grep)
if [ -z "$REMAINING_TAILSCALED" ] && [ -z "$REMAINING_TAILSCALE" ]; then
log "Tailscale processes successfully terminated."
else
log "Failed to terminate some Tailscale processes, attempting force kill..."
# Try force kill for any remaining processes
for PID in $(ps | grep "$TAILSCALED_PATH" | grep -v grep | awk '{print $1}'); do
kill -9 $PID 2>/dev/null
done
for PID in $(ps | grep "$TAILSCALE_PATH" | grep -v grep | awk '{print $1}'); do
kill -9 $PID 2>/dev/null
done
fi
fi
}
# Function: Check and start Tailscale
start_tailscale() {
# Only log when actually starting
log "Starting Tailscale client..."
# Run tailscale up without logging its output
#/tmp/tailscale/tailscale_1.80.3_arm/tailscale up --advertise-routes=192.168.0.0/24 >> "$LOG_FILE" 2>&1 &
"$TAILSCALE_PATH" up --advertise-routes=192.168.0.0/24 --accept-dns=false >/dev/null 2>&1 &
if [ $? -eq 0 ]; then
log "Tailscale started successfully."
else
log "Failed to start Tailscale."
fi
}
# Function: Check and start Tailscaled
start_tailscaled() {
if [ -z "$(pgrep -f "$TAILSCALED_PATH")" ]; then
log "Tailscaled is not running, starting..."
# Run tailscaled without logging its output
"$TAILSCALED_PATH" >/dev/null 2>&1 &
if [ $? -eq 0 ]; then
log "Tailscaled started successfully."
start_tailscale
else
log "Failed to start Tailscaled."
fi
fi
}
# Function: Check Tailscale status
check_tailscale_status() {
# Capture status but don't log it
STATUS=$("$TAILSCALE_PATH" status 2>/dev/null)
if echo "$STATUS" | grep "xiaomi-ax6000" >/dev/null; then
LINE=$(echo "$STATUS" | grep "xiaomi-ax6000")
FOURTH_FIELD=$(echo "$LINE" | awk '{print $5}')
if [ "$FOURTH_FIELD" = "offline" ]; then
log "Device xiaomi-ax6000 is offline, restarting Tailscale..."
start_tailscaled
fi
elif echo "$STATUS" | grep "Tailscale is stopped" >/dev/null; then
log "Tailscale is stopped, restarting..."
"$TAILSCALE_PATH" up >/dev/null 2>&1
else
log "Device xiaomi-ax6000 not found, starting Tailscale..."
start_tailscale
fi
}
# Main logic - Single execution for crontab
#log "Running Tailscale monitor check..."
#log "Running Tailscale monitor check..."
# Check userswitch setting
if check_ledstatus; then
# ledstatus is 1, monitor and start Tailscale if needed
if [ -z "$(pgrep -f "$TAILSCALED_PATH")" ]; then
log "Tailscaled not running, starting services..."
start_tailscaled
else
# Only check status without logging
check_tailscale_status
fi
else
# ledstatus is 0, kill Tailscale processes
kill_tailscale
fi
#log "Check completed."