From 1b8d5a8e911ac97a31a0ef69765ec6e0e6b4052f Mon Sep 17 00:00:00 2001 From: ETWen Date: Tue, 25 Aug 2026 17:03:36 +0800 Subject: [PATCH] feat(usb): Detect the USB target instead of assuming /dev/sda1 New Blanton_Script/usb_target.sh reports a USB mass-storage device's node, mount point or by-id path. It excludes whatever disk backs / and /host -- this platform can boot from a USB DOM, which also reports TRAN=usb -- refuses to guess when several USB disks are present, falls back to the whole device for superfloppy media, and when mounting, checks the result is actually writable rather than trusting that mount succeeded. Script B asks it for the device node and builds the stress command from the answer, so a stick that enumerates as sdb no longer sends the write test at whatever /dev/sda1 happens to be. The device is carried back through an echo marker, split in the shell literal as "< V1.0.8 history updated. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM --- src/Script_ABC_Blanton/1_Blanton_Script_A.ttl | 4 + src/Script_ABC_Blanton/2_Blanton_Script_B.ttl | 17 +- src/Script_ABC_Blanton/3_Blanton_Script_C.ttl | 4 +- .../Blanton_Script/usb_target.sh | 203 ++++++++++++++++++ 4 files changed, 224 insertions(+), 4 deletions(-) create mode 100644 src/Script_ABC_Blanton/Blanton_Script/usb_target.sh diff --git a/src/Script_ABC_Blanton/1_Blanton_Script_A.ttl b/src/Script_ABC_Blanton/1_Blanton_Script_A.ttl index c0d1977..4e604d7 100644 --- a/src/Script_ABC_Blanton/1_Blanton_Script_A.ttl +++ b/src/Script_ABC_Blanton/1_Blanton_Script_A.ttl @@ -47,6 +47,10 @@ ; ScriptB Re-enable bmc_monitor.sh start ; ScriptC Re-enable bmc_monitor.sh stop + cat bmc_poll.log ; ScriptC Copy bmc_poll.log + mgmt_ping.log into jobs/ before the USB archive +; Blanton_Script/usb_target.sh Created - auto-detect USB device node / mount point +; ScriptB USB stress uses the detected node, not a hard-coded /dev/sda1 +; ScriptB DDR memtester runs continuously (drop the 100-pass limit) +; ScriptC Move bgctl reset --yes after the USB archive ; ============================================================================= include "config.ttl" diff --git a/src/Script_ABC_Blanton/2_Blanton_Script_B.ttl b/src/Script_ABC_Blanton/2_Blanton_Script_B.ttl index 8513b49..808190f 100644 --- a/src/Script_ABC_Blanton/2_Blanton_Script_B.ttl +++ b/src/Script_ABC_Blanton/2_Blanton_Script_B.ttl @@ -33,16 +33,29 @@ wait prompt_sonic_root sendln "./Blanton_Script/bmc_monitor.sh start" ; ========== DDR MEMORY STRESS TEST ========== +;wait prompt_sonic_root +;sendln "bgctl run /usr/sbin/memtester 1G 100" wait prompt_sonic_root -sendln "bgctl run /usr/sbin/memtester 1G 100" +sendln "bgctl run /usr/sbin/memtester 1G" ; Continue Execture ; ========== SSD read/write ========== wait prompt_sonic_root sendln "bgctl run qfx5252-stress-ssd 1G --runtime 3600 --passes 5 --write --force --log /host/hw-eval/current/qfx5252-stress-ssd.log" ; ========== USB read/write ========== +; ---- Get USB partition node -> usb_dev ---- +usb_dev = '' wait prompt_sonic_root -sendln "bgctl run qfx5252-stress-usb /dev/sda1 256M --runtime 60 --passes 1 --write --log /host/hw-eval/qfx5252-stress-usb.log" +sendln 'D=$(bash ~/Blanton_Script/usb_target.sh -o dev 2>/dev/null); echo "<>"' +waitregex '<]*)>>' +usb_dev = groupmatchstr1 + +wait prompt_sonic_root +sprintf2 cmd "bgctl run qfx5252-stress-usb %s 256M --runtime 60 --passes 1 --write --log /host/hw-eval/qfx5252-stress-usb.log" usb_dev +sendln cmd + +;wait prompt_sonic_root +;sendln "bgctl run qfx5252-stress-usb /dev/sda1 256M --runtime 60 --passes 1 --write --log /host/hw-eval/qfx5252-stress-usb.log" ; ========== SHOW Background job ========== wait prompt_sonic_root diff --git a/src/Script_ABC_Blanton/3_Blanton_Script_C.ttl b/src/Script_ABC_Blanton/3_Blanton_Script_C.ttl index 066ca16..11a71f5 100644 --- a/src/Script_ABC_Blanton/3_Blanton_Script_C.ttl +++ b/src/Script_ABC_Blanton/3_Blanton_Script_C.ttl @@ -17,8 +17,6 @@ wait prompt_sonic_root sendln "bgctl stop --all" wait prompt_sonic_root sendln "bgctl stop --all" -wait prompt_sonic_root -sendln "bgctl reset --yes" ; BMC USB Test STOP wait prompt_sonic_root sendln "systemctl stop qfx5252-bmc-usb-net-test.service" @@ -124,5 +122,7 @@ sendln cmd ; ========== HW Test Session ========== wait prompt_sonic_root sendln "hw-test-session finish" +wait prompt_sonic_root +sendln "bgctl reset --yes" messagebox 'GOOD JOB! Test Case DONE' 'teraterm' \ No newline at end of file diff --git a/src/Script_ABC_Blanton/Blanton_Script/usb_target.sh b/src/Script_ABC_Blanton/Blanton_Script/usb_target.sh new file mode 100644 index 0000000..161eceb --- /dev/null +++ b/src/Script_ABC_Blanton/Blanton_Script/usb_target.sh @@ -0,0 +1,203 @@ +#!/bin/bash +############################################################################### +# usb_target.sh +# +# Version : V1.1.0 +# Author : ETWen +# Date : 20260825 +# Purpose : Auto-detect an inserted USB mass-storage device and report either +# its device node, its mount point, or both. +# +# stdout : requested value(s) only, for $(...) capture +# stderr : diagnostic messages +# +# Usage : usb_target.sh [-o dev|mnt|both|id] [-n] [-r seconds] +# +# -o dev print partition device node (e.g. /dev/sda1) +# -o mnt print mount point (e.g. /mnt/usb) [default] +# -o both print " " on one line +# -o id print stable by-id path (/dev/disk/by-id/...) +# -n detect only, do not mount +# -r sec udev enumeration wait, default 15 +# +# Exit : 0 success +# 1 no USB mass-storage found +# 2 multiple USB disks detected (refuse to guess) +# 3 no usable filesystem on the device +# 4 mount failed +# 5 mounted but not writable +# +# Version History +# V1.0.0 20260825 Initial Version +# V1.1.0 20260825 Add -o/-n/-r options; expose device node and by-id path +############################################################################### +set -u + +MNT_BASE="/mnt/usb" +RETRY=15 +OUTPUT="mnt" +DO_MOUNT=1 + +log() { echo "[usb] $*" >&2; } # diagnostics go to stderr; stdout stays clean + +while getopts "o:nr:h" opt; do + case "$opt" in + o) OUTPUT="$OPTARG" ;; + n) DO_MOUNT=0 ;; + r) RETRY="$OPTARG" ;; + h) sed -n '3,30p' "$0" >&2; exit 0 ;; + *) log "invalid option"; exit 1 ;; + esac +done +shift $((OPTIND - 1)) + +case "$OUTPUT" in + dev|mnt|both|id) ;; + *) log "invalid -o value: $OUTPUT"; exit 1 ;; +esac + +# "-o dev" / "-o id" alone does not require mounting. +[ "$OUTPUT" = "dev" ] && [ "$DO_MOUNT" = "1" ] && DO_MOUNT=0 +[ "$OUTPUT" = "id" ] && [ "$DO_MOUNT" = "1" ] && DO_MOUNT=0 + +#------------------------------------------------------------------------------ +# Identify the physical disk(s) backing rootfs / /host so they can be excluded. +# Needed because some platforms boot from a USB DOM, which also reports TRAN=usb. +#------------------------------------------------------------------------------ +get_system_disk() { + local src + for mp in /host / ; do + src=$(findmnt -no SOURCE "$mp" 2>/dev/null) || continue + lsblk -no PKNAME "$src" 2>/dev/null | head -1 + done | sort -u +} + +#------------------------------------------------------------------------------ +# List candidate USB disks (whole devices, not partitions). +#------------------------------------------------------------------------------ +find_usb_disks() { + local sysdisks; sysdisks=$(get_system_disk) + lsblk -dn -o NAME,TYPE,TRAN,RM 2>/dev/null | while read -r name type tran rm; do + [ "$type" = "disk" ] || continue + case "$name" in loop*|ram*|dm-*|sr*|zram*) continue ;; esac + + # Older util-linux may not expose the TRAN column; fall back to sysfs. + if [ "$tran" != "usb" ]; then + readlink -f "/sys/block/$name/device" 2>/dev/null | grep -q '/usb[0-9]' || continue + [ "$rm" = "1" ] || continue + fi + + echo "$sysdisks" | grep -qx "$name" && { log "skip $name (system disk)"; continue; } + echo "/dev/$name" + done +} + +#------------------------------------------------------------------------------ +# Pick a mountable partition from a disk; fall back to the whole device for +# superfloppy layouts (filesystem written directly, no partition table). +#------------------------------------------------------------------------------ +pick_partition() { + local disk="$1" p + p=$(lsblk -ln -o NAME,TYPE,FSTYPE "$disk" | \ + awk '$2=="part" && $3!="" {print "/dev/"$1; exit}') + [ -n "$p" ] && { echo "$p"; return; } + [ -n "$(lsblk -dn -o FSTYPE "$disk")" ] && echo "$disk" +} + +#------------------------------------------------------------------------------ +# Resolve a device node to a stable /dev/disk/by-id path, if one exists. +#------------------------------------------------------------------------------ +resolve_by_id() { + local dev="$1" real link + real=$(readlink -f "$dev") + for link in /dev/disk/by-id/*; do + [ -e "$link" ] || continue + case "$link" in *-part*|*) ;; esac + [ "$(readlink -f "$link")" = "$real" ] && { echo "$link"; return 0; } + done + return 1 +} + +#------------------------------------------------------------------------------ +# Main +#------------------------------------------------------------------------------ +disks="" +for i in $(seq 1 "$RETRY"); do + disks=$(find_usb_disks) + [ -n "$disks" ] && break + sleep 1 +done + +[ -z "$disks" ] && { log "no USB mass-storage found"; exit 1; } + +n=$(echo "$disks" | wc -l) +if [ "$n" -gt 1 ]; then + log "multiple USB disks detected, refuse to guess:" + log "$disks" + exit 2 +fi +disk="$disks" + +part=$(pick_partition "$disk") +[ -z "$part" ] && { log "$disk has no usable filesystem"; exit 3; } + +fstype=$(lsblk -no FSTYPE "$part") +log "found $part (disk=$disk fstype=$fstype)" + +# --- device-node only: no mount needed --------------------------------------- +if [ "$OUTPUT" = "dev" ]; then + echo "$part" + exit 0 +fi + +if [ "$OUTPUT" = "id" ]; then + if byid=$(resolve_by_id "$part"); then + echo "$byid" + exit 0 + fi + log "no by-id path for $part, falling back to device node" + echo "$part" + exit 0 +fi + +# --- mount point required ---------------------------------------------------- +mp=$(lsblk -no MOUNTPOINT "$part" | head -1) + +if [ -z "$mp" ] && [ "$DO_MOUNT" = "0" ]; then + log "$part is not mounted and -n was given" + exit 4 +fi + +if [ -z "$mp" ]; then + log "mounting $part -> $MNT_BASE" + mkdir -p "$MNT_BASE" + + # exfat/ntfs are not always built into the platform kernel. + case "$fstype" in + exfat) grep -qw exfat /proc/filesystems || modprobe exfat 2>/dev/null ;; + ntfs) grep -qw ntfs3 /proc/filesystems || modprobe ntfs3 2>/dev/null ;; + esac + + if ! mount -o rw,noatime "$part" "$MNT_BASE" 2>/dev/null; then + log "mount failed (fstype=$fstype)" + exit 4 + fi + mp="$MNT_BASE" + + # Verify it is actually writable (read-only media, dirty FAT, or full device). + if ! touch "$mp/.wtest" 2>/dev/null; then + log "mounted read-only or no space left" + umount "$mp" + exit 5 + fi + rm -f "$mp/.wtest" +else + log "$part already mounted at $mp" +fi + +if [ "$OUTPUT" = "both" ]; then + echo "$part $mp" +else + echo "$mp" +fi +exit 0