blob: e63557a047bad640221478a273c1701de937dc47 [file] [log] [blame]
Andrei Kartashev423d2cb2021-11-26 14:20:32 +03001#!/bin/bash -eu
2
3# SPDX-License-Identifier: Apache-2.0
4# Copyright 2020-2021 YADRO
5
6log_msg() {
7 echo "$@"
8}
9
10log_err() {
11 echo "$@" >&2
12}
13
14read_hw_mac() {
15 local iface="$1"
16 cat /sys/class/net/"${iface}"/address 2>/dev/null ||:
17}
18
19set_hw_mac() {
20 local iface="$1"
21 local mac="$2"
22 local up=""
23 if ip link show dev "${iface}" | grep -q "${iface}:.*\<UP\>" 2>/dev/null; then
24 up=true
25 fi
26
27 if [ "${up}" = true ]; then
28 ip link set dev "${iface}" down ||:
29 fi
30 ip link set dev "${iface}" address "${mac}" ||:
31 if [ "${up}" = true ]; then
32 ip link set dev "${iface}" up ||:
33 fi
34}
35
36set_fw_env_mac() {
37 local iface="$1"
38 local mac="$2"
39 local envname=""
40 case "${iface}" in
41 eth0)
42 envname="ethaddr"
43 ;;
44 eth1)
45 envname="eth1addr"
46 ;;
47 *)
48 return 1
49 ;;
50 esac
51 if ! fw_setenv "$envname" "$mac"; then
52 return 1
53 fi
54}
55
56######## MAIN ########
57FRU_DBUS_SERVICE="xyz.openbmc_project.FruDevice"
58FRU_DBUS_OBJECT_TEMPLATE="\/xyz.*_Motherboard"
59FRU_DBUS_INTERFACE="xyz.openbmc_project.FruDevice"
60fru_dbus_object=""
61
62######## Parse D-bus data ########
63n=1
64while true; do
65 fru_dbus_object=$(busctl tree ${FRU_DBUS_SERVICE} 2>/dev/null |
66 sed -n "s/^.*\(${FRU_DBUS_OBJECT_TEMPLATE}\).*$/\1/p"
67 ) && [ -n "${fru_dbus_object}" ] && break
68 if [ ${n} -lt 15 ]; then
69 n=$((n+1))
70 sleep 1
71 else
72 log_err "Failed to find baseboard FRU object"
73 exit 1
74 fi
75done
76
77dbusData=$(dbus-send --system --print-reply=literal \
78 --dest=${FRU_DBUS_SERVICE} \
79 "${fru_dbus_object}" \
80 org.freedesktop.DBus.Properties.GetAll \
81 string:${FRU_DBUS_INTERFACE} 2>/dev/null ||:)
82
83if [ -z "${dbusData}" ]; then
84 log_err "Failed to get data from D-Bus"
85 exit 1
86fi
87
88# This awk script matches strings 010xyyyyyyyyyyyy, where x is interface index
89# and yyyyyyyyyyyy - interface mac address.
90# The output would be in form ethx=yy:yy:yy:yy:yy:yy
91macsList=$(echo "${dbusData}" | \
92 awk '/BOARD_INFO_AM[0-9]+\s+variant\s+010[0-9a-f]{13}/{
93 totalMacDigits=12
94 singleOctet=2
95 offset=4
96 printf "eth%s=", substr($3, offset, 1)
97 for(i = 1 + offset; i < totalMacDigits + offset; i += singleOctet) {
98 printf "%s", substr($3, i, singleOctet)
99 if (i <= totalMacDigits + offset - singleOctet) printf ":"
100 }
101 printf "\n"
102 }'||:)
103
104if [ -z "${macsList}" ]; then
105 log_err "Failed to get MAC address"
106 exit 1
107fi
108
109# Get hardware model name from PRODUCT_PRODUCT_NAME
110# Examples:
111# 'VEGMAN N110 Server' -> 'VEGMAN-N110'
112# 'TATLIN.ARCHIVE.XS' -> 'TATLIN-ARCHIVE-XS'
113modelName=$(echo "${dbusData}" | \
114 awk '/PRODUCT_PRODUCT_NAME\s+variant\s+/{
115 if ($3 ~ /^VEGMAN/) {
116 printf "%s-%s", $3, $4
117 } else if ($3 ~ /^TATLIN/) {
118 print gensub(/\./, "-", "g", $3)
119 }
120 }'||:)
121
122serialNumber=$(echo "${dbusData}" | \
123 awk '/PRODUCT_SERIAL_NUMBER\s+variant\s+/{print $3}'||:)
124if [ -z "${serialNumber}" ]; then
125 log_err "Failed to get product Serial Number"
126 exit 1
127fi
128
129# shellcheck disable=SC1091
130source /etc/os-release
131
132
133######## Check and set MAC addresses ########
134retCode=0
135IFS='
136'
137for line in ${macsList} ; do
138 ifaceName=$(echo "${line}" | cut -f 1 -d '=' || :)
139 macAddr=$(echo "${line}" | cut -f 2- -d '=' || :)
140 if [ -n "${ifaceName}" ] && [ -n "${macAddr}" ]; then
141 curMacAddr=$(read_hw_mac "${ifaceName}")
142 if [ "${macAddr}" != "${curMacAddr}" ] ; then
143 log_msg "Changing MAC address for ${ifaceName}: ${curMacAddr} -> ${macAddr}"
144 # A factory assigned address was found, and it is newly assigned.
145 # Update the active interface and save the new value to the u-boot
146 # environment.
147 if ! set_hw_mac "${ifaceName}" "${macAddr}"; then
148 log_err "Failed to set address"
149 retCode=1
150 fi
151 if ! set_fw_env_mac "${ifaceName}" "${macAddr}"; then
152 log_err "Failed to set boot env for ${ifaceName}"
153 retCode=1
154 fi
155 fi
156 fi
157
158 [ ${retCode} -eq 0 ] || exit ${retCode}
159done
160
161
162######## Check and set hostname ########
163hostname=$(hostname)
164if [ "${OPENBMC_TARGET_MACHINE}" = "${hostname}" ] ; then
165 hostname="${modelName,,}-${serialNumber}"
166 log_msg "Changing hostname to ${hostname}"
167
Andrei Kartashev7c231d02022-06-29 01:24:51 +0300168 if ! hostnamectl set-hostname "${hostname}"; then
Andrei Kartashev423d2cb2021-11-26 14:20:32 +0300169 log_err "Failed to set new hostname"
170 exit 1
171 fi
172fi
173
174######## Run optional scripts ########
175snmp_handler="/usr/sbin/snmpd-generate-conf.sh"
176if [ -x ${snmp_handler} ]; then
177 if ! ${snmp_handler} "${modelName}"; then
178 log_err "Failed to setup snmp"
179 fi
180fi