summaryrefslogtreecommitdiff
path: root/meta-yadro
diff options
context:
space:
mode:
authorAndrei Kartashev <a.kartashev@yadro.com>2021-11-26 14:20:32 +0300
committerAlexander Filippov <a.filippov@yadro.com>2022-05-24 12:11:34 +0300
commit423d2cb71b8337f1e320034a3c42ae99124d2b02 (patch)
tree99b086a377629e061d4ecff74c6c590464482831 /meta-yadro
parent761d0bd1ae9c2f7e406588f64fadfd8c4c0dd600 (diff)
downloadopenbmc-423d2cb71b8337f1e320034a3c42ae99124d2b02.tar.xz
meta-yadro: vegman: add default FRU handler
default-fru-vegman recipe provides script to apply hardware configuration on first boot based on FRU EEPROM content. Signed-off-by: Andrei Kartashev <a.kartashev@yadro.com> Change-Id: I7a17c519259e4bb56a2a00900894ffdbd4edd2f6
Diffstat (limited to 'meta-yadro')
-rw-r--r--meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler.bb23
-rw-r--r--meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler/baseboard-fru-handler.service17
-rw-r--r--meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler/baseboard-fru-handler.sh180
-rw-r--r--meta-yadro/meta-vegman/recipes-yadro/packagegroups/packagegroup-yadro-apps.bb1
4 files changed, 221 insertions, 0 deletions
diff --git a/meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler.bb b/meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler.bb
new file mode 100644
index 0000000000..5329d6ed6b
--- /dev/null
+++ b/meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler.bb
@@ -0,0 +1,23 @@
+SUMMARY = "Apply default configuration from baseboard FRU"
+DESCRIPTION = "Provide baseboard FRU EEPROM handlers to apply platform configuration on system boot"
+
+inherit systemd
+
+SYSTEMD_SERVICE:${PN} = " \
+ baseboard-fru-handler.service \
+ "
+
+RDEPENDS:${PN} = "bash u-boot-fw-utils"
+S = "${WORKDIR}"
+SRC_URI = " \
+ file://baseboard-fru-handler.sh \
+ file://baseboard-fru-handler.service \
+ "
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+do_install() {
+ install -m 0755 ${S}/baseboard-fru-handler.sh -D -t ${D}${bindir}
+ install -m 0644 ${S}/baseboard-fru-handler.service -D -t ${D}${systemd_system_unitdir}
+}
diff --git a/meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler/baseboard-fru-handler.service b/meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler/baseboard-fru-handler.service
new file mode 100644
index 0000000000..19d9af7b00
--- /dev/null
+++ b/meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler/baseboard-fru-handler.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Enforce Static MAC addr mapping and hostname setting
+Wants=xyz.openbmc_project.FruDevice.service
+After=xyz.openbmc_project.FruDevice.service
+Wants=systemd-hostnamed.service
+After=systemd-hostnamed.service
+Before=xyz.openbmc_project.Network.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/bin/env baseboard-fru-handler.sh
+SyslogIdentifier=baseboard-fru-handler
+
+[Install]
+WantedBy=network.target
+
diff --git a/meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler/baseboard-fru-handler.sh b/meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler/baseboard-fru-handler.sh
new file mode 100644
index 0000000000..f52acd4a49
--- /dev/null
+++ b/meta-yadro/meta-vegman/recipes-yadro/fru/vegman-fru-handler/baseboard-fru-handler.sh
@@ -0,0 +1,180 @@
+#!/bin/bash -eu
+
+# SPDX-License-Identifier: Apache-2.0
+# Copyright 2020-2021 YADRO
+
+log_msg() {
+ echo "$@"
+}
+
+log_err() {
+ echo "$@" >&2
+}
+
+read_hw_mac() {
+ local iface="$1"
+ cat /sys/class/net/"${iface}"/address 2>/dev/null ||:
+}
+
+set_hw_mac() {
+ local iface="$1"
+ local mac="$2"
+ local up=""
+ if ip link show dev "${iface}" | grep -q "${iface}:.*\<UP\>" 2>/dev/null; then
+ up=true
+ fi
+
+ if [ "${up}" = true ]; then
+ ip link set dev "${iface}" down ||:
+ fi
+ ip link set dev "${iface}" address "${mac}" ||:
+ if [ "${up}" = true ]; then
+ ip link set dev "${iface}" up ||:
+ fi
+}
+
+set_fw_env_mac() {
+ local iface="$1"
+ local mac="$2"
+ local envname=""
+ case "${iface}" in
+ eth0)
+ envname="ethaddr"
+ ;;
+ eth1)
+ envname="eth1addr"
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+ if ! fw_setenv "$envname" "$mac"; then
+ return 1
+ fi
+}
+
+######## MAIN ########
+FRU_DBUS_SERVICE="xyz.openbmc_project.FruDevice"
+FRU_DBUS_OBJECT_TEMPLATE="\/xyz.*_Motherboard"
+FRU_DBUS_INTERFACE="xyz.openbmc_project.FruDevice"
+fru_dbus_object=""
+
+######## Parse D-bus data ########
+n=1
+while true; do
+ fru_dbus_object=$(busctl tree ${FRU_DBUS_SERVICE} 2>/dev/null |
+ sed -n "s/^.*\(${FRU_DBUS_OBJECT_TEMPLATE}\).*$/\1/p"
+ ) && [ -n "${fru_dbus_object}" ] && break
+ if [ ${n} -lt 15 ]; then
+ n=$((n+1))
+ sleep 1
+ else
+ log_err "Failed to find baseboard FRU object"
+ exit 1
+ fi
+done
+
+dbusData=$(dbus-send --system --print-reply=literal \
+ --dest=${FRU_DBUS_SERVICE} \
+ "${fru_dbus_object}" \
+ org.freedesktop.DBus.Properties.GetAll \
+ string:${FRU_DBUS_INTERFACE} 2>/dev/null ||:)
+
+if [ -z "${dbusData}" ]; then
+ log_err "Failed to get data from D-Bus"
+ exit 1
+fi
+
+# This awk script matches strings 010xyyyyyyyyyyyy, where x is interface index
+# and yyyyyyyyyyyy - interface mac address.
+# The output would be in form ethx=yy:yy:yy:yy:yy:yy
+macsList=$(echo "${dbusData}" | \
+ awk '/BOARD_INFO_AM[0-9]+\s+variant\s+010[0-9a-f]{13}/{
+ totalMacDigits=12
+ singleOctet=2
+ offset=4
+ printf "eth%s=", substr($3, offset, 1)
+ for(i = 1 + offset; i < totalMacDigits + offset; i += singleOctet) {
+ printf "%s", substr($3, i, singleOctet)
+ if (i <= totalMacDigits + offset - singleOctet) printf ":"
+ }
+ printf "\n"
+ }'||:)
+
+if [ -z "${macsList}" ]; then
+ log_err "Failed to get MAC address"
+ exit 1
+fi
+
+# Get hardware model name from PRODUCT_PRODUCT_NAME
+# Examples:
+# 'VEGMAN N110 Server' -> 'VEGMAN-N110'
+# 'TATLIN.ARCHIVE.XS' -> 'TATLIN-ARCHIVE-XS'
+modelName=$(echo "${dbusData}" | \
+ awk '/PRODUCT_PRODUCT_NAME\s+variant\s+/{
+ if ($3 ~ /^VEGMAN/) {
+ printf "%s-%s", $3, $4
+ } else if ($3 ~ /^TATLIN/) {
+ print gensub(/\./, "-", "g", $3)
+ }
+ }'||:)
+
+serialNumber=$(echo "${dbusData}" | \
+ awk '/PRODUCT_SERIAL_NUMBER\s+variant\s+/{print $3}'||:)
+if [ -z "${serialNumber}" ]; then
+ log_err "Failed to get product Serial Number"
+ exit 1
+fi
+
+# shellcheck disable=SC1091
+source /etc/os-release
+
+
+######## Check and set MAC addresses ########
+retCode=0
+IFS='
+'
+for line in ${macsList} ; do
+ ifaceName=$(echo "${line}" | cut -f 1 -d '=' || :)
+ macAddr=$(echo "${line}" | cut -f 2- -d '=' || :)
+ if [ -n "${ifaceName}" ] && [ -n "${macAddr}" ]; then
+ curMacAddr=$(read_hw_mac "${ifaceName}")
+ if [ "${macAddr}" != "${curMacAddr}" ] ; then
+ log_msg "Changing MAC address for ${ifaceName}: ${curMacAddr} -> ${macAddr}"
+ # A factory assigned address was found, and it is newly assigned.
+ # Update the active interface and save the new value to the u-boot
+ # environment.
+ if ! set_hw_mac "${ifaceName}" "${macAddr}"; then
+ log_err "Failed to set address"
+ retCode=1
+ fi
+ if ! set_fw_env_mac "${ifaceName}" "${macAddr}"; then
+ log_err "Failed to set boot env for ${ifaceName}"
+ retCode=1
+ fi
+ fi
+ fi
+
+ [ ${retCode} -eq 0 ] || exit ${retCode}
+done
+
+
+######## Check and set hostname ########
+hostname=$(hostname)
+if [ "${OPENBMC_TARGET_MACHINE}" = "${hostname}" ] ; then
+ hostname="${modelName,,}-${serialNumber}"
+ log_msg "Changing hostname to ${hostname}"
+
+ if ! hostnamectl set-hostname "${hostname}-${SN}"; then
+ log_err "Failed to set new hostname"
+ exit 1
+ fi
+fi
+
+######## Run optional scripts ########
+snmp_handler="/usr/sbin/snmpd-generate-conf.sh"
+if [ -x ${snmp_handler} ]; then
+ if ! ${snmp_handler} "${modelName}"; then
+ log_err "Failed to setup snmp"
+ fi
+fi
diff --git a/meta-yadro/meta-vegman/recipes-yadro/packagegroups/packagegroup-yadro-apps.bb b/meta-yadro/meta-vegman/recipes-yadro/packagegroups/packagegroup-yadro-apps.bb
index 4684dedf60..3b7e3a1848 100644
--- a/meta-yadro/meta-vegman/recipes-yadro/packagegroups/packagegroup-yadro-apps.bb
+++ b/meta-yadro/meta-vegman/recipes-yadro/packagegroups/packagegroup-yadro-apps.bb
@@ -39,6 +39,7 @@ RDEPENDS:${PN}-flash = " \
SUMMARY:${PN}-system = "System software"
RDEPENDS:${PN}-system = " \
+ vegman-fru-handler \
${PN}-interface \
${PN}-cli \
"