diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-03 13:54:25 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-03 13:54:25 +0000 |
commit | 9cb1c4df7b9ce1a9ad1312621b0f2b16a94fba3a (patch) | |
tree | 2efb72864cc69e174c9c5ee33efb88a5f1553b48 /modules.d/80cms | |
parent | Initial commit. (diff) | |
download | dracut-9cb1c4df7b9ce1a9ad1312621b0f2b16a94fba3a.tar.xz dracut-9cb1c4df7b9ce1a9ad1312621b0f2b16a94fba3a.zip |
Adding upstream version 060+5.upstream/060+5
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rwxr-xr-x | modules.d/80cms/cms-write-ifcfg.sh | 105 | ||||
-rwxr-xr-x | modules.d/80cms/cmsifup.sh | 43 | ||||
-rwxr-xr-x | modules.d/80cms/cmssetup.sh | 221 | ||||
-rwxr-xr-x | modules.d/80cms/module-setup.sh | 36 |
4 files changed, 405 insertions, 0 deletions
diff --git a/modules.d/80cms/cms-write-ifcfg.sh b/modules.d/80cms/cms-write-ifcfg.sh new file mode 100755 index 0000000..ecfd53e --- /dev/null +++ b/modules.d/80cms/cms-write-ifcfg.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +OLD_UMASK=$(umask) +umask 0022 +mkdir -p /run/initramfs/state/etc/sysconfig/network-scripts +umask "$OLD_UMASK" + +function cms_write_config() { + . /tmp/cms.conf + SUBCHANNELS="$(echo "$SUBCHANNELS" | sed 'y/ABCDEF/abcdef/')" + OLDIFS=$IFS + IFS=, + read -ra subch_array <<< "indexzero,$SUBCHANNELS" + IFS=$OLDIFS + devbusid=${subch_array[1]} + if [ "$NETTYPE" = "ctc" ]; then + driver="ctcm" + else + driver=$NETTYPE + fi + + DEVICE=$(cd "/sys/devices/${driver}/$devbusid/net/" && set -- * && [ "$1" != "*" ] && echo "$1") + + read -r uuid < /proc/sys/kernel/random/uuid + + IFCFGFILE=/run/initramfs/state/etc/sysconfig/network-scripts/ifcfg-$DEVICE + + strglobin "$IPADDR" '*:*:*' && ipv6=1 + + # to please NetworkManager on startup in loader before loader reconfigures net + cat > /etc/sysconfig/network << EOF +HOSTNAME=$HOSTNAME +EOF + echo "$HOSTNAME" > /etc/hostname + if [ "$ipv6" ]; then + echo "NETWORKING_IPV6=yes" >> /etc/sysconfig/network + else + echo "NETWORKING=yes" >> /etc/sysconfig/network + fi + + cat > "$IFCFGFILE" << EOF +DEVICE=$DEVICE +UUID=$uuid +ONBOOT=yes +BOOTPROTO=static +MTU=$MTU +SUBCHANNELS=$SUBCHANNELS +EOF + if [ "$ipv6" ]; then + cat >> "$IFCFGFILE" << EOF +IPV6INIT=yes +IPV6_AUTOCONF=no +IPV6ADDR=$IPADDR/$NETMASK +IPV6_DEFAULTGW=$GATEWAY +EOF + else + cat >> "$IFCFGFILE" << EOF +IPADDR=$IPADDR +NETMASK=$NETMASK +BROADCAST=$BROADCAST +GATEWAY=$GATEWAY +EOF + fi + if [ "$ipv6" ]; then + # shellcheck disable=SC2153 + IFS="," read -r DNS1 DNS2 _ <<< "$DNS" + else + IFS=":" read -r DNS1 DNS2 _ <<< "$DNS" + fi + # real DNS config for NetworkManager to generate /etc/resolv.conf + [[ $DNS1 ]] && echo "DNS1=$DNS1" >> "$IFCFGFILE" + [[ $DNS2 ]] && echo "DNS2=$DNS2" >> "$IFCFGFILE" + # just to please loader's readNetInfo && writeEnabledNetInfo + # which eats DNS1,DNS2,... and generates it themselves based on DNS + if [[ $ipv6 ]]; then + [[ $DNS ]] && echo "DNS=\"$DNS\"" >> "$IFCFGFILE" + else + [[ $DNS ]] && echo "DNS=\"${DNS/:/,}\"" >> "$IFCFGFILE" + fi + # colons in SEARCHDNS already replaced with spaces above for /etc/resolv.conf + [[ $SEARCHDNS ]] && echo "DOMAIN=\"$SEARCHDNS\"" >> "$IFCFGFILE" + [[ $NETTYPE ]] && echo "NETTYPE=$NETTYPE" >> "$IFCFGFILE" + [[ $PEERID ]] && echo "PEERID=$PEERID" >> "$IFCFGFILE" + [[ $PORTNAME ]] && echo "PORTNAME=$PORTNAME" >> "$IFCFGFILE" + [[ $CTCPROT ]] && echo "CTCPROT=$CTCPROT" >> "$IFCFGFILE" + [[ $MACADDR ]] && echo "MACADDR=$MACADDR" >> "$IFCFGFILE" + optstr="" + for option in LAYER2 PORTNO; do + [ -z "${!option}" ] && continue + [ -n "$optstr" ] && optstr=${optstr}" " + optstr=${optstr}$(echo ${option} | sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/')"="${!option} + done + # write single quotes since network.py removes double quotes but we need quotes + echo "OPTIONS='$optstr'" >> "$IFCFGFILE" + unset option + unset optstr + unset DNS1 + unset DNS2 + echo "files /etc/sysconfig/network-scripts" >> /run/initramfs/rwtab + echo "files /var/lib/dhclient" >> /run/initramfs/rwtab +} + +[ -f /tmp/cms.conf ] && cms_write_config diff --git a/modules.d/80cms/cmsifup.sh b/modules.d/80cms/cmsifup.sh new file mode 100755 index 0000000..285e20d --- /dev/null +++ b/modules.d/80cms/cmsifup.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +DEVICE=$1 + +. /tmp/cms.conf + +strglobin "$IPADDR" '*:*:*' && ipv6=1 + +if [ "$ipv6" ] && ! str_starts "$IPADDR" "["; then + IPADDR="[$IPADDR]" +fi + +if [ "$ipv6" ] && ! str_starts "$GATEWAY" "["; then + GATEWAY="[$GATEWAY]" +fi + +if [ "$ipv6" ]; then + # shellcheck disable=SC2153 + IFS="," read -r DNS1 DNS2 _ <<< "$DNS" +else + IFS=":" read -r DNS1 DNS2 _ <<< "$DNS" +fi + +{ + echo "ip=$IPADDR::$GATEWAY:$NETMASK:$HOSTNAME:$DEVICE:none:$MTU:$MACADDR" + for i in $DNS1 $DNS2; do + echo "nameserver=$i" + done +} > /etc/cmdline.d/80-cms.conf + +[ -e "/tmp/net.ifaces" ] && read -r IFACES < /tmp/net.ifaces +IFACES="$IFACES $DEVICE" +echo "$IFACES" >> /tmp/net.ifaces + +if [ -x /usr/libexec/nm-initrd-generator ] || [ -x /usr/lib/nm-initrd-generator ]; then + type nm_generate_connections > /dev/null 2>&1 || . /lib/nm-lib.sh + nm_generate_connections + nm_reload_connections +else + exec ifup "$DEVICE" +fi diff --git a/modules.d/80cms/cmssetup.sh b/modules.d/80cms/cmssetup.sh new file mode 100755 index 0000000..68e4563 --- /dev/null +++ b/modules.d/80cms/cmssetup.sh @@ -0,0 +1,221 @@ +#!/bin/bash + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh + +function sysecho() { + file="$1" + shift + local i=1 + while [ $i -le 10 ]; do + if [ ! -f "$file" ]; then + sleep 1 + i=$((i + 1)) + else + break + fi + done + local status + read -r status < "$file" + if [[ $status != "$*" ]]; then + [ -f "$file" ] && echo "$*" > "$file" + fi +} + +function dasd_settle() { + local dasd_status=/sys/bus/ccw/devices/$1/status + if [ ! -f "$dasd_status" ]; then + return 1 + fi + local i=1 + while [ $i -le 60 ]; do + local status + read -r status < "$dasd_status" + case $status in + online | unformatted) + return 0 + ;; + *) + sleep 0.1 + i=$((i + 1)) + ;; + esac + done + return 1 +} + +function dasd_settle_all() { + for dasdccw in $(while read -r line || [ -n "$line" ]; do echo "${line%%(*}"; done < /proc/dasd/devices); do + if ! dasd_settle "$dasdccw"; then + echo $"Could not access DASD $dasdccw in time" + return 1 + fi + done + return 0 +} + +# prints a canonocalized device bus ID for a given devno of any format +function canonicalize_devno() { + case ${#1} in + 3) echo "0.0.0${1}" ;; + 4) echo "0.0.${1}" ;; + *) echo "${1}" ;; + esac + return 0 +} + +# read file from CMS and write it to /tmp +function readcmsfile() { # $1=dasdport $2=filename + local dev + local numcpus + local devname + local ret=0 + if [ $# -ne 2 ]; then return; fi + # precondition: udevd created dasda block device node + if ! dasd_cio_free -d "$1"; then + echo $"DASD $1 could not be cleared from device blacklist" + return 1 + fi + + modprobe dasd_mod dasd="$CMSDASD" + modprobe dasd_eckd_mod + udevadm settle + + # precondition: dasd_eckd_mod driver incl. dependencies loaded, + # dasd_mod must be loaded without setting any DASD online + dev=$(canonicalize_devno "$1") + numcpus=$( + while read -r line || [ -n "$line" ]; do + if strstr "$line" "# processors"; then + echo "${line##*:}" + break + fi + done < /proc/cpuinfo + ) + + if [ "${numcpus}" -eq 1 ]; then + echo 1 > /sys/bus/ccw/devices/"$dev"/online + else + if ! sysecho /sys/bus/ccw/devices/"$dev"/online 1; then + echo $"DASD $dev could not be set online" + return 1 + fi + udevadm settle + if ! dasd_settle "$dev"; then + echo $"Could not access DASD $dev in time" + return 1 + fi + fi + + udevadm settle + + devname=$( + cd /sys/bus/ccw/devices/"$dev"/block || exit + set -- * + [ -b /dev/"$1" ] && echo "$1" + ) + devname=${devname:-dasda} + + [[ -d /mnt ]] || mkdir -p /mnt + if cmsfs-fuse --to=UTF-8 -a /dev/"$devname" /mnt; then + cat /mnt/"$2" > /run/initramfs/"$2" + umount /mnt || umount -l /mnt + udevadm settle + else + echo $"Could not read conf file $2 on CMS DASD $1." + ret=1 + fi + + if ! sysecho /sys/bus/ccw/devices/"$dev"/online 0; then + echo $"DASD $dev could not be set offline again" + #return 1 + fi + udevadm settle + + # unbind all dasds to unload the dasd modules for a clean start + ( + cd /sys/bus/ccw/drivers/dasd-eckd || exit + for i in *.*; do echo "$i" > unbind; done + ) + udevadm settle + modprobe -r dasd_eckd_mod + udevadm settle + modprobe -r dasd_diag_mod + udevadm settle + modprobe -r dasd_mod + udevadm settle + return $ret +} + +processcmsfile() { + source /tmp/cms.conf + SUBCHANNELS="$(echo "$SUBCHANNELS" | sed 'y/ABCDEF/abcdef/')" + + if [[ $NETTYPE ]]; then + ( + echo -n "$NETTYPE","$SUBCHANNELS" + [[ $PORTNAME ]] && echo -n ",portname=$PORTNAME" + [[ $LAYER2 ]] && echo -n ",layer2=$LAYER2" + [[ $NETTYPE == "ctc" ]] && [[ $CTCPROT ]] && echo -n ",protocol=$CTCPROT" + echo + ) >> /etc/ccw.conf + + OLDIFS=$IFS + IFS=, + read -r -a subch_array <<< "indexzero,$SUBCHANNELS" + IFS=$OLDIFS + devbusid=${subch_array[1]} + if [ "$NETTYPE" = "ctc" ]; then + driver="ctcm" + else + driver=$NETTYPE + fi + + # shellcheck disable=SC2016 + printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="%s", KERNELS=="%s", ENV{INTERFACE}=="?*", RUN+="/sbin/initqueue --onetime --unique --name cmsifup-$name /sbin/cmsifup $name"\n' "$driver" "$devbusid" > /etc/udev/rules.d/99-cms.rules + # remove the default net rules + rm -f -- /etc/udev/rules.d/91-default-net.rules + # shellcheck disable=SC2016 + [[ -f /etc/udev/rules.d/90-net.rules ]] \ + || printf 'SUBSYSTEM=="net", ACTION=="online", RUN+="/sbin/initqueue --onetime --env netif=$name source_hook initqueue/online"\n' >> /etc/udev/rules.d/99-cms.rules + udevadm control --reload + znet_cio_free + fi + + if [[ $DASD ]] && [[ $DASD != "none" ]]; then + echo "$DASD" | normalize_dasd_arg > /etc/dasd.conf + echo "options dasd_mod dasd=$DASD" > /etc/modprobe.d/dasd_mod.conf + dasd_cio_free + fi + + unset _do_zfcp + for i in ${!FCP_*}; do + echo "${!i}" | while read -r port rest || [ -n "$port" ]; do + case $port in + *.*.*) ;; + + *.*) + port="0.$port" + ;; + *) + port="0.0.$port" + ;; + esac + echo "$port" "$rest" >> /etc/zfcp.conf + done + _do_zfcp=1 + done + [[ $_do_zfcp ]] && zfcp_cio_free + unset _do_zfcp +} + +[[ $CMSDASD ]] || CMSDASD=$(getarg "CMSDASD=") +[[ $CMSCONFFILE ]] || CMSCONFFILE=$(getarg "CMSCONFFILE=") + +# Parse configuration +if [ -n "$CMSDASD" -a -n "$CMSCONFFILE" ]; then + if readcmsfile "$CMSDASD" "$CMSCONFFILE"; then + ln -s /run/initramfs/"$CMSCONFFILE" /tmp/"$CMSCONFFILE" + ln -s /run/initramfs/"$CMSCONFFILE" /tmp/cms.conf + processcmsfile + fi +fi diff --git a/modules.d/80cms/module-setup.sh b/modules.d/80cms/module-setup.sh new file mode 100755 index 0000000..2b280e0 --- /dev/null +++ b/modules.d/80cms/module-setup.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# called by dracut +check() { + arch=${DRACUT_ARCH:-$(uname -m)} + [ "$arch" = "s390" -o "$arch" = "s390x" ] || return 1 + return 255 +} + +# called by dracut +depends() { + arch=${DRACUT_ARCH:-$(uname -m)} + [ "$arch" = "s390" -o "$arch" = "s390x" ] || return 1 + echo znet zfcp dasd dasd_mod bash + return 0 +} + +# called by dracut +installkernel() { + instmods zfcp +} + +# called by dracut +install() { + inst_hook pre-trigger 30 "$moddir/cmssetup.sh" + inst_hook pre-pivot 95 "$moddir/cms-write-ifcfg.sh" + inst_script "$moddir/cmsifup.sh" /sbin/cmsifup + # shellcheck disable=SC2046 + inst_multiple /etc/cmsfs-fuse/filetypes.conf /etc/udev/rules.d/99-fuse.rules /etc/fuse.conf \ + cmsfs-fuse fusermount bash insmod rmmod cat normalize_dasd_arg sed \ + $(rpm -ql s390utils-base) awk getopt + + inst_libdir_file "gconv/*" + #inst /usr/lib/locale/locale-archive + dracut_need_initqueue +} |