#!/bin/sh # # Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # Released under the GNU General Public License version 2. # let FORCE=0 DEVPARM="" usage(){ echo "Usage: ${0} [ -f ] devno|busid" echo " -f Force unformatting for DASD volumes in the CMS device range of 19x." echo " devno The \"plain\" device number of the volume, e.g. 3184." echo " busid The full specification of the volume, e.g., 0.0.3184." } ARCH="$(/usr/bin/uname -m)" if [ "${ARCH}" != "s390x" ] && [ "${ARCH}" != "s390" ]; then echo "This script is only useful on IBM mainframes." exit 1 fi ############################################################ # Parse the parameters from the command line # ARGS=$(getopt -a --options f -n "killcdl" -- "$@") if [ $? -ne 0 ]; then usage exit 3 fi eval set -- "${ARGS}" for ARG; do case "${ARG}" in -f) FORCE=1 shift 1 ;; --) shift 1 ;; [0-9a-fA-F]*) if [ ! -z "${DEVPARM}" ]; then echo "More than one parameter specified." usage exit 4 fi DEVPARM=${1} shift 1 ;; *) echo "That looks invalid" usage exit 5 ;; esac done if [ -z "${DEVPARM}" ]; then echo "You must specify the device number of the DASD volume to be unformatted." usage exit 6 fi DEVNO=$(echo "${DEVPARM}" | tr A-Z a-z) # Validate the device number or busid provided set -- $(IFS='.'; echo ${DEVNO}) let NUMPARMS=${#} if [ ${NUMPARMS} -ne 1 ] && [ ${NUMPARMS} -ne 3 ]; then echo "You have not specified the device number in a recognizable format." echo "It must either be the plain device number, e.g., 0123, or in" echo "so-called busid format, e.g., 0.0.0123" exit 7 fi # Just a device number, SIMPLE=1. A busid, SIMPLE=0 SIMPLE=0 if [ ${NUMPARMS} -eq 1 ]; then let SIMPLE=1 let FIRST=0 let FIRSTLEN=1 let SECOND=0 let SECONDLEN=1 DEVNO="${1}" let DEVNOLEN=${#1} else FIRST="${1}" let FIRSTLEN=${#FIRST} SECOND="${2}" let SECONDLEN=${#SECOND} DEVNO="${3}" let DEVNOLEN=${#3} fi if [ ${FIRSTLEN} -ne 1 ] || [ ${SECONDLEN} -ne 1 ]; then echo "The first and second fields of the busid may only be one digit long." exit 8 fi if [ ${DEVNOLEN} -gt 4 ]; then echo "The device number may only be 4 digits long." exit 9 fi if [ ${DEVNOLEN} -lt 4 ]; then DEVNO=$(echo "0000${DEVNO}" | rev | cut -c1-4 | rev) fi BUSID="${FIRST}.${SECOND}.${DEVNO}" if [ ! -h /sys/bus/ccw/devices/${BUSID} ]; then echo "Busid ${BUSID} was not found." /usr/sbin/cio_ignore -i ${BUSID} > /dev/null if [ $? -eq 0 ]; then echo "That device is in the cio_ignore list." echo "Please remove it with \"cio_ignore -r ${BUSID}\" before trying again." fi exit 10 fi case ${DEVNO:0:3} in 019) if grep -q "version = FF" /proc/cpuinfo 2>/dev/null; then echo "That looks like a CMS disk." if [ ${FORCE} -eq 0 ]; then echo "Specify the -f option to force the operation." exit 11 fi echo "But you specified -f so we'll kill it anyway." fi ;; esac read ORIG_ONLINE_STATUS < /sys/bus/ccw/devices/${BUSID}/online DISCIPLINE="none" if [ -r /sys/bus/ccw/devices/${BUSID}/discipline ]; then # We have to bring the device online before the kernel will fill in # the value for discipline. if [ ${ORIG_ONLINE_STATUS} -eq 0 ]; then /usr/sbin/chccwdev -e ${BUSID} /usr/sbin/udevadm settle fi read STATUS < /sys/bus/ccw/devices/${BUSID}/status if [ "${STATUS}" == "unformatted" ]; then echo "DASD device ${BUSID} is already in an unformatted state." if [ ${ORIG_ONLINE_STATUS} -eq 0 ]; then /usr/sbin/chccwdev -d -s ${BUSID} /usr/sbin/udevadm settle fi exit 0 fi read DISCIPLINE < /sys/bus/ccw/devices/${BUSID}/discipline else read CU_TYPE < /sys/bus/ccw/devices/${BUSID}/cutype read DEV_TYPE < /sys/bus/ccw/devices/${BUSID}/devtype case "${CU_TYPE}" in 3990/*|2105/*|2107/*|1750/*|9343/*) DISCIPLINE=ECKD ;; 3880/*) case "${DEV_TYPE}" in 3390/*) DISCIPLINE=ECKD ;; esac ;; esac fi if [ "${DISCIPLINE}" != "ECKD" ]; then echo "This script only works on ECKD DASD." if [ ${ORIG_ONLINE_STATUS} -eq 0 ]; then /usr/sbin/chccwdev -d -s ${BUSID} fi exit 12 fi read STATUS < /sys/bus/ccw/devices/${BUSID}/online if [ ${STATUS} -eq 1 ]; then if [ ! -h /dev/disk/by-path/ccw-${BUSID} ]; then echo "The udev-generated symbolic link in /dev/disk/by-path was not found." exit 13 fi /usr/sbin/chccwdev -d -s ${BUSID} /usr/sbin/udevadm settle read STATUS < /sys/bus/ccw/devices/${BUSID}/online if [ ${STATUS} -ne 0 ]; then echo "Device number ${DEVNO} didn't go offline. Unable to continue." exit 14 fi fi /usr/sbin/chccwdev -a raw_track_access=1 -e ${BUSID} /usr/sbin/udevadm settle read STATUS < /sys/bus/ccw/devices/${BUSID}/online if [ ${STATUS} -ne 1 ]; then echo "Unable to bring ${DEVNO} online. Unable to continue." exit 15 fi # After this point, we will kill the formatting on the device perl -e 'for ($h=0;$h<2;$h++){printf "\0\0\0%c\0\0\0\x8%s",$h,(("\0"x8).("\xff"x8).("\0"x65512))}' | dd bs=65536 count=2 oflag=direct of=/dev/disk/by-path/ccw-${BUSID} >/dev/null 2>&1 if [ "$?" -ne 0 ]; then echo "The writing of the null record 0 failed." exit 16 fi echo "Setting ${BUSID} back offline with raw track access disabled." /usr/sbin/chccwdev -d -s -a raw_track_access=0 ${BUSID} /usr/sbin/udevadm settle if [ ${ORIG_ONLINE_STATUS} -eq 1 ]; then /usr/sbin/chccwdev -e ${BUSID} /usr/sbin/udevadm settle fi