summaryrefslogtreecommitdiffstats
path: root/modules.d/95fcoe
diff options
context:
space:
mode:
Diffstat (limited to 'modules.d/95fcoe')
-rwxr-xr-xmodules.d/95fcoe/cleanup-fcoe.sh15
-rwxr-xr-xmodules.d/95fcoe/fcoe-edd.sh54
-rwxr-xr-xmodules.d/95fcoe/fcoe-up.sh106
-rwxr-xr-xmodules.d/95fcoe/lldpad.sh19
-rwxr-xr-xmodules.d/95fcoe/module-setup.sh122
-rwxr-xr-xmodules.d/95fcoe/parse-fcoe.sh106
-rwxr-xr-xmodules.d/95fcoe/stop-fcoe.sh6
7 files changed, 428 insertions, 0 deletions
diff --git a/modules.d/95fcoe/cleanup-fcoe.sh b/modules.d/95fcoe/cleanup-fcoe.sh
new file mode 100755
index 0000000..210fb94
--- /dev/null
+++ b/modules.d/95fcoe/cleanup-fcoe.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
+# ex: ts=8 sw=4 sts=4 et filetype=sh
+
+if [ -e /var/run/lldpad.pid ]; then
+ lldpad -k
+ # with systemd version 230, this is not necessary anymore
+ # systemd commit cacf980ed44a28e276a6cc7f8fc41f991e2ab354
+ if [ -z "$DRACUT_SYSTEMD" ]; then
+ # shellcheck disable=SC2174
+ mkdir -m 0755 -p /run/initramfs/state/dev/shm
+ cp /dev/shm/lldpad.state /run/initramfs/state/dev/shm/ > /dev/null 2>&1
+ echo "files /dev/shm/lldpad.state" >> /run/initramfs/rwtab
+ fi
+fi
diff --git a/modules.d/95fcoe/fcoe-edd.sh b/modules.d/95fcoe/fcoe-edd.sh
new file mode 100755
index 0000000..17f8a7c
--- /dev/null
+++ b/modules.d/95fcoe/fcoe-edd.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+dcb="$1"
+
+_modprobe_r_edd="0"
+
+check_edd() {
+ local cnt=0
+
+ [ -d /sys/firmware/edd ] && return 0
+
+ _modprobe_r_edd="1"
+ modprobe edd || return $?
+
+ while [ $cnt -lt 600 ]; do
+ [ -d /sys/firmware/edd ] && return 0
+ cnt=$((cnt + 1))
+ sleep 0.1
+ done
+ return 1
+}
+
+check_edd || exit 1
+
+for disk in /sys/firmware/edd/int13_*; do
+ [ -d "$disk" ] || continue
+ if [ -e "${disk}/pci_dev/driver" ]; then
+ driver=$(readlink "${disk}/pci_dev/driver")
+ driver=${driver##*/}
+ fi
+ # i40e uses dev_port 1 for a virtual fcoe function
+ if [ "${driver}" = "i40e" ]; then
+ dev_port=1
+ fi
+ for nic in "${disk}"/pci_dev/net/*; do
+ [ -d "$nic" ] || continue
+ if [ -n "${dev_port}" -a -e "${nic}/dev_port" ]; then
+ if [ "$(cat "${nic}"/dev_port)" -ne "${dev_port}" ]; then
+ continue
+ fi
+ fi
+ if [ -e "${nic}"/address ]; then
+ fcoe_interface=${nic##*/}
+ if ! [ -e "/tmp/.fcoe-$fcoe_interface" ]; then
+ /sbin/fcoe-up "$fcoe_interface" "$dcb"
+ : > "/tmp/.fcoe-$fcoe_interface"
+ fi
+ fi
+ done
+done
+
+[ "$_modprobe_r_edd" = "1" ] && modprobe -r edd
+
+unset _modprobe_r_edd
diff --git a/modules.d/95fcoe/fcoe-up.sh b/modules.d/95fcoe/fcoe-up.sh
new file mode 100755
index 0000000..0828f03
--- /dev/null
+++ b/modules.d/95fcoe/fcoe-up.sh
@@ -0,0 +1,106 @@
+#!/bin/sh
+#
+# We get called like this:
+# fcoe-up <network-device> <dcb|nodcb> <fabric|vn2vn>
+#
+# Note currently only nodcb is supported, the dcb option is reserved for
+# future use.
+
+PATH=/usr/sbin:/usr/bin:/sbin:/bin
+type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
+type ip_to_var > /dev/null 2>&1 || . /lib/net-lib.sh
+
+# Huh? Missing arguments ??
+[ -z "$1" -o -z "$2" ] && exit 1
+
+netif=$1
+dcb=$2
+mode=$3
+vlan="yes"
+
+read -r iflink < /sys/class/net/"$netif"/iflink
+read -r ifindex < /sys/class/net/"$netif"/ifindex
+if [ "$iflink" != "$ifindex" ]; then
+ # Skip VLAN devices
+ exit 0
+fi
+
+ip link set dev "$netif" up
+linkup "$netif"
+
+# Some fcoemon implementations expect --syslog=true
+syslogopt="--syslog"
+if fcoemon -h | grep syslog | grep -q yes; then
+ syslogopt="$syslogopt=yes"
+fi
+
+netdriver=$(readlink -f /sys/class/net/"$netif"/device/driver)
+netdriver=${netdriver##*/}
+
+write_fcoemon_cfg() {
+ [ -f /etc/fcoe/cfg-"$netif" ] && return
+ echo FCOE_ENABLE=\"yes\" > /etc/fcoe/cfg-"$netif"
+ if [ "$dcb" = "dcb" ]; then
+ echo DCB_REQUIRED=\"yes\" >> /etc/fcoe/cfg-"$netif"
+ else
+ echo DCB_REQUIRED=\"no\" >> /etc/fcoe/cfg-"$netif"
+ fi
+ if [ "$vlan" = "yes" ]; then
+ echo AUTO_VLAN=\"yes\" >> /etc/fcoe/cfg-"$netif"
+ else
+ echo AUTO_VLAN=\"no\" >> /etc/fcoe/cfg-"$netif"
+ fi
+ if [ "$mode" = "vn2vn" ]; then
+ echo MODE=\"vn2vn\" >> /etc/fcoe/cfg-"$netif"
+ else
+ echo MODE=\"fabric\" >> /etc/fcoe/cfg-"$netif"
+ fi
+}
+
+if [ "$netdriver" = "bnx2x" ]; then
+ # If driver is bnx2x, do not use /sys/module/fcoe/parameters/create but fipvlan
+ modprobe 8021q
+ udevadm settle --timeout=30
+ # Sleep for 13 s to allow dcb negotiation
+ sleep 13
+ fipvlan "$netif" -c -s
+ need_shutdown
+ exit
+fi
+if [ "$dcb" = "dcb" ]; then
+ # wait for lldpad to be ready
+ i=0
+ while [ $i -lt 60 ]; do
+ lldptool -p && break
+ info "Waiting for lldpad to be ready"
+ sleep 1
+ i=$((i + 1))
+ done
+
+ while [ $i -lt 60 ]; do
+ dcbtool sc "$netif" dcb on && break
+ info "Retrying to turn dcb on"
+ sleep 1
+ i=$((i + 1))
+ done
+
+ while [ $i -lt 60 ]; do
+ dcbtool sc "$netif" pfc e:1 a:1 w:1 && break
+ info "Retrying to turn dcb on"
+ sleep 1
+ i=$((i + 1))
+ done
+
+ while [ $i -lt 60 ]; do
+ dcbtool sc "$netif" app:fcoe e:1 a:1 w:1 && break
+ info "Retrying to turn fcoe on"
+ sleep 1
+ i=$((i + 1))
+ done
+
+ sleep 1
+fi
+write_fcoemon_cfg
+fcoemon $syslogopt
+
+need_shutdown
diff --git a/modules.d/95fcoe/lldpad.sh b/modules.d/95fcoe/lldpad.sh
new file mode 100755
index 0000000..f992ae2
--- /dev/null
+++ b/modules.d/95fcoe/lldpad.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+if ! getargbool 1 rd.fcoe -d -n rd.nofcoe; then
+ info "rd.fcoe=0: skipping lldpad activation"
+ return 0
+fi
+
+# Note lldpad will stay running after switchroot, the system initscripts
+# are to kill it and start a new lldpad to take over. Data is transferred
+# between the 2 using a shm segment
+lldpad -d
+# wait for lldpad to be ready
+i=0
+while [ $i -lt 60 ]; do
+ lldptool -p && break
+ info "Waiting for lldpad to be ready"
+ sleep 1
+ i=$((i + 1))
+done
diff --git a/modules.d/95fcoe/module-setup.sh b/modules.d/95fcoe/module-setup.sh
new file mode 100755
index 0000000..3de85c2
--- /dev/null
+++ b/modules.d/95fcoe/module-setup.sh
@@ -0,0 +1,122 @@
+#!/bin/bash
+
+# called by dracut
+check() {
+ is_fcoe() {
+ block_is_fcoe "$1" || return 1
+ }
+
+ [[ $hostonly ]] || [[ $mount_needs ]] && {
+ for_each_host_dev_and_slaves is_fcoe || return 255
+ }
+
+ require_binaries dcbtool fipvlan lldpad ip readlink fcoemon fcoeadm tr || return 1
+ return 0
+}
+
+# called by dracut
+depends() {
+ echo network rootfs-block
+ return 0
+}
+
+# called by dracut
+installkernel() {
+ instmods fcoe libfcoe 8021q edd bnx2fc
+}
+
+get_vlan_parent() {
+ local link=$1
+
+ [ -d "$link" ] || return
+ read -r iflink < "$link"/iflink
+ for if in /sys/class/net/*; do
+ read -r idx < "$if"/ifindex
+ if [ "$idx" -eq "$iflink" ]; then
+ echo "${if##*/}"
+ fi
+ done
+}
+
+# called by dracut
+cmdline() {
+ {
+ for c in /sys/bus/fcoe/devices/ctlr_*; do
+ [ -L "$c" ] || continue
+ read -r enabled < "$c"/enabled
+ read -r mode < "$c"/mode
+ [ "$enabled" -eq 0 ] && continue
+ if [ "$mode" = "VN2VN" ]; then
+ mode="vn2vn"
+ else
+ mode="fabric"
+ fi
+ d=$(
+ cd -P "$c" || exit
+ echo "$PWD"
+ )
+ i=${d%/*}
+ ifname=${i##*/}
+ read -r mac < "${i}"/address
+ s=$(dcbtool gc "${i##*/}" dcb 2> /dev/null | sed -n 's/^DCB State:\t*\(.*\)/\1/p')
+ if [ -z "$s" ]; then
+ p=$(get_vlan_parent "${i}")
+ if [ "$p" ]; then
+ s=$(dcbtool gc "${p}" dcb 2> /dev/null | sed -n 's/^DCB State:\t*\(.*\)/\1/p')
+ ifname=${p##*/}
+ fi
+ fi
+ if [ "$s" = "on" ]; then
+ dcb="dcb"
+ else
+ dcb="nodcb"
+ fi
+
+ # Some Combined Network Adapters(CNAs) implement DCB in firmware.
+ # Do not run software-based DCB or LLDP on CNAs that implement DCB.
+ # If the network interface provides hardware DCB/DCBX capabilities,
+ # DCB_REQUIRED in "/etc/fcoe/cfg-xxx" is expected to set to "no".
+ #
+ # Force "nodcb" if there's any DCB_REQUIRED="no"(child or vlan parent).
+ if grep -q '^[[:blank:]]*DCB_REQUIRED="no"' /etc/fcoe/cfg-"${i##*/}" &> /dev/null; then
+ dcb="nodcb"
+ fi
+
+ if [ "$p" ]; then
+ if grep -q '^[[:blank:]]*DCB_REQUIRED="no"' /etc/fcoe/cfg-"${p}" &> /dev/null; then
+ dcb="nodcb"
+ fi
+ fi
+
+ echo "ifname=${ifname}:${mac}"
+ echo "fcoe=${ifname}:${dcb}:${mode}"
+ done
+ } | sort | uniq
+}
+
+# called by dracut
+install() {
+ inst_multiple ip dcbtool fipvlan lldpad readlink lldptool fcoemon fcoeadm tr
+ if [[ -e $dracutsysrootdir/etc/hba.conf ]]; then
+ inst_libdir_file 'libhbalinux.so*'
+ inst_simple "/etc/hba.conf"
+ fi
+
+ mkdir -m 0755 -p "$initdir/var/lib/lldpad"
+ mkdir -m 0755 -p "$initdir/etc/fcoe"
+
+ if [[ $hostonly_cmdline == "yes" ]]; then
+ local _fcoeconf
+ _fcoeconf=$(cmdline)
+ [[ $_fcoeconf ]] && printf "%s\n" "$_fcoeconf" >> "${initdir}/etc/cmdline.d/95fcoe.conf"
+ fi
+ inst_multiple "/etc/fcoe/cfg-*"
+
+ inst "$moddir/fcoe-up.sh" "/sbin/fcoe-up"
+ inst "$moddir/fcoe-edd.sh" "/sbin/fcoe-edd"
+ inst_hook pre-trigger 03 "$moddir/lldpad.sh"
+ inst_hook cmdline 99 "$moddir/parse-fcoe.sh"
+ inst_hook cleanup 90 "$moddir/cleanup-fcoe.sh"
+ inst_hook shutdown 40 "$moddir/stop-fcoe.sh"
+ dracut_need_initqueue
+}
diff --git a/modules.d/95fcoe/parse-fcoe.sh b/modules.d/95fcoe/parse-fcoe.sh
new file mode 100755
index 0000000..bde6b62
--- /dev/null
+++ b/modules.d/95fcoe/parse-fcoe.sh
@@ -0,0 +1,106 @@
+#!/bin/sh
+#
+# Supported formats:
+# fcoe=<networkdevice>:<dcb|nodcb>:<fabric|vn2vn>
+# fcoe=<macaddress>:<dcb|nodcb>:<fabric|vn2vn>
+#
+# Note currently only nodcb is supported, the dcb option is reserved for
+# future use.
+#
+# Note letters in the macaddress must be lowercase!
+#
+# Examples:
+# fcoe=eth0:nodcb:vn2vn
+# fcoe=4a:3f:4c:04:f8:d7:nodcb:fabric
+
+if [ -z "$fcoe" ] && ! getarg fcoe=; then
+ # If it's not set we don't continue
+ return 0
+fi
+
+if ! getargbool 1 rd.fcoe -d -n rd.nofcoe; then
+ info "rd.fcoe=0: skipping fcoe"
+ return 0
+fi
+
+if ! [ -e /sys/bus/fcoe/ctlr_create ] && ! modprobe -b -a fcoe && ! modprobe -b -a libfcoe; then
+ die "FCoE requested but kernel/initrd does not support FCoE"
+fi
+
+initqueue --onetime modprobe -b -q bnx2fc
+
+parse_fcoe_opts() {
+ local fcoe_interface
+ local fcoe_dcb
+ local fcoe_mode
+ local fcoe_mac
+ local OLDIFS="$IFS"
+ local IFS=:
+ # shellcheck disable=SC2086
+ # shellcheck disable=SC2048
+ set -- $*
+ IFS="$OLDIFS"
+
+ case $# in
+ 2)
+ fcoe_interface=$1
+ fcoe_dcb=$2
+ fcoe_mode="fabric"
+ unset fcoe_mac
+ ;;
+ 3)
+ fcoe_interface=$1
+ fcoe_dcb=$2
+ fcoe_mode=$3
+ unset fcoe_mac
+ ;;
+ 7)
+ fcoe_mac=$(echo "$1:$2:$3:$4:$5:$6" | tr "[:upper:]" "[:lower:]")
+ fcoe_dcb=$7
+ fcoe_mode="fabric"
+ unset fcoe_interface
+ ;;
+ 8)
+ fcoe_mac=$(echo "$1:$2:$3:$4:$5:$6" | tr "[:upper:]" "[:lower:]")
+ fcoe_dcb=$7
+ fcoe_mode=$8
+ unset fcoe_interface
+ ;;
+ *)
+ warn "Invalid arguments for fcoe=$fcoe"
+ return 1
+ ;;
+ esac
+
+ if [ "$fcoe_dcb" != "nodcb" -a "$fcoe_dcb" != "dcb" ]; then
+ warn "Invalid FCoE DCB option: $fcoe_dcb"
+ fi
+
+ if [ "$fcoe_interface" = "edd" ]; then
+ /sbin/initqueue --settled --unique /sbin/fcoe-edd "$fcoe_dcb"
+ return 0
+ fi
+
+ if [ -z "$fcoe_interface" -a -z "$fcoe_mac" ]; then
+ warn "fcoe: Neither interface nor MAC specified for fcoe=$fcoe"
+ return 1
+ fi
+
+ {
+ if [ -n "$fcoe_mac" ]; then
+ # shellcheck disable=SC2016
+ printf 'ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="%s", RUN+="/sbin/initqueue --onetime --unique --name fcoe-up-$name /sbin/fcoe-up $name %s %s"\n' "$fcoe_mac" "$fcoe_dcb" "$fcoe_mode"
+ # shellcheck disable=SC2016
+ printf 'ACTION=="add", SUBSYSTEM=="net", ATTR{address}=="%s", RUN+="/sbin/initqueue --onetime --timeout --unique --name fcoe-timeout-$name /sbin/fcoe-up $name %s %s"\n' "$fcoe_mac" "$fcoe_dcb" "$fcoe_mode"
+ else
+ # shellcheck disable=SC2016
+ printf 'ACTION=="add", SUBSYSTEM=="net", NAME=="%s", RUN+="/sbin/initqueue --onetime --unique --name fcoe-up-$name /sbin/fcoe-up $name %s %s"\n' "$fcoe_interface" "$fcoe_dcb" "$fcoe_mode"
+ # shellcheck disable=SC2016
+ printf 'ACTION=="add", SUBSYSTEM=="net", NAME=="%s", RUN+="/sbin/initqueue --onetime --timeout --unique --name fcoe-timeout-$name /sbin/fcoe-up $name %s %s"\n' "$fcoe_interface" "$fcoe_dcb" "$fcoe_mode"
+ fi
+ } >> /etc/udev/rules.d/92-fcoe.rules
+}
+
+for fcoe in $fcoe $(getargs fcoe=); do
+ parse_fcoe_opts "$fcoe"
+done
diff --git a/modules.d/95fcoe/stop-fcoe.sh b/modules.d/95fcoe/stop-fcoe.sh
new file mode 100755
index 0000000..a89cbbc
--- /dev/null
+++ b/modules.d/95fcoe/stop-fcoe.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+for f in /sys/bus/fcoe/devices/ctlr_*; do
+ [ -e "$f" ] || continue
+ echo 0 > "$f"/enabled
+done