Skip to content

server.met persistence still uses destructive backup and promotion moves

Summary

server.met still has save and auto-update paths that move or delete the live file before a validated replacement is safely promoted. This mirrors the older persistence hazards already fixed for known.met, cancelled.met, part-met, and ipfilter.dat.

Current Main Evidence

  • srchybrid\ServerList.cpp::AutoUpdate() deletes server_met.old and server_met.download, moves the live server.met to server_met.old, then downloads into server_met.download.
  • The auto-update path ignores move/delete failures and restores the backup at the end without validating every promotion step.
  • srchybrid\ServerList.cpp::SaveServermetToFile() writes server.met.new, commits it, then calls MoveFileEx(curservermet, server_met.old, MOVEFILE_REPLACE_EXISTING) and MoveFileEx(newservermet, curservermet, MOVEFILE_REPLACE_EXISTING) without checking either return value.

Risk

If the second promotion fails after the live file has been moved to server_met.old, the application can lose the active server list or leave a stale replacement state. Auto-update has a similar crash/failure window because it moves the existing live file before the download is known good.

Broadband Fit

This is a close-stock persistence fix. It does not require changing server selection, update policy, or protocol behavior.

Resolution

Implemented on main with a dedicated server.met persistence seam. Automatic server-list updates now download into a candidate path, validate the fixed server.met shape before promotion, and atomically publish only the downloaded sidecar list. Normal saves keep writing server.met.new, refresh server_met.old by copy-to-temp replacement, and atomically replace the live server.met without moving it out of the way first.

Acceptance Criteria

  • [x] download server-list updates to a temporary path first and validate before touching the live file
  • [x] promote server.met.new with the shared atomic-replace helper or an equivalent checked ReplaceFile/MoveFileEx flow
  • [x] preserve the previous live file when replacement fails
  • [x] check and log every promotion failure
  • [x] keep server_met.old as a backup artifact without making it a required destructive intermediate
  • [x] add targeted tests for failed write, failed promotion, backup-refresh failure, and failed downloaded-list validation