perf(delivery): stream verified restore file pages
This commit is contained in:
@@ -335,6 +335,12 @@ impl Roots {
|
|||||||
retain,
|
retain,
|
||||||
&mut buffer,
|
&mut buffer,
|
||||||
)?;
|
)?;
|
||||||
|
// These historical destination bytes have already been synchronized
|
||||||
|
// and fully verified. Keep their clean pages out of this finite
|
||||||
|
// restore working set; all descriptor/path witnesses still follow.
|
||||||
|
remaining(deadline)?;
|
||||||
|
rustix::fs::fadvise(&input, 0, None, rustix::fs::Advice::DontNeed)
|
||||||
|
.map_err(|_| Error::Filesystem)?;
|
||||||
if stamp(&input.metadata().map_err(|_| Error::Filesystem)?)? != pending.witness
|
if stamp(&input.metadata().map_err(|_| Error::Filesystem)?)? != pending.witness
|
||||||
|| anchor.observed(name)? != pending.witness
|
|| anchor.observed(name)? != pending.witness
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -487,6 +487,46 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn streamed_verified_pages_preserve_repeated_large_bytes_and_all_witnesses() {
|
||||||
|
let fixture = files::Fixture::new();
|
||||||
|
let roots = Arc::new(fixture.roots());
|
||||||
|
let data = vec![b'v'; 8 * 1024 * 1024];
|
||||||
|
let hash = format!("{:x}", Sha256::digest(&data));
|
||||||
|
let source = fixture.source().join(&hash);
|
||||||
|
fs::write(&source, &data).unwrap();
|
||||||
|
fs::set_permissions(&source, fs::Permissions::from_mode(0o600)).unwrap();
|
||||||
|
use std::os::unix::fs::MetadataExt;
|
||||||
|
let owner = fs::metadata(&source).unwrap();
|
||||||
|
let rows = (0..3)
|
||||||
|
.map(|index| restore_io::RestoreFile {
|
||||||
|
path: format!("artifacts/stream-{index}"),
|
||||||
|
uid: owner.uid(),
|
||||||
|
gid: owner.gid(),
|
||||||
|
mode: 0o644,
|
||||||
|
bytes: data.len() as u64,
|
||||||
|
sha256: hash.clone(),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let pool = Pool::new(Arc::clone(&roots)).unwrap_or_else(|_| panic!("pool"));
|
||||||
|
let verified = pool
|
||||||
|
.materialize(rows, &roots, now().unwrap() + 10_000_000_000)
|
||||||
|
.unwrap_or_else(|_| panic!("streamed verified copies"));
|
||||||
|
assert_eq!(verified.len(), 3);
|
||||||
|
for row in &verified {
|
||||||
|
roots
|
||||||
|
.final_file(row)
|
||||||
|
.unwrap_or_else(|_| panic!("final witness"));
|
||||||
|
let name = row.row.path.strip_prefix("artifacts/").unwrap();
|
||||||
|
assert_eq!(fs::read(fixture.target().join(name)).unwrap(), data);
|
||||||
|
roots
|
||||||
|
.final_file(row)
|
||||||
|
.unwrap_or_else(|_| panic!("unchanged witness"));
|
||||||
|
}
|
||||||
|
drop(pool);
|
||||||
|
roots.unchanged().unwrap_or_else(|_| panic!("root anchors"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn request_line_requires_finite_complete_frame() {
|
fn request_line_requires_finite_complete_frame() {
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
|
|||||||
@@ -515,6 +515,11 @@ The native restore helper keeps two joined threads and partitions each fixed bat
|
|||||||
into contiguous groups that minimize the heavier byte count. Ties prefer balanced
|
into contiguous groups that minimize the heavier byte count. Ties prefer balanced
|
||||||
file counts. Copy order, synchronization, complete byte readback and final
|
file counts. Copy order, synchronization, complete byte readback and final
|
||||||
nine-field witnesses are preserved; no extra worker or batch capacity is added.
|
nine-field witnesses are preserved; no extra worker or batch capacity is added.
|
||||||
|
After synchronization and complete byte verification, the native helper asks the
|
||||||
|
kernel to release clean cached pages for that restored file. Descriptor and path
|
||||||
|
witnesses are still checked afterwards. This per-file streaming hint avoids
|
||||||
|
retaining historical file contents in the fixed restore memory budget; it does
|
||||||
|
not change file bytes, durability, limits or the live filesystem checks.
|
||||||
Old configuration and maintenance receipts go into inactive
|
Old configuration and maintenance receipts go into inactive
|
||||||
`recovery/ID/history/`. The new boot's Sandbox preparation owns cgroup recreation.
|
`recovery/ID/history/`. The new boot's Sandbox preparation owns cgroup recreation.
|
||||||
Unknown/nonempty targets and differing existing files are refused; partial restores
|
Unknown/nonempty targets and differing existing files are refused; partial restores
|
||||||
|
|||||||
Reference in New Issue
Block a user