/usr/bin/scsi_ch_swp is in sdparm 1.08-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140  | #!/bin/bash
# scsi_ch_swp
#
# Script to change the Software Read Protect (SWP) state of a disk in Linux.
# When '-s <n>' (or '--set <n>') is not given then read SWP state.
#
# Uses sdparm and blockdev utilities.
#
# Douglas Gilbert 20130606
rdonly="--readonly"
swp="-1"
verbose=""
bdverbose=""
usage()
{
    echo "Usage: scsi_ch_swp [-h] [-s 0|1] [-v] [-w] <blk_device>"
    echo "  where:"
    echo "    -h, --help           print usage message"
    echo "    -s 0|1, --set 0|1    where:"
    echo "                           0  - clear SWP and set RW mode"
    echo "                           1  - set SWP and set RO mode"
    echo "                                (default: read SWP and get RO flag)"
    echo "    -v, --verbose        more verbose, show commands invoked"
    echo "    -w, --wr             access <blk_device> read-write when '-s 0'"
    echo "                         (default: access read-only in this case)"
    echo ""
    echo "Access the Software Write Protect (SWP) bit in the SCSI control"
    echo "mode page and if changed adjust the Linux block device (e.g."
    echo "/dev/sdc) settings accordingly. If supported, when the SWP bit"
    echo "is set (1) the device is read-only; when clear (0) the device"
    echo "is read-write (i.e. its contents can be read and changed)."
    echo "When no options given it reads SWP and gets blockdev's RO flag."
}
opt="$1"
while test ! -z "$opt" -a -z "${opt##-*}"; do
    opt=${opt#-}
    case "$opt" in
        h|-help) usage ; exit 0 ;;
        s|-set) shift ; let swp=$1 ;;
        v|-verbose) verbose="-v" ;;
        w|-wr) rdonly="" ;;
        vv) verbose="-vv" ;;
        vvv) verbose="-vvv" ;;
        *) echo "Unknown option: -$opt " ; exit 1 ;;
    esac
    shift
    opt="$1"
done
if [ $# -lt 1 ] ; then
    echo "Need at least a <blk_device> argument."
    echo ""
    usage
    exit 1
fi 
if [ ${verbose} ] ; then
    bdverbose="-v"
fi
if ( which sdparm >/dev/null 2>&1 ) ; then
    true
else
    echo "sdparm not found"
    sdparm ${rdonly} ${verbose}
fi
if ( which blockdev >/dev/null 2>&1 ) ; then
    true
else
    echo "blockdev not found"
    blockdev
fi
if [ $swp -lt 0 ] ; then
    if [ ${verbose} ] ; then
        echo sdparm --quiet ${rdonly} ${verbose} --get=SWP=1 $1
    fi
    sdparm --quiet ${rdonly} ${verbose} --get=SWP=1 $1
    if [ ${bdverbose} ] ; then
        echo "blockdev --getro ${bdverbose} $1"
    fi
    echo -n "blockdev's RO flag: "
    blockdev --getro ${bdverbose} $1
elif [ $swp = "0" ] ; then
    if [ ${verbose} ] ; then
        echo sdparm --quiet ${rdonly} ${verbose} --clear=SWP $1
    fi
    sdparm --quiet ${rdonly} ${verbose} --clear=SWP $1
    res=$?
    if [ $res -ne 0 ] ; then
        exit $res
    fi
    if [ ${bdverbose} ] ; then
        echo blockdev --setrw ${bdverbose} $1
    fi
    blockdev --setrw ${bdverbose} $1
    # res=$?
    # if [ $res -ne 0 ] ; then
        # exit $res
    # fi
    ## There is still some uncertainity whether calling blockdev --rereadpt
    ## is needed or defeats this operation. Feedback please.
    # # Need to re-read partition table before --setro takes effect
    # if [ ${bdverbose} ] ; then
        # echo blockdev --rereadpt ${bdverbose} $1
    # fi
    # blockdev --rereadpt ${bdverbose} $1
elif [ $swp = "1" ] ; then
    if [ ${verbose} ] ; then
        echo sdparm --quiet ${verbose} --set=SWP $1
    fi
    sdparm --quiet ${verbose} --set=SWP $1
    res=$?
    if [ $res -ne 0 ] ; then
        exit $res
    fi
    if [ ${bdverbose} ] ; then
        echo blockdev --setro ${bdverbose} $1
    fi
    blockdev --setro ${bdverbose} $1
    # res=$?
    # if [ $res -ne 0 ] ; then
        # exit $res
    # fi
    ## There is still some uncertainity whether calling blockdev --rereadpt
    ## is needed or defeats this operation. Feedback please.
    # # Need to re-read partition table before --setrw takes effect
    # if [ ${bdverbose} ] ; then
        # echo blockdev --rereadpt ${bdverbose} $1
    # fi
    # blockdev --rereadpt ${bdverbose} $1
else
    echo "option --set ${swp} is invalid"
    exit 1
fi
 |