Skip to content

Commit 1bc7b5f

Browse files
committed
refactor: move HermitImageThinFile into hermit-image-reader
1 parent 5f26d1b commit 1bc7b5f

File tree

4 files changed

+78
-69
lines changed

4 files changed

+78
-69
lines changed

hermit-image-reader/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ mod tar_parser;
2121
pub use tar_parser::{ImageFile, ImageParser, ImageParserError};
2222

2323
pub mod config;
24+
25+
pub mod thin_tree;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright (c) 2025 Hermit contributors
2+
// SPDX-License-Identifier: MIT OR Apache-2.0
3+
4+
use alloc::{
5+
collections::btree_map::BTreeMap,
6+
string::{String, ToString},
7+
};
8+
use core::ops::Range;
9+
10+
#[derive(Clone, Debug, PartialEq, Eq)]
11+
pub enum ThinTree {
12+
File(Range<usize>),
13+
Directory(BTreeMap<String, ThinTree>),
14+
}
15+
16+
impl ThinTree {
17+
/// Populate a thin directory tree, with `entry` pointing to `r`
18+
pub fn update(&mut self, entry: &[&str], r: Range<usize>) {
19+
let mut this = self;
20+
for i in entry {
21+
let dir = match this {
22+
Self::File(r) if r.start == r.end => {
23+
*this = Self::Directory(BTreeMap::new());
24+
if let Self::Directory(dir) = this {
25+
dir
26+
} else {
27+
unreachable!()
28+
}
29+
}
30+
Self::File(_) => panic!("file in hermit image got overridden"),
31+
Self::Directory(dir) => dir,
32+
};
33+
this = dir.entry(i.to_string()).or_insert(ThinTree::File(0..0));
34+
}
35+
*this = Self::File(r);
36+
}
37+
38+
/// Remove an entry from a thin directory tree
39+
pub fn unlink(&mut self, entry: &[&str]) {
40+
if entry.is_empty() {
41+
// we can't remove ourselves.
42+
return;
43+
}
44+
let (lead, to_remove) = entry.split_at(entry.len() - 1);
45+
let this = self.resolve_mut(lead);
46+
if let Some(Self::Directory(this)) = this {
47+
this.remove(to_remove[0]);
48+
}
49+
}
50+
51+
pub fn resolve(&self, entry: &[&str]) -> Option<&ThinTree> {
52+
entry.iter().try_fold(self, |this, &i| {
53+
if let Self::Directory(dir) = this {
54+
dir.get(i)
55+
} else {
56+
None
57+
}
58+
})
59+
}
60+
61+
pub fn resolve_mut(&mut self, entry: &[&str]) -> Option<&mut ThinTree> {
62+
entry.iter().try_fold(self, |this, &i| {
63+
if let Self::Directory(dir) = this {
64+
dir.get_mut(i)
65+
} else {
66+
None
67+
}
68+
})
69+
}
70+
}

src/hypercall.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use clean_path::clean;
1313
use uhyve_interface::{GuestPhysAddr, Hypercall, HypercallAddress, MAX_ARGC_ENVC, parameters::*};
1414

