Blob Blame History Raw
#! /bin/sh

[ -z "$DEVPATH" ] && exit 0
[ "$SUBSYSTEM" != "ccw" ] && exit 0

[ -e /etc/ccw.conf ] && MODE="dracut" || MODE="normal"
OLD_IFS="$IFS"

get_config_line_by_subchannel()
{
    local CHANNEL
    CHANNEL="$1"
    while read line; do
        IFS=","
        set $line
	IFS="$OLD_IFS"
        for i in $@; do
            if [ "$CHANNEL" = "$i" ]; then
                echo $line
                return 0
             fi
        done
    done < /etc/ccw.conf
    return 1
}

# borrowed from network-scrips, initscripts along with the get_config_by_subchannel
[ -z "$__sed_discard_ignored_files" ] && __sed_discard_ignored_files='/\(~\|\.bak\|\.old\|\.orig\|\.rpmnew\|\.rpmorig\|\.rpmsave\)$/d'

get_config_by_subchannel ()
{
    LANG=C grep -E -i -l \
        "^[[:space:]]*SUBCHANNELS=['\"]?([0-9]\.[0-9]\.[a-f0-9]+,){0,2}${1}(,[0-9]\.[0-9]\.[a-f0-9]+){0,2}['\"]?([[:space:]]+#|[[:space:]]*$)" \
        /etc/sysconfig/network-scripts/ifcfg-* \
        | LC_ALL=C sed -e "$__sed_discard_ignored_files"
}

get_config_by_subchannel_nm ()
{
    LANG=C grep -E -i -l \
        "^s390-subchannels=([0-9]\.[0-9]\.[a-f0-9]+;){0,2}${1};([0-9]\.[0-9]\.[a-f0-9]+;){0,2}$" \
        /etc/NetworkManager/system-connections/*.nmconnection \
        | LC_ALL=C sed -e "$__sed_discard_ignored_files"
}

CHANNEL=${DEVPATH##*/}

if [ $MODE = "dracut" ]; then
    CONFIG_LINE=$(get_config_line_by_subchannel $CHANNEL)

    [ $? -ne 0 -o -z "$CONFIG_LINE" ] && break

    IFS=","
    set $CONFIG_LINE
    IFS="$OLD_IFS"
    NETTYPE=$1
    shift
    SUBCHANNELS="$1"
    OPTIONS=""
    shift
    while [ $# -gt 0 ]; do
        case $1 in
            *=*) OPTIONS="$OPTIONS $1";;
            [0-9]*) SUBCHANNELS="$SUBCHANNELS,$1";;
        esac
        shift
    done
elif [ $MODE = "normal" ]; then
    NOLOCALE="yes"

    CONFIG_FILE=$(get_config_by_subchannel $CHANNEL)

    if [ -n "$CONFIG_FILE" ]; then
	. $CONFIG_FILE
    else
	CONFIG_FILE=$(get_config_by_subchannel_nm $CHANNEL)
	if [ -n "$CONFIG_FILE" ]; then
	    NETTYPE=$(sed -nr "/^\[ethernet\]/ { :l /^s390-nettype[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" $CONFIG_FILE)
	    SUBCHANNELS=$(sed -nr "/^\[ethernet\]/ { :l /^s390-subchannels[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" $CONFIG_FILE | sed -e "s/;/,/g" -e "s/,$//")
	    LAYER2=$(sed -nr "/^\[ethernet-s390-options\]/ { :l /^layer2[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" $CONFIG_FILE)
	else
	    exit 1
	fi
    fi
else
    echo "Unknown mode=$MODE"
    exit 1
fi


# now we have extracted these variables from the config files:
# SUBCHANNELS
# OPTIONS

# put LAYER2 option into its own variable
set $OPTIONS
OPTIONS=""
while [ $# -gt 0 ]; do
    case $1 in
        layer2=*) LAYER2=${1##layer2=};;
        *=*) OPTIONS="$OPTIONS $1";;
    esac
    shift
