fix(ecstore): merge peer pool meta reload monotonically (#6392)

The peer reload_pool_meta handler blindly replaced in-memory pool
metadata with the persisted snapshot, so a delayed or out-of-order
reload could roll back newer local queued/canceled/failed/complete
decommission state, and a missing pool.bin wiped local state to an
empty default.

Route peer reload through the same monotonic merge used by the admin
status refresh (merge_pool_status_refresh): entries are replaced only
when strictly newer and no local worker is active; missing snapshots
fail closed. The helper now reports whether any entry was replaced or
appended, and rejected stale/missing reloads are logged. The RPC
handler spawns missing decommission workers only after a reload
actually merged newer state, so duplicate deliveries cannot start
workers for an older generation.

Fixes rustfs/backlog#1917
This commit is contained in:
Zhengchao An
2026-08-23 15:55:06 +08:00
committed by GitHub
parent 0d30c69e5f
commit c442c543d3
3 changed files with 389 additions and 10 deletions
+7 -1
View File
@@ -1987,8 +1987,10 @@ impl Node for NodeService {
error_info: Some("errServerNotInitialized".to_string()),
}));
};
// Recover missing workers only after the reload merged newer state; a
// stale or duplicate reload must not spawn workers for an older generation.
match store.reload_pool_meta().await {
Ok(_) => match store.spawn_missing_local_decommission_routines().await {
Ok(true) => match store.spawn_missing_local_decommission_routines().await {
Ok(_) => Ok(Response::new(ReloadPoolMetaResponse {
success: true,
error_info: None,
@@ -1998,6 +2000,10 @@ impl Node for NodeService {
error_info: Some(err.to_string()),
})),
},
Ok(false) => Ok(Response::new(ReloadPoolMetaResponse {
success: true,
error_info: None,
})),
Err(err) => Ok(Response::new(ReloadPoolMetaResponse {
success: false,
error_info: Some(err.to_string()),