1515
use crate::{
16-
isolation::filemap::{HermitImageThinFile, MappedFileMutRef, UhyveFileMap},
16+
isolation::filemap::{HermitImageThinTree, MappedFileMutRef, UhyveFileMap},
1717
mem::{MemoryError, MmapMemory},
1818
params::EnvVars,
1919
virt_to_phys,
@@ -167,7 +167,7 @@ pub fn open(mem: &MmapMemory, sysopen: &mut OpenParams, file_map: &mut UhyveFile
167167
}
168168
MappedFileMutRef::InImage {
169169
image,
170-
thin: HermitImageThinFile::File(r),
170+
thin: HermitImageThinTree::File(r),
171171
} => {
172172
// For simplicity, create a temporary files with these contents.
173173
debug!("Attempting to open a temp file for unpacked {guest_path:#?}...");

src/isolation/filemap.rs

Lines changed: 4 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::{
1010
};
1111

1212
use clean_path::clean;
13+
pub use hermit_image_reader::thin_tree::ThinTree as HermitImageThinTree;
1314
use tempfile::TempDir;
1415
use uuid::Uuid;
1516

@@ -39,76 +40,12 @@ impl core::ops::Index<Range<usize>> for HermitImage {
3940
}
4041
}
4142

42-
#[derive(Clone, Debug, PartialEq, Eq)]
43-
pub enum HermitImageThinFile {
44-
File(Range<usize>),
45-
Directory(HashMap<String, HermitImageThinFile>),
46-
}
47-
48-
impl HermitImageThinFile {
49-
/// Populate a thin directory tree, with `entry` pointing to `r`
50-
pub fn update(&mut self, entry: &[&str], r: Range<usize>) {
51-
let mut this = self;
52-
for i in entry {
53-
let dir = match this {
54-
Self::File(r) if r.start == r.end => {
55-
*this = Self::Directory(HashMap::new());
56-
if let Self::Directory(dir) = this {
57-
dir
58-
} else {
59-
unreachable!()
60-
}
61-
}
62-
Self::File(_) => panic!("file in hermit image got overridden"),
63-
Self::Directory(dir) => dir,
64-
};
65-
this = dir
66-
.entry(i.to_string())
67-
.or_insert(HermitImageThinFile::File(0..0));
68-
}
69-
*this = Self::File(r);
70-
}
71-
72-
/// Remove an entry from a thin directory tree
73-
pub fn unlink(&mut self, entry: &[&str]) {
74-
if entry.is_empty() {
75-
// we can't remove ourselves.
76-
return;
77-
}
78-
let (lead, to_remove) = entry.split_at(entry.len() - 1);
79-
let this = self.resolve_mut(lead);
80-
if let Some(Self::Directory(this)) = this {
81-
this.remove(to_remove[0]);
82-
}
83-
}
84-
85-
pub fn resolve(&self, entry: &[&str]) -> Option<&HermitImageThinFile> {
86-
entry.iter().try_fold(self, |this, &i| {
87-
if let Self::Directory(dir) = this {
88-
dir.get(i)
89-
} else {
90-
None
91-
}
92-
})
93-
}
94-
95-
pub fn resolve_mut(&mut self, entry: &[&str]) -> Option<&mut HermitImageThinFile> {
96-
entry.iter().try_fold(self, |this, &i| {
97-
if let Self::Directory(dir) = this {
98-
dir.get_mut(i)
99-
} else {
100-
None
101-
}
102-
})
103-
}
104-
}
105-
10643
#[derive(Clone, Debug)]
10744
pub enum MappedFile {
10845
OnHost(PathBuf),
10946
InImage {
11047
image: Arc<HermitImage>,
111-
thin: HermitImageThinFile,
48+
thin: HermitImageThinTree,
11249
},
11350
}
11451

@@ -117,7 +54,7 @@ pub enum MappedFileMutRef<'a> {
11754
OnHost(PathBuf),
11855
InImage {
11956
image: &'a Arc<HermitImage>,
120-
thin: &'a mut HermitImageThinFile,
57+
thin: &'a mut HermitImageThinTree,
12158
},
12259
}
12360

@@ -203,7 +140,7 @@ impl UhyveFileMap {
203140
let mmap = unsafe { MmapOptions::new().map(tmpf.as_file()) }
204141
.expect("unable to mmap decompressed hermit image file");
205142

206-
let mut content = HermitImageThinFile::File(0..0);
143+
let mut content = HermitImageThinTree::File(0..0);
207144
for i in hermit_image_reader::ImageParser::new(&mmap[..]) {
208145
let i = i.expect("unable to read hermit image entry");
209146
if let Ok(name) = str::from_utf8(&i.name) {

0 commit comments

Comments
 (0)