Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/virtio/gpu/snapshot.rs
5394 views
1
// Copyright 2025 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
//! Utilities for working with directories for snapshots.
6
7
use std::collections::BTreeMap as Map;
8
use std::path::Path;
9
use std::path::PathBuf;
10
11
use anyhow::Context;
12
use serde::Deserialize;
13
use serde::Serialize;
14
15
fn get_files_recursively(directory: &Path, paths: &mut Vec<PathBuf>) -> anyhow::Result<()> {
16
if directory.is_dir() {
17
for entry in std::fs::read_dir(directory)? {
18
let entry = entry?;
19
let entry_path = entry.path();
20
if entry_path.is_dir() {
21
get_files_recursively(&entry_path, paths)?;
22
} else {
23
paths.push(entry_path.to_path_buf());
24
}
25
}
26
}
27
Ok(())
28
}
29
30
fn get_files_under(directory: &Path) -> anyhow::Result<Vec<PathBuf>> {
31
let mut paths = Vec::new();
32
get_files_recursively(directory, &mut paths)?;
33
Ok(paths)
34
}
35
36
// TODO: use an actual archive/zip when a common crate is available in
37
// both Android and Chrome.
38
#[derive(Serialize, Deserialize)]
39
pub struct DirectorySnapshot {
40
files: Map<PathBuf, Vec<u8>>,
41
}
42
43
pub fn pack_directory_to_snapshot(directory: &Path) -> anyhow::Result<DirectorySnapshot> {
44
let directory_files = get_files_under(directory).with_context(|| {
45
format!(
46
"failed to list snapshot files under {}",
47
directory.display()
48
)
49
})?;
50
51
let mut snapshot = DirectorySnapshot { files: Map::new() };
52
53
for path in directory_files.into_iter() {
54
let contents: Vec<u8> = std::fs::read(&path)
55
.with_context(|| format!("failed to read snapshot file {}", path.display()))?;
56
57
let relative_path = path
58
.strip_prefix(directory)
59
.with_context(|| {
60
format!(
61
"failed to strip {} from {}",
62
directory.display(),
63
path.display()
64
)
65
})?
66
.to_path_buf();
67
68
snapshot.files.insert(relative_path, contents);
69
}
70
71
Ok(snapshot)
72
}
73
74
pub fn unpack_snapshot_to_directory(
75
directory: &Path,
76
snapshot: DirectorySnapshot,
77
) -> anyhow::Result<()> {
78
for (path, contents) in snapshot.files.into_iter() {
79
let path = directory.join(path);
80
let path_directory = path
81
.parent()
82
.with_context(|| format!("failed to get parent directory for {}", path.display()))?;
83
std::fs::create_dir_all(path_directory)
84
.with_context(|| format!("failed to create directories for {}", path.display()))?;
85
std::fs::write(&path, contents)
86
.with_context(|| format!("failed to unpack snapshot to {}", path.display()))?;
87
}
88
89
Ok(())
90
}
91
92