Rename snapshot.tar.bz2 to snapshot-<slot>-<hash>.tar.bz2

This commit is contained in:
Michael Vines
2020-02-24 13:37:14 -07:00
parent 848c43a9ab
commit fcabc6f799
10 changed files with 220 additions and 97 deletions

View File

@@ -24,6 +24,7 @@ rand = "0.6.5"
rand_chacha = "0.1.1"
rayon = "1.2.0"
reed-solomon-erasure = { package = "solana-reed-solomon-erasure", version = "4.0.1-3", features = ["simd-accel"] }
regex = "1.3.4"
serde = "1.0.104"
serde_bytes = "0.11.3"
solana-client = { path = "../client", version = "1.1.0" }

View File

@@ -192,7 +192,10 @@ impl BankForks {
root,
&root_bank.src.roots(),
snapshot_package_sender.as_ref().unwrap(),
snapshot_utils::get_snapshot_archive_path(&config.snapshot_package_output_path),
snapshot_utils::get_snapshot_archive_path(
&config.snapshot_package_output_path,
&(root_bank.slot(), root_bank.hash()),
),
);
if r.is_err() {
warn!("Error generating snapshot for bank: {}, err: {:?}", root, r);

View File

@@ -52,40 +52,44 @@ pub fn load(
fs::create_dir_all(&snapshot_config.snapshot_path)
.expect("Couldn't create snapshot directory");
let tar = snapshot_utils::get_snapshot_archive_path(
match snapshot_utils::get_highest_snapshot_archive_path(
&snapshot_config.snapshot_package_output_path,
);
if tar.exists() {
info!("Loading snapshot package: {:?}", tar);
// Fail hard here if snapshot fails to load, don't silently continue
) {
Some(tar) => {
if tar.exists() {
info!("Loading snapshot package: {:?}", tar);
// Fail hard here if snapshot fails to load, don't silently continue
if account_paths.is_empty() {
panic!("Account paths not present when booting from snapshot")
if account_paths.is_empty() {
panic!("Account paths not present when booting from snapshot")
}
let deserialized_bank = snapshot_utils::bank_from_archive(
&account_paths,
&snapshot_config.snapshot_path,
&tar,
)
.expect("Load from snapshot failed");
let snapshot_hash = (
deserialized_bank.slot(),
deserialized_bank.get_accounts_hash(),
);
return to_loadresult(
blockstore_processor::process_blockstore_from_root(
genesis_config,
blockstore,
Arc::new(deserialized_bank),
&process_options,
&VerifyRecyclers::default(),
),
Some(snapshot_hash),
);
} else {
info!("Snapshot package does not exist: {:?}", tar);
}
}
let deserialized_bank = snapshot_utils::bank_from_archive(
&account_paths,
&snapshot_config.snapshot_path,
&tar,
)
.expect("Load from snapshot failed");
let snapshot_hash = (
deserialized_bank.slot(),
deserialized_bank.get_accounts_hash(),
);
return to_loadresult(
blockstore_processor::process_blockstore_from_root(
genesis_config,
blockstore,
Arc::new(deserialized_bank),
&process_options,
&VerifyRecyclers::default(),
),
Some(snapshot_hash),
);
} else {
info!("Snapshot package does not exist: {:?}", tar);
None => info!("No snapshot package available"),
}
} else {
info!("Snapshots disabled");

View File

@@ -3,6 +3,7 @@ use bincode::serialize_into;
use bzip2::bufread::BzDecoder;
use fs_extra::dir::CopyOptions;
use log::*;
use regex::Regex;
use solana_measure::measure::Measure;
use solana_runtime::{
accounts_db::{SnapshotStorage, SnapshotStorages},
@@ -11,7 +12,7 @@ use solana_runtime::{
MAX_SNAPSHOT_DATA_FILE_SIZE,
},
};
use solana_sdk::clock::Slot;
use solana_sdk::{clock::Slot, hash::Hash};
use std::{
cmp::Ordering,
env,
@@ -205,6 +206,13 @@ pub fn archive_snapshot_package(snapshot_package: &SnapshotPackage) -> Result<()
let metadata = fs::metadata(&archive_path)?;
fs::rename(&archive_path, &snapshot_package.tar_output_file)?;
// Keep around at most two snapshot archives
let archives = get_snapshot_archives(snapshot_package.tar_output_file.parent().unwrap());
for old_archive in archives.into_iter().skip(2) {
fs::remove_file(old_archive.0)
.unwrap_or_else(|err| info!("Failed to remove old snapshot: {:}", err));
}
timer.stop();
info!(
"Successfully created tarball. slot: {}, elapsed ms: {}, size={}",
@@ -497,8 +505,59 @@ fn is_snapshot_compression_disabled() -> bool {
}
}
pub fn get_snapshot_archive_path<P: AsRef<Path>>(snapshot_output_dir: P) -> PathBuf {
snapshot_output_dir.as_ref().join("snapshot.tar.bz2")
pub fn get_snapshot_archive_path<P: AsRef<Path>>(
snapshot_output_dir: P,
snapshot_hash: &(Slot, Hash),
) -> PathBuf {
snapshot_output_dir.as_ref().join(format!(
"snapshot-{}-{}.tar.bz2",
snapshot_hash.0, snapshot_hash.1
))
}
fn snapshot_hash_of(archive_filename: &str) -> Option<(Slot, Hash)> {
let snapshot_filename_regex = Regex::new(r"snapshot-(\d+)-([[:alnum:]]+)\.tar\.bz2$").unwrap();
if let Some(captures) = snapshot_filename_regex.captures(archive_filename) {
let slot_str = captures.get(1).unwrap().as_str();
let hash_str = captures.get(2).unwrap().as_str();
if let (Ok(slot), Ok(hash)) = (slot_str.parse::<Slot>(), hash_str.parse::<Hash>()) {
return Some((slot, hash));
}
}
None
}
fn get_snapshot_archives<P: AsRef<Path>>(snapshot_output_dir: P) -> Vec<(PathBuf, (Slot, Hash))> {
let files = fs::read_dir(&snapshot_output_dir)
.unwrap_or_else(|err| panic!("Unable to read snapshot directory: {}", err));
let mut archives: Vec<_> = files
.filter_map(|entry| {
if let Ok(entry) = entry {
let path = entry.path();
if path.is_file() {
if let Some(snapshot_hash) =
snapshot_hash_of(path.file_name().unwrap().to_str().unwrap())
{
return Some((path, snapshot_hash));
}
}
}
None
})
.collect();
archives.sort_by(|a, b| (b.1).0.cmp(&(a.1).0)); // reverse sort by slot
archives
}
pub fn get_highest_snapshot_archive_path<P: AsRef<Path>>(
snapshot_output_dir: P,
) -> Option<PathBuf> {
let archives = get_snapshot_archives(snapshot_output_dir);
archives.into_iter().next().map(|archive| archive.0)
}
pub fn untar_snapshot_in<P: AsRef<Path>, Q: AsRef<Path>>(
@@ -733,4 +792,13 @@ mod tests {
);
assert_matches!(result, Err(SnapshotError::IO(ref message)) if message.to_string().starts_with("invalid snapshot data file"));
}
#[test]
fn test_snapshot_hash_of() {
assert_eq!(
snapshot_hash_of(&format!("snapshot-42-{}.tar.bz2", Hash::default())),
Some((42, Hash::default()))
);
assert!(snapshot_hash_of("invalid").is_none());
}
}