From 2472a3b8b5b34dad6122fb78f7f0c91bda4cd7ae Mon Sep 17 00:00:00 2001 From: Mateusz Kusiak Date: Mon, 15 Dec 2025 17:49:06 +0100 Subject: [PATCH 1/2] dasharo-deploy: Add sanity check before flash This commit adds last resort check before performing any flashrom commands. For heads update, we shall not proceed if FD or ME is locked. Signed-off-by: Mateusz Kusiak --- include/dts-functions.sh | 35 +++++++++++++++++++++++++++++++++++ scripts/dasharo-deploy.sh | 10 +++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/include/dts-functions.sh b/include/dts-functions.sh index 75cb86ad..fbfac0eb 100644 --- a/include/dts-functions.sh +++ b/include/dts-functions.sh @@ -688,6 +688,41 @@ set_flashrom_update_params() { fi } +# A final check for locked regions before flashing via flashrom. +# Decide whether we can proceed if any regions are locked. +flashrom_sanity_check() { + local locked_regions=() + local region_list verb + + if [ "$BOARD_FD_REGION_RW" -eq 0 ]; then + locked_regions+=("FD") + fi + + if [ "$BOARD_ME_REGION_RW" -eq 0 ]; then + locked_regions+=("ME") + fi + + if [ "${#locked_regions[@]}" -eq 0 ]; then + return 0 + fi + + if [ "${#locked_regions[@]}" -eq 1 ]; then + region_list="${locked_regions[0]}" + verb="is" + else + region_list="${locked_regions[0]} and ${locked_regions[1]}" + verb="are" + fi + + if [[ "$SWITCHING_TO" == "heads" ]]; then + print_error "Cannot proceed with heads update when $region_list $verb locked!" + return 1 + fi + + print_warning "Proceeding without $region_list $verb flashing, as they $verb not critical." + return 0 +} + set_intel_regions_update_params() { local fd_me_locked="no" if [ $BOARD_HAS_FD_REGION -eq 0 ]; then diff --git a/scripts/dasharo-deploy.sh b/scripts/dasharo-deploy.sh index acb2f282..80e8d05b 100644 --- a/scripts/dasharo-deploy.sh +++ b/scripts/dasharo-deploy.sh @@ -1050,6 +1050,11 @@ deploy_firmware() { fi done + # Last restort check before flashing + if ! flashrom_sanity_check; then + return 1 + fi + _jobs_total=${#_jobs[@]} # Execute scheduled tasks @@ -1245,7 +1250,10 @@ update_workflow() { display_warning fi - deploy_firmware update + # Check if update succeeded + if ! deploy_firmware update; then + return 1 + fi # TODO: Could it be placed somewhere else? if [ ! -z "$SWITCHING_TO" ]; then From 84034b213cde9de614032c083c6c26a1fcc2edfd Mon Sep 17 00:00:00 2001 From: Mateusz Kusiak Date: Tue, 23 Dec 2025 13:05:58 +0100 Subject: [PATCH 2/2] WIP: Refactor sanity check Signed-off-by: Mateusz Kusiak --- include/dts-functions.sh | 51 ++++++++++++++++++++++++++++++++++----- scripts/dasharo-deploy.sh | 38 +++++++++++++---------------- 2 files changed, 62 insertions(+), 27 deletions(-) diff --git a/include/dts-functions.sh b/include/dts-functions.sh index fbfac0eb..743e2f23 100644 --- a/include/dts-functions.sh +++ b/include/dts-functions.sh @@ -688,17 +688,55 @@ set_flashrom_update_params() { fi } -# A final check for locked regions before flashing via flashrom. -# Decide whether we can proceed if any regions are locked. -flashrom_sanity_check() { +# Does combined check to assess whether the board has region and if its locked. +is_region_locked() { + local region="$1" + local has_var rw_var + + # Uppercase + region="${region^^}" + + has_var="BOARD_HAS_${region}_REGION" + rw_var="BOARD_${region}_REGION_RW" + + [[ "${!has_var}" -eq 1 && "${!rw_var}" -eq 0 ]] +} + +# Helper function to check whether a certain region is to be flashed. +# 0 if found, 1 otherwise. +flashrom_check_for_region() { + local region="$1" + local -n _args="$2" + local i + + # Iterate only up to length-1 since we inspect pairs (i, i+1) + for ((i = 0; i < ${#_args[@]} - 1; i++)); do + if [[ "${_args[i]}" == "-i" && "${_args[i + 1]}" == "$region" ]]; then + return 0 + fi + done + + return 1 +} + +# Does a final check for all flashrom parameters if FD or ME are to be flashed +# and if they're locked. Decide whether we can proceed if any regions are locked. +flashrom_region_check() { + local -n args="$1" local locked_regions=() local region_list verb - if [ "$BOARD_FD_REGION_RW" -eq 0 ]; then + # If switching to heads, always check the region, otherwise check region only + # if specified in params. + # The reason is we want to handle both "overwrites" form metadata as well as + # dynamically added params from set_intel_regions_update_params() + if { flashrom_check_for_region fd args || [[ "$SWITCHING_TO" == "heads" ]]; } && + is_region_locked fd; then locked_regions+=("FD") fi - if [ "$BOARD_ME_REGION_RW" -eq 0 ]; then + if { flashrom_check_for_region me args || [[ "$SWITCHING_TO" == "heads" ]]; } && + is_region_locked me; then locked_regions+=("ME") fi @@ -716,10 +754,11 @@ flashrom_sanity_check() { if [[ "$SWITCHING_TO" == "heads" ]]; then print_error "Cannot proceed with heads update when $region_list $verb locked!" + print_error "Refer to: https://docs.dasharo.com/guides/firmware-update/#known-issues" return 1 fi - print_warning "Proceeding without $region_list $verb flashing, as they $verb not critical." + print_warning "Proceeding without $region_list flashing, as it is not critical." return 0 } diff --git a/scripts/dasharo-deploy.sh b/scripts/dasharo-deploy.sh index 80e8d05b..6a62a008 100644 --- a/scripts/dasharo-deploy.sh +++ b/scripts/dasharo-deploy.sh @@ -880,9 +880,11 @@ deploy_firmware() { local _mode local _jobs=() # List of scheduled job indices local _messages=() # List of error messages - # _job_args_ # List of flashrom params per job indice + # _job_args_ # List of flashrom params per job indice # These are created dynamically in schedule_job() and referenced via nameref. local _jobs_total=0 + local _all_flashrom_args=() # An array for all flashrom args from all jobs + local n i # Loop iterators _mode="$1" # Helper function to schedule a flashrom job @@ -909,23 +911,6 @@ deploy_firmware() { args_ref=("$@") } - # Helper function to check whether fd flashing is among arguments - # 0 if found, 1 otherwise. - check_for_fd() { - local -n _args="$1" - local i - - # Scan argument array for the exact flashrom region selector "-i fd". - # Iterate only up to length-1 since we always inspect pairs (i, i+1). - for ((i = 0; i < ${#_args[@]} - 1; i++)); do - if [[ "${_args[i]}" == "-i" && "${_args[i + 1]}" == "fd" ]]; then - return 0 - fi - done - - return 1 - } - if [ "$_mode" == "update" ]; then echo "Updating Dasharo firmware..." print_warning "This may take several minutes. Please be patient and do not" @@ -1033,7 +1018,7 @@ deploy_firmware() { # shellcheck disable=SC2178 local -n args_ref="_job_args_$i" - if check_for_fd args_ref; then + if flashrom_check_for_region fd args_ref; then echo "Scheduling dedicated FD update..." schedule_job "Failed to flash FD" \ -p "$PROGRAMMER_BIOS" \ @@ -1050,8 +1035,19 @@ deploy_firmware() { fi done - # Last restort check before flashing - if ! flashrom_sanity_check; then + # Create array of all flashrom params to call flashrom_region_check only once + for n in "${!_jobs[@]}"; do + i="${_jobs[$n]}" + # _job_args_$i is a dynamically named (runtime-created) global array holding + # flashrom arguments for a single job. + # shellcheck disable=SC2178 + local -n args_ref="_job_args_$i" + + _all_flashrom_args+=("${args_ref[@]}") + done + + # Last resort check before flashing + if ! flashrom_region_check _all_flashrom_args; then return 1 fi