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:
		
				
					committed by
					
						 Thomas Lamprecht
						Thomas Lamprecht
					
				
			
			
				
	
			
			
			
						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)); | ||||||
|             } |             } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user