From dd0cb8b6a55462a72d10801b1cb6ea65084d95ff Mon Sep 17 00:00:00 2001 From: Xiang Zhu Date: Wed, 3 Aug 2022 13:25:48 -0700 Subject: [PATCH 1/9] Create a new function cleanup_accounts_paths, a trivial change --- core/src/validator.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/core/src/validator.rs b/core/src/validator.rs index 533cabab67e4c6..2305cd5f958e2b 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -456,14 +456,7 @@ impl Validator { info!("Cleaning accounts paths.."); *start_progress.write().unwrap() = ValidatorStartProgress::CleaningAccounts; let mut start = Measure::start("clean_accounts_paths"); - for accounts_path in &config.account_paths { - cleanup_accounts_path(accounts_path); - } - if let Some(ref shrink_paths) = config.account_shrink_paths { - for accounts_path in shrink_paths { - cleanup_accounts_path(accounts_path); - } - } + cleanup_accounts_paths(&config); start.stop(); info!("done. {}", start); @@ -2071,6 +2064,17 @@ fn cleanup_accounts_path(account_path: &std::path::Path) { } } +fn cleanup_accounts_paths(config: &ValidatorConfig) { + for accounts_path in &config.account_paths { + cleanup_accounts_path(accounts_path); + } + if let Some(ref shrink_paths) = config.account_shrink_paths { + for accounts_path in shrink_paths { + cleanup_accounts_path(accounts_path); + } + } +} + pub fn is_snapshot_config_valid( full_snapshot_interval_slots: Slot, incremental_snapshot_interval_slots: Slot, From fa7dc67389c909dc47f2a8eadd056ce48cd4f491 Mon Sep 17 00:00:00 2001 From: Xiang Zhu Date: Wed, 3 Aug 2022 16:09:15 -0700 Subject: [PATCH 2/9] Remove account files asynchronously --- core/src/validator.rs | 71 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/core/src/validator.rs b/core/src/validator.rs index 2305cd5f958e2b..c607fdb75c9489 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -2054,25 +2054,78 @@ fn get_stake_percent_in_gossip(bank: &Bank, cluster_info: &ClusterInfo, log: boo online_stake_percentage as u64 } -// Cleanup anything that looks like an accounts append-vec -fn cleanup_accounts_path(account_path: &std::path::Path) { - if let Err(e) = std::fs::remove_dir_all(account_path) { - warn!( - "encountered error removing accounts path: {:?}: {}", - account_path, e - ); +/* Move the to-be-deleted path under top_delete_path directory + * If the path has the form /, move it to be + * // + * If parent_path is absolute (starting with /), strip '/'. + */ +fn move_path_for_async_removal(top_delete_path: &str, timestamp: &String, path: &std::path::Path) { + let mut path_parent_from_top = std::path::PathBuf::from(top_delete_path); + + if let Some(mut path_parent) = path.parent() { + if path_parent.has_root() { + path_parent = path_parent.strip_prefix("/").unwrap(); + } + path_parent_from_top.push(path_parent); } + + // Make sure delete_path_parent exists first to allow moving the + // to-be-deleted path under it. + std::fs::create_dir_all(&path_parent_from_top).unwrap(); + + let path_filename = path.file_name().unwrap(); + + // Appending the timestamp is to avoid name collision so that the fs::rename + // call won't fail due to the existing files there. + let delete_path = path_parent_from_top.join(path_filename).join(timestamp); + + //println!("rename from {:?} to {:?}", path, delete_path); + std::fs::rename(&path, &delete_path).unwrap(); } +/* Delete directories/files asynchronously to avoid blocking on it. + Fist, in sync context, rename the original path into + the top to_be_deleted/ directory, then in the async context + call remove_dir_all for the top to_be_deleted directory. + The async rmdir process may not finish if the process is + unexpectly aborted, so the files may be left over undeleted. + causing the disk space resource leak. Always calling rmdir at the + top to_be_deleted directory allows cleaning up all the files + including the ones possibly left over by previous processes. +*/ fn cleanup_accounts_paths(config: &ValidatorConfig) { + // TBD this path to be changed to the actual one + let top_delete_path = "/tmp/to_be_deleted/"; + + let timestamp = std::time::SystemTime::now() + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs() + .to_string(); + for accounts_path in &config.account_paths { - cleanup_accounts_path(accounts_path); + move_path_for_async_removal(top_delete_path, ×tamp, accounts_path); } if let Some(ref shrink_paths) = config.account_shrink_paths { for accounts_path in shrink_paths { - cleanup_accounts_path(accounts_path); + move_path_for_async_removal(top_delete_path, ×tamp, accounts_path); } } + + // Done moving the direcetories/files in sync context. Now start + // the async task to remove them. Note that there is no waiting to ensure this + // async task is done. So if the process crashes or is aborted, + // some files may be left over. The next process will resume the deleting work + // from the top_delete_path to avoid accumulating and leftover files on disk. + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.spawn(async move { + if let Err(e) = tokio::fs::remove_dir_all(&top_delete_path).await { + warn!( + "encountered error deleting path: {:?}: {}", + top_delete_path, e + ); + } + }); } pub fn is_snapshot_config_valid( From a8449e8929056b6cc5163143652289c4aeece1b8 Mon Sep 17 00:00:00 2001 From: Xiang Zhu Date: Tue, 16 Aug 2022 16:40:57 -0700 Subject: [PATCH 3/9] Update and simplify the implementation after the validator test runs. --- core/src/validator.rs | 76 ++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/core/src/validator.rs b/core/src/validator.rs index c607fdb75c9489..e0c79331c32c2e 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -102,6 +102,7 @@ use { solana_vote_program::vote_state, std::{ collections::{HashMap, HashSet}, + ffi::OsString, net::SocketAddr, path::{Path, PathBuf}, sync::{ @@ -2054,33 +2055,33 @@ fn get_stake_percent_in_gossip(bank: &Bank, cluster_info: &ClusterInfo, log: boo online_stake_percentage as u64 } -/* Move the to-be-deleted path under top_delete_path directory - * If the path has the form /, move it to be - * // - * If parent_path is absolute (starting with /), strip '/'. +/* Rename to-be-deleted path to *_delete, and add it into the del_paths vector + * If the _delete path exists (could happen if the previous process was killed), + * then add .{count} to the path, and delete them together. This avoids file + * leaking and accumulation even the asyc deleting tasks were not successfully done */ -fn move_path_for_async_removal(top_delete_path: &str, timestamp: &String, path: &std::path::Path) { - let mut path_parent_from_top = std::path::PathBuf::from(top_delete_path); +fn move_path_for_async_removal(del_paths: &mut Vec, path: &std::path::Path) { + let mut del_path_str = OsString::from(path); + del_path_str.push("_deleted"); + info!("del_path_str = {del_path_str:?}"); + let mut loop_count: i32 = 0; + loop { + let mut with_appendix = del_path_str.clone(); + if loop_count > 0 { + with_appendix.push(format!("{loop_count}")); + } + let path_delete: PathBuf = PathBuf::from(with_appendix); - if let Some(mut path_parent) = path.parent() { - if path_parent.has_root() { - path_parent = path_parent.strip_prefix("/").unwrap(); + info!("loop_count {loop_count}, &path_delete {path_delete:?}"); + if path_delete.exists() { + del_paths.push(path_delete); + loop_count += 1; + } else { + std::fs::rename(&path, &path_delete).unwrap(); + del_paths.push(path_delete); + break; } - path_parent_from_top.push(path_parent); } - - // Make sure delete_path_parent exists first to allow moving the - // to-be-deleted path under it. - std::fs::create_dir_all(&path_parent_from_top).unwrap(); - - let path_filename = path.file_name().unwrap(); - - // Appending the timestamp is to avoid name collision so that the fs::rename - // call won't fail due to the existing files there. - let delete_path = path_parent_from_top.join(path_filename).join(timestamp); - - //println!("rename from {:?} to {:?}", path, delete_path); - std::fs::rename(&path, &delete_path).unwrap(); } /* Delete directories/files asynchronously to avoid blocking on it. @@ -2094,21 +2095,14 @@ fn move_path_for_async_removal(top_delete_path: &str, timestamp: &String, path: including the ones possibly left over by previous processes. */ fn cleanup_accounts_paths(config: &ValidatorConfig) { - // TBD this path to be changed to the actual one - let top_delete_path = "/tmp/to_be_deleted/"; - - let timestamp = std::time::SystemTime::now() - .duration_since(std::time::SystemTime::UNIX_EPOCH) - .unwrap() - .as_secs() - .to_string(); + let mut del_paths: Vec = Vec::new(); for accounts_path in &config.account_paths { - move_path_for_async_removal(top_delete_path, ×tamp, accounts_path); + move_path_for_async_removal(&mut del_paths, accounts_path); } if let Some(ref shrink_paths) = config.account_shrink_paths { for accounts_path in shrink_paths { - move_path_for_async_removal(top_delete_path, ×tamp, accounts_path); + move_path_for_async_removal(&mut del_paths, accounts_path); } } @@ -2118,14 +2112,14 @@ fn cleanup_accounts_paths(config: &ValidatorConfig) { // some files may be left over. The next process will resume the deleting work // from the top_delete_path to avoid accumulating and leftover files on disk. let rt = tokio::runtime::Runtime::new().unwrap(); - rt.spawn(async move { - if let Err(e) = tokio::fs::remove_dir_all(&top_delete_path).await { - warn!( - "encountered error deleting path: {:?}: {}", - top_delete_path, e - ); - } - }); + + for del_path in del_paths { + rt.spawn(async move { + if let Err(e) = tokio::fs::remove_dir_all(&del_path).await { + warn!("encountered error deleting path: {:?}: {}", del_path, e); + } + }); + } } pub fn is_snapshot_config_valid( From 93a6705f19bd518b3b45ec7502d3878af14cd1ae Mon Sep 17 00:00:00 2001 From: Xiang Zhu Date: Wed, 17 Aug 2022 14:53:02 -0700 Subject: [PATCH 4/9] Fixes after testing on the dev device --- core/src/validator.rs | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/core/src/validator.rs b/core/src/validator.rs index e0c79331c32c2e..254008b2594c48 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -364,6 +364,7 @@ pub struct Validator { ledger_metric_report_service: LedgerMetricReportService, accounts_background_service: AccountsBackgroundService, accounts_hash_verifier: AccountsHashVerifier, + pub async_runtime: Arc, } impl Validator { @@ -454,13 +455,19 @@ impl Validator { } } + let async_runtime = tokio::runtime::Runtime::new().unwrap(); + info!("Cleaning accounts paths.."); *start_progress.write().unwrap() = ValidatorStartProgress::CleaningAccounts; let mut start = Measure::start("clean_accounts_paths"); - cleanup_accounts_paths(&config); + cleanup_accounts_paths(&async_runtime, &config); start.stop(); info!("done. {}", start); + // This runtime is wrapped with arc, put into the validator self. + // It will stay during the lifetime of the validator. + let async_runtime = Arc::new(async_runtime); + let exit = Arc::new(AtomicBool::new(false)); { let exit = exit.clone(); @@ -1060,6 +1067,7 @@ impl Validator { ledger_metric_report_service, accounts_background_service, accounts_hash_verifier, + async_runtime, }) } @@ -2057,13 +2065,12 @@ fn get_stake_percent_in_gossip(bank: &Bank, cluster_info: &ClusterInfo, log: boo /* Rename to-be-deleted path to *_delete, and add it into the del_paths vector * If the _delete path exists (could happen if the previous process was killed), - * then add .{count} to the path, and delete them together. This avoids file + * then append {count} to the path, and delete them together. This avoids file * leaking and accumulation even the asyc deleting tasks were not successfully done */ fn move_path_for_async_removal(del_paths: &mut Vec, path: &std::path::Path) { let mut del_path_str = OsString::from(path); del_path_str.push("_deleted"); - info!("del_path_str = {del_path_str:?}"); let mut loop_count: i32 = 0; loop { let mut with_appendix = del_path_str.clone(); @@ -2072,7 +2079,6 @@ fn move_path_for_async_removal(del_paths: &mut Vec, path: &std::path::P } let path_delete: PathBuf = PathBuf::from(with_appendix); - info!("loop_count {loop_count}, &path_delete {path_delete:?}"); if path_delete.exists() { del_paths.push(path_delete); loop_count += 1; @@ -2087,16 +2093,14 @@ fn move_path_for_async_removal(del_paths: &mut Vec, path: &std::path::P /* Delete directories/files asynchronously to avoid blocking on it. Fist, in sync context, rename the original path into the top to_be_deleted/ directory, then in the async context - call remove_dir_all for the top to_be_deleted directory. + call the tokio async remove_dir_all. The async rmdir process may not finish if the process is unexpectly aborted, so the files may be left over undeleted. - causing the disk space resource leak. Always calling rmdir at the - top to_be_deleted directory allows cleaning up all the files - including the ones possibly left over by previous processes. + causing the disk space resource leak. This function finds all + the leftover files and also delete them. */ -fn cleanup_accounts_paths(config: &ValidatorConfig) { +fn cleanup_accounts_paths(async_runtime: &tokio::runtime::Runtime, config: &ValidatorConfig) { let mut del_paths: Vec = Vec::new(); - for accounts_path in &config.account_paths { move_path_for_async_removal(&mut del_paths, accounts_path); } @@ -2110,11 +2114,10 @@ fn cleanup_accounts_paths(config: &ValidatorConfig) { // the async task to remove them. Note that there is no waiting to ensure this // async task is done. So if the process crashes or is aborted, // some files may be left over. The next process will resume the deleting work - // from the top_delete_path to avoid accumulating and leftover files on disk. - let rt = tokio::runtime::Runtime::new().unwrap(); + // if it finds any leftover file. for del_path in del_paths { - rt.spawn(async move { + async_runtime.spawn(async move { if let Err(e) = tokio::fs::remove_dir_all(&del_path).await { warn!("encountered error deleting path: {:?}: {}", del_path, e); } From 724768bd680fb3a3a55d00a4bd8d917a9d876352 Mon Sep 17 00:00:00 2001 From: Xiang Zhu Date: Thu, 18 Aug 2022 12:51:44 -0700 Subject: [PATCH 5/9] Discard tokio. Use thread instead --- core/src/validator.rs | 67 ++++++++++++------------------------------- 1 file changed, 19 insertions(+), 48 deletions(-) diff --git a/core/src/validator.rs b/core/src/validator.rs index 254008b2594c48..f72feb78736230 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -364,7 +364,6 @@ pub struct Validator { ledger_metric_report_service: LedgerMetricReportService, accounts_background_service: AccountsBackgroundService, accounts_hash_verifier: AccountsHashVerifier, - pub async_runtime: Arc, } impl Validator { @@ -455,19 +454,13 @@ impl Validator { } } - let async_runtime = tokio::runtime::Runtime::new().unwrap(); - info!("Cleaning accounts paths.."); *start_progress.write().unwrap() = ValidatorStartProgress::CleaningAccounts; let mut start = Measure::start("clean_accounts_paths"); - cleanup_accounts_paths(&async_runtime, &config); + cleanup_accounts_paths(&config); start.stop(); info!("done. {}", start); - // This runtime is wrapped with arc, put into the validator self. - // It will stay during the lifetime of the validator. - let async_runtime = Arc::new(async_runtime); - let exit = Arc::new(AtomicBool::new(false)); { let exit = exit.clone(); @@ -1067,7 +1060,6 @@ impl Validator { ledger_metric_report_service, accounts_background_service, accounts_hash_verifier, - async_runtime, }) } @@ -2063,31 +2055,25 @@ fn get_stake_percent_in_gossip(bank: &Bank, cluster_info: &ClusterInfo, log: boo online_stake_percentage as u64 } -/* Rename to-be-deleted path to *_delete, and add it into the del_paths vector - * If the _delete path exists (could happen if the previous process was killed), - * then append {count} to the path, and delete them together. This avoids file - * leaking and accumulation even the asyc deleting tasks were not successfully done - */ -fn move_path_for_async_removal(del_paths: &mut Vec, path: &std::path::Path) { +fn move_and_async_delete_path(path: &std::path::Path) { let mut del_path_str = OsString::from(path); del_path_str.push("_deleted"); - let mut loop_count: i32 = 0; - loop { - let mut with_appendix = del_path_str.clone(); - if loop_count > 0 { - with_appendix.push(format!("{loop_count}")); - } - let path_delete: PathBuf = PathBuf::from(with_appendix); + let path_delete = PathBuf::from(del_path_str); - if path_delete.exists() { - del_paths.push(path_delete); - loop_count += 1; - } else { - std::fs::rename(&path, &path_delete).unwrap(); - del_paths.push(path_delete); - break; - } + if path_delete.exists() { + info!("{path_delete:?} exists, delete it first."); + std::fs::remove_dir_all(&path_delete).unwrap(); } + + std::fs::rename(&path, &path_delete).unwrap(); + + Builder::new() + .name("delete_path".to_string()) + .spawn(move || { + std::fs::remove_dir_all(&path_delete).unwrap(); + info!("In the spawned thread, done deleting path {path_delete:?}"); + }) + .unwrap(); } /* Delete directories/files asynchronously to avoid blocking on it. @@ -2099,30 +2085,15 @@ fn move_path_for_async_removal(del_paths: &mut Vec, path: &std::path::P causing the disk space resource leak. This function finds all the leftover files and also delete them. */ -fn cleanup_accounts_paths(async_runtime: &tokio::runtime::Runtime, config: &ValidatorConfig) { - let mut del_paths: Vec = Vec::new(); +fn cleanup_accounts_paths(config: &ValidatorConfig) { for accounts_path in &config.account_paths { - move_path_for_async_removal(&mut del_paths, accounts_path); + move_and_async_delete_path(accounts_path); } if let Some(ref shrink_paths) = config.account_shrink_paths { for accounts_path in shrink_paths { - move_path_for_async_removal(&mut del_paths, accounts_path); + move_and_async_delete_path(accounts_path); } } - - // Done moving the direcetories/files in sync context. Now start - // the async task to remove them. Note that there is no waiting to ensure this - // async task is done. So if the process crashes or is aborted, - // some files may be left over. The next process will resume the deleting work - // if it finds any leftover file. - - for del_path in del_paths { - async_runtime.spawn(async move { - if let Err(e) = tokio::fs::remove_dir_all(&del_path).await { - warn!("encountered error deleting path: {:?}: {}", del_path, e); - } - }); - } } pub fn is_snapshot_config_valid( From bc605ffd6fb0d1734f02f98b949e5e54c2df3305 Mon Sep 17 00:00:00 2001 From: Xiang Zhu Date: Thu, 18 Aug 2022 13:01:49 -0700 Subject: [PATCH 6/9] Fix comments format --- core/src/validator.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/core/src/validator.rs b/core/src/validator.rs index f72feb78736230..312bbb881b5870 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -2055,6 +2055,12 @@ fn get_stake_percent_in_gossip(bank: &Bank, cluster_info: &ClusterInfo, log: boo online_stake_percentage as u64 } +/// Delete directories/files asynchronously to avoid blocking on it. +/// Fist, in sync context, rename the original path to *_deleted, +/// then spawn a thread to delete the renamed path. +/// If the process is killed and the deleting process is not done, +/// the leftover path will be deleted in the next process life, so +/// there is no file space leaking. fn move_and_async_delete_path(path: &std::path::Path) { let mut del_path_str = OsString::from(path); del_path_str.push("_deleted"); @@ -2076,15 +2082,6 @@ fn move_and_async_delete_path(path: &std::path::Path) { .unwrap(); } -/* Delete directories/files asynchronously to avoid blocking on it. - Fist, in sync context, rename the original path into - the top to_be_deleted/ directory, then in the async context - call the tokio async remove_dir_all. - The async rmdir process may not finish if the process is - unexpectly aborted, so the files may be left over undeleted. - causing the disk space resource leak. This function finds all - the leftover files and also delete them. -*/ fn cleanup_accounts_paths(config: &ValidatorConfig) { for accounts_path in &config.account_paths { move_and_async_delete_path(accounts_path); From cc14f5b7ea2a99e8c198ddf7fcf7c3410210db7b Mon Sep 17 00:00:00 2001 From: Jeff Washington Date: Fri, 19 Aug 2022 01:12:04 +0000 Subject: [PATCH 7/9] Fix config type to pass the github test --- core/src/validator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/validator.rs b/core/src/validator.rs index 312bbb881b5870..3ce09129608cda 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -457,7 +457,7 @@ impl Validator { info!("Cleaning accounts paths.."); *start_progress.write().unwrap() = ValidatorStartProgress::CleaningAccounts; let mut start = Measure::start("clean_accounts_paths"); - cleanup_accounts_paths(&config); + cleanup_accounts_paths(config); start.stop(); info!("done. {}", start); @@ -2061,7 +2061,7 @@ fn get_stake_percent_in_gossip(bank: &Bank, cluster_info: &ClusterInfo, log: boo /// If the process is killed and the deleting process is not done, /// the leftover path will be deleted in the next process life, so /// there is no file space leaking. -fn move_and_async_delete_path(path: &std::path::Path) { +fn move_and_async_delete_path(path: &Path) { let mut del_path_str = OsString::from(path); del_path_str.push("_deleted"); let path_delete = PathBuf::from(del_path_str); From c632860f96a21bb22857e26dc0ba215e7591fa0e Mon Sep 17 00:00:00 2001 From: Jeff Washington Date: Fri, 19 Aug 2022 04:01:39 +0000 Subject: [PATCH 8/9] Fix failed tests. Handle the case of non-existing path --- core/src/validator.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/validator.rs b/core/src/validator.rs index 3ce09129608cda..fbe3e680053698 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -2071,6 +2071,11 @@ fn move_and_async_delete_path(path: &Path) { std::fs::remove_dir_all(&path_delete).unwrap(); } + if !path.exists() { + info!("move_and_async_delete_path: path {path:?} does not exist"); + return; + } + std::fs::rename(&path, &path_delete).unwrap(); Builder::new() From 72e4e9b2df96f91c14d32eb0ff41c49073dffad6 Mon Sep 17 00:00:00 2001 From: Jeff Washington Date: Fri, 19 Aug 2022 23:22:38 +0000 Subject: [PATCH 9/9] Final cleanup, addressing the review comments Avoided OsString. Made the function more generic with "impl AsRef" --- core/src/validator.rs | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/core/src/validator.rs b/core/src/validator.rs index fbe3e680053698..e0c9da7fa81a9d 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -102,7 +102,6 @@ use { solana_vote_program::vote_state, std::{ collections::{HashMap, HashSet}, - ffi::OsString, net::SocketAddr, path::{Path, PathBuf}, sync::{ @@ -2061,18 +2060,25 @@ fn get_stake_percent_in_gossip(bank: &Bank, cluster_info: &ClusterInfo, log: boo /// If the process is killed and the deleting process is not done, /// the leftover path will be deleted in the next process life, so /// there is no file space leaking. -fn move_and_async_delete_path(path: &Path) { - let mut del_path_str = OsString::from(path); - del_path_str.push("_deleted"); - let path_delete = PathBuf::from(del_path_str); +fn move_and_async_delete_path(path: impl AsRef + Copy) { + let mut path_delete = PathBuf::new(); + path_delete.push(path); + path_delete.set_file_name(format!( + "{}{}", + path_delete.file_name().unwrap().to_str().unwrap(), + "_to_be_deleted" + )); if path_delete.exists() { - info!("{path_delete:?} exists, delete it first."); + debug!("{} exists, delete it first.", path_delete.display()); std::fs::remove_dir_all(&path_delete).unwrap(); } - if !path.exists() { - info!("move_and_async_delete_path: path {path:?} does not exist"); + if !path.as_ref().exists() { + info!( + "move_and_async_delete_path: path {} does not exist", + path.as_ref().display() + ); return; } @@ -2082,7 +2088,10 @@ fn move_and_async_delete_path(path: &Path) { .name("delete_path".to_string()) .spawn(move || { std::fs::remove_dir_all(&path_delete).unwrap(); - info!("In the spawned thread, done deleting path {path_delete:?}"); + info!( + "Cleaning path {} done asynchronously in a spawned thread", + path_delete.display() + ); }) .unwrap(); }