diff --git a/download-utils/src/lib.rs b/download-utils/src/lib.rs index ec4b3747f..2158f6ad1 100644 --- a/download-utils/src/lib.rs +++ b/download-utils/src/lib.rs @@ -178,11 +178,11 @@ pub fn download_genesis_if_missing( pub fn download_snapshot( rpc_addr: &SocketAddr, - ledger_path: &Path, + snapshot_output_dir: &Path, desired_snapshot_hash: (Slot, Hash), use_progress_bar: bool, ) -> Result<(), String> { - snapshot_utils::purge_old_snapshot_archives(ledger_path); + snapshot_utils::purge_old_snapshot_archives(snapshot_output_dir); for compression in &[ ArchiveFormat::TarZstd, @@ -190,7 +190,7 @@ pub fn download_snapshot( ArchiveFormat::TarBzip2, ] { let desired_snapshot_package = snapshot_utils::get_snapshot_archive_path( - ledger_path.to_path_buf(), + snapshot_output_dir.to_path_buf(), &desired_snapshot_hash, *compression, ); diff --git a/runtime/src/snapshot_utils.rs b/runtime/src/snapshot_utils.rs index 8dc25c626..20aa2369e 100644 --- a/runtime/src/snapshot_utils.rs +++ b/runtime/src/snapshot_utils.rs @@ -44,6 +44,7 @@ const MAX_SNAPSHOT_DATA_FILE_SIZE: u64 = 32 * 1024 * 1024 * 1024; // 32 GiB const VERSION_STRING_V1_2_0: &str = "1.2.0"; const DEFAULT_SNAPSHOT_VERSION: SnapshotVersion = SnapshotVersion::V1_2_0; const TMP_SNAPSHOT_PREFIX: &str = "tmp-snapshot-"; +const TMP_SNAPSHOT_EXTENSION: &str = ".tmp"; // when downloading #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum SnapshotVersion { @@ -206,11 +207,12 @@ fn get_archive_ext(archive_format: ArchiveFormat) -> &'static str { pub fn remove_tmp_snapshot_archives(snapshot_path: &Path) { if let Ok(entries) = fs::read_dir(&snapshot_path) { for entry in entries.filter_map(|entry| entry.ok()) { - if entry + let filename = entry .file_name() .into_string() - .unwrap_or_else(|_| String::new()) - .starts_with(TMP_SNAPSHOT_PREFIX) + .unwrap_or_else(|_| String::new()); + if filename.starts_with(TMP_SNAPSHOT_PREFIX) + | filename.ends_with(TMP_SNAPSHOT_EXTENSION) { if entry.path().is_file() { fs::remove_file(entry.path()) diff --git a/validator/src/main.rs b/validator/src/main.rs index 760bbb902..7b98063a3 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -341,7 +341,7 @@ fn get_rpc_node( blacklisted_rpc_nodes: &mut HashSet, snapshot_not_required: bool, no_untrusted_rpc: bool, - ledger_path: &std::path::Path, + snapshot_output_dir: &Path, ) -> Option<(ContactInfo, Option<(Slot, Hash)>)> { let mut blacklist_timeout = Instant::now(); let mut newer_cluster_snapshot_timeout = None; @@ -420,7 +420,7 @@ fn get_rpc_node( blacklist_timeout = Instant::now(); let mut highest_snapshot_hash: Option<(Slot, Hash)> = - get_highest_snapshot_archive_path(ledger_path) + get_highest_snapshot_archive_path(snapshot_output_dir) .map(|(_path, (slot, hash, _compression))| (slot, hash)); let eligible_rpc_peers = if snapshot_not_required { rpc_peers @@ -758,6 +758,7 @@ fn rpc_bootstrap( node: &Node, identity_keypair: &Arc, ledger_path: &Path, + snapshot_output_dir: &Path, vote_account: &Pubkey, authorized_voter_keypairs: &[Arc], cluster_entrypoints: &[ContactInfo], @@ -809,7 +810,7 @@ fn rpc_bootstrap( &mut blacklisted_rpc_nodes, bootstrap_config.no_snapshot_fetch, bootstrap_config.no_untrusted_rpc, - ledger_path, + snapshot_output_dir, ); if rpc_node_details.is_none() { return; @@ -865,7 +866,7 @@ fn rpc_bootstrap( let mut use_local_snapshot = false; if let Some(highest_local_snapshot_slot) = - get_highest_snapshot_archive_path(ledger_path) + get_highest_snapshot_archive_path(snapshot_output_dir) .map(|(_path, (slot, _hash, _compression))| slot) { if highest_local_snapshot_slot @@ -905,7 +906,7 @@ fn rpc_bootstrap( gossip_exit_flag.store(true, Ordering::Relaxed); let ret = download_snapshot( &rpc_contact_info.rpc, - &ledger_path, + &snapshot_output_dir, snapshot_hash, use_progress_bar, ); @@ -1203,6 +1204,13 @@ pub fn main() { .multiple(true) .help("Path to accounts shrink path which can hold a compacted account set."), ) + .arg( + Arg::with_name("snapshots_path") + .long("snapshots") + .value_name("PATHS") + .takes_value(true) + .help("Snapshots location"), + ) .arg( Arg::with_name("gossip_port") .long("gossip-port") @@ -2058,7 +2066,12 @@ pub fn main() { let snapshot_interval_slots = value_t_or_exit!(matches, "snapshot_interval_slots", u64); let maximum_local_snapshot_age = value_t_or_exit!(matches, "maximum_local_snapshot_age", u64); - let snapshot_path = ledger_path.join("snapshot"); + let snapshot_output_dir = if matches.is_present("snapshots_path") { + PathBuf::from(matches.value_of("snapshots_path").unwrap()) + } else { + ledger_path.clone() + }; + let snapshot_path = snapshot_output_dir.join("snapshot"); fs::create_dir_all(&snapshot_path).unwrap_or_else(|err| { eprintln!( "Failed to create snapshots directory {:?}: {}", @@ -2094,7 +2107,7 @@ pub fn main() { std::u64::MAX }, snapshot_path, - snapshot_package_output_path: ledger_path.clone(), + snapshot_package_output_path: snapshot_output_dir.clone(), archive_format, snapshot_version, }); @@ -2291,7 +2304,7 @@ pub fn main() { enable_recycler_warming(); } solana_ledger::entry::init_poh(); - solana_runtime::snapshot_utils::remove_tmp_snapshot_archives(&ledger_path); + solana_runtime::snapshot_utils::remove_tmp_snapshot_archives(&snapshot_output_dir); let should_check_duplicate_instance = !matches.is_present("no_duplicate_instance_check"); if !cluster_entrypoints.is_empty() { @@ -2299,6 +2312,7 @@ pub fn main() { &node, &identity_keypair, &ledger_path, + &snapshot_output_dir, &vote_account, &authorized_voter_keypairs, &cluster_entrypoints,