Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Account files remove #26910

Merged
merged 9 commits into from
Aug 20, 2022
57 changes: 42 additions & 15 deletions core/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ use {
solana_vote_program::vote_state,
std::{
collections::{HashMap, HashSet},
ffi::OsString,
net::SocketAddr,
path::{Path, PathBuf},
sync::{
Expand Down Expand Up @@ -456,14 +457,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);

Expand Down Expand Up @@ -2061,13 +2055,46 @@ 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
);
/// 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: &Path) {
let mut del_path_str = OsString::from(path);
del_path_str.push("_deleted");
let path_delete = PathBuf::from(del_path_str);

if path_delete.exists() {
info!("{path_delete:?} exists, delete it first.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: For Paths, (and PathBuf), they have a .display() method for this purpose. I'd recommend that here, and all user-facing logs.

Suggested change
info!("{path_delete:?} exists, delete it first.");
info!("{} exists, delete it first.", path.display());

std::fs::remove_dir_all(&path_delete).unwrap();
}

if !path.exists() {
info!("move_and_async_delete_path: path {path:?} does not exist");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same nit w.r.t. path.display().

Probably can also dial this log level down to debug!(). If we're trying to delete a file/directory and it doesn't exist, then the end result is the same :)

return;
}

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();
}

fn cleanup_accounts_paths(config: &ValidatorConfig) {
for accounts_path in &config.account_paths {
move_and_async_delete_path(accounts_path);
}
if let Some(ref shrink_paths) = config.account_shrink_paths {
for accounts_path in shrink_paths {
move_and_async_delete_path(accounts_path);
}
}
}

Expand Down