meta-google: ipmi-fru-sh: Add lookup for FruDevice names

This makes it possible to specify a FRU lookup by a dynamically
discovered FRUs from entity manager.

Change-Id: Icf83aa3eff1cbc08a8fa3f99754e5c10e3e583fc
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/meta-google/recipes-google/ipmi/ipmi-fru-sh/lib.sh b/meta-google/recipes-google/ipmi/ipmi-fru-sh/lib.sh
index 3ae0f08..940be7f 100644
--- a/meta-google/recipes-google/ipmi/ipmi-fru-sh/lib.sh
+++ b/meta-google/recipes-google/ipmi/ipmi-fru-sh/lib.sh
@@ -44,6 +44,33 @@
 
 declare -A IPMI_FRU_EEPROM_FILE=()
 
+ipmi_fru_device_to_file() {
+  local fdn="$1"
+
+  local json
+  json="$(busctl -j call xyz.openbmc_project.FruDevice \
+    /xyz/openbmc_project/FruDevice/"$fdn" org.freedesktop.DBus.Properties \
+    GetAll s xyz.openbmc_project.FruDevice)" || return 80
+
+  local jqq='.data[0] | (.BUS.data | tostring) + " " + (.ADDRESS.data | tostring)'
+  local busaddr
+  busaddr="$(echo "$json" | jq -r "$jqq")" || return
+
+  # FRU 0 is hardcoded and FruDevice does not report the correct bus for it
+  # Hardcode a workaround for this specifically known bus
+  if [ "$busaddr" = '0 0' ]; then
+    echo "/etc/fru/baseboard.fru.bin"
+  else
+    local dev="$(printf '%d-%04x' $busaddr)"
+    local efile="/sys/bus/i2c/devices/$dev/eeprom"
+    # The at24 eeprom driver is not guaranteed to be bound
+    if [ ! -e "$efile" ]; then
+      echo "$dev" >/sys/bus/i2c/drivers/at24/bind || return
+    fi
+    echo "$efile"
+  fi
+}
+
 ipmi_fru_alloc() {
   local name="$1"
   local -n ret="$2"
@@ -58,6 +85,19 @@
     local file
     file="$(of_name_to_eeprom "$ofn")" || return
     IPMI_FRU_EEPROM_FILE["$ret"]="$file"
+  elif [[ "$name" =~ ^frudev-name:(.*)$ ]]; then
+    local fdn="${BASH_REMATCH[1]}"
+    local start=$SECONDS
+    local file
+    while (( SECONDS - start < 60 )); do
+      local rc=0
+      file="$(ipmi_fru_device_to_file "$fdn")" || rc=$?
+      (( rc == 0 )) && break
+      # Immediately return any errors, 80 is special to signify retry
+      (( rc != 80 )) && return $rc
+      sleep 1
+    done
+    IPMI_FRU_EEPROM_FILE["$ret"]="$file"
   else
     echo "Invalid IPMI FRU eeprom specification: $name" >&2
     return 1