diff --git a/crates/ecstore/src/store/init.rs b/crates/ecstore/src/store/init.rs
index e83e701c8..4e7128188 100644
--- a/crates/ecstore/src/store/init.rs
+++ b/crates/ecstore/src/store/init.rs
@@ -101,6 +101,10 @@ fn should_retry_local_decommission_resume(err: &Error, attempt: usize) -> bool {
matches!(err, Error::ConfigNotFound) && attempt < LOCAL_DECOMMISSION_RESUME_MAX_CONFIG_RETRIES
}
+fn should_retry_format_load(err: &Error) -> bool {
+ !matches!(err, Error::CorruptedFormat)
+}
+
fn should_auto_start_rebalance_after_init(decommission_running: bool, rebalance_meta_loaded: bool) -> bool {
rebalance_meta_loaded && !decommission_running
}
@@ -319,6 +323,7 @@ impl ECStore {
.await
{
Ok(fm) => break Ok(fm),
+ Err(e) if !should_retry_format_load(&e) => break Err(e),
// Wrap the final error if we are giving up
Err(e) if times >= 10 => {
break Err(Error::other(format!("store init failed to load formats after {times} retries: {e}")));
@@ -551,7 +556,7 @@ mod tests {
LOCAL_DECOMMISSION_RESUME_MAX_CONFIG_RETRIES, load_pool_meta_for_startup, pool_first_endpoint_is_local,
pool_meta_has_active_decommission, preflight_startup_rpc_secret_with, resolve_startup_pool_defaults_with,
resolve_store_init_stage_result, save_validated_pool_meta_for_startup, should_auto_start_rebalance_after_init,
- should_retry_local_decommission_resume, wait_for_local_decommission_resume_delay,
+ should_retry_format_load, should_retry_local_decommission_resume, wait_for_local_decommission_resume_delay,
};
#[cfg(feature = "test-util")]
use crate::{
@@ -773,6 +778,13 @@ mod tests {
assert!(!should_retry_local_decommission_resume(&StorageError::SlowDown, 0));
}
+ #[test]
+ fn test_should_retry_format_load_rejects_permanent_corruption() {
+ assert!(!should_retry_format_load(&StorageError::CorruptedFormat));
+ assert!(should_retry_format_load(&StorageError::ErasureReadQuorum));
+ assert!(should_retry_format_load(&StorageError::FirstDiskWait));
+ }
+
#[test]
fn test_should_auto_start_rebalance_after_init_allows_loaded_rebalance_without_decommission() {
assert!(should_auto_start_rebalance_after_init(false, true));
diff --git a/crates/ecstore/src/store/init_format.rs b/crates/ecstore/src/store/init_format.rs
index f9aceb381..cf95c27fb 100644
--- a/crates/ecstore/src/store/init_format.rs
+++ b/crates/ecstore/src/store/init_format.rs
@@ -25,11 +25,16 @@ use crate::{
},
layout::endpoints::Endpoints,
};
-use futures::future::join_all;
+use futures::{future::join_all, stream, stream::StreamExt};
use std::collections::{HashMap, HashSet};
+use tokio::io::AsyncReadExt;
use tracing::{debug, error, info, warn};
use uuid::Uuid;
+const LEGACY_FORMAT_READ_CONCURRENCY: usize = 16;
+const LEGACY_FORMAT_BASE_MAX_BYTES: usize = 16 * 1024;
+const LEGACY_FORMAT_MAX_BYTES_PER_DISK: usize = 64;
+
pub async fn init_disks(eps: &Endpoints, opt: &DiskOption) -> (Vec