mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
block: qcow: Use thiserror for errors
Added thiserror for missing files in the qcow module. Signed-off-by: SamrutGadde <samrut.gadde@gmail.com>
This commit is contained in:
parent
193c006669
commit
f25315d151
@ -19,11 +19,11 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
|||||||
use libc::{EINVAL, ENOSPC, ENOTSUP};
|
use libc::{EINVAL, ENOSPC, ENOTSUP};
|
||||||
use remain::sorted;
|
use remain::sorted;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::fmt::{self, Display};
|
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::{self, Read, Seek, SeekFrom, Write};
|
use std::io::{self, Read, Seek, SeekFrom, Write};
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
use thiserror::Error;
|
||||||
use vmm_sys_util::{
|
use vmm_sys_util::{
|
||||||
file_traits::FileSetLen, file_traits::FileSync, seek_hole::SeekHole, write_zeroes::PunchHole,
|
file_traits::FileSetLen, file_traits::FileSync, seek_hole::SeekHole, write_zeroes::PunchHole,
|
||||||
write_zeroes::WriteZeroesAt,
|
write_zeroes::WriteZeroesAt,
|
||||||
@ -32,105 +32,92 @@ use vmm_sys_util::{
|
|||||||
pub use crate::qcow::raw_file::RawFile;
|
pub use crate::qcow::raw_file::RawFile;
|
||||||
|
|
||||||
#[sorted]
|
#[sorted]
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("Backing file io error: {0}")]
|
||||||
BackingFileIo(io::Error),
|
BackingFileIo(io::Error),
|
||||||
|
#[error("Backing file open error: {0}")]
|
||||||
BackingFileOpen(Box<crate::Error>),
|
BackingFileOpen(Box<crate::Error>),
|
||||||
|
#[error("Backing file name is too long: {0} bytes over")]
|
||||||
BackingFileTooLong(usize),
|
BackingFileTooLong(usize),
|
||||||
|
#[error("Compressed blocks not supported")]
|
||||||
CompressedBlocksNotSupported,
|
CompressedBlocksNotSupported,
|
||||||
|
#[error("Failed to evict cache: {0}")]
|
||||||
EvictingCache(io::Error),
|
EvictingCache(io::Error),
|
||||||
|
#[error("File larger than max of {}: {0}", MAX_QCOW_FILE_SIZE)]
|
||||||
FileTooBig(u64),
|
FileTooBig(u64),
|
||||||
|
#[error("Failed to get file size: {0}")]
|
||||||
GettingFileSize(io::Error),
|
GettingFileSize(io::Error),
|
||||||
|
#[error("Failed to get refcount: {0}")]
|
||||||
GettingRefcount(refcount::Error),
|
GettingRefcount(refcount::Error),
|
||||||
|
#[error("Failed to parse filename: {0}")]
|
||||||
InvalidBackingFileName(str::Utf8Error),
|
InvalidBackingFileName(str::Utf8Error),
|
||||||
|
#[error("Invalid cluster index")]
|
||||||
InvalidClusterIndex,
|
InvalidClusterIndex,
|
||||||
|
#[error("Invalid cluster size")]
|
||||||
InvalidClusterSize,
|
InvalidClusterSize,
|
||||||
|
#[error("Invalid index")]
|
||||||
InvalidIndex,
|
InvalidIndex,
|
||||||
|
#[error("Invalid L1 table offset")]
|
||||||
InvalidL1TableOffset,
|
InvalidL1TableOffset,
|
||||||
|
#[error("Invalid L1 table size: {0}")]
|
||||||
InvalidL1TableSize(u32),
|
InvalidL1TableSize(u32),
|
||||||
|
#[error("Invalid magic")]
|
||||||
InvalidMagic,
|
InvalidMagic,
|
||||||
|
#[error("Invalid offset: {0}")]
|
||||||
InvalidOffset(u64),
|
InvalidOffset(u64),
|
||||||
|
#[error("Invalid refcount table offset")]
|
||||||
InvalidRefcountTableOffset,
|
InvalidRefcountTableOffset,
|
||||||
|
#[error("Invalid refcount table size: {0}")]
|
||||||
InvalidRefcountTableSize(u64),
|
InvalidRefcountTableSize(u64),
|
||||||
|
#[error("No free clusters")]
|
||||||
NoFreeClusters,
|
NoFreeClusters,
|
||||||
|
#[error("No refcount clusters")]
|
||||||
NoRefcountClusters,
|
NoRefcountClusters,
|
||||||
|
#[error("Not enough space for refcounts")]
|
||||||
NotEnoughSpaceForRefcounts,
|
NotEnoughSpaceForRefcounts,
|
||||||
|
#[error("Failed to open file {0}")]
|
||||||
OpeningFile(io::Error),
|
OpeningFile(io::Error),
|
||||||
|
#[error("Failed to read data: {0}")]
|
||||||
ReadingData(io::Error),
|
ReadingData(io::Error),
|
||||||
|
#[error("Failed to read header: {0}")]
|
||||||
ReadingHeader(io::Error),
|
ReadingHeader(io::Error),
|
||||||
|
#[error("Failed to read pointers: {0}")]
|
||||||
ReadingPointers(io::Error),
|
ReadingPointers(io::Error),
|
||||||
|
#[error("Failed to read ref count block: {0}")]
|
||||||
ReadingRefCountBlock(refcount::Error),
|
ReadingRefCountBlock(refcount::Error),
|
||||||
|
#[error("Failed to read ref counts: {0}")]
|
||||||
ReadingRefCounts(io::Error),
|
ReadingRefCounts(io::Error),
|
||||||
|
#[error("Failed to rebuild ref counts: {0}")]
|
||||||
RebuildingRefCounts(io::Error),
|
RebuildingRefCounts(io::Error),
|
||||||
|
#[error("Refcount table offset past file end")]
|
||||||
RefcountTableOffEnd,
|
RefcountTableOffEnd,
|
||||||
|
#[error("Too many clusters specified for refcount")]
|
||||||
RefcountTableTooLarge,
|
RefcountTableTooLarge,
|
||||||
|
#[error("Failed to seek file: {0}")]
|
||||||
SeekingFile(io::Error),
|
SeekingFile(io::Error),
|
||||||
|
#[error("Failed to set file size: {0}")]
|
||||||
SettingFileSize(io::Error),
|
SettingFileSize(io::Error),
|
||||||
|
#[error("Failed to set refcount refcount: {0}")]
|
||||||
SettingRefcountRefcount(io::Error),
|
SettingRefcountRefcount(io::Error),
|
||||||
|
#[error("Size too small for number of clusters")]
|
||||||
SizeTooSmallForNumberOfClusters,
|
SizeTooSmallForNumberOfClusters,
|
||||||
|
#[error("L1 entry table too large: {0}")]
|
||||||
TooManyL1Entries(u64),
|
TooManyL1Entries(u64),
|
||||||
|
#[error("Ref count table too large: {0}")]
|
||||||
TooManyRefcounts(u64),
|
TooManyRefcounts(u64),
|
||||||
|
#[error("Unsupported refcount order")]
|
||||||
UnsupportedRefcountOrder,
|
UnsupportedRefcountOrder,
|
||||||
|
#[error("Unsupported version: {0}")]
|
||||||
UnsupportedVersion(u32),
|
UnsupportedVersion(u32),
|
||||||
|
#[error("Failed to write data: {0}")]
|
||||||
WritingData(io::Error),
|
WritingData(io::Error),
|
||||||
|
#[error("Failed to write header: {0}")]
|
||||||
WritingHeader(io::Error),
|
WritingHeader(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
impl Display for Error {
|
|
||||||
#[remain::check]
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use self::Error::*;
|
|
||||||
|
|
||||||
#[sorted]
|
|
||||||
match self {
|
|
||||||
BackingFileIo(e) => write!(f, "backing file io error: {}", e),
|
|
||||||
BackingFileOpen(e) => write!(f, "backing file open error: {}", *e),
|
|
||||||
BackingFileTooLong(len) => {
|
|
||||||
write!(f, "backing file name is too long: {} bytes over", len)
|
|
||||||
}
|
|
||||||
CompressedBlocksNotSupported => write!(f, "compressed blocks not supported"),
|
|
||||||
EvictingCache(e) => write!(f, "failed to evict cache: {e}"),
|
|
||||||
FileTooBig(size) => write!(f, "file larger than max of {MAX_QCOW_FILE_SIZE}: {size}"),
|
|
||||||
GettingFileSize(e) => write!(f, "failed to get file size: {e}"),
|
|
||||||
GettingRefcount(e) => write!(f, "failed to get refcount: {e}"),
|
|
||||||
InvalidBackingFileName(e) => write!(f, "failed to parse filename: {}", e),
|
|
||||||
InvalidClusterIndex => write!(f, "invalid cluster index"),
|
|
||||||
InvalidClusterSize => write!(f, "invalid cluster size"),
|
|
||||||
InvalidIndex => write!(f, "invalid index"),
|
|
||||||
InvalidL1TableOffset => write!(f, "invalid L1 table offset"),
|
|
||||||
InvalidL1TableSize(size) => write!(f, "invalid L1 table size {size}"),
|
|
||||||
InvalidMagic => write!(f, "invalid magic"),
|
|
||||||
InvalidOffset(_) => write!(f, "invalid offset"),
|
|
||||||
InvalidRefcountTableOffset => write!(f, "invalid refcount table offset"),
|
|
||||||
InvalidRefcountTableSize(size) => write!(f, "invalid refcount table size: {size}"),
|
|
||||||
NoFreeClusters => write!(f, "no free clusters"),
|
|
||||||
NoRefcountClusters => write!(f, "no refcount clusters"),
|
|
||||||
NotEnoughSpaceForRefcounts => write!(f, "not enough space for refcounts"),
|
|
||||||
OpeningFile(e) => write!(f, "failed to open file: {e}"),
|
|
||||||
ReadingData(e) => write!(f, "failed to read data: {e}"),
|
|
||||||
ReadingHeader(e) => write!(f, "failed to read header: {e}"),
|
|
||||||
ReadingPointers(e) => write!(f, "failed to read pointers: {e}"),
|
|
||||||
ReadingRefCountBlock(e) => write!(f, "failed to read ref count block: {e}"),
|
|
||||||
ReadingRefCounts(e) => write!(f, "failed to read ref counts: {e}"),
|
|
||||||
RebuildingRefCounts(e) => write!(f, "failed to rebuild ref counts: {e}"),
|
|
||||||
RefcountTableOffEnd => write!(f, "refcount table offset past file end"),
|
|
||||||
RefcountTableTooLarge => write!(f, "too many clusters specified for refcount table"),
|
|
||||||
SeekingFile(e) => write!(f, "failed to seek file: {e}"),
|
|
||||||
SettingFileSize(e) => write!(f, "failed to set file size: {e}"),
|
|
||||||
SettingRefcountRefcount(e) => write!(f, "failed to set refcount refcount: {e}"),
|
|
||||||
SizeTooSmallForNumberOfClusters => write!(f, "size too small for number of clusters"),
|
|
||||||
TooManyL1Entries(count) => write!(f, "l1 entry table too large: {count}"),
|
|
||||||
TooManyRefcounts(count) => write!(f, "ref count table too large: {count}"),
|
|
||||||
UnsupportedRefcountOrder => write!(f, "unsupported refcount order"),
|
|
||||||
UnsupportedVersion(v) => write!(f, "unsupported version: {v}"),
|
|
||||||
WritingData(e) => write!(f, "failed to write data: {e}"),
|
|
||||||
WritingHeader(e) => write!(f, "failed to write header: {e}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum ImageType {
|
pub enum ImageType {
|
||||||
Raw,
|
Raw,
|
||||||
Qcow2,
|
Qcow2,
|
||||||
|
@ -4,50 +4,37 @@
|
|||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
||||||
|
|
||||||
use std::fmt::{self, Display};
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use libc::EINVAL;
|
use libc::EINVAL;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::qcow::{
|
use crate::qcow::{
|
||||||
qcow_raw_file::QcowRawFile,
|
qcow_raw_file::QcowRawFile,
|
||||||
vec_cache::{CacheMap, Cacheable, VecCache},
|
vec_cache::{CacheMap, Cacheable, VecCache},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// `EvictingCache` - Error writing a refblock from the cache to disk.
|
/// `EvictingCache` - Error writing a refblock from the cache to disk.
|
||||||
|
#[error("Failed to write a refblock from the cache to disk: {0}")]
|
||||||
EvictingRefCounts(io::Error),
|
EvictingRefCounts(io::Error),
|
||||||
/// `InvalidIndex` - Address requested isn't within the range of the disk.
|
/// `InvalidIndex` - Address requested isn't within the range of the disk.
|
||||||
|
#[error("Address requested is not within the range of the disk")]
|
||||||
InvalidIndex,
|
InvalidIndex,
|
||||||
/// `NeedCluster` - Handle this error by reading the cluster and calling the function again.
|
/// `NeedCluster` - Handle this error by reading the cluster and calling the function again.
|
||||||
|
#[error("Cluster with addr={0} needs to be read")]
|
||||||
NeedCluster(u64),
|
NeedCluster(u64),
|
||||||
/// `NeedNewCluster` - Handle this error by allocating a cluster and calling the function again.
|
/// `NeedNewCluster` - Handle this error by allocating a cluster and calling the function again.
|
||||||
|
#[error("New cluster needs to be allocated for refcounts")]
|
||||||
NeedNewCluster,
|
NeedNewCluster,
|
||||||
/// `ReadingRefCounts` - Error reading the file in to the refcount cache.
|
/// `ReadingRefCounts` - Error reading the file in to the refcount cache.
|
||||||
|
#[error("Failed to read the file into the refcount cache: {0}")]
|
||||||
ReadingRefCounts(io::Error),
|
ReadingRefCounts(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
impl Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use self::Error::*;
|
|
||||||
|
|
||||||
match self {
|
|
||||||
EvictingRefCounts(e) => {
|
|
||||||
write!(f, "failed to write a refblock from the cache to disk: {e}")
|
|
||||||
}
|
|
||||||
InvalidIndex => write!(f, "address requested is not within the range of the disk"),
|
|
||||||
NeedCluster(addr) => write!(f, "cluster with addr={addr} needs to be read"),
|
|
||||||
NeedNewCluster => write!(f, "new cluster needs to be allocated for refcounts"),
|
|
||||||
ReadingRefCounts(e) => {
|
|
||||||
write!(f, "failed to read the file into the refcount cache: {e}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents the refcount entries for an open qcow file.
|
/// Represents the refcount entries for an open qcow file.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RefCount {
|
pub struct RefCount {
|
||||||
|
Loading…
Reference in New Issue
Block a user