| ##/bin/bash | |
| # SPDX-License-Identifier: GPL-2.0 | |
| # Copyright (c) 2013 Fusion IO, Inc. All Rights Reserved. | |
| # | |
| # common functions for setting up and tearing down a dmflakey device | |
| FLAKEY_ALLOW_WRITES=0 | |
| FLAKEY_DROP_WRITES=1 | |
| FLAKEY_ERROR_WRITES=2 | |
| export FLAKEY_NAME="flakey-test.$seq" | |
| export FLAKEY_RTNAME="flakey-rttest.$seq" | |
| export FLAKEY_LOGNAME="flakey-logtest.$seq" | |
| _init_flakey() | |
| { | |
| # Scratch device | |
| if [ -z "$NON_FLAKEY_DEV" ]; then | |
| # Set up the device switch | |
| local backing_dev="$SCRATCH_DEV" | |
| export NON_FLAKEY_DEV="$SCRATCH_DEV" | |
| SCRATCH_DEV=/dev/mapper/$FLAKEY_NAME | |
| else | |
| # Already set up; recreate tables | |
| local backing_dev="$NON_FLAKEY_DEV" | |
| fi | |
| local BLK_DEV_SIZE=`blockdev --getsz $backing_dev` | |
| FLAKEY_TABLE="0 $BLK_DEV_SIZE flakey $backing_dev 0 180 0" | |
| FLAKEY_TABLE_DROP="0 $BLK_DEV_SIZE flakey $backing_dev 0 0 180 1 drop_writes" | |
| FLAKEY_TABLE_ERROR="0 $BLK_DEV_SIZE flakey $backing_dev 0 0 180 1 error_writes" | |
| _dmsetup_create $FLAKEY_NAME --table "$FLAKEY_TABLE" || \ | |
| _fatal "failed to create flakey device" | |
| # Realtime device | |
| if [ -n "$SCRATCH_RTDEV" ]; then | |
| if [ -z "$NON_FLAKEY_RTDEV" ]; then | |
| # Set up the device switch | |
| local backing_dev="$SCRATCH_RTDEV" | |
| export NON_FLAKEY_RTDEV="$SCRATCH_RTDEV" | |
| SCRATCH_RTDEV=/dev/mapper/$FLAKEY_RTNAME | |
| else | |
| # Already set up; recreate tables | |
| local backing_dev="$NON_FLAKEY_RTDEV" | |
| fi | |
| local BLK_DEV_SIZE=`blockdev --getsz $backing_dev` | |
| FLAKEY_RTTABLE="0 $BLK_DEV_SIZE flakey $backing_dev 0 180 0" | |
| FLAKEY_RTTABLE_DROP="0 $BLK_DEV_SIZE flakey $backing_dev 0 0 180 1 drop_writes" | |
| FLAKEY_RTTABLE_ERROR="0 $BLK_DEV_SIZE flakey $backing_dev 0 0 180 1 error_writes" | |
| _dmsetup_create $FLAKEY_RTNAME --table "$FLAKEY_RTTABLE" || \ | |
| _fatal "failed to create flakey rt device" | |
| fi | |
| # External log device | |
| if [ -n "$SCRATCH_LOGDEV" ]; then | |
| if [ -z "$NON_FLAKEY_LOGDEV" ]; then | |
| # Set up the device switch | |
| local backing_dev="$SCRATCH_LOGDEV" | |
| export NON_FLAKEY_LOGDEV="$SCRATCH_LOGDEV" | |
| SCRATCH_LOGDEV=/dev/mapper/$FLAKEY_LOGNAME | |
| else | |
| # Already set up; recreate tables | |
| local backing_dev="$NON_FLAKEY_LOGDEV" | |
| fi | |
| local BLK_DEV_SIZE=`blockdev --getsz $backing_dev` | |
| FLAKEY_LOGTABLE="0 $BLK_DEV_SIZE flakey $backing_dev 0 180 0" | |
| FLAKEY_LOGTABLE_DROP="0 $BLK_DEV_SIZE flakey $backing_dev 0 0 180 1 drop_writes" | |
| FLAKEY_LOGTABLE_ERROR="0 $BLK_DEV_SIZE flakey $backing_dev 0 0 180 1 error_writes" | |
| _dmsetup_create $FLAKEY_LOGNAME --table "$FLAKEY_LOGTABLE" || \ | |
| _fatal "failed to create flakey log device" | |
| fi | |
| } | |
| _cleanup_flakey() | |
| { | |
| # If dmsetup load fails then we need to make sure to do resume here | |
| # otherwise the umount will hang | |
| test -n "$NON_FLAKEY_LOGDEV" && $DMSETUP_PROG resume $FLAKEY_LOGNAME &> /dev/null | |
| test -n "$NON_FLAKEY_RTDEV" && $DMSETUP_PROG resume $FLAKEY_RTNAME &> /dev/null | |
| test -n "$NON_FLAKEY_DEV" && $DMSETUP_PROG resume $FLAKEY_NAME &> /dev/null | |
| _unmount $SCRATCH_MNT > /dev/null 2>&1 | |
| test -n "$NON_FLAKEY_DEV" && _dmsetup_remove $FLAKEY_NAME | |
| test -n "$NON_FLAKEY_LOGDEV" && _dmsetup_remove $FLAKEY_LOGNAME | |
| test -n "$NON_FLAKEY_RTDEV" && _dmsetup_remove $FLAKEY_RTNAME | |
| SCRATCH_DEV="$NON_FLAKEY_DEV" | |
| unset NON_FLAKEY_DEV | |
| if [ -n "$NON_FLAKEY_LOGDEV" ]; then | |
| SCRATCH_LOGDEV="$NON_FLAKEY_LOGDEV" | |
| unset NON_FLAKEY_LOGDEV | |
| fi | |
| if [ -n "$NON_FLAKEY_RTDEV" ]; then | |
| SCRATCH_RTDEV="$NON_FLAKEY_RTDEV" | |
| unset NON_FLAKEY_RTDEV | |
| fi | |
| } | |
| # _load_flakey_table <table> [lockfs] | |
| # | |
| # This defaults to --nolockfs, which doesn't freeze_fs() before loading the new | |
| # table, so it simulates power failure. | |
| _load_flakey_table() | |
| { | |
| case "$1" in | |
| "$FLAKEY_DROP_WRITES") | |
| table="$FLAKEY_TABLE_DROP" | |
| logtable="$FLAKEY_LOGTABLE_DROP" | |
| rttable="$FLAKEY_RTTABLE_DROP" | |
| ;; | |
| "$FLAKEY_ERROR_WRITES") | |
| table="$FLAKEY_TABLE_ERROR" | |
| logtable="$FLAKEY_LOGTABLE_ERROR" | |
| rttable="$FLAKEY_RTTABLE_ERROR" | |
| ;; | |
| *) | |
| table="$FLAKEY_TABLE" | |
| logtable="$FLAKEY_LOGTABLE" | |
| rttable="$FLAKEY_RTTABLE" | |
| ;; | |
| esac | |
| suspend_opt="--nolockfs" | |
| [ $# -gt 1 ] && [ $2 -eq 1 ] && suspend_opt="" | |
| # Suspend the scratch device before the log and realtime devices so | |
| # that the kernel can freeze and flush the filesystem if the caller | |
| # wanted a freeze. | |
| $DMSETUP_PROG suspend $suspend_opt $FLAKEY_NAME | |
| [ $? -ne 0 ] && _fatal "failed to suspend $FLAKEY_NAME" | |
| if [ -n "$NON_FLAKEY_RTDEV" ]; then | |
| $DMSETUP_PROG suspend $suspend_opt $FLAKEY_RTNAME | |
| [ $? -ne 0 ] && _fatal "failed to suspend flakey-rttest" | |
| fi | |
| if [ -n "$NON_FLAKEY_LOGDEV" ]; then | |
| $DMSETUP_PROG suspend $suspend_opt $FLAKEY_LOGNAME | |
| [ $? -ne 0 ] && _fatal "failed to suspend flakey-logtest" | |
| fi | |
| # There may be multiple dm targets in the table, and these dm targets | |
| # will be joined by the newline ("\n"). Option --table can not cope with | |
| # the multiple-targets case, so get them by reading from standard input. | |
| echo -e "$table" | $DMSETUP_PROG load $FLAKEY_NAME | |
| [ $? -ne 0 ] && _fatal "failed to load table into $FLAKEY_NAME" | |
| if [ -n "$NON_FLAKEY_RTDEV" ]; then | |
| echo -e "$rttable" | $DMSETUP_PROG load $FLAKEY_RTNAME | |
| [ $? -ne 0 ] && _fatal "failed to load table into flakey-rttest" | |
| fi | |
| if [ -n "$NON_FLAKEY_LOGDEV" ]; then | |
| echo -e "$logtable" | $DMSETUP_PROG load $FLAKEY_LOGNAME | |
| [ $? -ne 0 ] && _fatal "failed to load table into flakey-logtest" | |
| fi | |
| # Resume devices in the opposite order that we suspended them. | |
| if [ -n "$NON_FLAKEY_LOGDEV" ]; then | |
| $DMSETUP_PROG resume $FLAKEY_LOGNAME | |
| [ $? -ne 0 ] && _fatal "failed to resume flakey-logtest" | |
| fi | |
| if [ -n "$NON_FLAKEY_RTDEV" ]; then | |
| $DMSETUP_PROG resume $FLAKEY_RTNAME | |
| [ $? -ne 0 ] && _fatal "failed to resume flakey-rttest" | |
| fi | |
| $DMSETUP_PROG resume $FLAKEY_NAME | |
| [ $? -ne 0 ] && _fatal "failed to resume $FLAKEY_NAME" | |
| } | |
| # Silently drop all writes and unmount/remount to simulate a crash/power | |
| # failure. | |
| _flakey_drop_and_remount() | |
| { | |
| # If the full environment is set up, configure ourselves for shutdown | |
| type _prepare_for_eio_shutdown &>/dev/null && \ | |
| _prepare_for_eio_shutdown $SCRATCH_DEV | |
| _load_flakey_table $FLAKEY_DROP_WRITES | |
| _scratch_unmount | |
| if [ "x$1" = "xyes" ]; then | |
| _check_scratch_fs | |
| fi | |
| _load_flakey_table $FLAKEY_ALLOW_WRITES | |
| _scratch_mount | |
| } | |
| _require_flakey_with_error_writes() | |
| { | |
| local SIZE | |
| local TABLE | |
| local NAME=$FLAKEY_NAME | |
| _require_dm_target flakey | |
| SIZE=`blockdev --getsz $SCRATCH_DEV` | |
| TABLE="0 $SIZE flakey $SCRATCH_DEV 0 0 180 1 error_writes" | |
| _dmsetup_create $NAME --table "$TABLE" || \ | |
| _notrun "This test requires error_writes feature in dm-flakey" | |
| _dmsetup_remove $FLAKEY_NAME | |
| } |