From 20ee70cd1829cd414d09040460defecf9792a370 Mon Sep 17 00:00:00 2001 From: Brooks Date: Fri, 17 May 2024 00:09:42 -0400 Subject: [PATCH] Supports archiving account storage files that are backed by Mmap or File (#1393) --- accounts-db/src/accounts_file.rs | 27 +++++++++++++++++++++++++++ runtime/src/snapshot_utils.rs | 28 ++++++++++++++++------------ 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/accounts-db/src/accounts_file.rs b/accounts-db/src/accounts_file.rs index d9d16d026c250a..09e100725655f3 100644 --- a/accounts-db/src/accounts_file.rs +++ b/accounts-db/src/accounts_file.rs @@ -289,6 +289,24 @@ impl AccountsFile { .data_for_archive(), } } + + /// Returns the way to access this accounts file when archiving + pub fn internals_for_archive(&self) -> InternalsForArchive { + // Figure out if the backing access to this accounts file is Mmap or File I/O. + // For now, let `can_append()` fill the gap. + if self.can_append() { + match self { + Self::AppendVec(av) => InternalsForArchive::Mmap(av.data_for_archive()), + Self::TieredStorage(ts) => InternalsForArchive::Mmap( + ts.reader() + .expect("must be a reader when archiving") + .data_for_archive(), + ), + } + } else { + InternalsForArchive::FileIo(self.path()) + } + } } /// An enum that creates AccountsFile instance with the specified format. @@ -310,6 +328,15 @@ impl AccountsFileProvider { } } +/// The access method to use when archiving an AccountsFile +#[derive(Debug)] +pub enum InternalsForArchive<'a> { + /// Accessing the internals is done via Mmap + Mmap(&'a [u8]), + /// Accessing the internals is done via File I/O + FileIo(&'a Path), +} + /// Information after storing accounts #[derive(Debug)] pub struct StoredAccountsInfo { diff --git a/runtime/src/snapshot_utils.rs b/runtime/src/snapshot_utils.rs index 42187302536e1a..688090977b82c5 100644 --- a/runtime/src/snapshot_utils.rs +++ b/runtime/src/snapshot_utils.rs @@ -20,7 +20,7 @@ use { solana_accounts_db::{ account_storage::AccountStorageMap, accounts_db::{AccountStorageEntry, AtomicAccountsFileId}, - accounts_file::{AccountsFile, AccountsFileError, StorageAccess}, + accounts_file::{AccountsFile, AccountsFileError, InternalsForArchive, StorageAccess}, hardened_unpack::{self, ParallelSelector, UnpackError}, shared_buffer_reader::{SharedBuffer, SharedBufferReader}, utils::{move_and_async_delete_path, ACCOUNTS_RUN_DIR, ACCOUNTS_SNAPSHOT_DIR}, @@ -823,17 +823,21 @@ pub fn archive_snapshot_package( storage.slot(), storage.append_vec_id(), )); - let mut header = tar::Header::new_gnu(); - header.set_path(path_in_archive).map_err(|err| { - E::ArchiveAccountStorageFile(err, storage.path().to_path_buf()) - })?; - header.set_size(storage.capacity()); - header.set_cksum(); - archive - .append(&header, storage.accounts.data_for_archive()) - .map_err(|err| { - E::ArchiveAccountStorageFile(err, storage.path().to_path_buf()) - })?; + match storage.accounts.internals_for_archive() { + InternalsForArchive::Mmap(data) => { + let mut header = tar::Header::new_gnu(); + header.set_path(path_in_archive).map_err(|err| { + E::ArchiveAccountStorageFile(err, storage.path().to_path_buf()) + })?; + header.set_size(storage.capacity()); + header.set_cksum(); + archive.append(&header, data) + } + InternalsForArchive::FileIo(path) => { + archive.append_path_with_name(path, path_in_archive) + } + } + .map_err(|err| E::ArchiveAccountStorageFile(err, storage.path().to_path_buf()))?; } archive.into_inner().map_err(E::FinishArchive)?;