MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / parse_qcow

Function parse_qcow

block/src/qcow/mod.rs:376–643  ·  view source on GitHub ↗

Parses and validates a QCOW2 image file, returning the metadata, backing file and sparse flag. Used by [`QcowFile`] and [`QcowDisk`] constructors.

(
    mut file: RawFile,
    max_nesting_depth: u32,
    sparse: bool,
)

Source from the content-addressed store, hash-verified

374///
375/// Used by [`QcowFile`] and [`QcowDisk`] constructors.
376pub(crate) fn parse_qcow(
377 mut file: RawFile,
378 max_nesting_depth: u32,
379 sparse: bool,
380) -> BlockResult<(metadata::QcowState, Option<BackingFile>, bool)> {
381 let mut header = QcowHeader::new(&mut file).map_err(|e| {
382 let kind = match &e {
383 Error::InvalidMagic
384 | Error::BackingFileTooLong(_)
385 | Error::InvalidBackingFileName(_) => BlockErrorKind::InvalidFormat,
386 Error::UnsupportedFeature(_) | Error::UnsupportedCompressionType => {
387 BlockErrorKind::UnsupportedFeature
388 }
389 _ => BlockErrorKind::Io,
390 };
391 BlockError::new(kind, e)
392 })?;
393
394 // Only v2 and v3 files are supported.
395 if header.version != 2 && header.version != 3 {
396 return Err(BlockError::new(
397 BlockErrorKind::UnsupportedFeature,
398 Error::UnsupportedVersion(header.version),
399 ));
400 }
401
402 // Make sure that the L1 table fits in RAM.
403 if u64::from(header.l1_size) > MAX_RAM_POINTER_TABLE_SIZE {
404 return Err(BlockError::new(
405 BlockErrorKind::InvalidFormat,
406 Error::InvalidL1TableSize(header.l1_size),
407 ));
408 }
409
410 let cluster_bits: u32 = header.cluster_bits;
411 if !(MIN_CLUSTER_BITS..=MAX_CLUSTER_BITS).contains(&cluster_bits) {
412 return Err(BlockError::new(
413 BlockErrorKind::InvalidFormat,
414 Error::InvalidClusterSize,
415 ));
416 }
417 let cluster_size = 0x01u64 << cluster_bits;
418
419 // Limit the total size of the disk.
420 if header.size > MAX_QCOW_FILE_SIZE {
421 return Err(BlockError::new(
422 BlockErrorKind::InvalidFormat,
423 Error::FileTooBig(header.size),
424 ));
425 }
426
427 let direct_io = file.is_direct();
428
429 let backing_file = BackingFile::new(
430 header.backing_file.as_ref(),
431 direct_io,
432 max_nesting_depth,
433 sparse,

Callers 3

newMethod · 0.85
newMethod · 0.85

Calls 15

newFunction · 0.85
rebuild_refcountsFunction · 0.85
div_round_up_u64Function · 0.85
max_refcount_clustersFunction · 0.85
containsMethod · 0.80
is_directMethod · 0.80
metadataMethod · 0.80
is_writableMethod · 0.80
fileMethod · 0.80
is_corruptMethod · 0.80
read_pointer_tableMethod · 0.80

Tested by

no test coverage detected