healing tracker

Signed-off-by: junxiang Mu <1948535941@qq.com>
This commit is contained in:
junxiang Mu
2024-10-15 18:28:55 +08:00
parent e4f5ca7ea8
commit 3f2772c74c
16 changed files with 636 additions and 44 deletions
+70 -4
View File
@@ -1,10 +1,12 @@
use super::error::{is_sys_err_io, is_sys_err_not_empty, is_sys_err_too_many_files, os_is_not_exist, os_is_permission};
use super::os::is_root_disk;
use super::{endpoint::Endpoint, error::DiskError, format::FormatV3};
use super::{
os, DeleteOptions, DiskAPI, DiskInfo, DiskInfoOptions, DiskLocation, DiskMetrics, FileInfoVersions, FileReader, FileWriter,
MetaCacheEntry, ReadMultipleReq, ReadMultipleResp, ReadOptions, RenameDataResp, UpdateMetadataOpts, VolumeInfo,
WalkDirOptions,
Info, MetaCacheEntry, ReadMultipleReq, ReadMultipleResp, ReadOptions, RenameDataResp, UpdateMetadataOpts, VolumeInfo,
WalkDirOptions, BUCKET_META_PREFIX, RUSTFS_META_BUCKET,
};
use crate::cache_value::cache::Cache;
use crate::disk::error::{
convert_access_error, is_sys_err_handle_invalid, is_sys_err_invalid_arg, is_sys_err_is_dir, is_sys_err_not_dir,
map_err_not_exists, os_err_to_file_err,
@@ -12,14 +14,19 @@ use crate::disk::error::{
use crate::disk::os::check_path_length;
use crate::disk::{LocalFileReader, LocalFileWriter, STORAGE_FORMAT_FILE};
use crate::error::{Error, Result};
use crate::utils::fs::{lstat, O_APPEND, O_CREATE, O_RDONLY, O_WRONLY};
use crate::global::{GLOBAL_IsErasureSD, GLOBAL_RootDiskThreshold};
use crate::heal::heal_commands::HealingTracker;
use crate::heal::heal_ops::HEALING_TRACKER_FILENAME;
use crate::utils::fs::{lstat, read_file, O_APPEND, O_CREATE, O_RDONLY, O_WRONLY};
use crate::utils::path::{clean, has_suffix, SLASH_SEPARATOR};
use crate::utils::stat_linux::get_info;
use crate::{
file_meta::FileMeta,
store_api::{FileInfo, RawFileInfo},
utils,
};
use path_absolutize::Absolutize;
use std::fmt::Debug;
use std::{
fs::Metadata,
path::{Path, PathBuf},
@@ -49,18 +56,29 @@ impl FormatInfo {
}
}
#[derive(Debug)]
pub struct LocalDisk {
pub root: PathBuf,
pub format_path: PathBuf,
pub format_info: RwLock<FormatInfo>,
pub endpoint: Endpoint,
disk_info_cache: Cache<DiskInfo>,
// pub id: Mutex<Option<Uuid>>,
// pub format_data: Mutex<Vec<u8>>,
// pub format_file_info: Mutex<Option<Metadata>>,
// pub format_last_check: Mutex<Option<OffsetDateTime>>,
}
impl Debug for LocalDisk {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("LocalDisk")
.field("root", &self.root)
.field("format_path", &self.format_path)
.field("format_info", &self.format_info)
.field("endpoint", &self.endpoint)
.finish()
}
}
impl LocalDisk {
pub async fn new(ep: &Endpoint, cleanup: bool) -> Result<Self> {
let root = fs::canonicalize(ep.url.path()).await?;
@@ -101,6 +119,33 @@ impl LocalDisk {
last_check: format_last_check,
};
let derive_path = root.to_string_lossy().to_string();
let disk_id = id.map_or("".to_string(), |id| id.to_string());
let update_fn = || async move {
if let Ok((info, root)) = get_disk_info(&derive_path).await {
let mut disk_info = DiskInfo {
total: info.total,
free: info.free,
used: info.used,
used_inodes: info.files - info.ffree,
free_inodes: info.ffree,
major: info.major,
minor: info.minor,
fs_type: info.fstype,
root_disk: root,
id: disk_id,
..Default::default()
};
if root {
return Err(Error::new(DiskError::DriveIsRoot));
}
// disk_info.healing =
} else {
return Ok(DiskInfo::default());
}
};
// TODO: DIRECT suport
// TODD: DiskInfo
let disk = Self {
@@ -1612,6 +1657,27 @@ impl DiskAPI for LocalDisk {
}
}
async fn get_disk_info(drive_path: &str) -> Result<(Info, bool)> {
check_path_length(drive_path)?;
let disk_info = get_info(drive_path, false)?;
let root_drive = if !*GLOBAL_IsErasureSD.read().await {
let root_disk_threshold = *GLOBAL_RootDiskThreshold.read().await;
if root_disk_threshold > 0 {
disk_info.total <= root_disk_threshold
} else {
match is_root_disk(drive_path, SLASH_SEPARATOR) {
Ok(result) => result,
Err(_) => false,
}
}
} else {
false
};
Ok((disk_info, root_drive))
}
#[cfg(test)]
mod test {
+18 -6
View File
@@ -14,10 +14,7 @@ pub const FORMAT_CONFIG_FILE: &str = "format.json";
const STORAGE_FORMAT_FILE: &str = "xl.meta";
use crate::{
erasure::{ReadAt, Write},
error::{Error, Result},
file_meta::FileMeta,
store_api::{FileInfo, RawFileInfo},
erasure::{ReadAt, Write}, error::{Error, Result}, file_meta::FileMeta, heal::heal_commands::HealingTracker, store_api::{FileInfo, RawFileInfo}
};
use endpoint::Endpoint;
@@ -167,8 +164,8 @@ pub struct DiskInfo {
pub used: u64,
pub used_inodes: u64,
pub free_inodes: u64,
pub major: u32,
pub minor: u32,
pub major: u64,
pub minor: u64,
pub nr_requests: u64,
pub fs_type: String,
pub root_disk: bool,
@@ -192,6 +189,21 @@ pub struct DiskMetrics {
total_deletes: u64,
}
#[derive(Clone, Debug, Default)]
pub struct Info {
pub total: u64,
pub free: u64,
pub used: u64,
pub files: u64,
pub ffree: u64,
pub fstype: String,
pub major: u64,
pub minor: u64,
pub name: String,
pub rotational: bool,
pub nrrequests: u64,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct FileInfoVersions {
// Name of the volume.
+9 -1
View File
@@ -8,7 +8,7 @@ use tokio::fs;
use crate::{
disk::error::{is_sys_err_not_dir, is_sys_err_path_not_found, os_is_not_exist},
error::{Error, Result},
utils,
utils::{self, stat_linux::same_disk},
};
use super::error::{os_err_to_file_err, os_is_exist, DiskError};
@@ -51,6 +51,14 @@ pub fn check_path_length(path_name: &str) -> Result<()> {
Ok(())
}
pub fn is_root_disk(disk_path: &str, root_disk: &str) -> Result<bool> {
if cfg!(target_os = "windows") {
return Ok(false);
}
same_disk(disk_path, root_disk)
}
pub async fn make_dir_all(path: impl AsRef<Path>, base_dir: impl AsRef<Path>) -> Result<()> {
check_path_length(path.as_ref().to_string_lossy().to_string().as_str())?;
+1 -3
View File
@@ -20,9 +20,7 @@ use super::{
RenameDataResp, UpdateMetadataOpts, VolumeInfo, WalkDirOptions,
};
use crate::{
disk::error::DiskError,
error::{Error, Result},
store_api::{FileInfo, RawFileInfo},
disk::error::DiskError, error::{Error, Result}, heal::heal_commands::HealingTracker, store_api::{FileInfo, RawFileInfo}
};
use protos::proto_gen::node_service::RenamePartRequst;