fix(heal): harden resumable set repair failures (#5693)

* fix(heal): enforce resumable task control

* fix(ecstore): surface bucket and metadata heal errors

* chore: refresh guardrail path references

---------

Signed-off-by: cxymds <cxymds@gmail.com>
This commit is contained in:
cxymds
2026-08-04 20:35:58 +08:00
committed by GitHub
parent 3c8bd5b929
commit 31959b90db
15 changed files with 1276 additions and 191 deletions
+18 -3
View File
@@ -107,13 +107,21 @@ impl Error {
Error::TaskTimeout | Error::TransientSkip { .. } => true,
Error::Storage(err) => {
err.is_quorum_error()
|| matches!(err, EcstoreError::SlowDown | EcstoreError::OperationCanceled | EcstoreError::Lock(_))
|| matches!(
err,
EcstoreError::DiskNotFound
| EcstoreError::VolumeNotFound
| EcstoreError::SlowDown
| EcstoreError::OperationCanceled
| EcstoreError::Lock(_)
)
|| is_recoverable_heal_error_message(&err.to_string())
}
Error::Disk(err) => {
matches!(
err,
DiskError::ErasureReadQuorum
DiskError::DiskNotFound
| DiskError::ErasureReadQuorum
| DiskError::ErasureWriteQuorum
| DiskError::Timeout
| DiskError::SourceStalled
@@ -159,7 +167,7 @@ impl From<Error> for std::io::Error {
#[cfg(test)]
mod tests {
use super::Error;
use crate::heal::EcstoreError;
use crate::heal::{DiskError, EcstoreError};
#[test]
fn incomplete_target_rename_is_recoverable() {
@@ -173,4 +181,11 @@ mod tests {
assert!(task_error.is_recoverable_heal());
assert!(storage_error.is_recoverable_heal());
}
#[test]
fn offline_disk_errors_are_recoverable() {
assert!(Error::Disk(DiskError::DiskNotFound).is_recoverable_heal());
assert!(Error::Storage(EcstoreError::DiskNotFound).is_recoverable_heal());
assert!(Error::Storage(EcstoreError::VolumeNotFound).is_recoverable_heal());
}
}