diff --git a/README.md b/README.md index d0a064b..cebe172 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,15 @@ help / clear / quit 1. **守护脚本**自动恢复设备(掉线后重枚举): ```bash + # 部署 (脚本在项目内 usb_guard.sh, 目标设备通用 VID/PID 可在脚本头部修改) + su -c 'cp ~/Proj/TransferSu/usb_guard.sh /data/local/tmp/ && chmod 755 /data/local/tmp/usb_guard.sh' + # 启动 su -c 'setsid sh /data/local/tmp/usb_guard.sh /dev/null 2>&1 &' ``` + 守护脚本功能: ① 应用稳定性调优参数 (SCSI 超时 120s 等) + ② 三种掉线场景自动重枚举恢复 (dmesg 检测 / 异常断开 / 健康探测)。 + 默认绑定 GL3224 读卡器 (VID:PID 05e3:0747), 换设备改脚本头部变量。 + 开机自启: `~/.termux/boot/boot_usb_guard.sh` (Termux:Boot 插件)。 2. **限速传输 + 无限补传 + 校验**: ``` /src/ /dst/ --bwlimit 30000 --retry -1 --verify diff --git a/usb_guard.sh b/usb_guard.sh new file mode 100755 index 0000000..3bbb4ca --- /dev/null +++ b/usb_guard.sh @@ -0,0 +1,92 @@ +#!/system/bin/sh +# USB 读卡器守护脚本 v5 - 仅针对 GL3224 读卡器 (VID:PID 05e3:0747) +# 功能: ①应用稳定性调优 ②掉线自动恢复(3场景) +# 安全: 仅当 USB 端口 2-1 上的设备 VID/PID 匹配时才干预, 其他设备完全不受影响 +DEV_PATH="2-1" +TARGET_VID="05e3" +TARGET_PID="0747" +LOGFILE="/data/local/tmp/usb_guard.log" +AUTHORIZED="/sys/bus/usb/devices/${DEV_PATH}/authorized" +BLKDEV="" +LAST_HEALTH=0 +TUNED=0 + +log() { echo "[$(date '+%F %T')] $1" >> "$LOGFILE"; } + +# 校验当前 2-1 口上的设备是否为目标读卡器 +is_target() { + [ "$(cat /sys/bus/usb/devices/${DEV_PATH}/idVendor 2>/dev/null)" = "$TARGET_VID" ] && \ + [ "$(cat /sys/bus/usb/devices/${DEV_PATH}/idProduct 2>/dev/null)" = "$TARGET_PID" ] +} + +# 动态解析该 USB 设备对应的块设备名 (如 sdg), 避免硬编码 +find_blkdev() { + for b in /sys/class/block/sd[a-z]; do + target=$(readlink -f "$b" 2>/dev/null) + case "$target" in + *"${DEV_PATH}:1.0"*) echo "${b##*/}"; return 0 ;; + esac + done + return 1 +} + +apply_tuning() { + [ -n "$BLKDEV" ] && [ -e "/sys/block/$BLKDEV" ] || return + echo 120 > /sys/block/$BLKDEV/device/timeout 2>/dev/null + echo 256 > /sys/block/$BLKDEV/queue/max_sectors_kb 2>/dev/null + echo none > /sys/block/$BLKDEV/queue/scheduler 2>/dev/null + TUNED=1 + log "已应用调优参数 ($BLKDEV: timeout=120s, max_sectors=256KB, scheduler=none)" +} + +recover() { + log "$1 -> 执行重枚举..." + echo 0 > "$AUTHORIZED" 2>/dev/null + sleep 3 + echo 1 > "$AUTHORIZED" 2>/dev/null + sleep 7 + if [ -f "$AUTHORIZED" ] && [ "$(cat "$AUTHORIZED" 2>/dev/null)" = "1" ]; then + log "重枚举成功,设备恢复" + TUNED=0 + BLKDEV="" + else + log "重枚举失败,请手动检查" + fi + dmesg -c > /dev/null 2>&1 +} + +log "守护脚本启动 v5 (目标: GL3224 05e3:0747)" + +while true; do + if [ -f "$AUTHORIZED" ] && is_target; then + # 解析块设备名 + [ -z "$BLKDEV" ] && BLKDEV=$(find_blkdev) + # 场景B: 异常断开 + if [ "$(cat "$AUTHORIZED" 2>/dev/null)" = "0" ]; then + recover "场景B: 设备异常断开" + continue + fi + # 健康时确保调优参数 + if [ "$TUNED" = "0" ] && [ -n "$BLKDEV" ]; then + apply_tuning + fi + # 场景A: SCSI offline 日志 + if dmesg 2>/dev/null | tail -30 | grep -q "device offline or changed"; then + recover "场景A: 检测到设备假死" + continue + fi + # 场景C: 健康探测 (每12秒, 读扇区0, 5秒超时) + now=$(date +%s) + if [ $((now - LAST_HEALTH)) -ge 12 ] && [ -n "$BLKDEV" ]; then + LAST_HEALTH=$now + if ! timeout 5 dd if="/dev/block/$BLKDEV" bs=512 count=1 of=/dev/null 2>/dev/null; then + recover "场景C: 健康探测超时(静默假死)" + continue + fi + fi + else + # 非目标设备: 完全旁观, 不做任何操作 + sleep 10 + fi + sleep 2 +done