Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 21 additions & 38 deletions Runner/suites/Kernel/Baseport/Storage/UFS_Validation/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,12 @@ log_info "------------- Starting $TESTNAME Test ------------"

check_dependencies dd grep cut head tail udevadm

# --- Kernel Config Checks ---
MANDATORY_CONFIGS="CONFIG_SCSI_UFSHCD CONFIG_SCSI_UFS_QCOM"
OPTIONAL_CONFIGS="CONFIG_SCSI_UFSHCD_PLATFORM CONFIG_SCSI_UFSHCD_PCI CONFIG_SCSI_UFS_CDNS_PLATFORM CONFIG_SCSI_UFS_HISI CONFIG_SCSI_UFS_EXYNOS CONFIG_SCSI_UFS_ROCKCHIP CONFIG_SCSI_UFS_BSG"

log_info "Checking mandatory kernel configs for UFS..."
if ! check_kernel_config "$MANDATORY_CONFIGS" 2>/dev/null; then
log_skip "Missing one or more mandatory UFS kernel configs: $MANDATORY_CONFIGS"
log_skip "Missing mandatory UFS kernel configs: $MANDATORY_CONFIGS"
echo "$TESTNAME SKIP" > "$res_file"
exit 0
fi
Expand All @@ -61,45 +60,19 @@ for cfg in $OPTIONAL_CONFIGS; do
done
[ -n "$missing_optional" ] && log_info "Optional configs not present but continuing:$missing_optional"

# --- Device Tree Check ---
check_dt_nodes "/sys/bus/platform/devices/*ufs*" || {
echo "$TESTNAME SKIP" > "$res_file"
exit 0
}

# --- UFS Block Detection ---
detect_ufs_partition_block() {
if command -v lsblk >/dev/null 2>&1 && command -v udevadm >/dev/null 2>&1; then
for part in $(lsblk -lnpo NAME,TYPE | awk '$2 == "part" {print $1}'); do
if udevadm info --query=all --name="$part" 2>/dev/null | grep -qi "ufs"; then
echo "$part"
return 0
fi
done
fi

for part in /dev/sd[a-z][0-9]*; do
[ -e "$part" ] || continue
if command -v udevadm >/dev/null 2>&1 &&
udevadm info --query=all --name="$part" 2>/dev/null | grep -qi "ufs"; then
echo "$part"
return 0
fi
done

return 1
}

block_dev=$(detect_ufs_partition_block)
if [ -z "$block_dev" ]; then
log_skip "No UFS block device found."
echo "$TESTNAME SKIP" > "$res_file"
exit 0
fi

log_info "Detected UFS block: $block_dev"

# --- RootFS Detection ---
if command -v findmnt >/dev/null 2>&1; then
rootfs_dev=$(findmnt -n -o SOURCE /)
else
Expand All @@ -110,10 +83,13 @@ fi
resolved_block=$(readlink -f "$block_dev" 2>/dev/null)
resolved_rootfs=$(readlink -f "$rootfs_dev" 2>/dev/null)

# --- Read Test (check if 'iflag=direct' supported) ---
log_info "Running basic read test on $block_dev (non-rootfs)..."
if [ -n "$resolved_block" ] && [ -n "$resolved_rootfs" ] && [ "$resolved_block" = "$resolved_rootfs" ]; then
log_warn "Detected block ($resolved_block) is the root filesystem. Skipping read test."
echo "$TESTNAME SKIP" > "$res_file"
exit 0
fi

# Test for iflag=direct support
log_info "Running basic read test on $block_dev (non-rootfs)..."
if echo | dd of=/dev/null iflag=direct 2>/dev/null; then
DD_CMD="dd if=$block_dev of=/dev/null bs=1M count=32 iflag=direct"
else
Expand All @@ -130,34 +106,41 @@ else
exit 1
fi

# --- I/O Stress Test ---
log_info "Running I/O stress test (64MB read+write on tmpfile)..."
tmpfile="$test_path/ufs_test.img"

# Prepare dd write command
if echo | dd of=/dev/null conv=fsync 2>/dev/null; then
DD_WRITE="dd if=/dev/zero of=$tmpfile bs=1M count=64 conv=fsync"
else
log_warn "'conv=fsync' not supported by dd. Using basic write."
DD_WRITE="dd if=/dev/zero of=$tmpfile bs=1M count=64"
fi

