use thiserror crate
This commit is contained in:
parent
41d6d10373
commit
8ef4220adf
@ -7,3 +7,4 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "*"
|
libc = "*"
|
||||||
lazy_static="1.4.0"
|
lazy_static="1.4.0"
|
||||||
|
thiserror = "1.0"
|
||||||
|
@ -1,79 +1,73 @@
|
|||||||
use std::{result, io, fmt};
|
use std::{result, io};
|
||||||
use crate::netlink;
|
use crate::netlink;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug,Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("not running as pid 1")]
|
||||||
Pid1,
|
Pid1,
|
||||||
|
#[error("failed to load kernel command line from /proc/cmdline: {0}")]
|
||||||
KernelCmdLine(io::Error),
|
KernelCmdLine(io::Error),
|
||||||
|
#[error("Cannot mount rootfs because no phinit.root is set")]
|
||||||
NoRootVar,
|
NoRootVar,
|
||||||
|
#[error("Cannot mount rootfs because no phinit.rootfs is set")]
|
||||||
NoRootFsVar,
|
NoRootFsVar,
|
||||||
|
#[error("Failed to mount rootfs {0}: {1}")]
|
||||||
RootFsMount(String, io::Error),
|
RootFsMount(String, io::Error),
|
||||||
|
#[error("unable to mount procfs: {0}")]
|
||||||
MountProcFS(io::Error),
|
MountProcFS(io::Error),
|
||||||
|
#[error("failed to mount tmpfs at {0}: {1}")]
|
||||||
MountTmpFS(String, io::Error),
|
MountTmpFS(String, io::Error),
|
||||||
|
#[error("failed to mount sysfs at /sys: {0}")]
|
||||||
MountSysFS(io::Error),
|
MountSysFS(io::Error),
|
||||||
|
#[error("failed to mount cgroup at /sys/fs/cgroup: {0}")]
|
||||||
MountCGroup(io::Error),
|
MountCGroup(io::Error),
|
||||||
|
#[error("failed to mount devtmpfs at /dev: {0}")]
|
||||||
MountDevTmpFS(io::Error),
|
MountDevTmpFS(io::Error),
|
||||||
|
#[error("failed to mount /dev/pts: {0}")]
|
||||||
MountDevPts(io::Error),
|
MountDevPts(io::Error),
|
||||||
|
#[error("failed to mount overlayfs: {0}")]
|
||||||
MountOverlay(io::Error),
|
MountOverlay(io::Error),
|
||||||
|
#[error("failed to move mount from {0} to {1}: {2}")]
|
||||||
MoveMount(String, String, io::Error),
|
MoveMount(String, String, io::Error),
|
||||||
|
#[error("failed to mount 9p volume {0} at {1}: {2}")]
|
||||||
Mount9P(String, String, io::Error),
|
Mount9P(String, String, io::Error),
|
||||||
|
#[error("failed to unmount {0}: {1}")]
|
||||||
Umount(String, io::Error),
|
Umount(String, io::Error),
|
||||||
|
#[error("failed to mkdir {0}: {1}")]
|
||||||
MkDir(String, io::Error),
|
MkDir(String, io::Error),
|
||||||
|
#[error("sethostname() failed: {0}")]
|
||||||
SetHostname(io::Error),
|
SetHostname(io::Error),
|
||||||
|
#[error("call to setsid() failed: {0}")]
|
||||||
SetSid(io::Error),
|
SetSid(io::Error),
|
||||||
|
#[error("failed to set controlling terminal: {0}")]
|
||||||
SetControllingTty(io::Error),
|
SetControllingTty(io::Error),
|
||||||
|
#[error("failed to pivot_root({0}, {1}): {2}")]
|
||||||
PivotRoot(String, String, io::Error),
|
PivotRoot(String, String, io::Error),
|
||||||
|
#[error("failed to waitpid(): {0}")]
|
||||||
WaitPid(io::Error),
|
WaitPid(io::Error),
|
||||||
|
#[error("failed to write /etc/hosts: {0}")]
|
||||||
WriteEtcHosts(io::Error),
|
WriteEtcHosts(io::Error),
|
||||||
|
#[error("error launching shell: {0}")]
|
||||||
RunShell(io::Error),
|
RunShell(io::Error),
|
||||||
|
#[error("failed to create CString")]
|
||||||
CStringConv,
|
CStringConv,
|
||||||
|
#[error("failed to chmod: {0}")]
|
||||||
ChmodFailed(io::Error),
|
ChmodFailed(io::Error),
|
||||||
|
#[error("failed to chown: {0}")]
|
||||||
ChownFailed(io::Error),
|
ChownFailed(io::Error),
|
||||||
|
#[error("unable to execute {0}: {1}")]
|
||||||
LaunchFailed(String, io::Error),
|
LaunchFailed(String, io::Error),
|
||||||
|
#[error("could not reboot system: {0}")]
|
||||||
RebootFailed(io::Error),
|
RebootFailed(io::Error),
|
||||||
|
#[error("failed to open log file: {0}")]
|
||||||
OpenLogFailed(io::Error),
|
OpenLogFailed(io::Error),
|
||||||
|
#[error("error creating .Xauthority file: {0}")]
|
||||||
XAuthFail(io::Error),
|
XAuthFail(io::Error),
|
||||||
|
#[error("error writing bashrc file: {0}")]
|
||||||
WriteBashrc(io::Error),
|
WriteBashrc(io::Error),
|
||||||
|
#[error("error configuring network: {0}")]
|
||||||
NetworkConfigure(netlink::Error),
|
NetworkConfigure(netlink::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
Pid1 => write!(f, "not running as pid 1"),
|
|
||||||
KernelCmdLine(err) => write!(f, "failed to load kernel command line from /proc/cmdline: {}", err),
|
|
||||||
NoRootVar => write!(f, "Cannot mount rootfs because no phinit.root is set"),
|
|
||||||
NoRootFsVar => write!(f, "Cannot mount rootfs because no phinit.rootfs is set"),
|
|
||||||
RootFsMount(rootfs, err) => write!(f, "Failed to mount rootfs {}: {}", rootfs, err),
|
|
||||||
MountProcFS(err) => write!(f, "unable to mount procfs: {}", err),
|
|
||||||
MountTmpFS(target,err) => write!(f, "failed to mount tmpfs at {}: {}", target, err),
|
|
||||||
MountSysFS(err) => write!(f, "failed to mount sysfs at /sys: {}", err),
|
|
||||||
MountCGroup(err) => write!(f, "failed to mount cgroup at /sys/fs/cgroup: {}", err),
|
|
||||||
MountDevTmpFS(err) => write!(f, "failed to mount devtmpfs at /dev: {}", err),
|
|
||||||
MountDevPts(err) => write!(f, "failed to mount /dev/pts: {}", err),
|
|
||||||
MountOverlay(err) => write!(f, "failed to mount overlayfs: {}", err),
|
|
||||||
MoveMount(from, to, err) => write!(f, "failed to move mount from {} to {}: {}", from, to, err),
|
|
||||||
Mount9P(tag,target, err) => write!(f, "failed to mount 9p volume {} at {}: {}", tag, target, err),
|
|
||||||
Umount(target, err) => write!(f, "failed to unmount {}: {}", target, err),
|
|
||||||
MkDir(target, err) => write!(f, "failed to mkdir {}: {}", target, err),
|
|
||||||
SetHostname(err) => write!(f, "sethostname() failed: {}", err),
|
|
||||||
SetSid(err) => write!(f, "call to setsid() failed: {}", err),
|
|
||||||
SetControllingTty(err) => write!(f, "failed to set controlling terminal: {}", err),
|
|
||||||
PivotRoot(newroot, putroot, err) => write!(f, "failed to pivot_root({}, {}): {}", newroot, putroot, err),
|
|
||||||
WaitPid(err) => write!(f, "failed to waitpid(): {}", err),
|
|
||||||
WriteEtcHosts(err) => write!(f, "failed to write /etc/hosts: {}", err),
|
|
||||||
RunShell(err) => write!(f, "error launching shell: {}", err),
|
|
||||||
CStringConv => write!(f, "failed to create CString"),
|
|
||||||
ChmodFailed(err) => write!(f, "failed to chmod: {}", err),
|
|
||||||
ChownFailed(err) => write!(f, "failed to chown: {}", err),
|
|
||||||
LaunchFailed(exec, err) => write!(f, "unable to execute {}: {}", exec, err),
|
|
||||||
RebootFailed(err) => write!(f, "could not reboot system: {}", err),
|
|
||||||
OpenLogFailed(err) => write!(f, "failed to open log file: {}", err),
|
|
||||||
XAuthFail(err) => write!(f, "error creating .Xauthority file: {}", err),
|
|
||||||
WriteBashrc(err) => write!(f, "error writing bashrc file: {}", err),
|
|
||||||
NetworkConfigure(err) => write!(f, "error configuring network: {}", err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
@ -2,10 +2,12 @@ use std::cell::Cell;
|
|||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::{mem, result, fmt, io};
|
use std::{mem, result, io};
|
||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
use libc::{
|
use libc::{
|
||||||
PF_NETLINK, SOCK_RAW, SOCK_CLOEXEC, SOCK_NONBLOCK
|
PF_NETLINK, SOCK_RAW, SOCK_CLOEXEC, SOCK_NONBLOCK
|
||||||
};
|
};
|
||||||
@ -54,34 +56,26 @@ pub const IFF_UP: u32 = libc::IFF_UP as u32;
|
|||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("failed to create netlink socket: {0}")]
|
||||||
Socket(io::Error),
|
Socket(io::Error),
|
||||||
|
#[error("failed calling bind() on netlink socket: {0}")]
|
||||||
SocketBind(io::Error),
|
SocketBind(io::Error),
|
||||||
|
#[error("failed calling sendto() on netlink socket: {0}")]
|
||||||
SocketSend(io::Error),
|
SocketSend(io::Error),
|
||||||
|
#[error("failed calling recv() on netlink socket: {0}")]
|
||||||
SocketRecv(io::Error),
|
SocketRecv(io::Error),
|
||||||
|
#[error("failed to convert interface name to index: {0}")]
|
||||||
NameToIndex(io::Error),
|
NameToIndex(io::Error),
|
||||||
|
#[error("error response to netlink request: {0}")]
|
||||||
ErrorResponse(io::Error),
|
ErrorResponse(io::Error),
|
||||||
|
#[error("could not parse response message from netlink")]
|
||||||
UnexpectedResponse,
|
UnexpectedResponse,
|
||||||
|
#[error("failed to transmit entire netlink message")]
|
||||||
ShortSend,
|
ShortSend,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
Socket(e) => write!(f, "failed to create netlink socket: {}", e),
|
|
||||||
SocketBind(e) => write!(f, "failed calling bind() on netlink socket: {}", e),
|
|
||||||
SocketSend(e) => write!(f, "failed calling sendto() on netlink socket: {}", e),
|
|
||||||
SocketRecv(e) => write!(f, "failed calling recv() on netlink socket: {}", e),
|
|
||||||
NameToIndex(e) => write!(f, "failed to convert interface name to index: {}", e),
|
|
||||||
ErrorResponse(e) => write!(f, "error response to netlink request: {}", e),
|
|
||||||
UnexpectedResponse => write!(f, "could not parse response message from netlink"),
|
|
||||||
ShortSend => write!(f, "failed to transmit entire netlink message"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct NetlinkSocket {
|
pub struct NetlinkSocket {
|
||||||
sock: RawFd,
|
sock: RawFd,
|
||||||
seq: Cell<u32>,
|
seq: Cell<u32>,
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::{RwLock, Arc};
|
use std::sync::{RwLock, Arc};
|
||||||
use std::{result, io, fmt, thread};
|
use std::{result, io, thread};
|
||||||
|
|
||||||
use crate::{disk, virtio};
|
use crate::{disk, virtio};
|
||||||
use crate::virtio::{VirtioBus, VirtioDeviceOps, VirtQueue, DeviceConfigArea, Chain};
|
use crate::virtio::{VirtioBus, VirtioDeviceOps, VirtQueue, DeviceConfigArea, Chain};
|
||||||
use crate::memory::MemoryManager;
|
use crate::memory::MemoryManager;
|
||||||
use crate::disk::DiskImage;
|
use crate::disk::DiskImage;
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
const VIRTIO_BLK_F_RO: u64 = 1 << 5;
|
const VIRTIO_BLK_F_RO: u64 = 1 << 5;
|
||||||
const VIRTIO_BLK_F_BLK_SIZE: u64 = 1 << 6;
|
const VIRTIO_BLK_F_BLK_SIZE: u64 = 1 << 6;
|
||||||
const VIRTIO_BLK_F_FLUSH: u64 = 1 << 9;
|
const VIRTIO_BLK_F_FLUSH: u64 = 1 << 9;
|
||||||
@ -26,34 +28,22 @@ const SECTOR_SIZE: usize = 1 << SECTOR_SHIFT;
|
|||||||
|
|
||||||
const QUEUE_SIZE: usize = 256;
|
const QUEUE_SIZE: usize = 256;
|
||||||
|
|
||||||
|
#[derive(Debug,Error)]
|
||||||
enum Error {
|
enum Error {
|
||||||
IoChainError(io::Error),
|
#[error("i/o error on virtio chain operation: {0}")]
|
||||||
|
IoChainError(#[from] io::Error),
|
||||||
|
#[error("error reading disk image: {0}")]
|
||||||
DiskRead(disk::Error),
|
DiskRead(disk::Error),
|
||||||
|
#[error("error writing disk image: {0}")]
|
||||||
DiskWrite(disk::Error),
|
DiskWrite(disk::Error),
|
||||||
|
#[error("error flushing disk image: {0}")]
|
||||||
DiskFlush(disk::Error),
|
DiskFlush(disk::Error),
|
||||||
|
#[error("error waiting on virtqueue: {0}")]
|
||||||
VirtQueueWait(virtio::Error),
|
VirtQueueWait(virtio::Error),
|
||||||
|
#[error("virtqueue read descriptor size ({0}) is invalid. Not a multiple of sector size")]
|
||||||
InvalidReadDescriptor(usize),
|
InvalidReadDescriptor(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for Error {
|
|
||||||
fn from(e: io::Error) -> Self {
|
|
||||||
Error::IoChainError(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
IoChainError(e) => write!(f, "i/o error on virtio chain operation: {}", e),
|
|
||||||
DiskRead(e) => write!(f, "error reading disk image: {}", e),
|
|
||||||
DiskWrite(e) => write!(f, "error writing disk image: {}", e),
|
|
||||||
DiskFlush(e) => write!(f, "error flushing disk image: {}", e),
|
|
||||||
VirtQueueWait(e) =>write!(f, "error waiting on virtqueue: {}", e),
|
|
||||||
InvalidReadDescriptor(sz) => write!(f, "virtqueue read descriptor size ({}) is invalid. Not a multiple of sector size", sz),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
pub struct VirtioBlock<D: DiskImage+'static> {
|
pub struct VirtioBlock<D: DiskImage+'static> {
|
||||||
|
@ -2,40 +2,35 @@ use crate::virtio::{VirtioDeviceOps, VirtQueue, VirtioBus, Chain};
|
|||||||
use crate::memory::MemoryManager;
|
use crate::memory::MemoryManager;
|
||||||
use crate::{system, virtio};
|
use crate::{system, virtio};
|
||||||
use std::sync::{RwLock, Arc};
|
use std::sync::{RwLock, Arc};
|
||||||
use std::{fmt, result, thread, io};
|
use std::{result, thread, io};
|
||||||
use crate::system::{EPoll,Event};
|
use crate::system::{EPoll,Event};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
use crate::system::Tap;
|
use crate::system::Tap;
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
const VIRTIO_ID_NET: u16 = 1;
|
const VIRTIO_ID_NET: u16 = 1;
|
||||||
const MAC_ADDR_LEN: usize = 6;
|
const MAC_ADDR_LEN: usize = 6;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("Error writing to virtqueue chain: {0}")]
|
||||||
ChainWrite(io::Error),
|
ChainWrite(io::Error),
|
||||||
|
#[error("Error reading from virtqueue chain: {0}")]
|
||||||
ChainRead(io::Error),
|
ChainRead(io::Error),
|
||||||
ChainIoEvent(system::Error),
|
#[error("Error reading from virtqueue ioevent: {0}")]
|
||||||
|
ChainIoEvent(io::Error),
|
||||||
|
#[error("Failed to set up Poll: {0}")]
|
||||||
SetupPoll(system::Error),
|
SetupPoll(system::Error),
|
||||||
|
#[error("Error reading from tap device: {0}")]
|
||||||
TapRead(io::Error),
|
TapRead(io::Error),
|
||||||
|
#[error("Error writing to tap device: {0}")]
|
||||||
TapWrite(io::Error),
|
TapWrite(io::Error),
|
||||||
|
#[error("Poll wait returned error: {0}")]
|
||||||
PollWait(system::Error),
|
PollWait(system::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
ChainWrite(err) => write!(f, "Error writing to virtqueue chain: {}", err),
|
|
||||||
ChainRead(err) => write!(f, "Error reading from virtqueue chain: {}", err),
|
|
||||||
ChainIoEvent(err) => write!(f, "Error reading from virtqueue ioevent: {}", err),
|
|
||||||
SetupPoll(e) => write!(f, "Failed to set up Poll: {}", e),
|
|
||||||
TapRead(e) => write!(f, "Error reading from tap device: {}", e),
|
|
||||||
TapWrite(e) => write!(f, "Error writing to tap device: {}", e),
|
|
||||||
PollWait(e) => write!(f, "Poll wait returned error: {}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
use std::{result, io, fmt};
|
use std::{result, io};
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::system;
|
use crate::system;
|
||||||
use crate::memory::Error as MemError;
|
use crate::memory::Error as MemError;
|
||||||
@ -80,56 +82,42 @@ pub trait VfdObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
IoEventError(system::Error),
|
#[error("error reading from ioevent fd: {0}")]
|
||||||
EventFdCreate(system::Error),
|
IoEventError(io::Error),
|
||||||
ChainIoError(io::Error),
|
#[error("error creating eventfd: {0}")]
|
||||||
|
EventFdCreate(io::Error),
|
||||||
|
#[error("i/o error on virtio chain operation: {0}")]
|
||||||
|
ChainIoError(#[from] io::Error),
|
||||||
|
#[error("unexpected virtio wayland command: {0}")]
|
||||||
UnexpectedCommand(u32),
|
UnexpectedCommand(u32),
|
||||||
|
#[error("failed to allocate shared memory: {0}")]
|
||||||
ShmAllocFailed(system::Error),
|
ShmAllocFailed(system::Error),
|
||||||
|
#[error("failed to register memory with hypervisor: {0}")]
|
||||||
RegisterMemoryFailed(MemError),
|
RegisterMemoryFailed(MemError),
|
||||||
|
#[error("failed to create pipes: {0}")]
|
||||||
CreatePipesFailed(system::Error),
|
CreatePipesFailed(system::Error),
|
||||||
|
#[error("error reading from socket: {0}")]
|
||||||
SocketReceive(system::ErrnoError),
|
SocketReceive(system::ErrnoError),
|
||||||
|
#[error("error connecting to socket: {0}")]
|
||||||
SocketConnect(io::Error),
|
SocketConnect(io::Error),
|
||||||
|
#[error("error reading from pipe: {0}")]
|
||||||
PipeReceive(io::Error),
|
PipeReceive(io::Error),
|
||||||
|
#[error("error writing to vfd: {0}")]
|
||||||
SendVfd(io::Error),
|
SendVfd(io::Error),
|
||||||
|
#[error("attempt to send to incorrect vfd type")]
|
||||||
InvalidSendVfd,
|
InvalidSendVfd,
|
||||||
|
#[error("message has too many vfd ids: {0}")]
|
||||||
TooManySendVfds(usize),
|
TooManySendVfds(usize),
|
||||||
|
#[error("failed creating poll context: {0}")]
|
||||||
FailedPollContextCreate(system::Error),
|
FailedPollContextCreate(system::Error),
|
||||||
|
#[error("failed adding fd to poll context: {0}")]
|
||||||
FailedPollAdd(system::Error),
|
FailedPollAdd(system::Error),
|
||||||
|
#[error("error calling dma sync: {0}")]
|
||||||
DmaSync(system::ErrnoError),
|
DmaSync(system::ErrnoError),
|
||||||
|
#[error("failed creating DMA buf: {0}")]
|
||||||
DmaBuf(MemError),
|
DmaBuf(MemError),
|
||||||
|
#[error("failed creating DMA buf: {0}")]
|
||||||
DmaBufSize(system::Error),
|
DmaBufSize(system::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
IoEventError(e) => write!(f, "error reading from ioevent fd: {}", e),
|
|
||||||
EventFdCreate(e) => write!(f, "error creating eventfd: {}", e),
|
|
||||||
ChainIoError(e) => write!(f, "i/o error on virtio chain operation: {}", e),
|
|
||||||
UnexpectedCommand(cmd) => write!(f, "unexpected virtio wayland command: {}", cmd),
|
|
||||||
ShmAllocFailed(e) => write!(f, "failed to allocate shared memory: {}", e),
|
|
||||||
RegisterMemoryFailed(e) => write!(f, "failed to register memory with hypervisor: {}", e),
|
|
||||||
CreatePipesFailed(e) => write!(f, "failed to create pipes: {}", e),
|
|
||||||
SocketReceive(e) => write!(f, "error reading from socket: {}", e),
|
|
||||||
SocketConnect(e) => write!(f, "error connecting to socket: {}", e),
|
|
||||||
PipeReceive(e) => write!(f, "error reading from pipe: {}", e),
|
|
||||||
SendVfd(e) => write!(f, "error writing to vfd: {}", e),
|
|
||||||
InvalidSendVfd => write!(f, "attempt to send to incorrect vfd type"),
|
|
||||||
TooManySendVfds(n) => write!(f, "message has too many vfd ids: {}", n),
|
|
||||||
FailedPollContextCreate(e) => write!(f, "failed creating poll context: {}", e),
|
|
||||||
FailedPollAdd(e) => write!(f, "failed adding fd to poll context: {}", e),
|
|
||||||
DmaSync(e) => write!(f, "error calling dma sync: {}", e),
|
|
||||||
DmaBuf(e) => write!(f, "failed creating DMA buf: {}", e),
|
|
||||||
DmaBufSize(e) => write!(f, "failed getting DMA buf size: {}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<io::Error> for Error {
|
|
||||||
fn from(e: io::Error) -> Self {
|
|
||||||
Error::ChainIoError(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{io, error, fmt, result, cmp};
|
use std::{io, result, cmp};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::os::linux::fs::MetadataExt;
|
use std::os::linux::fs::MetadataExt;
|
||||||
use std::io::{SeekFrom, Seek};
|
use std::io::{SeekFrom, Seek};
|
||||||
@ -12,6 +12,7 @@ mod memory;
|
|||||||
pub use raw::RawDiskImage;
|
pub use raw::RawDiskImage;
|
||||||
pub use realmfs::RealmFSImage;
|
pub use realmfs::RealmFSImage;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
const SECTOR_SIZE: usize = 512;
|
const SECTOR_SIZE: usize = 512;
|
||||||
|
|
||||||
@ -59,36 +60,26 @@ fn generate_disk_image_id(disk_file: &File) -> Vec<u8> {
|
|||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("attempted write to read-only device")]
|
||||||
ReadOnly,
|
ReadOnly,
|
||||||
|
#[error("disk image {0} does not exist")]
|
||||||
ImageDoesntExit(PathBuf),
|
ImageDoesntExit(PathBuf),
|
||||||
|
#[error("failed to open disk image {0:?}: {1}")]
|
||||||
DiskOpen(PathBuf,io::Error),
|
DiskOpen(PathBuf,io::Error),
|
||||||
|
#[error("failed to open disk image {0} because the file is too short")]
|
||||||
DiskOpenTooShort(PathBuf),
|
DiskOpenTooShort(PathBuf),
|
||||||
|
#[error("error reading from disk image: {0}")]
|
||||||
DiskRead(io::Error),
|
DiskRead(io::Error),
|
||||||
|
#[error("error writing to disk image: {0}")]
|
||||||
DiskWrite(io::Error),
|
DiskWrite(io::Error),
|
||||||
|
#[error("error seeking to offset on disk image: {0}")]
|
||||||
DiskSeek(io::Error),
|
DiskSeek(io::Error),
|
||||||
|
#[error("attempt to access invalid sector offset {0}")]
|
||||||
BadSectorOffset(u64),
|
BadSectorOffset(u64),
|
||||||
|
#[error("failed to create memory overlay: {0}")]
|
||||||
MemoryOverlayCreate(system::Error),
|
MemoryOverlayCreate(system::Error),
|
||||||
|
#[error("disk not open")]
|
||||||
NotOpen,
|
NotOpen,
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for Error {}
|
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
ReadOnly => write!(f, "attempted write to read-only device"),
|
|
||||||
ImageDoesntExit(path) => write!(f, "disk image {} does not exist", path.display()),
|
|
||||||
DiskOpen(path, err) => write!(f, "failed to open disk image {}: {}", path.display(), err),
|
|
||||||
DiskOpenTooShort(path) => write!(f, "failed to open disk image {} because file is too short", path.display()),
|
|
||||||
DiskRead(err) => write!(f, "error reading from disk image: {}", err),
|
|
||||||
DiskWrite(err) => write!(f, "error writing to disk image: {}", err),
|
|
||||||
DiskSeek(err) => write!(f, "error seeking to offset on disk image: {}", err),
|
|
||||||
BadSectorOffset(sector) => write!(f, "attempt to access invalid sector offset {}", sector),
|
|
||||||
MemoryOverlayCreate(err) => write!(f, "failed to create memory overlay: {}", err),
|
|
||||||
NotOpen => write!(f, "disk not open"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -13,41 +13,35 @@ pub use manager::MemoryManager;
|
|||||||
|
|
||||||
pub use drm::{DrmDescriptor,DrmPlaneDescriptor};
|
pub use drm::{DrmDescriptor,DrmPlaneDescriptor};
|
||||||
|
|
||||||
use std::{result, fmt, io};
|
use std::{result, io};
|
||||||
use crate::{system, kvm};
|
use crate::system;
|
||||||
|
|
||||||
#[derive(Debug)]
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug,Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("failed to allocate memory for device")]
|
||||||
DeviceMemoryAllocFailed,
|
DeviceMemoryAllocFailed,
|
||||||
|
#[error("failed to create memory mapping for device memory: {0}")]
|
||||||
MappingFailed(system::Error),
|
MappingFailed(system::Error),
|
||||||
RegisterMemoryFailed(kvm::Error),
|
#[error("failed to register memory for device memory: {0}")]
|
||||||
UnregisterMemoryFailed(kvm::Error),
|
RegisterMemoryFailed(kvm_ioctls::Error),
|
||||||
|
#[error("failed to unregister memory for device memory: {0}")]
|
||||||
|
UnregisterMemoryFailed(kvm_ioctls::Error),
|
||||||
|
#[error("failed to open device with libgbm: {0}")]
|
||||||
GbmCreateDevice(system::Error),
|
GbmCreateDevice(system::Error),
|
||||||
|
#[error("failed to allocate buffer with libgbm: {0}")]
|
||||||
GbmCreateBuffer(system::Error),
|
GbmCreateBuffer(system::Error),
|
||||||
|
#[error("error opening render node: {0}")]
|
||||||
OpenRenderNode(io::Error),
|
OpenRenderNode(io::Error),
|
||||||
|
#[error("exporting prime handle to fd failed: {0}")]
|
||||||
PrimeHandleToFD(system::ErrnoError),
|
PrimeHandleToFD(system::ErrnoError),
|
||||||
|
#[error("failed to create buffer: {0}")]
|
||||||
CreateBuffer(io::Error),
|
CreateBuffer(io::Error),
|
||||||
|
#[error("no DRM allocator is available")]
|
||||||
NoDrmAllocator,
|
NoDrmAllocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
DeviceMemoryAllocFailed => write!(f, "failed to allocate memory for device"),
|
|
||||||
MappingFailed(e) => write!(f, "failed to create memory mapping for device memory: {}", e),
|
|
||||||
RegisterMemoryFailed(e) => write!(f, "failed to register memory for device memory: {}", e),
|
|
||||||
UnregisterMemoryFailed(e) => write!(f, "failed to unregister memory for device memory: {}", e),
|
|
||||||
GbmCreateDevice(e) => write!(f, "failed to open device with libgbm: {}", e),
|
|
||||||
GbmCreateBuffer(e) => write!(f, "failed to allocate buffer with libgbm: {}", e),
|
|
||||||
PrimeHandleToFD(err) => write!(f, "exporting prime handle to fd failed: {}", err),
|
|
||||||
OpenRenderNode(err) => write!(f, "error opening render node: {}", err),
|
|
||||||
CreateBuffer(err) => write!(f, "failed to create buffer: {}", err),
|
|
||||||
NoDrmAllocator => write!(f, "no DRM allocator is available"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#[macro_use]pub mod ioctl;
|
#[macro_use]pub mod ioctl;
|
||||||
mod epoll;
|
mod epoll;
|
||||||
mod errno;
|
mod errno;
|
||||||
mod eventfd;
|
|
||||||
mod socket;
|
mod socket;
|
||||||
mod filedesc;
|
mod filedesc;
|
||||||
mod memfd;
|
mod memfd;
|
||||||
@ -9,26 +8,34 @@ mod tap;
|
|||||||
pub mod netlink;
|
pub mod netlink;
|
||||||
|
|
||||||
pub use filedesc::{FileDesc, FileFlags};
|
pub use filedesc::{FileDesc, FileFlags};
|
||||||
pub use eventfd::EventFd;
|
|
||||||
pub use memfd::MemoryFd;
|
pub use memfd::MemoryFd;
|
||||||
pub use epoll::{EPoll,Event};
|
pub use epoll::{EPoll,Event};
|
||||||
pub use socket::ScmSocket;
|
pub use socket::ScmSocket;
|
||||||
pub use netlink::NetlinkSocket;
|
pub use netlink::NetlinkSocket;
|
||||||
pub use tap::Tap;
|
pub use tap::Tap;
|
||||||
use std::{fmt, result, io};
|
use std::{result, io};
|
||||||
|
|
||||||
pub use errno::Error as ErrnoError;
|
pub use errno::Error as ErrnoError;
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("{0}")]
|
||||||
Errno(errno::Error),
|
Errno(errno::Error),
|
||||||
|
#[error("failed to open /dev/kvm: {0}")]
|
||||||
OpenKvmFailed(errno::Error),
|
OpenKvmFailed(errno::Error),
|
||||||
|
#[error("attempt to access invalid offset into mapping")]
|
||||||
InvalidOffset,
|
InvalidOffset,
|
||||||
|
#[error("attempt to access invalid address: {0:16x}")]
|
||||||
InvalidAddress(u64),
|
InvalidAddress(u64),
|
||||||
|
#[error("failed to call {0} ioctl: {1}")]
|
||||||
IoctlError(&'static str, errno::Error),
|
IoctlError(&'static str, errno::Error),
|
||||||
|
#[error("failed writing to eventfd")]
|
||||||
EventFdWrite,
|
EventFdWrite,
|
||||||
|
#[error("failed reading from eventfd")]
|
||||||
EventFdRead,
|
EventFdRead,
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -62,22 +69,6 @@ impl Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for Error {}
|
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
Errno(err) => err.fmt(f),
|
|
||||||
InvalidOffset => write!(f, "attempt to access invalid offset into mapping"),
|
|
||||||
InvalidAddress(addr) => write!(f, "attempt to access invalid address: {0:16x}", addr),
|
|
||||||
OpenKvmFailed(err) => write!(f, "failed to open /dev/kvm: {}", err),
|
|
||||||
IoctlError(name, err) => write!(f, "failed to call {} ioctl: {}", name, err),
|
|
||||||
EventFdWrite => write!(f, "failed writing to eventfd"),
|
|
||||||
EventFdRead => write!(f, "failed reading from eventfd"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<errno::Error> for Error {
|
impl From<errno::Error> for Error {
|
||||||
fn from(err: errno::Error) -> Error {
|
fn from(err: errno::Error) -> Error {
|
||||||
Error::Errno(err)
|
Error::Errno(err)
|
||||||
|
@ -2,7 +2,7 @@ use std::cell::Cell;
|
|||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::{mem, result, fmt, io};
|
use std::{mem, result, io};
|
||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
@ -10,6 +10,8 @@ use libc::{
|
|||||||
PF_NETLINK, SOCK_RAW, SOCK_CLOEXEC, SOCK_NONBLOCK
|
PF_NETLINK, SOCK_RAW, SOCK_CLOEXEC, SOCK_NONBLOCK
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
const NETLINK_ROUTE: i32 = 0;
|
const NETLINK_ROUTE: i32 = 0;
|
||||||
|
|
||||||
const IFLA_IFNAME: u16 = 3;
|
const IFLA_IFNAME: u16 = 3;
|
||||||
@ -54,34 +56,26 @@ pub const IFF_UP: u32 = libc::IFF_UP as u32;
|
|||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("failed to create netlink socket: {0}")]
|
||||||
Socket(io::Error),
|
Socket(io::Error),
|
||||||
|
#[error("failed calling bind() on netlink socket: {0}")]
|
||||||
SocketBind(io::Error),
|
SocketBind(io::Error),
|
||||||
|
#[error("failed calling sendto() on netlink socket: {0}")]
|
||||||
SocketSend(io::Error),
|
SocketSend(io::Error),
|
||||||
|
#[error("failed calling recv() on netlink socket: {0}")]
|
||||||
SocketRecv(io::Error),
|
SocketRecv(io::Error),
|
||||||
|
#[error("failed to convert interface name to index: {0}")]
|
||||||
NameToIndex(io::Error),
|
NameToIndex(io::Error),
|
||||||
|
#[error("error response to netlink request: {0}")]
|
||||||
ErrorResponse(io::Error),
|
ErrorResponse(io::Error),
|
||||||
|
#[error("could not parse response message from netlink")]
|
||||||
UnexpectedResponse,
|
UnexpectedResponse,
|
||||||
|
#[error("failed to transmit entire netlink message")]
|
||||||
ShortSend,
|
ShortSend,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
Socket(e) => write!(f, "failed to create netlink socket: {}", e),
|
|
||||||
SocketBind(e) => write!(f, "failed calling bind() on netlink socket: {}", e),
|
|
||||||
SocketSend(e) => write!(f, "failed calling sendto() on netlink socket: {}", e),
|
|
||||||
SocketRecv(e) => write!(f, "failed calling recv() on netlink socket: {}", e),
|
|
||||||
NameToIndex(e) => write!(f, "failed to convert interface name to index: {}", e),
|
|
||||||
ErrorResponse(e) => write!(f, "error response to netlink request: {}", e),
|
|
||||||
UnexpectedResponse => write!(f, "could not parse response message from netlink"),
|
|
||||||
ShortSend => write!(f, "failed to transmit entire netlink message"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct NetlinkSocket {
|
pub struct NetlinkSocket {
|
||||||
sock: RawFd,
|
sock: RawFd,
|
||||||
seq: Cell<u32>,
|
seq: Cell<u32>,
|
||||||
|
@ -16,40 +16,32 @@ pub use self::chain::Chain;
|
|||||||
pub use self::device_config::DeviceConfigArea;
|
pub use self::device_config::DeviceConfigArea;
|
||||||
|
|
||||||
use byteorder::{ByteOrder,LittleEndian};
|
use byteorder::{ByteOrder,LittleEndian};
|
||||||
use std::{result, fmt};
|
use std::result;
|
||||||
use crate::{system, kvm};
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
CreateEventFd(system::Error),
|
#[error("failed to create EventFd for VirtQueue: {0}")]
|
||||||
CreateIoEventFd(kvm::Error),
|
CreateEventFd(std::io::Error),
|
||||||
ReadIoEventFd(system::Error),
|
#[error("failed to create IoEventFd for VirtQueue: {0}")]
|
||||||
IrqFd(kvm::Error),
|
CreateIoEventFd(kvm_ioctls::Error),
|
||||||
|
#[error("failed to read from IoEventFd: {0}")]
|
||||||
|
ReadIoEventFd(std::io::Error),
|
||||||
|
#[error("VirtQueue: {0}")]
|
||||||
|
IrqFd(kvm_ioctls::Error),
|
||||||
|
#[error("vring not enabled")]
|
||||||
VringNotEnabled,
|
VringNotEnabled,
|
||||||
|
#[error("vring descriptor table range is invalid 0x{0:x}")]
|
||||||
VringRangeInvalid(u64),
|
VringRangeInvalid(u64),
|
||||||
|
#[error("vring avail ring range range is invalid 0x{0:x}")]
|
||||||
VringAvailInvalid(u64),
|
VringAvailInvalid(u64),
|
||||||
|
#[error("vring used ring range is invalid 0x{0:x}")]
|
||||||
VringUsedInvalid(u64),
|
VringUsedInvalid(u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
CreateIoEventFd(e) => write!(f, "failed to create IoEventFd for VirtQueue: {}", e),
|
|
||||||
CreateEventFd(e) => write!(f, "failed to create EventFd for VirtQueue: {}", e),
|
|
||||||
ReadIoEventFd(e) => write!(f, "failed to read from IoEventFd: {}", e),
|
|
||||||
IrqFd(e) => write!(f, "VirtQueue: {}", e),
|
|
||||||
VringNotEnabled => write!(f, "vring is not enabled"),
|
|
||||||
VringRangeInvalid(addr) => write!(f, "vring descriptor table range is invalid 0x{:x}", addr),
|
|
||||||
VringAvailInvalid(addr) => write!(f, "vring avail ring range range is invalid 0x{:x}", addr),
|
|
||||||
VringUsedInvalid(addr) => write!(f, "vring used ring range is invalid 0x{:x}", addr),
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_config_buffer(config: &[u8], offset: usize, size: usize) -> u64 {
|
pub fn read_config_buffer(config: &[u8], offset: usize, size: usize) -> u64 {
|
||||||
if offset + size > config.len() {
|
if offset + size > config.len() {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,31 +1,29 @@
|
|||||||
use crate::{kvm, system, memory};
|
use crate::{system, memory};
|
||||||
use crate::system::ErrnoError;
|
use crate::system::ErrnoError;
|
||||||
use std::{fmt, result};
|
use std::result;
|
||||||
|
use kvm_ioctls::Cap;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("failed to create memory manager: {0}")]
|
||||||
MemoryManagerCreate(memory::Error),
|
MemoryManagerCreate(memory::Error),
|
||||||
MemoryRegister(kvm::Error),
|
#[error("failed to register memory region: {0}")]
|
||||||
|
MemoryRegister(kvm_ioctls::Error),
|
||||||
|
#[error("failed to create memory region: {0}")]
|
||||||
MemoryRegionCreate(system::Error),
|
MemoryRegionCreate(system::Error),
|
||||||
|
#[error("error loading kernel: {0}")]
|
||||||
LoadKernel(system::Error),
|
LoadKernel(system::Error),
|
||||||
KvmError(kvm::Error),
|
#[error("{0}")]
|
||||||
|
KvmError(kvm_ioctls::Error),
|
||||||
|
#[error("kernel does not support a required kvm extension: {0:?}")]
|
||||||
|
KvmMissingExtension(Cap),
|
||||||
|
#[error("{0}")]
|
||||||
SystemError(system::Error),
|
SystemError(system::Error),
|
||||||
|
#[error("failed to call {0} ioctl: {1}")]
|
||||||
IoctlError(&'static str, ErrnoError),
|
IoctlError(&'static str, ErrnoError),
|
||||||
}
|
#[error("error setting up vm: {0}")]
|
||||||
|
SetupError(kvm_ioctls::Error),
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
use Error::*;
|
|
||||||
match self {
|
|
||||||
MemoryManagerCreate(err) => write!(f, "failed to create memory manager: {}", err),
|
|
||||||
MemoryRegister(err) => write!(f, "failed to register memory region: {}", err),
|
|
||||||
MemoryRegionCreate(err) => write!(f, "failed to create memory region: {}", err),
|
|
||||||
LoadKernel(err) => write!(f, "error loading kernel: {}", err),
|
|
||||||
KvmError(e) => e.fmt(f),
|
|
||||||
SystemError(e) => e.fmt(f),
|
|
||||||
IoctlError(name, err) => write!(f, "failed to call {} ioctl: {}", name, err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
@ -1,48 +1,40 @@
|
|||||||
use std::{result, io};
|
use std::{result, io};
|
||||||
use std::fmt;
|
use kvm_ioctls::Cap;
|
||||||
use crate::{system, kvm, virtio};
|
use crate::{system, virtio};
|
||||||
use crate::system::netlink;
|
use crate::system::netlink;
|
||||||
use crate::vm::arch;
|
use crate::vm::arch;
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Error,Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
CreateVmFailed(kvm::Error),
|
#[error("failed to open kvm instance: {0}")]
|
||||||
|
KvmOpenError(kvm_ioctls::Error),
|
||||||
|
#[error("failed to create VM file descriptor: {0}")]
|
||||||
|
VmFdOpenError(kvm_ioctls::Error),
|
||||||
|
#[error("error on KVM operation: {0}")]
|
||||||
|
KvmError(kvm_ioctls::Error),
|
||||||
|
#[error("unexpected KVM version")]
|
||||||
|
BadVersion,
|
||||||
|
#[error("kernel does not support a required kvm extension: {0:?}")]
|
||||||
|
MissingRequiredExtension(Cap),
|
||||||
|
#[error("error configuring VM: {0}")]
|
||||||
|
VmSetup(kvm_ioctls::Error),
|
||||||
|
#[error("memory mapping failed: {0}")]
|
||||||
MappingFailed(system::Error),
|
MappingFailed(system::Error),
|
||||||
|
#[error("error reading/restoring terminal state: {0}")]
|
||||||
TerminalTermios(io::Error),
|
TerminalTermios(io::Error),
|
||||||
IoError(io::Error),
|
#[error("i/o error: {0}")]
|
||||||
|
IoError(#[from] io::Error),
|
||||||
|
#[error("{0}")]
|
||||||
ArchError(arch::Error),
|
ArchError(arch::Error),
|
||||||
NetworkSetup(netlink::Error),
|
#[error("error setting up network: {0}")]
|
||||||
|
NetworkSetup(#[from] netlink::Error),
|
||||||
|
#[error("setting up boot fs failed: {0}")]
|
||||||
SetupBootFs(io::Error),
|
SetupBootFs(io::Error),
|
||||||
|
#[error("setting up virtio devices failed: {0}")]
|
||||||
SetupVirtio(virtio::Error),
|
SetupVirtio(virtio::Error),
|
||||||
}
|
#[error("failed to create Vcpu: {0}")]
|
||||||
|
CreateVcpu(kvm_ioctls::Error),
|
||||||
|
}
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
Error::TerminalTermios(e) => write!(f, "error reading/restoring terminal state: {}", e),
|
|
||||||
Error::IoError(e) => write!(f, "i/o error: {}", e),
|
|
||||||
Error::NetworkSetup(e) => write!(f, "error setting up network: {}", e),
|
|
||||||
Error::CreateVmFailed(e) => write!(f, "call to create vm failed: {}", e),
|
|
||||||
Error::MappingFailed(e) => write!(f, "memory mapping failed: {}", e),
|
|
||||||
Error::SetupBootFs(e) => write!(f, "setting up boot fs failed: {}", e),
|
|
||||||
Error::SetupVirtio(e) => write!(f, "setting up virtio devices failed: {}", e),
|
|
||||||
Error::ArchError(e) => e.fmt(f),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<io::Error> for Error {
|
|
||||||
fn from(err: io::Error) -> Error {
|
|
||||||
Error::IoError(err).into()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<netlink::Error> for Error {
|
|
||||||
fn from(err: netlink::Error) -> Error {
|
|
||||||
Error::NetworkSetup(err).into()
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user