You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
7.8 KiB
240 lines
7.8 KiB
From 1b827040f8b3e1e4fec19de76526fe0620654502 Mon Sep 17 00:00:00 2001 |
|
From: Harald Hoyer <harald@redhat.com> |
|
Date: Mon, 7 Oct 2013 14:24:36 +0200 |
|
Subject: [PATCH] fcoe: add FCoE UEFI boot device support |
|
|
|
--- |
|
modules.d/95fcoe/module-setup.sh | 1 + |
|
modules.d/95fcoe/parse-uefifcoe.sh | 35 +++++++ |
|
modules.d/99base/module-setup.sh | 1 + |
|
modules.d/99base/uefi-lib.sh | 155 +++++++++++++++++++++++++++++ |
|
4 files changed, 192 insertions(+) |
|
create mode 100755 modules.d/95fcoe/parse-uefifcoe.sh |
|
create mode 100755 modules.d/99base/uefi-lib.sh |
|
|
|
diff --git a/modules.d/95fcoe/module-setup.sh b/modules.d/95fcoe/module-setup.sh |
|
index d3c58cc6..08ba4eac 100755 |
|
--- a/modules.d/95fcoe/module-setup.sh |
|
+++ b/modules.d/95fcoe/module-setup.sh |
|
@@ -32,6 +32,7 @@ install() { |
|
inst "$moddir/fcoe-up.sh" "/sbin/fcoe-up" |
|
inst "$moddir/fcoe-edd.sh" "/sbin/fcoe-edd" |
|
inst "$moddir/fcoe-genrules.sh" "/sbin/fcoe-genrules.sh" |
|
+ inst_hook cmdline 20 "$moddir/parse-uefifcoe.sh" |
|
inst_hook cmdline 99 "$moddir/parse-fcoe.sh" |
|
dracut_need_initqueue |
|
} |
|
diff --git a/modules.d/95fcoe/parse-uefifcoe.sh b/modules.d/95fcoe/parse-uefifcoe.sh |
|
new file mode 100755 |
|
index 00000000..e03bcb39 |
|
--- /dev/null |
|
+++ b/modules.d/95fcoe/parse-uefifcoe.sh |
|
@@ -0,0 +1,35 @@ |
|
+#!/bin/bash |
|
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- |
|
+# ex: ts=8 sw=4 sts=4 et filetype=sh |
|
+ |
|
+command -v getarg >/dev/null || . /lib/dracut-lib.sh |
|
+command -v get_fcoe_boot_mac >/dev/null || . /lib/uefi-lib.sh |
|
+command -v set_ifname >/dev/null || . /lib/net-lib.sh |
|
+ |
|
+print_fcoe_uefi_conf() |
|
+{ |
|
+ local mac dev vlan |
|
+ mac=$(get_fcoe_boot_mac) |
|
+ [ -z "$mac" ] && continue |
|
+ dev=$(set_ifname fcoe $mac) |
|
+ vlan=$(get_fcoe_boot_vlan) |
|
+ if [ "$vlan" -ne "0" ]; then |
|
+ case "$vlan" in |
|
+ [0-9]*) |
|
+ printf "%s\n" "vlan=$dev.$vlan:$dev" |
|
+ dev="$dev.$vlan" |
|
+ ;; |
|
+ *) |
|
+ printf "%s\n" "vlan=$vlan:$dev" |
|
+ dev="$vlan" |
|
+ ;; |
|
+ esac |
|
+ fi |
|
+ # fcoe=eth0:nodcb |
|
+ printf "%s\n" "$dev:nodcb" |
|
+} |
|
+ |
|
+ |
|
+if [ -e /sys/firmware/efi/vars/FcoeBootDevice-a0ebca23-5f9c-447a-a268-22b6c158c2ac/data ]; then |
|
+ print_fcoe_uefi_conf > /etc/cmdline.d/40-fcoe-uefi.conf |
|
+fi |
|
diff --git a/modules.d/99base/module-setup.sh b/modules.d/99base/module-setup.sh |
|
index 52ce4004..d33a0fb4 100755 |
|
--- a/modules.d/99base/module-setup.sh |
|
+++ b/modules.d/99base/module-setup.sh |
|
@@ -42,6 +42,7 @@ install() { |
|
mkdir -p ${initdir}/tmp |
|
|
|
inst_simple "$moddir/dracut-lib.sh" "/lib/dracut-lib.sh" |
|
+ inst_simple "$moddir/uefi-lib.sh" "/lib/uefi-lib.sh" |
|
|
|
if ! dracut_module_included "systemd"; then |
|
inst_multiple switch_root || dfatal "Failed to install switch_root" |
|
diff --git a/modules.d/99base/uefi-lib.sh b/modules.d/99base/uefi-lib.sh |
|
new file mode 100755 |
|
index 00000000..faedbac5 |
|
--- /dev/null |
|
+++ b/modules.d/99base/uefi-lib.sh |
|
@@ -0,0 +1,155 @@ |
|
+#!/bin/bash |
|
+# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- |
|
+# ex: ts=8 sw=4 sts=4 et filetype=sh |
|
+# |
|
+# Copyright 2013 Red Hat, Inc. All rights reserved. |
|
+# Copyright 2013 Harald Hoyer <harald@redhat.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; either version 2 of the License, or |
|
+# (at your option) any later version. |
|
+# |
|
+# 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, see <http://www.gnu.org/licenses/>. |
|
+# |
|
+ |
|
+getbyte () { |
|
+ local IFS= LC_CTYPE=C res c |
|
+ read -r -n 1 -d '' c |
|
+ res=$? |
|
+ # the single quote in the argument of the printf |
|
+ # yields the numeric value of $c (ASCII since LC_CTYPE=C) |
|
+ [[ -n $c ]] && c=$(printf '%u' "'$c") || c=0 |
|
+ printf "$c" |
|
+ return $res |
|
+} |
|
+ |
|
+getword () { |
|
+ local b1 b2 val |
|
+ b1=$(getbyte) || return 1 |
|
+ b2=$(getbyte) || return 1 |
|
+ (( val = b2 * 256 + b1 )) |
|
+ echo $val |
|
+ return 0 |
|
+} |
|
+ |
|
+# Acpi(PNP0A08,0x0)/Pci(0x3,0x0)/Pci(0x0,0x0)/MAC(90E2BA265ED4,0x0)/Vlan(172)/Fibre(0x4EA06104A0CC0050,0x0) |
|
+uefi_device_path() |
|
+{ |
|
+ local IFS= LC_CTYPE=C res tt len type hextype first |
|
+ first=1 |
|
+ |
|
+ while :; do |
|
+ type=$(getbyte) || return 1 |
|
+ subtype=$(getbyte) || return 1 |
|
+ len=$(getword) || return 1 |
|
+ hextype=$(printf "%02x%02x" "$type" "$subtype") |
|
+ if [[ $first == 1 ]]; then |
|
+ first=0 |
|
+ elif [[ $hextype != "7fff" ]]; then |
|
+ printf "/" |
|
+ fi |
|
+ case $hextype in |
|
+ 0101) |
|
+ # PCI |
|
+ tt=$(getword) |
|
+ printf "PCI(0x%x,0x%x)" $(($tt / 256)) $(($tt & 255)) |
|
+ ;; |
|
+ 0201) |
|
+ # ACPI |
|
+ printf "Acpi(0x%x,0x%x)" $(($(getword) + $(getword) * 65536)) $(($(getword) + $(getword) * 65536)) |
|
+ ;; |
|
+ 0303) |
|
+ # FIBRE |
|
+ getword &>/dev/null |
|
+ getword &>/dev/null |
|
+ printf "Fibre(0x%x%x%x%x%x%x%x%x,0x%x)" \ |
|
+ $(getbyte) $(getbyte) $(getbyte) $(getbyte) \ |
|
+ $(getbyte) $(getbyte) $(getbyte) $(getbyte) \ |
|
+ $(( $(getword) + $(getword) * 65536 + 4294967296 * ( $(getword) + $(getword) * 65536 ) )) |
|
+ ;; |
|
+ 030b) |
|
+ # MAC |
|
+ printf "MAC(%02x%02x%02x%02x%02x%02x," $(getbyte) $(getbyte) $(getbyte) $(getbyte) $(getbyte) $(getbyte) |
|
+ read -r -N 26 tt || return 1 |
|
+ printf "0x%x)" $(getbyte) |
|
+ ;; |
|
+ 0314) |
|
+ # VLAN |
|
+ printf "VLAN(%d)" $(getword) |
|
+ ;; |
|
+ 7fff) |
|
+ # END |
|
+ printf "\n" |
|
+ return 0 |
|
+ ;; |
|
+ *) |
|
+ printf "Unknown(Type:%d SubType:%d len=%d)" "$type" "$subtype" "$len" |
|
+ read -r -N $(($len-4)) tt || return 1 |
|
+ ;; |
|
+ esac |
|
+ done |
|
+} |
|
+ |
|
+get_fcoe_boot_mac() |
|
+{ |
|
+ data=${1:-/sys/firmware/efi/vars/FcoeBootDevice-a0ebca23-5f9c-447a-a268-22b6c158c2ac/data} |
|
+ [ -f $data ] || return 1 |
|
+ local IFS= LC_CTYPE=C tt len type hextype |
|
+ first=1 |
|
+ |
|
+ while :; do |
|
+ type=$(getbyte) || return 1 |
|
+ subtype=$(getbyte) || return 1 |
|
+ len=$(getword) || return 1 |
|
+ hextype=$(printf "%02x%02x" "$type" "$subtype") |
|
+ case $hextype in |
|
+ 030b) |
|
+ # MAC |
|
+ printf "%02x:%02x:%02x:%02x:%02x:%02x" $(getbyte) $(getbyte) $(getbyte) $(getbyte) $(getbyte) $(getbyte) |
|
+ read -r -N 27 tt || return 1 |
|
+ ;; |
|
+ 7fff) |
|
+ # END |
|
+ return 0 |
|
+ ;; |
|
+ *) |
|
+ read -r -N $(($len-4)) tt || return 1 |
|
+ ;; |
|
+ esac |
|
+ done < $data |
|
+} |
|
+ |
|
+get_fcoe_boot_vlan() |
|
+{ |
|
+ data=${1:-/sys/firmware/efi/vars/FcoeBootDevice-a0ebca23-5f9c-447a-a268-22b6c158c2ac/data} |
|
+ [ -f $data ] || return 1 |
|
+ local IFS= LC_CTYPE=C tt len type hextype |
|
+ first=1 |
|
+ |
|
+ while :; do |
|
+ type=$(getbyte) || return 1 |
|
+ subtype=$(getbyte) || return 1 |
|
+ len=$(getword) || return 1 |
|
+ hextype=$(printf "%02x%02x" "$type" "$subtype") |
|
+ case $hextype in |
|
+ 0314) |
|
+ # VLAN |
|
+ printf "%d" $(getword) |
|
+ ;; |
|
+ 7fff) |
|
+ # END |
|
+ return 0 |
|
+ ;; |
|
+ *) |
|
+ read -r -N $(($len-4)) tt || return 1 |
|
+ ;; |
|
+ esac |
|
+ done < $data |
|
+}
|
|
|