blob: ceabee52b868725cdceed888ce1b00b60fa891a0 [file] [log] [blame]
#!/bin/bash -E
# Copyright(c) 2015-2017 Intel Corporation. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
dev=""
mode=""
size=""
sector_size=""
blockdev=""
bs=4096
rc=77
. ./common
trap 'err $LINENO' ERR
# sample json:
# {
# "dev":"namespace5.0",
# "mode":"sector",
# "size":32440320,
# "uuid":"51805176-e124-4635-ae17-0e6a4a16671a",
# "sector_size":4096,
# "blockdev":"pmem5s"
# }
check_min_kver "4.14" || do_skip "may not support badblocks clearing on pmem via btt"
create()
{
json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem -m sector)
rc=2
eval "$(echo "$json" | json2var)"
[ -n "$dev" ] || err "$LINENO"
[ "$mode" = "sector" ] || err "$LINENO"
[ -n "$size" ] || err "$LINENO"
[ -n "$sector_size" ] || err "$LINENO"
[ -n "$blockdev" ] || err "$LINENO"
[ $size -gt 0 ] || err "$LINENO"
}
reset()
{
$NDCTL disable-region -b $NFIT_TEST_BUS0 all
$NDCTL zero-labels -b $NFIT_TEST_BUS0 all
$NDCTL enable-region -b $NFIT_TEST_BUS0 all
}
# re-enable the BTT namespace, and do IO to it in an attempt to
# verify it still comes up ok, and functions as expected
post_repair_test()
{
echo "${FUNCNAME[0]}: I/O to BTT namespace"
test -b /dev/$blockdev
dd if=/dev/urandom of=test-bin bs=$sector_size count=$((size/sector_size)) > /dev/null 2>&1
dd if=test-bin of=/dev/$blockdev bs=$sector_size count=$((size/sector_size)) > /dev/null 2>&1
dd if=/dev/$blockdev of=test-bin-read bs=$sector_size count=$((size/sector_size)) > /dev/null 2>&1
diff test-bin test-bin-read
rm -f test-bin*
echo "done"
}
test_normal()
{
echo "=== ${FUNCNAME[0]} ==="
# disable the namespace
$NDCTL disable-namespace $dev
$NDCTL check-namespace $dev
$NDCTL enable-namespace $dev
post_repair_test
}
test_force()
{
echo "=== ${FUNCNAME[0]} ==="
$NDCTL check-namespace --force $dev
post_repair_test
}
set_raw()
{
$NDCTL disable-namespace $dev
echo -n "set raw_mode: "
echo 1 | tee /sys/bus/nd/devices/$dev/force_raw
$NDCTL enable-namespace $dev
raw_bdev="${blockdev%%s}"
test -b /dev/$raw_bdev
raw_size="$(cat /sys/bus/nd/devices/$dev/size)"
}
unset_raw()
{
$NDCTL disable-namespace $dev
echo -n "set raw_mode: "
echo 0 | tee /sys/bus/nd/devices/$dev/force_raw
$NDCTL enable-namespace $dev
raw_bdev=""
}
test_bad_info2()
{
echo "=== ${FUNCNAME[0]} ==="
set_raw
seek="$((raw_size/bs - 1))"
echo "wiping info2 block (offset = $seek blocks)"
dd if=/dev/zero of=/dev/$raw_bdev bs=$bs count=1 seek=$seek
unset_raw
$NDCTL disable-namespace $dev
$NDCTL check-namespace $dev 2>&1 | grep "info2 needs to be restored"
$NDCTL check-namespace --repair $dev
$NDCTL enable-namespace $dev
post_repair_test
}
test_bad_info()
{
echo "=== ${FUNCNAME[0]} ==="
set_raw
echo "wiping info block"
dd if=/dev/zero of=/dev/$raw_bdev bs=$bs count=2 seek=0
unset_raw
$NDCTL disable-namespace $dev
$NDCTL check-namespace $dev 2>&1 | grep -E "info block at offset .* needs to be restored"
$NDCTL check-namespace --repair $dev
$NDCTL enable-namespace $dev
post_repair_test
}
test_bitmap()
{
echo "=== ${FUNCNAME[0]} ==="
reset && create
set_raw
# scribble over the last 4K of the map
rm -f /tmp/scribble
for (( i=0 ; i<512 ; i++ )); do
echo -n -e \\x1e\\x1e\\x00\\xc0\\x1e\\x1e\\x00\\xc0 >> /tmp/scribble
done
seek="$((raw_size/bs - (256*64/bs) - 2))"
echo "scribbling over map entries (offset = $seek blocks)"
dd if=/tmp/scribble of=/dev/$raw_bdev bs=$bs seek=$seek
rm -f /tmp/scribble
unset_raw
$NDCTL disable-namespace $dev
$NDCTL check-namespace $dev 2>&1 | grep "bitmap error"
# This is not repairable
reset && create
}
do_tests()
{
test_normal
test_force
test_bad_info2
test_bad_info
test_bitmap
}
# setup (reset nfit_test dimms, create the BTT namespace)
modprobe nfit_test
rc=1
reset && create
do_tests
reset
_cleanup
exit 0