Loop device support

This commit is contained in:
Roey Darwish Dror
2019-06-17 20:34:24 +03:00
parent 379f11af42
commit d4cdd187a0
8 changed files with 192 additions and 10 deletions

View File

@@ -0,0 +1,52 @@
use crate::error::{Error, ErrorKind};
use crate::tool::Tool;
use failure::ResultExt;
use log::info;
use std::path::{Path, PathBuf};
#[derive(Debug)]
pub struct LoopDevice {
path: PathBuf,
losetup: Tool,
}
impl LoopDevice {
pub fn create(file: &Path) -> Result<Self, Error> {
let losetup = Tool::find("losetup")?;
let output = losetup
.execute()
.args(&["--find", "-P", "--show"])
.arg(file)
.output()
.context(ErrorKind::Image)?;
if !output.status.success() {
Err(ErrorKind::Losetup(
String::from_utf8(output.stderr).unwrap(),
))?
}
Ok(LoopDevice {
path: PathBuf::from(String::from_utf8(output.stdout).unwrap().trim()),
losetup,
})
}
pub fn path(&self) -> &Path {
&self.path
}
}
impl Drop for LoopDevice {
fn drop(&mut self) {
info!("Detaching loop device {}", self.path.display());
self.losetup
.execute()
.arg("-d")
.arg(&self.path)
.spawn()
.unwrap()
.wait()
.ok();
}
}

View File

@@ -1,5 +1,6 @@
mod crypt;
mod filesystem;
mod loop_device;
mod markers;
mod mount_stack;
mod partition;
@@ -7,6 +8,7 @@ mod storage_device;
pub use crypt::EncryptedDevice;
pub use filesystem::{Filesystem, FilesystemType};
pub use loop_device::LoopDevice;
pub use markers::BlockDevice;
pub use mount_stack::MountStack;
pub use storage_device::StorageDevice;

View File

@@ -4,16 +4,18 @@ use crate::error::{Error, ErrorKind};
use failure::ResultExt;
use log::debug;
use std::fs::read_to_string;
use std::marker::PhantomData;
use std::path::{Path, PathBuf};
#[derive(Debug)]
pub struct StorageDevice {
pub struct StorageDevice<'a> {
name: String,
path: PathBuf,
origin: PhantomData<&'a Origin>,
}
impl StorageDevice {
pub fn from_path(path: PathBuf) -> Result<Self, Error> {
impl<'a> StorageDevice<'a> {
pub fn from_path(path: &'a Path) -> Result<Self, Error> {
let real_path = path.canonicalize().context(ErrorKind::DeviceQuery)?;
let device_name = real_path
.file_name()
@@ -30,6 +32,7 @@ impl StorageDevice {
let _self = Self {
name: device_name,
path: real_path,
origin: PhantomData,
};
if !(_self.is_removable_device()? || _self.is_loop_device()) {
return Err(ErrorKind::DangerousDevice)?;
@@ -78,10 +81,10 @@ impl StorageDevice {
}
}
impl BlockDevice for StorageDevice {
impl<'a> BlockDevice for StorageDevice<'a> {
fn path(&self) -> &Path {
&self.path
}
}
impl Origin for StorageDevice {}
impl<'a> Origin for StorageDevice<'a> {}