Hi all,
here is the updated code integrating Jeremy's review comments.
It tries to conform to rawhide as closely as possible and in addition
already contains support for all known current s390x network features.
Review and comments greatly appreciated.
attachments are three bash scripts implementing our improvements:
linuxrc.s390: initial installation dialog for RHEL on System z
(sorry, had to gzip it due to mailing list size limit)
lsznet.raw: list sensible network device hardware setups for Linux on
System z
controlunits.sh: define some common control unit mappings
original references:
https://www.redhat.com/archives/anaconda-devel-list/2008-November/msg00183.html
https://www.redhat.com/archives/anaconda-devel-list/2008-December/msg00102.html
On 02/24/2009 07:03 PM, Steffen Maier wrote:
> On 01/05/2009 06:02 AM, Jeremy Katz wrote:
>> Yeah, I think that given the rearranging, etc, there's an effort
>> which could definitely be made to remove some of the "cruft" rather
>> than just trying to keep the old to keep the old.
>
> Done.
>
> I'll post the updated code for review in another e-mail.
Steffen
Linux on System z Development
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Erich Baier
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
Attachment:
linuxrc.s390.gz
Description: GNU Zip compressed data
#! /bin/bash
# lsznet.raw: list sensible network device hardware setups for Linux on s390(x)
# Copyright (C) IBM Corp. 2008,2009
# Author: Steffen Maier <maier de ibm com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License only.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
readonly SYSFS=/sys
# DEBUG=0 turns off debugging. >=1 means increasing debugging.
readonly DEBUG=0
# nothing to be changed below here
readonly CMD=${0##*/}
function error() {
echo "$CMD: ERROR: $*" 1>&2
exit 1;
}
# currently requires bash version 3.0 or later
. ./controlunits.sh
# The arrays (among other things) should be adapted, if any of those device
# drivers start supporting different CU types/models.
# $CU_CARDTYPE array is the only one which may contain entries with spaces
readonly -a CU_CARDTYPE=(
"OSA (QDIO)"
"HiperSockets"
"CTC adapter"
"escon channel"
"ficon channel"
"LCS p390"
"LCS OSA"
)
readonly -a CU_DEVNAME=(
eth
hsi
ctc
ctc
ctc
eth
eth
)
readonly -a CU_GROUPCHANNELS=(
3
3
2
2
2
2
2
)
readonly -a CHPIDTYPES=(
[10]=OSE
[11]=OSD
[24]=IQD
)
readonly PREFIXFORMAT=[[:xdigit:]]*
readonly SSIDFORMAT=[0-3]
readonly BUSIDFORMAT=[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]
readonly IDFORMAT=$PREFIXFORMAT.$SSIDFORMAT.$BUSIDFORMAT
readonly SUBCHANNEL_TYPE_IO=0
function debug() {
level=$1
shift
[ $DEBUG -ge $level ] && echo "$*" 1>&2
}
# Returns symbolic name of CHPID type in $chpidtype_symbolic,
# if an entry in the array $CHPIDTYPES has been found at index of argument 1.
# Returns "?" otherwise.
# Always succeeds and returns 0.
function search_chpt() {
local chpidtype_number=$1
chpidtype_symbolic=${CHPIDTYPES[$chpidtype_number]}
if [ "$chpidtype_symbolic" == "" ]; then
chpidtype_symbolic="?"
fi
return 0
}
# build_list:
#
# Prints list on standard output consisting of all subchannels and
# ccwdevices whose control unit type/model match supported network
# device types on s390. Each matching entry is accompanied with
# (almost all) corresponding attributes.
#
function build_list() {
# use /sys/devices/css*/ for startpath
readonly STARTPATH=$SYSFS/devices
# change to base directory so path globbing length with find is minimal
cd $STARTPATH
# fail out gracefully, if there is not expected sysfs environment
# (could even fail out near the top, if $(uname -m) != s390x)
csses=css$PREFIXFORMAT
for d in $csses; do
[ -d $d ] || exit
done
find $csses -name "$IDFORMAT" |
while read dir; do
debug 6 " examining sysfs directory $dir"
# must not use $...FORMAT (file globs) here since this is a regex:
[[ "$dir" =~ ^css\([[:xdigit:]]+\)/\([[:xdigit:]]+\\.[0-3]\\.[[:xdigit:]]{4}\)/\([[:xdigit:]]+\\.[0-3]\\.[[:xdigit:]]{4}\)$ ]]
case $? in
0)
# string matched the pattern
debug 6 " ${BASH_REMATCH[ ]}"
prefix=${BASH_REMATCH[1]}
subch=${BASH_REMATCH[2]}
devbusid=${BASH_REMATCH[3]}
subch_p=css$prefix/$subch
dev_p=$subch_p/$devbusid
debug 6 " $subch_p $dev_p"
;;
1)
# string did not match the pattern
continue
;;
2)
error "syntax error in regex of match operator =~, code needs to be fixed"
;;
*)
error "unexpected return code of regex match operator =~, code needs to be fixed"
;;
esac
debug 5 " sysfs directory matched regex $dir"
# skip non-I/O-subchannels, i.e. chsc and message subchannels
if [ -f $subch_p/type ]; then
read type < $subch_p/type
if [ $type != $SUBCHANNEL_TYPE_IO ]; then
debug 3 " skip non-I/O subchannel"
continue
fi
fi
# get subchannel information...
# ATTENTION: hex values from sysfs are WITHOUT leading 0x prefix!
read chpid_list < $subch_p/chpids
read -a chpids <<< "$chpid_list"
if [ ${#chpids[ ]} -ne 8 ]; then
error "sysfs reported ${#chpids[ ]} CHPIDs instead of expected 8"
fi
read pim pam pom foo < $subch_p/pimpampom
pimchpidZ=""
local chp
for ((chp=0; chp < 8; chp++)); do
mask=$((0x80 >> chp))
if (( 0x$pim & $mask )); then
pimchpidZ=${pimchpidZ}${chpids[chp]}
else
pimchpidZ=${pimchpidZ}"ZZ"
fi
done
# get device information...
read cutype < $dev_p/cutype
read active < $dev_p/online
# skip already active subchannels and those that are already in a
# ccwgroup and thus not available any more:
[ $active == "1" ] && continue
[ -h $dev_p/group_device ] && continue
# get chpid information...
pimchpids=${pimchpidZ//ZZ/}
[ $pimchpids == "" ] && continue
# Taking the first 2 hex digits as CHPID relies somewhat on the fact
# that network adaptors don't use multipathing and only have one CHP.
# Anyway it's OK since we're only interested in CHPID type and I guess
# this should be equal for all possible multipaths to the same device.
chpid=${pimchpids:0:2}
chpid_p=css$prefix/chp$prefix.$chpid
read chptype < $chpid_p/type
# filter and output...
if search_cu $cutype; then
if [ "${CU_DEVDRV[$cu_idx]}" == "ctcm" ]; then
# assume CTC are mostly virtual and ignore chpid from sysfs
chpidtype_symbolic="-"
else
search_chpt $chptype
fi
echo $pimchpids $devbusid $cutype $chpidtype_symbolic ${CU_DEVDRV[$cu_idx]} ${CU_DEVNAME[$cu_idx]} ${CU_GROUPCHANNELS[$cu_idx]} ${CU_CARDTYPE[$cu_idx]}
else
debug 5 " skip non-network device $devbusid CU $cutype"
fi
done
}
# search_groups:
#
# Prints enumeration list on standard output consisting of possible
# hardware configurations (ccwgroups) for network devices on s390.
# Each configuration suggestion includes corresponding attributes
# that are of potential interest for the user and fit in a fixed column
# table on an 80 column screen.
#
# PRECONDITION: Standard input has to be stably sorted by device bus IDs and
# then by CHPIDs, i.e. grouped by CHPIDs.
#
function search_groups() {
local w_prefix w_ssid w_devno
local d_prefix d_ssid d_devno
local prefix ssid devno x
local chp devbusid cutype chpidtypename devdrv devname groupchs cardtype
# remembered last state variables for possible ccwgroup:
local r_prefix="Z"
local r_ssid="Z"
local r_devno="ZZZZ"
local r_chp="ZZ"
local r_cutype="ZZZZ/ZZ"
local count=0
local item=1
local skipped=0
while read chp devbusid cutype chpidtypename devdrv devname groupchs cardtype; do
debug 1 " # $chp $devbusid $cutype $chpidtypename $devdrv $devname $groupchs $cardtype"
IFS=.
read prefix ssid devno x <<< "$devbusid"
unset IFS
if [ $r_chp != $chp \
-o $r_prefix != $prefix \
-o $r_ssid != $ssid \
-o $r_cutype != $cutype ]; then
# restart with new read channel info and remember it
r_prefix=$prefix
r_ssid=$ssid
r_devno=$devno
r_chp=$chp
r_cutype=$cutype
count=1
debug 2 " INFO: restart on different CHPID or prefix or CUtype/model"
continue
fi
count=$((count + 1))
if [ $count -eq 2 ]; then
# about to check if write channel is one above read channel
if [ $((0x$devno)) -ne $((0x$r_devno + 1)) ]; then
# start with new read channel info
r_prefix=$prefix
r_ssid=$ssid
r_devno=$devno
r_chp=$chp
r_cutype=$cutype
count=1
skipped=$((skipped + 1))
# unimplemented possible packed channel usage option:
# remember unused channels for later use as data channel
debug 2 " INFO: restart on unmatching read channel"
continue
fi
w_prefix=$prefix
w_ssid=$ssid
w_devno=$devno
elif [ $count -eq 3 ]; then
# remember data channel info
d_prefix=$prefix
d_ssid=$ssid
d_devno=$devno
fi
debug 2 " INFO: groupchs=$groupchs count=$count"
if [ $count -ne $groupchs ]; then
debug 2 " INFO: skip"
continue
fi
# found possible ccwgroup
case $count in
2)
chlist=$r_prefix.$r_ssid.$r_devno,$w_prefix.$w_ssid.$w_devno
;;
3)
chlist=$r_prefix.$r_ssid.$r_devno,$w_prefix.$w_ssid.$w_devno,$d_prefix.$d_ssid.$d_devno
;;
*)
error "unknown number of channels for group, code needs to be fixed"
;;
esac
echo $item $cutype $chp $chpidtypename $devdrv $devname $chlist "$cardtype"
item=$((item + 1))
# restart after successful detection
r_prefix="Z"
count=0
done
debug 1 " STATISTIC: skipped $skipped devnos because of unmatching read channel"
}
build_list |
# stable sort by device bus IDs and then by CHPIDs => grouped by CHPIDs
# (sorting only works since keys are fixed no. of digits with leading zeros!)
sort -s -k 1,1 -k 2,2 |
#cat ; exit # move at desired line and uncomment to see intermediate output
search_groups
Attachment:
controlunits.sh
Description: application/shellscript