#!/bin/bash # Definitions used for platform detection DGX1_GREPSTR="DGX-1" DGX2_GREPSTR="DGX-2" DCS_GREPSTR="DRIVE CONSTELLATION" DCS_LEGACY_GREPSTR="X11DPG-OT\|SYS-4029GP-TRT" C2_OVX_GREPSTR="SYS-420GP-TNR" C2_IO_GREPSTR="PIO-420GP-TNR-01-NC24B\|X12DPG-OA6" # The xen functions simply check for the existence of an xvda device XEN_VM_GREPSTR="" VIRTUALBOX_GREPSTR="VirtualBox" # PLATFORM_FUNCTIONS is a global variable that begins with special case and # complex static functions. It includes all is_XX_PLATFORM functions, and # will be updated by generate_platform_functions() within this script. PLATFORM_FUNCTIONS="is_kvm_vm is_xen_vm is_virtualbox is_l4t_ut2_1 is_dgx_a100 is_dgxstation_a100" FORCE_FILENAME="/usr/share/nvidia/force_platform" OEM_FILENAME="/etc/nvidia-platform" JSON_PLATFORM_CONFIG_DIRECTORY="${JSON_PLATFORM_CONFIG_DIRECTORY:-/etc/nvidia-platform.d/}" # return the OEM supplied filename if # provided to supercede the force_platform get_force_platform() { if [ -s ${OEM_FILENAME} ]; then platform=$(cat ${OEM_FILENAME}) echo "${platform}" return 0 elif [ -s ${FORCE_FILENAME} ]; then forced_platform=$(cat ${FORCE_FILENAME}) echo "${forced_platform}" return 0 fi return 1 } # Arg 1 = platform short name # Arg 2 = attribute name # Arg 3 = default value if attribute not configured # eg: get_system_config_with_default "dgx_a100" "IMPIDefaultSerialTTY" "ttyS1" get_system_config_with_default() { local platshort="${1}" local attribute="${2}" local default="${3}" retVal=$(get_system_config "${platshort}" "${attribute}") if [ $? -ne 0 ]; then echo "${default}" else echo "${retVal}" fi return 0 } # Arg 1 = platform short name # Arg 2 = attribute name # eg: get_system_config "dgx_a100" "GpuRelaxedOrdering" # Possible errors are the following: # 1. The JSON config directory may not exist. Return 1. # 2. jq calls on JSON file may contain syntax errors. Return 1. # 3. jq calls JSON file syntax correct but attribute doesn't exist, # jq returns null (rc 0). Return 1 get_system_config() { if [ ! -d "${JSON_PLATFORM_CONFIG_DIRECTORY}" ]; then return 1 fi query_string='.''['\""${1}"\"']''['\""${2}"\"']' for config_file in "${JSON_PLATFORM_CONFIG_DIRECTORY}"/*.json ; do config_data=$(cat "${config_file}" | jq -r "${query_string}" 2>/dev/null) # check for JSON syntax error in JSON file, continue to next if error. if [ $? -ne 0 ]; then continue fi case "${config_data}" in "True") echo 0 return 0 ;; "False") echo 1 return 0 ;; # JSON syntax ok but attribute missing null) continue ;; *) echo "${config_data}" return 0 ;; esac done # nothing found, return 1 to use default return 1 } # Check if a platform is forced and matches the target # Arg 1 = target platform name # Returns: 0 if forced platform matches target, 1 otherwise # Echoes the target platform name if matched check_forced_platform() { local target="${1}" forced_platform=$(get_force_platform) if [ $? -eq 0 ]; then if [ "${forced_platform}" = "${target}" ]; then echo "${target}" return 0 fi return 1 fi return 1 } # Arg 1 = name = the product name from dmidecode # Arg 2 = grepstr = the grep string for the platform we're testing for # Arg 3 = target = the name of the platform # eg: test_platform ${name} ${DGX1_GREPSTR} "dgx1" test_platform() { name=${1} grepstr=${2} target=${3} if check_forced_platform "${target}"; then return 0 fi if echo ${name} | grep -qi "${grepstr}"; then echo ${target} return fi false } # Arg 1 = grepstr = the grep string for the platform we're testing for # Arg 2 = target = the name of the platform # Uses dmidecode system-family instead of name parameter # eg: test_platform_family ${DGX_SPARK_GREPSTR} "DGX_Spark" test_platform_family() { grepstr=${1} target=${2} if check_forced_platform "${target}"; then return 0 fi family=$(get_system_product_family) if echo ${family} | grep -qi "${grepstr}"; then echo ${target} return fi false } get_plat_grepstr() { platname=${1} echo "$(get_system_config_with_default ${platname} 'GrepStr' '^$^')" } is_dgx_a100() { name=${1} grepstr="$(get_plat_grepstr dgx_a100)" grepstr_negate="$(get_plat_grepstr dgx_a800)" target="dgx_a100" if check_forced_platform "${target}"; then return 0 fi if echo ${name} | grep -qi "${grepstr}"; then # Return false if we are actually a DGX A800 if echo ${name} | grep -qi "${grepstr_negate}"; then false return fi echo ${target} return fi false } is_l4t_ut2_1() { local prod_name=$(ipmitool fru print 0 2> /dev/null | grep 'Product Name' | cut -d':' -f2- | awk '{$1=$1};1') local target="l4t_ut2_1" local grepstr=$(get_plat_grepstr ${target}) if check_forced_platform "${target}"; then return 0 fi if echo "${prod_name}" | grep -q ".*${grepstr}.*"; then echo ${target} return fi false } is_dgxstation_a100() { name=${1} grepstr="$(get_plat_grepstr dgxstation_a100)" grepstr_negate="$(get_plat_grepstr dgxstation_a800)" target="dgxstation_a100" if check_forced_platform "${target}"; then return 0 fi if echo ${name} | grep -qi "${grepstr}"; then # Return false if we are actually a DGXSTATION A800 if echo ${name} | grep -qi "${grepstr_negate}"; then false return fi echo ${target} return fi false } is_kvm_vm() { dmitable="/sys/firmware/dmi/tables/DMI" # Check if any platform is forced first forced_platform=$(get_force_platform) if [ $? -eq 0 ]; then echo "${forced_platform}" return fi if cat ${dmitable} | grep -qi "$(get_plat_grepstr kvm)"; then echo "kvm" return fi false } is_xen_vm() { if [ -e /dev/xvda ]; then echo "xen" return fi false } is_virtualbox() { dmitable="/sys/firmware/dmi/tables/DMI" if cat ${dmitable} | grep -qi "${VIRTUALBOX_GREPSTR}"; then echo "vbox" return fi false } is_other() { name=${1} forced_platform=$(get_force_platform) if [ $? -eq 0 ]; then echo "${forced_platform}" else echo "other" fi } get_platform_short() { PRODUCT_NAME=${1} for method in ${PLATFORM_FUNCTIONS}; do if ${method} "${PRODUCT_NAME}"; then break fi done } get_system_product_family() { product_family=$(dmidecode --string system-family) if [ $? -eq 0 ]; then echo ${product_family} return fi echo "unknown" } get_system_product_name() { product_name=$(dmidecode --string system-product-name) if [ $? -eq 0 ]; then echo ${product_name} return fi echo "unknown" } get_serial_number() { location=${1} serial_number=$(dmidecode --string ${location}-serial-number) if [ $? -eq 0 ]; then echo ${serial_number} return fi echo "unknown" } plat_uses_dgx_a100_raid_config() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "ConfigureDGXA100Raid" "1") } plat_uses_dgxstation_a100_raid_config() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "ConfigureDGXStationA100Raid" "1") } plat_needs_earlycon() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") echo $(get_system_config_with_default "${platshort}" "NeedsEarlycon" "1") } plat_needs_iommu_pt() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NeedsIommuPt" "1") } plat_needs_nvme_relaxed_ordering_config() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NVMERelaxedOrdering" "1") } plat_needs_numa_balance_disable_config() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NeedsDisableNumaBalance" "1") } plat_needs_gpu_relaxed_ordering_config() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "GpuRelaxedOrdering" "1") } plat_get_bmc_passwd_min_len() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") PWMIN="1" # return min as default echo $(get_system_config_with_default "${platshort}" "BMCPasswordMinLength" "${PWMIN}") } plat_get_bmc_passwd_max_len() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") PWMAX="20" # return default max 20 echo $(get_system_config_with_default "${platshort}" "BMCPasswordMaxLength" "${PWMAX}") } plat_get_bmc_passwd_supports_zero_fill() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "BMCPasswordSupportsZerofill" "1") } plat_get_bmc_passwd_has_complexity_reqs() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "BMCPasswordComplexityReq" "1") } plat_get_crashdump_mem() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") MEMRESV="" echo $(get_system_config_with_default "${platshort}" "CrashdumpMem" "${MEMRESV}") } plat_get_nvsm_alerts_supported() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NVSMAlertsSupported" "1") } plat_get_pci_realloc() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") pci_realloc_grub="" echo $(get_system_config_with_default "${platshort}" "PciRealloc" "${pci_realloc_grub}") } plat_needs_mrrs_config() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NeedsMRRSConfig" "1") } plat_needs_acc_bytes_tune() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NeedsAccBytesTuning" "1") } plat_get_default_serial_tty() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") TTY="ttyS1" echo $(get_system_config_with_default "${platshort}" "IPMIDefaultSerialTTY" "${TTY}") } plat_needs_oem_config_xconfig_override() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NeedsOEMXconfigOverride" "1") } plat_needs_initial_nvidia_xconfig() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NeedsInitialNvidiaXconfig" "1") } plat_needs_adaptive_nvidia_xconfig() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NeedsAdaptiveNvidiaXconfig" "1") } plat_needs_enable_power_meter_config() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "EnablePowerMeterCap" "1") } plat_needs_disable_init_on_alloc() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NeedsDisableInitOnAlloc" "1") } plat_needs_containerd_override() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NeedsContainerdOverride" "1") } plat_needs_oem_config_postact_netplan_apply() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "NeedsOemConfigPostActNetplanApply" "1") } plat_uses_fabric_manager() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "UsesFabricManager" "1") } plat_use_disable_acs_redir() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "UsePciDisableAcsRedir" "1") } plat_is_dgx_server_type() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "IsDgxServerType" "1") } plat_is_dgx_desktop_type() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") return $(get_system_config_with_default "${platshort}" "IsDgxDesktopType" "1") } plat_get_console() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") echo $(get_system_config_with_default "${platshort}" "ConsoleSetting" "tty0") } plat_get_serial_baud_rate() { prodname=$(get_system_product_name) platshort=$(get_platform_short "${prodname}") echo $(get_system_config_with_default "${platshort}" "SerialBaudRate" "115200") } # Dynamic function to generate platform functions using eval generate_platform_functions() { # Add legacy platforms that are not in JSON with direct GREPSTR references local legacy_platforms="dgx1 dgx2 dcs dcs_legacy c2_ovx c2_io" for platform in ${legacy_platforms}; do PLATFORM_FUNCTIONS="${PLATFORM_FUNCTIONS} is_${platform}" # Convert platform name to GREPSTR variable name (e.g., dgx1 -> DGX1_GREPSTR) local grepstr_var=$(echo "${platform}" | tr '[:lower:]' '[:upper:]' | sed 's/$/_GREPSTR/') eval "is_${platform}() { test_platform \"\$1\" \"\$${grepstr_var}\" \"${platform}\"; }" done if [ ! -d "${JSON_PLATFORM_CONFIG_DIRECTORY}" ]; then return 1 fi # Process each JSON file in the config directory for config_file in "${JSON_PLATFORM_CONFIG_DIRECTORY}"/*.json; do [ -f "${config_file}" ] || continue # Extract platform keys and generate functions for platform in $(jq -r 'keys[]' "${config_file}" 2>/dev/null); do # Skip if function already exists if type "is_${platform}" >/dev/null 2>&1; then continue fi # Add to global list PLATFORM_FUNCTIONS="${PLATFORM_FUNCTIONS} is_${platform}" # Determine whether the platform uses DMI system family for detection. # Note: "True" is represented as 0 (enabled), "False" as 1 (disabled). uses_family=$(get_system_config_with_default "${platform}" "UsesDmiSystemFamilyForDetection" "1") if [ "${uses_family}" = "1" ]; then # Generate function using standard test_platform eval "is_${platform}() { test_platform \"\$1\" \"\$(get_plat_grepstr ${platform})\" \"${platform}\"; }" else # Generate function using test_platform_family (no name parameter needed) eval "is_${platform}() { test_platform_family \"\$(get_plat_grepstr ${platform})\" \"${platform}\"; }" fi done done PLATFORM_FUNCTIONS="${PLATFORM_FUNCTIONS} is_other" } # Initialize platform functions when script is sourced generate_platform_functions