From 1f1e73ce083d8508f41addab3153403d01892b4d Mon Sep 17 00:00:00 2001 From: weisd Date: Thu, 19 Sep 2024 09:41:29 +0800 Subject: [PATCH] fix get_disk_id --- ecstore/src/disk/local.rs | 106 ++++++++++++++++++++----------------- ecstore/src/disk/mod.rs | 2 +- ecstore/src/disk/remote.rs | 4 +- ecstore/src/sets.rs | 2 +- ecstore/src/utils/fs.rs | 24 +++++++++ ecstore/src/utils/mod.rs | 1 + 6 files changed, 85 insertions(+), 54 deletions(-) create mode 100644 ecstore/src/utils/fs.rs diff --git a/ecstore/src/disk/local.rs b/ecstore/src/disk/local.rs index 3c34f3368..e0a1679ac 100644 --- a/ecstore/src/disk/local.rs +++ b/ecstore/src/disk/local.rs @@ -32,11 +32,13 @@ pub struct FormatInfo { } impl FormatInfo { - pub fn last_check_valid(&self)->bool{ + pub fn last_check_valid(&self) -> bool { let now = OffsetDateTime::now_utc(); - self.file_info.is_some() && self.id.is_some() && self.last_check.is_some() && (now.unix_timestamp() - self.last_check.unwrap().unix_timestamp() <=1) + self.file_info.is_some() + && self.id.is_some() + && self.last_check.is_some() + && (now.unix_timestamp() - self.last_check.unwrap().unix_timestamp() <= 1) } - } #[derive(Debug)] @@ -44,6 +46,7 @@ pub struct LocalDisk { pub root: PathBuf, pub format_path: PathBuf, pub format_info: Mutex, + pub endpoint: Endpoint, // pub id: Mutex>, // pub format_data: Mutex>, // pub format_file_info: Mutex>, @@ -92,6 +95,7 @@ impl LocalDisk { let disk = Self { root, + endpoint: ep.clone(), format_path: format_path, format_info: Mutex::new(format_info), // // format_legacy, @@ -105,16 +109,16 @@ impl LocalDisk { Ok(disk) } - async fn check_format_json(&self) ->Result{ - let p = self.format_path; - let md = fs::metadata(&p).await.map_err(|e|match e.kind(){ - ErrorKind::NotFound => DiskError::DiskNotFound, - ErrorKind::PermissionDenied => DiskError::FileAccessDenied, - _ => { - warn!("check_format_json err {:?}",e); - DiskError::CorruptedBackend}, - })?; - Ok(md) + 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, + ErrorKind::PermissionDenied => DiskError::FileAccessDenied, + _ => { + warn!("check_format_json err {:?}", e); + DiskError::CorruptedBackend + } + })?; + Ok(md) } async fn make_meta_volumes(&self) -> Result<()> { let buckets = format!("{}/{}", super::RUSTFS_META_BUCKET, super::BUCKET_META_PREFIX); @@ -455,58 +459,60 @@ impl DiskAPI for LocalDisk { self.root.clone() } - async fn get_disk_id(&self) -> Option { + async fn get_disk_id(&self) -> Result> { warn!("local get_disk_id"); // TODO: check format file let mut format_info = self.format_info.lock().await; - let id = format_info.id.clone(); + let id = format_info.id.clone(); - if format_info.last_check_valid(){ - return id - } - - let file_meta = self.check_format_json().await?; - - if let Some(file_info) = format_info.file_info{ - if file_meta == file_info{ - - format_info.last_check = Some(OffsetDateTime::now_utc()); - - return id + if format_info.last_check_valid() { + return Ok(id); } - } + let file_meta = self.check_format_json().await?; - let b = fs::read(&format_info.file_path).await.map_err(|e|match e.kind(){ - ErrorKind::NotFound => DiskError::DiskNotFound, - ErrorKind::PermissionDenied => DiskError::FileAccessDenied, - _ => { - warn!("check_format_json err {:?}",e); - DiskError::CorruptedBackend}, - })?; + if let Some(file_info) = &format_info.file_info { + if utils::fs::same_file(&file_meta, file_info) { + format_info.last_check = Some(OffsetDateTime::now_utc()); + return Ok(id); + } + } - let fm = FormatV3::try_from(b.as_slice()).map_err(|e|{ - warn!("decode format.json err {:?}",e); + let b = fs::read(&self.format_path).await.map_err(|e| match e.kind() { + ErrorKind::NotFound => DiskError::DiskNotFound, + ErrorKind::PermissionDenied => DiskError::FileAccessDenied, + _ => { + warn!("check_format_json err {:?}", e); + DiskError::CorruptedBackend + } + })?; + + let fm = FormatV3::try_from(b.as_slice()).map_err(|e| { + warn!("decode format.json err {:?}", e); DiskError::CorruptedBackend - })?; - - let (m,n) = fm.find_disk_index_by_disk_id(fm.erasure.this)?; + })?; - let disk_id = fm.erasure.this; + let (m, n) = fm.find_disk_index_by_disk_id(fm.erasure.this)?; - if m != self.endpoint.set_idx || n != self.endpoint.disk_idx { - return DiskError::InconsistentDisk; - } + let disk_id = fm.erasure.this; - format_info.id = Some(disk_id); - format_info.file_info= Some(file_meta); - format_info.data = b; - format_info.last_check = Some(OffsetDateTime::now_utc()); -; + match (self.endpoint.set_idx, self.endpoint.disk_idx) { + (Some(set_idx), Some(disk_idx)) => { + if m != set_idx || n != disk_idx { + return Err(Error::new(DiskError::InconsistentDisk)); + } + } + _ => return Err(Error::new(DiskError::InconsistentDisk)), + } -Some(disk_id) + format_info.id = Some(disk_id); + format_info.file_info = Some(file_meta); + format_info.data = b; + format_info.last_check = Some(OffsetDateTime::now_utc()); + + Ok(Some(disk_id)) // TODO: 判断源文件id,是否有效 } diff --git a/ecstore/src/disk/mod.rs b/ecstore/src/disk/mod.rs index d2f63c4f9..487edd405 100644 --- a/ecstore/src/disk/mod.rs +++ b/ecstore/src/disk/mod.rs @@ -47,7 +47,7 @@ pub trait DiskAPI: Debug + Send + Sync + 'static { fn is_local(&self) -> bool; fn path(&self) -> PathBuf; async fn close(&self) -> Result<()>; - async fn get_disk_id(&self) -> Option; + async fn get_disk_id(&self) -> Result>; async fn set_disk_id(&self, id: Option) -> Result<()>; async fn delete(&self, volume: &str, path: &str, opt: DeleteOptions) -> Result<()>; diff --git a/ecstore/src/disk/remote.rs b/ecstore/src/disk/remote.rs index b0d5a8a0c..d9e47a908 100644 --- a/ecstore/src/disk/remote.rs +++ b/ecstore/src/disk/remote.rs @@ -105,8 +105,8 @@ impl DiskAPI for RemoteDisk { self.root.clone() } - async fn get_disk_id(&self) -> Option { - self.id.lock().await.clone() + async fn get_disk_id(&self) -> Result> { + Ok(self.id.lock().await.clone()) } async fn set_disk_id(&self, id: Option) -> Result<()> { let mut lock = self.id.lock().await; diff --git a/ecstore/src/sets.rs b/ecstore/src/sets.rs index 8698b2103..c9e049d56 100644 --- a/ecstore/src/sets.rs +++ b/ecstore/src/sets.rs @@ -78,7 +78,7 @@ impl Sets { disk = local_disk; } - if let Some(_disk_id) = disk.as_ref().unwrap().get_disk_id().await { + if let Some(_disk_id) = disk.as_ref().unwrap().get_disk_id().await? { set_drive.push(disk); } else { warn!("sets new set_drive {}-{} get_disk_id is none", i, j); diff --git a/ecstore/src/utils/fs.rs b/ecstore/src/utils/fs.rs new file mode 100644 index 000000000..730047855 --- /dev/null +++ b/ecstore/src/utils/fs.rs @@ -0,0 +1,24 @@ +use std::{fs::Metadata, os::unix::fs::MetadataExt}; + +pub fn same_file(f1: &Metadata, f2: &Metadata) -> bool { + if f1.dev() != f2.dev() { + return false; + } + + if f1.ino() != f2.ino() { + return false; + } + + if f1.size() != f2.size() { + return false; + } + if f1.permissions() != f2.permissions() { + return false; + } + + if f1.mtime() != f2.mtime() { + return false; + } + + true +} diff --git a/ecstore/src/utils/mod.rs b/ecstore/src/utils/mod.rs index 2b78d9e75..90e120d08 100644 --- a/ecstore/src/utils/mod.rs +++ b/ecstore/src/utils/mod.rs @@ -1,5 +1,6 @@ pub mod crypto; pub mod ellipses; +pub mod fs; pub mod hash; pub mod net; pub mod path;