mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-06 03:59:14 +00:00
fix(heal): recover replacement after transient disk errors (#7059)
* fix(heal): recover replacement after transient disk errors * fix(heal): satisfy replacement status clippy lint
This commit is contained in:
@@ -650,14 +650,15 @@ fn aggregate_replacement_recovery_cluster_status(
|
||||
reason.get_or_insert("peer_replacement_recovery_status_not_definitive");
|
||||
}
|
||||
|
||||
let first_records = snapshots
|
||||
.first()
|
||||
// Replacement recovery state is anchored on one surviving disk. Nodes
|
||||
// without that disk legitimately report a definitive empty snapshot, so
|
||||
// only non-empty snapshots must agree with each other.
|
||||
let mut non_empty_records = snapshots
|
||||
.iter()
|
||||
.filter(|snapshot| !snapshot.records.is_empty())
|
||||
.map(|snapshot| canonical_replacement_records(&snapshot.records));
|
||||
if let Some(first_records) = &first_records
|
||||
&& snapshots
|
||||
.iter()
|
||||
.skip(1)
|
||||
.any(|snapshot| canonical_replacement_records(&snapshot.records) != *first_records)
|
||||
if let Some(first_records) = non_empty_records.next()
|
||||
&& non_empty_records.any(|records| records != first_records)
|
||||
{
|
||||
reason.get_or_insert("peer_replacement_recovery_status_conflict");
|
||||
}
|
||||
@@ -1627,6 +1628,22 @@ mod tests {
|
||||
assert_eq!(cluster.records.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn replacement_recovery_cluster_accepts_definitive_empty_peers() {
|
||||
let local = rustfs_heal::ReplacementRecoverySnapshot {
|
||||
records: Vec::new(),
|
||||
definitive: true,
|
||||
reason: None,
|
||||
};
|
||||
let peer = replacement_snapshot("11111111-1111-4111-8111-111111111111");
|
||||
let cluster = aggregate_replacement_recovery_cluster_status(vec![local], vec![Ok(Some(peer))], 2, true);
|
||||
|
||||
assert!(cluster.definitive);
|
||||
assert!(cluster.reason.is_none());
|
||||
assert_eq!(cluster.records.len(), 1);
|
||||
assert_eq!(cluster.records[0].state, rustfs_heal::ReplacementRecoveryState::Completed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn replacement_recovery_cluster_rejects_conflicting_records_inside_a_snapshot() {
|
||||
let mut local = replacement_snapshot("11111111-1111-4111-8111-111111111111");
|
||||
|
||||
Reference in New Issue
Block a user