#! /bin/sh # # dasd_configure # $Id: dasd_configure,v 1.10 2004/11/26 15:50:48 hare Exp $ # # Copyright (c) 2001-2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # Configures or deconfigures a DASD device # # Usage: # dasd_configure [-f -t ] [use_diag] # # -f force creation of udev rules, do not check values in /sys. # -t DASD type. Must be provided if -f is used. # ccwid = x.y.ssss where # x is always 0 until IBM creates something that uses that number # y is the logical channel subsystem (lcss) number. Most often this is 0, but it could be non-zero # ssss is the four digit subchannel address of the device, in hexidecimal, with leading zeros. # online = 0 to take the device offline # 1 to bring the device online # use_diag = 0 to _not_ use z/VM DIAG250 I/O, which is the default # 1 to use z/VM DIAG250 I/O # # Return values: # 1 If the "Usage:" line is displayed, not enough parameters specified. # 1 sysfs not mounted (if the "Usage:" line is not displayed). # 2 Invalid status for # 3 No device found for # 4 Could not change state of the device # 5 Device is not a DASD # 6 Could not load module # 7 Failed to activate DASD # 8 DASD not formatted # 9 Only dasd-fba or dasd-eckd is supported. # if [ "${DEBUG}" != "yes" ]; then DEBUG="no" fi exitcode=0 DASD_FORCE=0 DASD_TYPE="unknown" DATUM=$(date) add_channel_for_cio() { echo "$* # $DATUM" >> /boot/zipl/active_devices.txt } remove_channel_for_cio() { [ -w /boot/zipl/active_devices.txt ] && sed -i -e "/^$1/d" /boot/zipl/active_devices.txt } mesg () { echo "$@" } debug_mesg () { case "$DEBUG" in yes) mesg "$@" ;; *) ;; esac } if [ $# -lt 2 ] ; then echo "Usage: $0 [options] [use_diag]" echo echo " -f force creation of udev rules, do not check values in /sys." echo " -t DASD type. Must be provided if -f is used." echo " ccwid = x.y.ssss where" echo " x is always 0 until IBM creates something that uses that number" echo " y is the logical channel subsystem (lcss) number. Most often this is 0, but it could be non-zero" echo " ssss is the four digit subchannel address of the device, in hexidecimal, with leading zeros." echo " online = 0 to take the device offline" echo " 1 to bring the device online" echo " use_diag = 0 to _not_ use z/VM DIAG250 I/O, which is the default" echo " 1 to use z/VM DIAG250 I/O" exit 1 fi while [ $# -gt 0 ] ; do case "$1" in -f) # force creation of udev rules, do not check values in /sys DASD_FORCE=1 ;; -t*) # drive type. Must be provided if -f is used. if [ "$1" = "-t" ] ; then if [ "$2" = "dasd-eckd" -o "$2" = "dasd-fba" ]; then DASD_TYPE=$2 shift else debug_mesg "Only dasd-eckd or dasd-fba are supported." exit 9 fi fi ;; *) break; ;; esac shift done if [ $DASD_FORCE -eq 0 ]; then # Get the mount point for sysfs while read MNTPT MNTDIR MNTSYS MNTTYPE; do if test "$MNTSYS" = "sysfs"; then SYSFS="$MNTDIR" break; fi done &1 > /dev/null if [ -x /sbin/vmcp -a $? -eq 0 ]; then # Unconditionally load the vmcp module, loader might be broken [ -x /sbin/modprobe ] && /sbin/modprobe -q vmcp # Wait until udev is settled [ -x /sbin/udevadm ] && /sbin/udevadm settle --timeout=30 # Check read-only status of virtual DASDs from z/VM if /sbin/vmcp q v dasd > /dasd_attr.lst 2> /dev/null; then while read x dev type label attr1 attr2 rest; do dev=`echo $dev|tr A-F a-f` if test "$type" = "ON"; then attr="$attr2" else attr="$attr1" fi if [ "$CCW_CHAN_ID" = "0.0.$dev" ]; then if test "$attr" = "R/O"; then _ccw_use_readonly="1" fi fi done < /dasd_attr.lst fi rm -f /dasd_attr.lst fi # if [ -x /sbin/vmcp -a $? -eq 0 ] if [ "$ONLINE" -eq 1 ]; then # Check whether we need to do something read _ccw_use_diag < $_ccw_status_dir/use_diag if [ "$_ccw_use_diag" -ne "$USE_DIAG" ] && [ "$_ccw_dev_status" -eq 1 ] ; then # We need to change the DIAG access mode # so we have to set the device offline first debug_mesg "Setting device offline for DIAG access" echo "0" > $_ccw_status_dir/online # Re-read device status read _ccw_dev_status < $_ccw_status_dir/online if [ "$_ccw_dev_status" -ne 0 ]; then mesg "Could not set the device offline for DIAG access" exit 4 fi fi if [ "$_ccw_dev_status" -eq 0 ]; then # Set readonly access if detected if [ "$_ccw_use_readonly" ]; then debug_mesg "Setting device read-only" echo 1 > $_ccw_status_dir/readonly fi if [ "$USE_DIAG" -eq 1 ]; then # Load the diag module if possible [ -x /sbin/modprobe ] && /sbin/modprobe -q dasd_diag_mod _has_dasd_diag=$(/bin/sed -n '/^dasd_diag_mod/p' /proc/modules) if [ "$_has_dasd_diag" ]; then # DIAG mode is special: # We can only be sure if DIAG is available # _after_ we have activated the device debug_mesg "Activating DIAG access mode" echo "$USE_DIAG" > $_ccw_status_dir/use_diag read _ccw_use_diag < $_ccw_status_dir/use_diag # Set the device online debug_mesg "Setting device online" echo "1" > $_ccw_status_dir/online 2>/dev/null # Re-read device status read _ccw_dev_status < $_ccw_status_dir/online if [ "$_ccw_dev_status" -eq 0 ]; then mesg "Could not activate DIAG access mode for device ${CCW_CHAN_ID}" USE_DIAG=0 echo "$USE_DIAG" > $_ccw_status_dir/use_diag # Set the device online debug_mesg "Setting device online" echo "1" > $_ccw_status_dir/online else MODULE=dasd_diag_mod fi else debug_mesg "DIAG mode not available" USE_DIAG=0 # Set the device online debug_mesg "Setting device online" echo "1" > $_ccw_status_dir/online fi # if [ "$_has_dasd_diag" ]; else if [ "$_ccw_use_diag" -eq 1 ] ; then debug_mesg "Deactivating DIAG access mode" echo "0" > $_ccw_status_dir/use_diag read _ccw_use_diag < $_ccw_status_dir/use_diag fi # Set the device online debug_mesg "Setting device online" echo "1" > $_ccw_status_dir/online fi # if [ "$USE_DIAG" -eq 1 ] # Re-read device status read _ccw_dev_status < $_ccw_status_dir/online if [ "$_ccw_dev_status" -eq 0 ]; then mesg "Could not set device ${CCW_CHAN_ID} online" exit 4 fi # Wait for the device to come online read _dasd_state < $_ccw_status_dir/status i=0 while [ "$_dasd_state" != "online" ] ; do if [ "$_dasd_state" = "unformatted" ] ; then mesg "Device ${CCW_CHAN_ID} is unformatted" exitcode=8 break fi [ $i -gt 30 ] && break i=$(expr $i + 1) sleep .1 read _dasd_state < $_ccw_status_dir/status done else debug_mesg "Device ${CCW_CHAN_ID} is already online" fi # if [ "$_ccw_dev_status" -eq 0 ] read _dasd_state < $_ccw_status_dir/status if [ "$_dasd_state" != "online" ] && [ "$_dasd_state" != "unformatted" ] ; then mesg "Failed to activate device ${CCW_CHAN_ID}, device in state $_dasd_state" exit 7 fi else if [ "$_ccw_dev_status" -eq 1 ]; then # Set the device offline debug_mesg "Setting device offline" echo "$ONLINE" > $_ccw_status_dir/online # Re-read to check whether we have succeeded _ccw_dev_status=$(cat $_ccw_status_dir/online) if [ "$?" -ne 0 -o "$_ccw_dev_status" -ne "$ONLINE" ]; then mesg "Could not set device ${CCW_CHAN_ID} offline" exit 4 fi else debug_mesg "Device ${CCW_CHAN_ID} is already offline" fi if [ -d "$_ccw_status_dir" ] ; then # Always disabling DIAG access echo "0" > $_ccw_status_dir/use_diag fi # Set readonly access if detected if [ "$_ccw_use_readonly" ]; then debug_mesg "Setting device read-only" echo 1 > $_ccw_status_dir/readonly fi fi # if [ "$ONLINE" -eq 1 ] # Wait until udev is settled [ -x /sbin/udevadm ] && /sbin/udevadm settle --timeout=30 fi # Second instance of if [ $DASD_FORCE -eq 0 ] if [ $DEBUG = "no" ]; then RULES_DIR=/etc/udev/rules.d else RULES_DIR=. fi RULES_FILE=51-dasd-${CCW_CHAN_ID}.rules if [ -d "$RULES_DIR" ]; then if [ -f ${RULES_DIR}/${RULES_FILE} ]; then rm -f ${RULES_DIR}/${RULES_FILE} fi remove_channel_for_cio "${CCW_CHAN_ID}" if [ "$ONLINE" -eq "1" ]; then add_channel_for_cio "${CCW_CHAN_ID}" # Write a new hwcfg file cat > ${RULES_DIR}/${RULES_FILE} <> ${RULES_DIR}/${RULES_FILE} <> ${RULES_DIR}/${RULES_FILE} <