From da4daee64593a598e1b1d7cc45aa769eb512405e Mon Sep 17 00:00:00 2001 From: weisd Date: Thu, 12 Dec 2024 09:54:06 +0800 Subject: [PATCH] fix: bug crash when disk drop --- ecstore/src/disk/error.rs | 4 ++++ ecstore/src/disk/local.rs | 2 ++ ecstore/src/set_disk.rs | 2 +- ecstore/src/sets.rs | 20 +++++++++++++++++--- ecstore/src/store.rs | 1 + rustfs/src/main.rs | 8 ++++++-- 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/ecstore/src/disk/error.rs b/ecstore/src/disk/error.rs index dae1081eb..d20c00a3f 100644 --- a/ecstore/src/disk/error.rs +++ b/ecstore/src/disk/error.rs @@ -265,6 +265,10 @@ pub fn os_err_to_file_err(e: io::Error) -> Error { } } +pub fn is_unformatted_disk(err: &Error) -> bool { + matches!(err.downcast_ref::(), Some(DiskError::UnformattedDisk)) +} + pub fn is_err_file_not_found(err: &Error) -> bool { matches!(err.downcast_ref::(), Some(DiskError::FileNotFound)) } diff --git a/ecstore/src/disk/local.rs b/ecstore/src/disk/local.rs index 51ba61c41..8ab0f6ee0 100644 --- a/ecstore/src/disk/local.rs +++ b/ecstore/src/disk/local.rs @@ -252,6 +252,7 @@ impl LocalDisk { true } + #[tracing::instrument(level = "debug", skip(self))] async fn check_format_json(&self) -> Result { let md = fs::metadata(&self.format_path).await.map_err(|e| match e.kind() { ErrorKind::NotFound => DiskError::DiskNotFound, @@ -1051,6 +1052,7 @@ impl DiskAPI for LocalDisk { } } + #[tracing::instrument(level = "debug", skip(self))] async fn get_disk_id(&self) -> Result> { let mut format_info = self.format_info.write().await; diff --git a/ecstore/src/set_disk.rs b/ecstore/src/set_disk.rs index 621ab8e6e..cde79dfc6 100644 --- a/ecstore/src/set_disk.rs +++ b/ecstore/src/set_disk.rs @@ -1605,7 +1605,7 @@ impl SetDisks { // TODO: 优化并发 可用数量中断 let (parts_metadata, errs) = Self::read_all_fileinfo(&disks, "", bucket, object, vid.as_str(), read_data, false).await; // warn!("get_object_fileinfo parts_metadata {:?}", &parts_metadata); - warn!("get_object_fileinfo {}/{} errs {:?}", bucket, object, &errs); + // warn!("get_object_fileinfo {}/{} errs {:?}", bucket, object, &errs); let _min_disks = self.set_drive_count - self.default_parity_count; diff --git a/ecstore/src/sets.rs b/ecstore/src/sets.rs index 505610579..594e88f58 100644 --- a/ecstore/src/sets.rs +++ b/ecstore/src/sets.rs @@ -11,7 +11,7 @@ use uuid::Uuid; use crate::{ disk::{ - error::DiskError, + error::{is_unformatted_disk, DiskError}, format::{DistributionAlgoVersion, FormatV3}, new_disk, DiskAPI, DiskInfo, DiskOption, DiskStore, }, @@ -34,8 +34,8 @@ use crate::{ use crate::heal::heal_ops::HealSequence; use tokio::time::Duration; use tokio_util::sync::CancellationToken; -use tracing::info; use tracing::warn; +use tracing::{error, info}; #[derive(Debug, Clone)] pub struct Sets { @@ -56,6 +56,7 @@ pub struct Sets { } impl Sets { + #[tracing::instrument(level = "debug", skip(disks, endpoints, fm, pool_idx, partiy_count))] pub async fn new( disks: Vec>, endpoints: &PoolEndpoints, @@ -120,7 +121,20 @@ impl Sets { disk = local_disk; } - if let Some(_disk_id) = disk.as_ref().unwrap().get_disk_id().await? { + let has_disk_id = match disk.as_ref().unwrap().get_disk_id().await { + Ok(res) => res, + Err(err) => { + if is_unformatted_disk(&err) { + error!("get_disk_id err {:?}", err); + } else { + warn!("get_disk_id err {:?}", err); + } + + None + } + }; + + if let Some(_disk_id) = has_disk_id { set_drive.push(disk); } else { warn!("sets new set_drive {}-{} get_disk_id is none", i, j); diff --git a/ecstore/src/store.rs b/ecstore/src/store.rs index 1e9ad8f77..cfaedd03e 100644 --- a/ecstore/src/store.rs +++ b/ecstore/src/store.rs @@ -94,6 +94,7 @@ pub struct ECStore { impl ECStore { #[allow(clippy::new_ret_no_self)] + #[tracing::instrument(level = "debug", skip(endpoint_pools))] pub async fn new(_address: String, endpoint_pools: EndpointServerPools) -> Result> { // let layouts = DisksLayout::from_volumes(endpoints.as_slice())?; diff --git a/rustfs/src/main.rs b/rustfs/src/main.rs index fe7f2eb62..4dea0f4fa 100644 --- a/rustfs/src/main.rs +++ b/rustfs/src/main.rs @@ -209,10 +209,14 @@ async fn run(opt: config::Opt) -> Result<()> { // init store let store = ECStore::new(server_address.clone(), endpoint_pools.clone()) .await - .map_err(|err| Error::from_string(err.to_string()))?; + .map_err(|err| { + error!("ECStore::new {:?}", &err); + panic!("{}", err); + Error::from_string(err.to_string()) + })?; ECStore::init(store.clone()).await.map_err(|err| { - error!("init faild {:?}", &err); + error!("ECStore init faild {:?}", &err); Error::from_string(err.to_string()) })?; warn!(" init store success!");