在小米AX6000中通过米家控制tailscale
由于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 sizeif [ -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 fileKEEP_LINES=$(wc -l < "$LOG_FILE" | awk '{print int($1 * 0.2)}')if [ $KEEP_LINES -gt 0 ]; thentail -n $KEEP_LINES "$LOG_FILE" > "$LOG_FILE.tmp"mv "$LOG_FILE.tmp" "$LOG_FILE"else# If calculation fails, just truncate the fileecho "" > "$LOG_FILE"fifiecho "$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" ]; thenLED_STATUS=$(grep -o "option BLUE_LED '[01]'" "$LED_CONFIG" | grep -o "[01]")# Get last LED_STATUS stateLAST_LED_STATUS=""if [ -f "$LAST_LED_STATUS_FILE" ]; thenLAST_LED_STATUS=$(cat "$LAST_LED_STATUS_FILE")fi# Log only when LED_STATUS state changesif [ "$LED_STATUS" != "$LAST_LED_STATUS" ]; thenif [ "$LED_STATUS" = "1" ]; thenlog "LED_STATUS state changed to enabled (1), Tailscale should run."elselog "LED_STATUS state changed to disabled (0), Tailscale should not run."fi# Save new stateecho "$LED_STATUS" > "$LAST_LED_STATUS_FILE"fiif [ "$LED_STATUS" = "1" ]; thenreturn 0elsereturn 1fielse# Check if we've already logged this errorif [ -f "$LAST_LED_STATUS_FILE" ] && [ "$(cat "$LAST_LED_STATUS_FILE")" != "error" ]; thenlog "xiaoqiang config file not found at $LED_CONFIG"echo "error" > "$LAST_LED_STATUS_FILE"fireturn 1fi
}# Function: Kill Tailscale processes
kill_tailscale() {# Find process IDs for tailscale processesTAILSCALED_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 killif [ -n "$TAILSCALED_PIDS" ] || [ -n "$TAILSCALE_PIDS" ]; thenlog "Stopping Tailscale processes..."# Kill tailscale processesfor PID in $TAILSCALE_PIDS; dokill $PID 2>/dev/nulldone# Kill tailscaled processesfor PID in $TAILSCALED_PIDS; dokill $PID 2>/dev/nulldone# Give processes a moment to terminatesleep 1# Verify processes were terminatedREMAINING_TAILSCALED=$(ps | grep "$TAILSCALED_PATH" | grep -v grep)REMAINING_TAILSCALE=$(ps | grep "$TAILSCALE_PATH" | grep -v grep)if [ -z "$REMAINING_TAILSCALED" ] && [ -z "$REMAINING_TAILSCALE" ]; thenlog "Tailscale processes successfully terminated."elselog "Failed to terminate some Tailscale processes, attempting force kill..."# Try force kill for any remaining processesfor PID in $(ps | grep "$TAILSCALED_PATH" | grep -v grep | awk '{print $1}'); dokill -9 $PID 2>/dev/nulldonefor PID in $(ps | grep "$TAILSCALE_PATH" | grep -v grep | awk '{print $1}'); dokill -9 $PID 2>/dev/nulldonefifi
}# Function: Check and start Tailscale
start_tailscale() {# Only log when actually startinglog "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 ]; thenlog "Tailscale started successfully."elselog "Failed to start Tailscale."fi
}# Function: Check and start Tailscaled
start_tailscaled() {if [ -z "$(pgrep -f "$TAILSCALED_PATH")" ]; thenlog "Tailscaled is not running, starting..."# Run tailscaled without logging its output"$TAILSCALED_PATH" >/dev/null 2>&1 &if [ $? -eq 0 ]; thenlog "Tailscaled started successfully."start_tailscaleelselog "Failed to start Tailscaled."fifi
}# Function: Check Tailscale status
check_tailscale_status() {# Capture status but don't log itSTATUS=$("$TAILSCALE_PATH" status 2>/dev/null)if echo "$STATUS" | grep "xiaomi-ax6000" >/dev/null; thenLINE=$(echo "$STATUS" | grep "xiaomi-ax6000")FOURTH_FIELD=$(echo "$LINE" | awk '{print $5}')if [ "$FOURTH_FIELD" = "offline" ]; thenlog "Device xiaomi-ax6000 is offline, restarting Tailscale..."start_tailscaledfielif echo "$STATUS" | grep "Tailscale is stopped" >/dev/null; thenlog "Tailscale is stopped, restarting...""$TAILSCALE_PATH" up >/dev/null 2>&1elselog "Device xiaomi-ax6000 not found, starting Tailscale..."start_tailscalefi
}# 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 neededif [ -z "$(pgrep -f "$TAILSCALED_PATH")" ]; thenlog "Tailscaled not running, starting services..."start_tailscaledelse# Only check status without loggingcheck_tailscale_statusfi
else# ledstatus is 0, kill Tailscale processeskill_tailscale
fi#log "Check completed."