done

# translate variables from the interface config files to OPTIONS
if [ -n "$PORTNAME" ]; then
        if [ "$NETTYPE" = "lcs" ]; then
		OPTIONS="$OPTIONS portno=$PORTNAME"
        else
		OPTIONS="$OPTIONS portname=$PORTNAME"
        fi
fi
if [ "$NETTYPE" = "ctc" -a -n "$CTCPROT" ]; then
	OPTIONS="$OPTIONS protocol=$CTCPROT"
fi

# SUBCHANNELS is only set on mainframe ccwgroup devices
[ -z "$SUBCHANNELS" -o -z "$NETTYPE" ] && exit 0
if [ "$NETTYPE" = "ctc" ]; then
    DIR="/sys/bus/ccwgroup/drivers/ctcm"
else
    DIR="/sys/bus/ccwgroup/drivers/$NETTYPE"
fi

i=0
while [ $i -lt 20 ]; do
    [ -e $DIR ] && break
    sleep 0.1
    i=$(($i+1))
done

# driver missing or not loaded
[ ! -e $DIR ] && exit 0

IFS=","
set $SUBCHANNELS
IFS="$OLD_IFS"
CHANNEL1=$1
CHANNEL2=$2
SYSDIR="$DIR/$CHANNEL1"

[ -e $SYSDIR ] && exit 0

# check if the interface is already online
if [ -e $SYSDIR/online ]; then
    read on <$SYSDIR/online
    [ "$on" = "1" ] && exit 0
fi

DRIVER=$(readlink $DEVPATH/driver)
DRIVER=${DRIVER##*/}
if [ "$DRIVER" = "lcs" -a "$NETTYPE" = "ctc" ]; then
    echo "$CHANNEL" > /sys/bus/ccw/drivers/lcs/unbind
    echo "$CHANNEL" > /sys/bus/ccw/drivers/ctcm/bind
    echo "$CHANNEL2" > /sys/bus/ccw/drivers/lcs/unbind
    echo "$CHANNEL2" > /sys/bus/ccw/drivers/ctcm/bind
fi
if [ "$DRIVER" = "ctcm" -a "$NETTYPE" = "lcs" ]; then
    echo "$CHANNEL" > /sys/bus/ccw/drivers/ctcm/unbind
    echo "$CHANNEL" > /sys/bus/ccw/drivers/lcs/bind
    echo "$CHANNEL2" > /sys/bus/ccw/drivers/ctcm/unbind
    echo "$CHANNEL2" > /sys/bus/ccw/drivers/lcs/bind
fi

if [ ! -e $SYSDIR ]; then
    echo "$SUBCHANNELS" > $DIR/group
    i=0
    while [ $i -lt 20 ]; do
        [ -e $SYSDIR ] && break
        sleep 0.1
        i=$(($i+1))
    done

    [ ! -e $SYSDIR ] && exit 1
fi

# check if the interface is already online
if [ -e $SYSDIR/online ]; then
    read on <$SYSDIR/online
    [ "$on" = "1" ] && exit 0
fi

# first set layer2, other options may depend on it
[ -n "$LAYER2" ] && echo $LAYER2 > $SYSDIR/layer2

if [ -n "$OPTIONS" ]; then
    for i in $OPTIONS; do
	OPT=${i%%=*}
	VAL=${i##*=}
	if [ -e "$SYSDIR/$OPT" ]; then
    	    echo "$VAL" > "$SYSDIR/$OPT" || \
            echo "Could not set value \"$VAL\" for OPTION \"$OPT\" with SUBCHANNELS \"$SUBCHANNELS\""
        else
    	    echo "OPTION \"$OPT\" does not exist for SUBCHANNELS \"$SUBCHANNELS\""
        fi
    done
fi

[ -e $SYSDIR/online ] && echo 1 > $SYSDIR/online