#!/bin/sh #----------------------------------------------------------------------- # dasd - zLinux dasd utility - 2.6 Kernel. #----------------------------------------------------------------------- # 04/27/2006 John C. Miller - john@jmit.com # 02/18/2009 JCM - Fixed the get_dasd_node subr to work with SLES11. # Also added dasd node to display on "DASD LIST" #----------------------------------------------------------------------- # You are free to use, distribute, modify and otherwise mangle this code. # I only ask that if you do, you leave my name in place. Thanks. #----------------------------------------------------------------------- # # This script manipulates the "online" pseudo-file in the # /sys/bus/ccw/{drivers,devices}/devicenumber directories to bring # volumes online and offline. Output of the fdasd command is parsed # to obtain partition information. Depending on whether the reiser # or ext2/ext3 filesystems are used, the reisertunefs or e2label # command output is parsed to get the partition label. # # Usage: # dasd - Display dasd command options (help). # dasd list - List all volumes regardless of status. # dasd list all - Same as "dasd list" # dasd list online - List all online volumes and partition info. # dasd list offline - List all offline volumes. # dasd varyon x.y.zzzz - Bring a volume online. # dasd varyoff x.y.zzzz - Take a volume offline. # # For convenience: # - The subcommands varyon = varyonline = online, and # varyoff = varyoffline = offline. # - You only need to enter enough of the address to adequately describe the # address. e.g. 0.0.0144 = 0144 = 144. If unsure, enter the entire # address like 0.0.0188 for example. # # So the following commands are identical: # # dasd varyon 0.0.0105 # dasd varyon 105 # dasd online 105 # # Note: You may need to modify the list_label subroutine if you are not # using either reiser, ext2, or ext3 file systems. This routine only # knows how to get the partition label for these kinds of file systems. # If you do use some other file system, this script will not barf or fail, # you just won't get the partition labels listed on the "dasd list online" # command. # #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # subroutines - listed first because of shell script limitations. #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - die() { echo $1 exit } #--- # fs_type - Get filesystem type of a partition # Input: A partition e.g. /dev/dasda1 # Output: zfs_type is set to Ext/Ext3, reiser, etc. # $? set to 0 if fstype found, 1 otherwise. #--- fs_type() { #--- # First see if partition is mounted, and get type from # ouput of the mount command. #--- zfs_type=$(mount|grep $1|cut -d" " -f5) if [ ! -z $zfs_type ] ; then echo $zfs_type return 0 fi #--- # No luck above. See if e2label runs ok, which means it is # ext2 or ext3. #--- if e2label $1 > /dev/null 2>&1 ; then zfs_type='ext2' echo $zfs_type return 0 fi #--- # Still no luck. Try reiserfstune. #--- if reiserfstune $1 > /dev/null 2>&1 ; then zfs_type='reiserfs' echo $zfs_type return 0 fi #--- # Can't figure out fs type. Admit it. #--- zfs_type="(unknown)" echo $zfs_type return 1 } #--- # list_label - Get label of partition if possible. # Input: A partition e.g. /dev/dasda1 # Output: Echo the partition label. # $? set to 0 if fstype found, 1 otherwise. #--- list_label() { #--- # Try e2label first. # If label is blank, say (none). #--- if zfs_label=`e2label $1 2>/dev/null` ; then [ -z "$zfs_label" ] && zfs_label="(none)" echo $zfs_label return 0 fi #--- # No luck. Try reiserfstune. # If label is blank, say (none). #--- if zfs_label=`reiserfstune $1 2>/dev/null | grep LABEL` ; then [ -z "$zfs_label" ] && zfs_label="(none)" echo $zfs_label|cut -f2 -d" " return 0 fi #--- # No luck so far. See if part is mounted, and if so say it. #--- if [ ! -z "$(mount|grep $1)" ] ; then echo "(mounted)" else echo "(unknown)" fi } #--- # list_dasd_partitions # Input: Dasd volume node like: /dev/dasda # Output: Echo partitions, labels, and types of partitions. #--- list_dasd_partitions() { echo " Partition: Label: Part Type: FS Type:" # Run fdasd command, and massage the output. fdasd -p $1 \ | grep "/dev/dasd" | grep -v "^Disk" | grep -v "WARNING" \ | awk '{print $1,$6,$7}' \ | while read NODE T1 T2 T3 do DESC="$T1 $T2 $T3" printf " %-12s %-16s %-10s %-10s\n" $NODE $(list_label $NODE) "$DESC" $(fs_type $NODE) done } #--- # online - Bring a volume online. # Input: Volume address # Output: Echos dasd node of volume. #--- online() { DIR=/sys/bus/ccw/devices cd $DIR || die "Unable to find device directory $DIR." devname=`ls -d *$1` cd $devname || die "Unable to change to $DIR/$devname." [ ! -f online ] && return 0 onl=`cat online` return $onl } #--- # get_dasd_node - Find dasd node # Input: Address of dasd # Output: $devnode contains blank if not found or te dasd node like "dasda" #--- get_dasd_node() { devnode="" DIR=/sys/bus/ccw/devices cd $DIR || die "Unable to find device directory $DIR." devname=`ls -d *$1` cd $devname || die "Cannot find device $1." # [ -h 'block:dasd*' ] || return 0 devnode=`ls -ld block* | sed 's:\.\.\/::g' | awk -F">" '{print $2}' | awk -F"/" '{print $2}'` # The following line was added to adapt to a change in SLES11. [ "x$devnode" = "x" ] && devnode=`ls -ld block/dasd* | awk -F"/" '{print $2}'` } help() { clear echo "dasd is a utility for manipulating zLinux dasd." echo echo "Options: dasd list List all dasd volumes regardless of online status." echo " dasd list online List all online dasd volumes and partition info." echo " dasd list offline List all offline dasd volumes." echo " dasd varyonline Vary dasd at online." echo " dasd varyoffline Vary dasd at offline." echo } list_all() { DIR2=/sys/bus/ccw/drivers cd $DIR2/dasd-eckd echo "------------------------ All Dasd -----------------------" echo "Addr State Type Node " echo "---------------------------------------------------------" for addr in `ls -d ?.?.*` ; do onlin=`cat $DIR2/dasd-eckd/$addr/online` if [ $onlin -eq 1 ] ; then get_dasd_node $addr onlinemsg="Online " else onlinemsg="Offline" devnode="" fi printf "%-9s %-9s eckd %s\n" $addr $onlinemsg $devnode done cd $DIR2/dasd-fba for addr in `ls -d ?.?.*` ; do onlin=`cat $DIR2/dasd-fba/$addr/online` if [ $onlin -eq 1 ] ; then get_dasd_node $addr onlinemsg="Online " else onlinemsg="Offline" fi printf "%-9s %-9s fba %s\n" $addr $onlinemsg $devnode done echo } list_online() { # List ECKD dasd echo "----------------------- Online Dasd ---------------------" DIR=/sys/bus/ccw/drivers/dasd-eckd cd $DIR/ for x in `ls -d ?.?.*` ; do online $x onl=$? if [ $onl -eq 1 ] ; then get_dasd_node $x echo $x $devnode eckd list_dasd_partitions /dev/$devnode echo fi done # List FBA DIR=/sys/bus/ccw/drivers/dasd-fba cd $DIR for x in `ls -d ?.?.*` ; do online $x onl=$? if [ $onl -eq 1 ] ; then get_dasd_node $x echo $x $devnode fba echo fi done } list_offline() { # List ECKD dasd echo "----------------------- Offline dasd ---------------------" DIR=/sys/bus/ccw/drivers/dasd-eckd cd $DIR/ for x in `ls -d ?.?.*` ; do online $x onl=$? if [ $onl -eq 0 ] ; then echo $x eckd fi done # List FBA DIR=/sys/bus/ccw/drivers/dasd-fba cd $DIR for x in `ls -d ?.?.*` ; do online $x onl=$? if [ $onl -eq 0 ] ; then echo $x fba echo fi done } varyon() { DEVDIR=/sys/bus/ccw/devices test "x$1" = "x" && die "dasd address not specified; exiting." # Make sure device directory exists, and we can chdir to it. cd $DEVDIR if ! cd *$1 > /dev/null 2>&1 ; then echo "Could not find device $1." exit fi echo 1 > online echo "$1 set to online." ls -l | grep "block" } varyoff() { DEVDIR=/sys/bus/ccw/devices test "x$1" = "x" && die "dasd address not specified; exiting." # Make sure device directory exists, and we can chdir to it. cd $DEVDIR if ! cd *$1 > /dev/null 2>&1 ; then echo "Could not find device $1." exit fi echo 0 > online echo "$1 set to offline." ls -l | grep "block" } #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # Main line code: Call appropriate subroutine. #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case "$1" in help) help ;; list) [ "x$2" = "x" ] && list_all [ "x$2" = "xall" ] && list_all [ "x$2" = "xonline" ] && list_online [ "x$2" = "xoffline" ] && list_offline ;; listall) list_all ;; online) varyon $2 ;; varyon) varyon $2 ;; varyonline) varyon $2 ;; offline) varyoff $2 ;; varyoff) varyoff $2 ;; varyoffline) varyoff $2 ;; *) help exit 1 esac