file-restore: add size to image files and components
Read image sizes (.pxar.fidx/.img.didx) from manifest and partition sizes from /sys/... Requires a change to ArchiveEntry, as DirEntryAttribute::Directory does not have a size associated with it (and that's probably good). Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
This commit is contained in:
parent
1ed9069ad3
commit
6a59fa0e18
|
@ -1354,6 +1354,18 @@ pub struct ArchiveEntry {
|
||||||
|
|
||||||
impl ArchiveEntry {
|
impl ArchiveEntry {
|
||||||
pub fn new(filepath: &[u8], entry_type: Option<&DirEntryAttribute>) -> Self {
|
pub fn new(filepath: &[u8], entry_type: Option<&DirEntryAttribute>) -> Self {
|
||||||
|
let size = match entry_type {
|
||||||
|
Some(DirEntryAttribute::File { size, .. }) => Some(*size),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
Self::new_with_size(filepath, entry_type, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_size(
|
||||||
|
filepath: &[u8],
|
||||||
|
entry_type: Option<&DirEntryAttribute>,
|
||||||
|
size: Option<u64>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
filepath: base64::encode(filepath),
|
filepath: base64::encode(filepath),
|
||||||
text: String::from_utf8_lossy(filepath.split(|x| *x == b'/').last().unwrap())
|
text: String::from_utf8_lossy(filepath.split(|x| *x == b'/').last().unwrap())
|
||||||
|
@ -1363,13 +1375,10 @@ impl ArchiveEntry {
|
||||||
None => "v".to_owned(),
|
None => "v".to_owned(),
|
||||||
},
|
},
|
||||||
leaf: !matches!(entry_type, None | Some(DirEntryAttribute::Directory { .. })),
|
leaf: !matches!(entry_type, None | Some(DirEntryAttribute::Directory { .. })),
|
||||||
size: match entry_type {
|
size,
|
||||||
Some(DirEntryAttribute::File { size, .. }) => Some(*size),
|
|
||||||
_ => None
|
|
||||||
},
|
|
||||||
mtime: match entry_type {
|
mtime: match entry_type {
|
||||||
Some(DirEntryAttribute::File { mtime, .. }) => Some(*mtime),
|
Some(DirEntryAttribute::File { mtime, .. }) => Some(*mtime),
|
||||||
_ => None
|
_ => None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,7 @@ async fn list(
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
entries.push(ArchiveEntry::new(path.as_bytes(), attr));
|
entries.push(ArchiveEntry::new_with_size(path.as_bytes(), attr, Some(file.size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(entries)
|
Ok(entries)
|
||||||
|
|
|
@ -200,11 +200,12 @@ fn list(
|
||||||
for c in comps {
|
for c in comps {
|
||||||
let mut c_path = path.clone();
|
let mut c_path = path.clone();
|
||||||
c_path.push(b'/');
|
c_path.push(b'/');
|
||||||
c_path.extend(c.as_bytes());
|
c_path.extend(c.0.as_bytes());
|
||||||
res.push(ArchiveEntry::new(
|
res.push(ArchiveEntry::new_with_size(
|
||||||
&c_path[..],
|
&c_path[..],
|
||||||
// this marks the beginning of a filesystem, i.e. '/', so this is a Directory
|
// this marks the beginning of a filesystem, i.e. '/', so this is a Directory
|
||||||
Some(&DirEntryAttribute::Directory { start: 0 }),
|
Some(&DirEntryAttribute::Directory { start: 0 }),
|
||||||
|
Some(c.1),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,13 +36,14 @@ lazy_static! {
|
||||||
pub enum ResolveResult {
|
pub enum ResolveResult {
|
||||||
Path(PathBuf),
|
Path(PathBuf),
|
||||||
BucketTypes(Vec<&'static str>),
|
BucketTypes(Vec<&'static str>),
|
||||||
BucketComponents(Vec<String>),
|
BucketComponents(Vec<(String, u64)>),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PartitionBucketData {
|
struct PartitionBucketData {
|
||||||
dev_node: String,
|
dev_node: String,
|
||||||
number: i32,
|
number: i32,
|
||||||
mountpoint: Option<PathBuf>,
|
mountpoint: Option<PathBuf>,
|
||||||
|
size: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A "Bucket" represents a mapping found on a disk, e.g. a partition, a zfs dataset or an LV. A
|
/// A "Bucket" represents a mapping found on a disk, e.g. a partition, a zfs dataset or an LV. A
|
||||||
|
@ -83,6 +84,12 @@ impl Bucket {
|
||||||
Bucket::Partition(data) => data.number.to_string(),
|
Bucket::Partition(data) => data.number.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn size(&self) -> u64 {
|
||||||
|
match self {
|
||||||
|
Bucket::Partition(data) => data.size,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Functions related to the local filesystem. This mostly exists so we can use 'supported_fs' in
|
/// Functions related to the local filesystem. This mostly exists so we can use 'supported_fs' in
|
||||||
|
@ -209,15 +216,23 @@ impl DiskState {
|
||||||
.trim()
|
.trim()
|
||||||
.parse::<i32>()?;
|
.parse::<i32>()?;
|
||||||
|
|
||||||
|
// this *always* contains the number of 512-byte sectors, regardless of the true
|
||||||
|
// blocksize of this disk - which should always be 512 here anyway
|
||||||
|
let size = fs::file_read_firstline(&format!("{}/size", part_path))?
|
||||||
|
.trim()
|
||||||
|
.parse::<u64>()?
|
||||||
|
* 512;
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"drive '{}' ('{}'): found partition '{}' ({})",
|
"drive '{}' ('{}'): found partition '{}' ({}, {}B)",
|
||||||
name, fidx, devnode, number
|
name, fidx, devnode, number, size
|
||||||
);
|
);
|
||||||
|
|
||||||
let bucket = Bucket::Partition(PartitionBucketData {
|
let bucket = Bucket::Partition(PartitionBucketData {
|
||||||
dev_node: devnode,
|
dev_node: devnode,
|
||||||
mountpoint: None,
|
mountpoint: None,
|
||||||
number,
|
number,
|
||||||
|
size,
|
||||||
});
|
});
|
||||||
|
|
||||||
parts.push(bucket);
|
parts.push(bucket);
|
||||||
|
@ -281,7 +296,7 @@ impl DiskState {
|
||||||
let comps = buckets
|
let comps = buckets
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|b| b.type_string() == bucket_type)
|
.filter(|b| b.type_string() == bucket_type)
|
||||||
.map(Bucket::component_string)
|
.map(|b| (b.component_string(), b.size()))
|
||||||
.collect();
|
.collect();
|
||||||
return Ok(ResolveResult::BucketComponents(comps));
|
return Ok(ResolveResult::BucketComponents(comps));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue