From: Damien Le Moal <damien.lemoal@wdc.com>
To: linux-block@vger.kernel.org, Omar Sandoval <osandov@fb.com>,
Masato Suzuki <masato.suzuki@wdc.com>,
Shinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Cc: Omar Sandoval <osandov@osandov.com>, Jens Axboe <axboe@kernel.dk>,
Matias Bjorling <matias.bjorling@wdc.com>,
Hannes Reinecke <hare@suse.de>, Mike Snitzer <snitzer@redhat.com>,
"Martin K . Petersen" <martin.petersen@oracle.com>
Subject: [PATCH blktests 09/14] tests: Introduce zbd test group
Date: Wed, 9 Jan 2019 10:35:37 +0900 [thread overview]
Message-ID: <20190109013542.23686-10-damien.lemoal@wdc.com> (raw)
In-Reply-To: <20190109013542.23686-1-damien.lemoal@wdc.com>
From: Masato Suzuki <masato.suzuki@wdc.com>
The zoned block device (zbd) test group is used to gather all tests
specific to zoned block devices (null_blk device with zoned mode enabled,
SMR disks, dm-linear on top of zoned devices, etc). Execution of this group
requires that the kernel be compiled with the block layer
CONFIG_BLK_DEV_ZONED option enabled and also requires the null_blk driver
to have zoned mode support (added in kernel 4.19).
This group rc script allows all tests to operate even if TEST_DEVS is not
set in the config. If TEST_DEVS is not set, the rc script creates a
null_blk device with zoned mode enabled and the created device assigned to
TEST_DEVS. If TEST_DEVS is set, all tests are executed against the
specified devices, which all must be zoned. With this, all tests scripts
can be written by only defining the test_device() function while allowing
operation on both nullblk and user specified devices.
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Signed-off-by: Masato Suzuki <masato.suzuki@wdc.com>
---
tests/zbd/rc | 250 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 250 insertions(+)
create mode 100644 tests/zbd/rc
diff --git a/tests/zbd/rc b/tests/zbd/rc
new file mode 100644
index 0000000..bf68264
--- /dev/null
+++ b/tests/zbd/rc
@@ -0,0 +1,250 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2018 Western Digital Corporation or its affiliates.
+#
+# Tests for Zone Block Device.
+
+. common/rc
+. common/null_blk
+
+#
+# Test requirement check functions
+#
+
+group_requires() {
+ _have_root || return $?
+ _have_program blkzone || return $?
+ _have_program dd || return $?
+ _have_kernel_option BLK_DEV_ZONED || return $?
+ _have_modules null_blk && _have_module_param null_blk zoned
+
+ # If TEST_DEVS is set in config file, use it as is.
+ # Otherwise, create a zoned null_blk device and set TEST_DEVS.
+ if [[ -n "${TEST_DEVS}" ]] ; then
+ return 0
+ fi
+
+ local test_dev
+ local sysfs_dir
+ if ! _init_null_blk zone_size=4 gb=1 zoned=1 ; then
+ return 1
+ fi
+ test_dev=/dev/nullb0
+ if ! sysfs_dir="$(_find_sysfs_dir "$test_dev")"; then
+ _error "could not find sysfs directory for ${test_dev}"
+ return 1
+ fi
+ export _NULL_BLK_ZONED_CREATED=1
+ TEST_DEVS+=( "${test_dev}" )
+
+ # shellcheck disable=SC2034
+ TEST_DEV_SYSFS_DIRS["$test_dev"]="$sysfs_dir"
+
+ return 0
+}
+
+group_device_requires() {
+ _test_dev_is_zoned
+}
+
+group_exit() {
+ if [[ -n "${_NULL_BLK_ZONED_CREATED}" ]] ; then
+ _exit_null_blk
+ unset _NULL_BLK_ZONED_CREATED
+ fi
+}
+
+#
+# Zone types and conditions
+#
+export ZONE_TYPE_CONVENTIONAL=1
+export ZONE_TYPE_SEQ_WRITE_REQUIRED=2
+export ZONE_TYPE_SEQ_WRITE_PREFERRED=3
+
+export ZONE_COND_EMPTY=1
+export ZONE_COND_IMPLICIT_OPEN=2
+export ZONE_COND_FULL=14
+
+export ZONE_TYPE_ARRAY=(
+ [1]="CONVENTIONAL"
+ [2]="SEQ_WRITE_REQUIRED"
+ [3]="SEQ_WRITE_PREFERRED"
+)
+
+export ZONE_COND_ARRAY=(
+ [0]="NOT_WP"
+ [1]="EMPTY"
+ [2]="IMPLICIT_OPEN"
+ [3]="EXPLICIT_OPEN"
+ [4]="CLOSE"
+ [13]="READ_ONLY"
+ [14]="FULL"
+ [15]="OFFLINE"
+)
+
+# sysfs variable array indices
+export SV_CAPACITY=0
+export SV_CHUNK_SECTORS=1
+export SV_PHYS_BLK_SIZE=2
+export SV_PHYS_BLK_SECTORS=3
+export SV_NR_ZONES=4
+
+#
+# Helper functions
+#
+
+# Obtain zone related sysfs variables and keep in a global array until put
+# function call.
+_get_sysfs_variable() {
+ unset SYSFS_VARS
+ local _dir=${TEST_DEV_SYSFS}
+ SYSFS_VARS[$SV_CAPACITY]=$(<"${_dir}"/size)
+ SYSFS_VARS[$SV_CHUNK_SECTORS]=$(<"${_dir}"/queue/chunk_sectors)
+ SYSFS_VARS[$SV_PHYS_BLK_SIZE]=$(<"${_dir}"/queue/physical_block_size)
+ SYSFS_VARS[$SV_PHYS_BLK_SECTORS]=$((SYSFS_VARS[SV_PHYS_BLK_SIZE] / 512))
+
+ # If the nr_zones sysfs attribute exists, get its value. Otherwise,
+ # calculate its value based on the total capacity and zone size, taking
+ # into account that the last zone can be smaller than other zones.
+ if [[ -e ${TEST_DEV_SYSFS}/queue/nr_zones ]]; then
+ SYSFS_VARS[$SV_NR_ZONES]=$(<"${_dir}"/queue/nr_zones)
+ else
+ SYSFS_VARS[$SV_NR_ZONES]=$(( (SYSFS_VARS[SV_CAPACITY] - 1) \
+ / SYSFS_VARS[SV_CHUNK_SECTORS] + 1 ))
+ fi
+}
+
+_put_sysfs_variable() {
+ unset SYSFS_VARS
+}
+
+# Issue zone report command and keep reported information in global arrays
+# until put function call.
+_get_blkzone_report() {
+ local target_dev=${1}
+
+ # Initialize arrays to store parsed blkzone reports.
+ # Number of reported zones is set in REPORTED_COUNT.
+ # The arrays have REPORTED_COUNT+1 elements with additional one at tail
+ # to simplify loop operation.
+ ZONE_STARTS=()
+ ZONE_LENGTHS=()
+ ZONE_WPTRS=()
+ ZONE_CONDS=()
+ ZONE_TYPES=()
+ NR_CONV_ZONES=0
+ REPORTED_COUNT=0
+
+ TMP_REPORT_FILE=${TMPDIR}/blkzone_report
+ if ! blkzone report "${target_dev}" > "${TMP_REPORT_FILE}"; then
+ echo "blkzone command failed"
+ return $?
+ fi
+
+ local _IFS=$IFS
+ local -i loop=0
+ IFS=$' ,:'
+ while read -r -a _tokens
+ do
+ ZONE_STARTS+=($((_tokens[1])))
+ ZONE_LENGTHS+=($((_tokens[3])))
+ ZONE_WPTRS+=($((_tokens[5])))
+ ZONE_CONDS+=($((${_tokens[11]%\(*})))
+ ZONE_TYPES+=($((${_tokens[13]%\(*})))
+ if [[ ${ZONE_TYPES[-1]} -eq ${ZONE_TYPE_CONVENTIONAL} ]]; then
+ (( NR_CONV_ZONES++ ))
+ fi
+ (( loop++ ))
+ done < "${TMP_REPORT_FILE}"
+ IFS="$_IFS"
+ REPORTED_COUNT=${loop}
+
+ if [[ ${REPORTED_COUNT} -eq 0 ]] ; then
+ echo "blkzone report returned no zone"
+ return 1
+ fi
+
+ # Set value to allow additioanl element access at array end
+ local -i max_idx=$((REPORTED_COUNT - 1))
+ ZONE_STARTS+=( $((ZONE_STARTS[max_idx] + ZONE_LENGTHS[max_idx])) )
+ ZONE_LENGTHS+=( "${ZONE_LENGTHS[max_idx]}" )
+ ZONE_WPTRS+=( "${ZONE_WPTRS[max_idx]}" )
+ ZONE_CONDS+=( "${ZONE_CONDS[max_idx]}" )
+ ZONE_TYPES+=( "${ZONE_TYPES[max_idx]}" )
+
+ rm -f "${TMP_REPORT_FILE}"
+}
+
+_put_blkzone_report() {
+ unset ZONE_STARTS
+ unset ZONE_LENGTHS
+ unset ZONE_WPTRS
+ unset ZONE_CONDS
+ unset ZONE_TYPES
+ unset REPORTED_COUNT
+ unset NR_CONV_ZONES
+}
+
+# Issue reset zone command with zone count option.
+# Call _get_blkzone_report() beforehand.
+_reset_zones() {
+ local target_dev=${1}
+ local -i idx=${2}
+ local -i count=${3}
+
+ if ! blkzone reset -o "${ZONE_STARTS[idx]}" -c "${count}" \
+ "${target_dev}" >> "$FULL" 2>&1 ; then
+ echo "blkzone reset command failed"
+ return 1
+ fi
+}
+
+# Issue dd command with five arguments and record command line in FULL file.
+# args: target device, r/w, start sector, sector len, block size in bytes
+_dd() {
+ local target_dev=${1}
+ local rw=${2}
+ local -i start_sector=${3}
+ local -i start_byte=$(( start_sector * 512 ))
+ local -i sector_count=${4}
+ local -i bs=${5}
+ local -i block_count=$(( sector_count * 512 / bs ))
+
+ local _cmd="dd bs=${bs} count=${block_count}"
+
+ if [[ ${rw} = "read" ]]; then
+ _cmd="${_cmd} if=${target_dev} of=/dev/null"
+ _cmd="${_cmd} iflag=skip_bytes skip=${start_byte}"
+ elif [[ ${rw} = "write" ]]; then
+ _cmd="${_cmd} if=/dev/zero of=${target_dev}"
+ _cmd="${_cmd} oflag=seek_bytes,direct seek=${start_byte}"
+ fi
+
+ echo "${_cmd}" >> "$FULL" 2>&1
+
+ if ! eval "${_cmd}" >> "$FULL" 2>&1 ; then
+ echo "dd command failed"
+ return 1
+ fi
+
+ sync
+}
+
+# Search zones and find two contiguous sequential required zones.
+# Return index of the first zone of the found two zones.
+# Call _get_blkzone_report() beforehand.
+_find_two_contiguous_seq_zones() {
+ local -i type_seq=${ZONE_TYPE_SEQ_WRITE_REQUIRED}
+ for ((idx = NR_CONV_ZONES; idx < REPORTED_COUNT; idx++)); do
+ if [[ ${ZONE_TYPES[idx]} -eq ${type_seq} &&
+ ${ZONE_TYPES[idx+1]} -eq ${type_seq} ]];
+ then
+ echo "${idx}"
+ return 0
+ fi
+ done
+
+ echo "Contiguous sequential write required zones not found"
+ return 1
+}
+
--
2.20.1
next prev parent reply other threads:[~2019-01-09 1:36 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-09 1:35 [PATCH blktests 00/14] Implement zoned block device support Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 01/14] config: Introduce ZONED variable Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 02/14] common: Introduce _test_dev_is_zoned() helper function Damien Le Moal
2019-01-09 8:46 ` Johannes Thumshirn
2019-01-09 1:35 ` [PATCH blktests 03/14] common: Move set_scheduler() function from multipath-over-rdma to rc Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 04/14] block/004: Adjust fio conditions for zoned block device Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 05/14] block/013: Skip for zoned block devices Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 06/14] block/018,024: Skip when ZONED is set Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 07/14] check: Introduce group_exit() function Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 08/14] src: Introduce zbdioctl program Damien Le Moal
2019-01-09 1:35 ` Damien Le Moal [this message]
2019-01-09 1:35 ` [PATCH blktests 10/14] zbd/001: sysfs and ioctl consistency test Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 11/14] zbd/002: report zone test Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 12/14] zbd/003: Test sequential zones reset Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 13/14] zbd/004: Check write split accross sequential zones Damien Le Moal
2019-01-09 1:35 ` [PATCH blktests 14/14] zbd/005: Test write ordering Damien Le Moal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190109013542.23686-10-damien.lemoal@wdc.com \
--to=damien.lemoal@wdc.com \
--cc=axboe@kernel.dk \
--cc=hare@suse.de \
--cc=linux-block@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=masato.suzuki@wdc.com \
--cc=matias.bjorling@wdc.com \
--cc=osandov@fb.com \
--cc=osandov@osandov.com \
--cc=shinichiro.kawasaki@wdc.com \
--cc=snitzer@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).