# Use simplified dd read for BusyBox compatibility
if $DD_WRITE >/dev/null 2>&1 &&
dd if="$tmpfile" of=/dev/null bs=1M count=64 >/dev/null 2>&1; then
log_pass "UFS I/O stress test passed"
if command -v stat >/dev/null 2>&1; then
stat --format="[INFO] Size: %s bytes File: %n" "$tmpfile"
else
find "$tmpfile" -printf "[INFO] Size: %s bytes File: %p\n"
fi
rm -f "$tmpfile"
else
log_fail "UFS I/O stress test failed"
df -h . | sed 's/^/[INFO] /'
ls -lh "$test_path"/ufs_test.img | sed 's/^/[INFO] /'
rm -f "$tmpfile"
if [ -f "$tmpfile" ]; then
if command -v stat >/dev/null 2>&1; then
stat --format="[INFO] Size: %s bytes File: %n" "$tmpfile"
else
find "$tmpfile" -printf "[INFO] Size: %s bytes File: %p\n"
fi
rm -f "$tmpfile"
fi
echo "$TESTNAME FAIL" > "$res_file"
exit 1
fi
# --- Dmesg Errors ---
scan_dmesg_errors "ufs" "$test_path"

scan_dmesg_errors "ufs" "$test_path"
log_pass "$TESTNAME completed successfully"
echo "$TESTNAME PASS" > "$res_file"
exit 0
40 changes: 21 additions & 19 deletions Runner/suites/Kernel/Baseport/Storage/eMMC_Validation/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,31 +40,26 @@ log_info "------------ Starting $TESTNAME Test -------------"

check_dependencies dd grep cut head tail udevadm

# --- Kernel Config Checks ---
MANDATORY_CONFIGS="CONFIG_MMC CONFIG_MMC_BLOCK"
OPTIONAL_CONFIGS="CONFIG_MMC_SDHCI CONFIG_MMC_SDHCI_MSM CONFIG_MMC_BLOCK_MINORS"

missing_optional=""
log_info "Checking mandatory kernel configs for eMMC..."
if ! check_kernel_config "$MANDATORY_CONFIGS" 2>/dev/null; then
log_skip "Missing one or more mandatory eMMC kernel configs: $MANDATORY_CONFIGS"
log_skip "Missing mandatory eMMC kernel configs: $MANDATORY_CONFIGS"
echo "$TESTNAME SKIP" > "$res_file"
exit 0
fi

log_info "Checking optional kernel configs for eMMC..."
missing_optional=""
for cfg in $OPTIONAL_CONFIGS; do
if ! check_kernel_config "$cfg" 2>/dev/null; then
log_info "[OPTIONAL] $cfg is not enabled"
missing_optional="$missing_optional $cfg"
fi
done
[ -n "$missing_optional" ] && log_info "Optional configs not present but continuing:$missing_optional"

if [ -n "$missing_optional" ]; then
log_info "Optional configs not present but continuing:$missing_optional"
fi

