| #!/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 |