blob: 9a483d9394e79ca34738b78f673b7b6ad4fe4da0 [file] [log] [blame]
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (C) 2019 Linaro Ltd.
# shellcheck disable=SC1091
. ../../lib/sh-test-lib
OUTPUT="$(pwd)/output"
RESULT_FILE="${OUTPUT}/result.txt"
PARTDEV=""
PARTNAME=""
DEVICE=""
DEVNAME=""
SKIP_INSTALL="false"
FORMAT_DEVICE="false"
MOUNT_DIR=$(mktemp -d "/tmp/block-device.XXXXX")
TMPFILE=$(mktemp "/tmp/10M.XXXXX")
RESULT=pass
usage() {
echo "\
Usage: $0
[-d </dev/sdXN>]
[-f <true|false>]
[-s <true|false>]
-d </dev/sdXN>
This is the block device to be tested, eg. /dev/sda1.
It should be a partition, not a raw block device
-f <true|false>
This will erase the device and create a new partition table
with a single ext4 partition on it.
-s <true|false>
Tell the test to skip installation of dependencies, or not
This test will perform tests on a block device.
"
}
while getopts "d:f:s:h" opts; do
case "$opts" in
d) PARTDEV="${OPTARG}";
PARTNAME=$(basename -- "${PARTDEV}");
DEVICE=${PARTDEV/%[[:digit:]]/}
DEVNAME=$(basename -- "${DEVICE}")
;;
f) FORMAT_DEVICE="${OPTARG,,}" ;;
s) SKIP_INSTALL="${OPTARG,,}" ;;
h|*) usage ; exit 1 ;;
esac
done
install() {
if [ "${SKIP_INSTALL}" = "true" ]; then
info_msg "Skip installing dependencies"
else
# install dependencies
dist=
dist_name
case "${dist}" in
debian|ubuntu)
pkgs="bonnie++"
install_deps "${pkgs}" "${SKIP_INSTALL}"
;;
fedora|centos)
pkgs="bonnie++"
install_deps "${pkgs}" "${SKIP_INSTALL}"
;;
# When we don't have a package manager
# Assume dependencies pre-installed
*)
echo "Unsupported distro: ${dist}! Package installation skipped!"
;;
esac
fi
}
block_device_exists () {
local device=$1
if [[ -b ${device} ]]; then
echo true
else
echo false
fi
}
wait_for_device () {
local device=$1
local retries=20
echo -n "Waiting for ${device}: "
for ((i=0;i<retries;++i)); do
local exists
exists=$(block_device_exists "${device}")
if [[ "${exists}" == "true" ]]; then
echo "done"
echo "block-device-${DEVNAME}-present pass" | tee -a "${RESULT_FILE}"
sleep 0.5 # allow the device some time to settle after being plugged in
return
fi
echo -n "."
sleep 0.5
done
echo "failed"
echo "block-device-preset-${DEVNAME} fail" | tee -a "${RESULT_FILE}"
exit 1
}
device_mounted() {
local dev
dev="$1"
if grep -qs "${dev}" /proc/mounts; then
echo "1"
else
echo "0"
fi
}
format_device() {
if [ "${RESULT}" != "fail" ] && [ "${FORMAT_DEVICE}" = "true" ] ; then
local mounted
mounted=$(device_mounted "${PARTDEV}")
if [ "${mounted}" = "1" ]; then
RESULT=fail
echo "block-device-${DEVNAME}-not-mounted ${RESULT}" | tee -a "${RESULT_FILE}"
return
fi
echo "block-device-${DEVNAME}-not-mounted ${RESULT}" | tee -a "${RESULT_FILE}"
if [ "${RESULT}" = "pass" ]; then
echo "Erase device ${DEVICE}"
if ! dd if=/dev/zero of="${DEVICE}" bs=512 count=2048; then
RESULT=fail
fi
fi
echo "block-device-${DEVNAME}-erase ${RESULT}" | tee -a "${RESULT_FILE}"
if [ "${RESULT}" = "pass" ]; then
echo "Create partition table on ${DEVICE}"
echo 'type=83' | sfdisk --force "${DEVICE}" || RESULT=fail
fi
echo "block-device-${DEVNAME}-partition ${RESULT}" | tee -a "${RESULT_FILE}"
if [ "${RESULT}" = "pass" ]; then
PARTDEV="${DEVICE}1"
echo "Format ${PARTDEV} as ext4"
mkfs.ext4 -F "${PARTDEV}" || RESULT=fail
fi
echo "block-device-${PARTNAME}-format ${RESULT}" | tee -a "${RESULT_FILE}"
else
echo "block-device-${PARTNAME}-format skip" | tee -a "${RESULT_FILE}"
fi
}
mount_device () {
if [ "${RESULT}" == "pass" ] ; then
local mounted
mounted=$(device_mounted "${PARTDEV}")
if [ "${mounted}" = "1" ]; then
RESULT=skip
else
mkdir -p "${MOUNT_DIR}"
mount -t auto "${PARTDEV}" "${MOUNT_DIR}" || RESULT=fail
fi
echo "block-device-${PARTNAME}-mount ${RESULT}" | tee -a "${RESULT_FILE}"
fi
}
umount_device () {
umount "${MOUNT_DIR}" || RESULT=fail
echo "block-device-${PARTNAME}-umount ${RESULT}" | tee -a "${RESULT_FILE}"
}
copy_timing_test () {
test_name=$1
infile=$2
outfile=$3
if [ "${RESULT}" == "pass" ] ; then
timings=$(mktemp "/tmp/block-device.timings.XXXXXXXXXXXX")
(dd if="${infile}" of="${outfile}" 2> "${timings}" && sync) || RESULT=fail
cat "${timings}"
if [ "${RESULT}" == "pass" ] ; then
local seconds
local mbps
seconds=$(tail -1 "${timings}" | awk '{print $8}')
mbps=$(tail -1 "${timings}" | awk '{print $10}')
echo "block-device-${PARTNAME}-${test_name}-timing ${RESULT} ${seconds} seconds" | tee -a "${RESULT_FILE}"
echo "block-device-${PARTNAME}-${test_name}-throughput ${RESULT} ${mbps} MB/s" | tee -a "${RESULT_FILE}"
fi
rm -f "${timings}"
echo "block-device-${PARTNAME}-${test_name}-cp ${RESULT}" | tee -a "${RESULT_FILE}"
fi
if [ "${RESULT}" == "pass" ] ; then
cmp "${infile}" "${outfile}" || RESULT=fail
echo "block-device-${PARTNAME}-${test_name}-cmp ${RESULT}" | tee -a "${RESULT_FILE}"
fi
}
write_timing () {
if [ "${RESULT}" == "pass" ] ; then
echo "Writing 10MB file to ${PARTDEV}"
dd if=/dev/urandom of="${TMPFILE}" bs=1024 count=10240 || RESULT=fail
echo "block-device-${PARTNAME}-create-10M-file ${RESULT}" | tee -a "${RESULT_FILE}"
fi
if [ "${RESULT}" == "pass" ] ; then
# shellcheck disable=SC2086
copy_timing_test "write" "${TMPFILE}" "${MOUNT_DIR}/$(basename -- ${TMPFILE})" || RESULT=fail
fi
rm -f "${TMPFILE}"
}
read_timing () {
if [ "${RESULT}" == "pass" ] ; then
echo "Reading 10MB file to ${PARTDEV}"
# shellcheck disable=SC2086
copy_timing_test "read" "${MOUNT_DIR}/$(basename -- ${TMPFILE})" "${TMPFILE}" || RESULT=fail
rm -f "${TMPFILE}"
fi
}
bonnie_test () {
if [ "${RESULT}" == "pass" ] ; then
BONNIE_LOG=$(mktemp "/tmp/bonnie.XXXXX")
bonnie\+\+ -u root -d "${MOUNT_DIR}" | tee -a "${BONNIE_LOG}" || RESULT=fail
echo "block-device-${PARTNAME}-bonnie++ ${RESULT}" | tee -a "${RESULT_FILE}"
fi
}
################################################################################
# Run the test actions
################################################################################
echo "Test Parameters"
echo "---------------"
echo "PARTDEV: ${PARTDEV}"
echo "PARTNAME: ${PARTNAME}"
echo "DEVICE: ${DEVICE}"
echo "RESULT_FILE: ${RESULT_FILE}"
echo ""
echo "MOUNT_DIR: ${MOUNT_DIR}"
echo "TMPFILE: ${TMPFILE}"
echo ""
install
create_out_dir "${OUTPUT}"
wait_for_device "${DEVICE}"
format_device
mount_device
write_timing
read_timing
bonnie_test
umount_device
# Cleanup temporary files
rm -f "${TMPFILE}"
rm -rf "${MOUNT_DIR}"