#!/bin/bash ############################################################################### # Tape hotplug agent for Linux 2.4 kernels # # Copyright (c) 2002 IBM Development Germany, Boeblingen # # the GNU Public License applies # # Author: Stefan Bader , 2002 # # History: # 2002-10-14 Stefan Bader # Fixed remove char case (missing statement) # 2002-10-01 Stefan Bader # Created inital version # # Generated by: # /usr/src/linux/drivers/s390/char/tape.c # # Evionment: # ACTION ::= add | remove # DEVNO ::= <4 digit hex number> # MAJOR ::= # MINOR ::= # INTERFACE ::= char | block ############################################################################### : ${ACTION?Bad invocation: \$ACTION is not set} : ${DEVNO?Bad invocation: \$DEVNO is not set} : ${MAJOR?Bad invocation: \$MAJOR is not set} : ${MINOR?Bad invocation: \$MINOR is not set} : ${INTERFACE?Bad invocation: \$INTERFACE is not set} # Convert to lowercase (just in case) DEVNO=$(echo $DEVNO | tr A-F a-f) cd /etc/hotplug . hotplug.functions mesg "$ACTION $DEVNO $MAJOR $MINOR $INTERFACE" if test -r tape.permissions; then . tape.permissions else mesg "Tape permission handling not found" exit 1 fi #============================================================================== # To preserve the script from doing anything real, call it with # CONDOM=echo : ${CONDOM=} # To try things on an alternate location set ROOTDIR to a different base #: ${ROOTDIR=} : ${ROOTDIR=} # Abort on error or unset variables: set -o errexit set -o nounset #============================================================================== #------------------------------------------------------------------------------ # Environment: none # Parameters : $1 : abort message # $2 : optional return code #------------------------------------------------------------------------------ # Abort handling abort() { local RC if test "$#" -lt 2; then RC=1 else RC=$2 fi mesg "$1 RC($RC)" exit $RC } #------------------------------------------------------------------------------ # Environment: INTERFACE # MINOR # Parameters: none # # Prints: Tape number [0..127] # Returns: 0 #------------------------------------------------------------------------------ tape_number() { if test "$INTERFACE" = "block"; then echo $MINOR else echo "$(($MINOR / 2))" fi return 0 } #------------------------------------------------------------------------------ # Environment: ROOTDIR # DEVNO # CONDOM # Parameters: $1 : variable part of the link name # $2 : variable part of the target node name # # Creates a symbolic link to access the tape device by devno # # Prints: nothing # Returns: 0 on success, otherwise 1 #------------------------------------------------------------------------------ create_symlink() { local LINK=$ROOTDIR/dev/tape/$DEVNO/$1 local TARGET=../../../$2$(tape_number) # Do not create link if devfs compatibility mode is not started if test ! -d $ROOTDIR/dev/tape; then return 0 fi if test ! -d $(dirname $LINK); then $CONDOM mkdir -p $(dirname $LINK) || return 1 fi mesg "Creating symlink $LINK -> $TARGET" $CONDOM rm -f $LINK || return 1 $CONDOM ln -s $TARGET $LINK || return 1 return 0 } #------------------------------------------------------------------------------ # Environment: MAJOR # MINOR # Parameters: $1 : node name # $2 : device type (b|c) # # Tests whether the node already exists with the correct type, major and minor # # Prints: nothing # Returns: 0 if the node is ok, otherwise 1 #------------------------------------------------------------------------------ verify_node() { local NAME="$1" local TYPE="$2" local RC=1 if test -$TYPE "$NAME"; then local MAJMIN=$(ls -l "$NAME"|awk '{print $5 $6}') if test "$(echo $MAJMIN|cut -d, -f1)" = "$MAJOR"; then if test "$(echo $MAJMIN|cut -d, -f2)" = "$MINOR"; then RC=0 fi fi fi return $RC } #------------------------------------------------------------------------------ # Environment: ROOTDIR # INTERFACE # CONDOM # MAJOR # MINOR # OWNER # PERMISSIONS # Parameters: $1 : device type (b|c) # $2 : variable part of the device node name ([brn]tibm) # # Creates a device node for the tpae device (if it doesn't exist) and sets # the permissions. # # Prints: nothing # Returns: 0 on success, otherwise 1 #------------------------------------------------------------------------------ create_node() { local TYPE="$1" local NAME="$ROOTDIR/dev/$2$(tape_number)" # FIXME: This would currently recreate the device node if it isn't # right even if devfs compatibility isn't enabled. Should # ownership and permissions be preserved in that case??? if ! verify_node $NAME $TYPE; then mesg "Creating devicenode $NAME" $CONDOM rm -f "$NAME" || return 1 $CONDOM mknod "$NAME" $TYPE $MAJOR $MINOR || return 1 fi # We only want to change ownership and permissions if devfs compa- # tibility is enabled. tape_permissions $DEVNO if test "$OWNER" != "" -a -d $ROOTDIR/dev/tape; then $CONDOM chown $OWNER "$NAME" || return 1 if test "$PERMISSIONS" != ""; then $CONDOM chmod "$PERMISSIONS" "$NAME" || return 1 fi fi return 0 } #------------------------------------------------------------------------------ # Main #------------------------------------------------------------------------------ case "$ACTION" in add) case "$INTERFACE" in block) create_node b btibm || return 1 create_symlink block/disc btibm || return 1 ;; char) create_node c ntibm || return 1 create_symlink char/norewind ntibm || return 1 MINOR=$(($MINOR + 1)) create_node c rtibm || return 1 create_symlink char/rewind rtibm || return 1 ;; *) abort "Unknown interface type <$INTERFACE>" ;; esac ;; remove) case "$INTERFACE" in char) $CONDOM rm -rf $ROOTDIR/dev/tape/$DEVNO/char if test -d $ROOTDIR/dev/tape; then $CONDOM rm -f \ $ROOTDIR/dev/[nr]tibm$(tape_number) fi ;; block) $CONDOM rm -rf $ROOTDIR/dev/tape/$DEVNO/block if test -d $ROOTDIR/dev/tape; then $CONDOM \ rm -f $ROOTDIR/dev/btibm$(tape_number) fi ;; *) abort "Unknown interface type <$INTERFACE>" ;; esac if test "$(ls $ROOTDIR/dev/tape/$DEVNO)" = ""; then $CONDOM rmdir $ROOTDIR/dev/tape/$DEVNO fi ;; *) abort "$(basename $0): $ACTION event not supported" ;; esac exit 0