# --- Device Tree and Block Device Check ---
check_dt_nodes "/sys/bus/mmc/devices/*mmc*" || {
echo "$TESTNAME SKIP" > "$res_file"
exit 0
Expand All @@ -76,27 +71,26 @@ if [ -z "$block_dev" ]; then
echo "$TESTNAME SKIP" > "$res_file"
exit 0
fi

log_info "Detected eMMC block: $block_dev"

# --- RootFS check fallback if findmnt is missing ---
rootfs_dev="unknown"
if command -v findmnt >/dev/null 2>&1; then
rootfs_dev=$(findmnt -n -o SOURCE /)
else
log_warn "findmnt not available, using fallback rootfs detection"
rootfs_dev=$(awk '$2 == "/" { print $1 }' /proc/mounts)
fi

# --- Prevent direct read from rootfs ---
if [ "$block_dev" = "$rootfs_dev" ]; then
log_warn "eMMC block $block_dev is mounted as rootfs. Skipping direct read test."
resolved_block=$(readlink -f "$block_dev" 2>/dev/null)
resolved_rootfs=$(readlink -f "$rootfs_dev" 2>/dev/null)

if [ -n "$resolved_block" ] && [ -n "$resolved_rootfs" ] && [ "$resolved_block" = "$resolved_rootfs" ]; then
log_warn "Detected eMMC block ($resolved_block) is the root filesystem. Skipping read test."
else
log_info "Running basic read test on $block_dev (non-rootfs)..."
if dd if="$block_dev" of=/dev/null bs=1M count=32 iflag=direct status=none 2>/dev/null; then
log_pass "eMMC read test succeeded"
else
log_warn "'iflag=direct' not supported by dd. Falling back to standard dd."
log_warn "'iflag=direct' not supported by dd. Trying fallback..."
if dd if="$block_dev" of=/dev/null bs=1M count=32 status=none 2>/dev/null; then
log_pass "eMMC read test succeeded (fallback)"
else
Expand All @@ -107,13 +101,17 @@ else
fi
fi

# --- I/O Stress Test ---
log_info "Running I/O stress test (64MB read+write on tmpfile)..."
tmpfile="$test_path/emmc_test.img"

if dd if=/dev/zero of="$tmpfile" bs=1M count=64 conv=fsync status=none 2>/dev/null; then
if dd if="$tmpfile" of=/dev/null bs=1M status=none 2>/dev/null; then
log_pass "eMMC I/O stress test passed"
if command -v stat >/dev/null 2>&1; then
stat --format="[INFO] Size: %s bytes File: %n" "$tmpfile"
else
find "$tmpfile" -printf "[INFO] Size: %s bytes File: %p\n"
fi
rm -f "$tmpfile"
else
log_fail "eMMC I/O stress test failed (read)"
Expand All @@ -122,10 +120,15 @@ if dd if=/dev/zero of="$tmpfile" bs=1M count=64 conv=fsync status=none 2>/dev/nu
exit 1
fi
else
log_warn "'conv=fsync' not supported by dd. Using basic write fallback."
log_warn "'conv=fsync' not supported. Trying basic write fallback."
if dd if=/dev/zero of="$tmpfile" bs=1M count=64 status=none 2>/dev/null &&
dd if="$tmpfile" of=/dev/null bs=1M status=none 2>/dev/null; then
log_pass "eMMC I/O stress test passed (fallback)"
if command -v stat >/dev/null 2>&1; then
stat --format="[INFO] Size: %s bytes File: %n" "$tmpfile"
else
find "$tmpfile" -printf "[INFO] Size: %s bytes File: %p\n"
fi
rm -f "$tmpfile"
else
log_fail "eMMC I/O stress test failed (fallback)"
Expand All @@ -135,9 +138,8 @@ else
fi
fi

# --- Dmesg Scan ---
scan_dmesg_errors "mmc" "$test_path"

log_pass "$TESTNAME completed successfully"
echo "$TESTNAME PASS" > "$res_file"
exit 0

26 changes: 21 additions & 5 deletions Runner/utils/functestlib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1439,20 +1439,36 @@ detect_ufs_partition_block() {

# Check for dmesg I/O errors and log summary
scan_dmesg_errors() {
label="$1"
output_dir="$2"
label="$1" # Example: "ufs", "emmc", "wifi"
output_dir="$2" # Directory to store logs
extra_keywords="$3" # (Optional) Space-separated keywords for this label

[ -z "$label" ] && return 1
[ -z "$output_dir" ] && output_dir="."

snapshot_file="$output_dir/${label}_dmesg_snapshot.log"
error_file="$output_dir/${label}_dmesg_errors.log"

log_info "Scanning dmesg for recent I/O errors..."
log_info "Scanning dmesg for recent $label-related I/O errors..."

dmesg | tail -n 300 > "$snapshot_file"
grep -iE "error|fail|timeout|reset|crc" "$snapshot_file" > "$error_file"

# Common error indicators
common_keywords="error fail timeout reset crc abort fault invalid fatal warn"

# Build keyword pattern (common + optional extra)
pattern="($common_keywords"
if [ -n "$extra_keywords" ]; then
pattern="$pattern|$extra_keywords"
fi
pattern="$pattern)"

# Filter: lines must match label and error pattern
grep -iE "$label" "$snapshot_file" | grep -iE "$pattern" > "$error_file"

if [ -s "$error_file" ]; then
log_warn "Detected potential $label-related errors in dmesg:"
while read -r line; do
while IFS= read -r line; do
log_warn " dmesg: $line"
done < "$error_file"
else
Expand Down
Loading