diff options
author | Andrei Kartashev <a.kartashev@yadro.com> | 2021-11-26 14:20:32 +0300 |
---|---|---|
committer | Alexander Filippov <a.filippov@yadro.com> | 2022-05-24 12:11:34 +0300 |
commit | 423d2cb71b8337f1e320034a3c42ae99124d2b02 (patch) | |
tree | 99b086a377629e061d4ecff74c6c590464482831 /meta-yadro | |
parent | 761d0bd1ae9c2f7e406588f64fadfd8c4c0dd600 (diff) | |
download | openbmc-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')
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 \ " |