forked from pop-os/distinst
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
34 changed files
with
2,628 additions
and
756 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[package] | ||
name = "disk-types" | ||
version = "0.1.5" | ||
authors = ["Jeremy Soller <[email protected]>", "Michael Aaron Murphy <[email protected]>"] | ||
description = "Common traits and types for handling block devices, partitions, file systems, etc." | ||
repository = "https://github.com/pop-os/disk-types" | ||
readme = "README.md" | ||
license = "MIT" | ||
keywords = ["disk", "partition"] | ||
categories = ["filesystem", "os"] | ||
edition = "2018" | ||
|
||
[dependencies] | ||
sys-mount = "1.2.1" | ||
tempdir = "0.3.7" | ||
os-detect = { path = "../os-detect" } | ||
sysfs-class = "0.1.2" | ||
libparted = "0.1.4" | ||
err-derive = "0.3" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
//! Detect whether a Linux system is in EFI or BIOS mode. | ||
//! | ||
//! ```rust,no_run | ||
//! use distinst_bootloader::Bootloader; | ||
//! | ||
//! match Bootloader::detect() { | ||
//! Bootloader::Efi => println!("System is in EFI mode"), | ||
//! Bootloader::Bios => println!("System is in BIOS mode") | ||
//! } | ||
//! ``` | ||
use std::path::Path; | ||
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering}; | ||
|
||
/// Force the installation to perform either a BIOS or EFI installation. | ||
pub static FORCE_BOOTLOADER: AtomicUsize = ATOMIC_USIZE_INIT; | ||
|
||
/// Bootloader type | ||
#[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||
pub enum Bootloader { | ||
Bios, | ||
Efi, | ||
} | ||
|
||
impl Bootloader { | ||
/// Detects whether the system is running from EFI. | ||
pub fn detect() -> Bootloader { | ||
match FORCE_BOOTLOADER.load(Ordering::SeqCst) { | ||
1 => { | ||
return Bootloader::Bios; | ||
} | ||
2 => { | ||
return Bootloader::Efi; | ||
} | ||
_ => () | ||
} | ||
|
||
if Path::new("/sys/firmware/efi").is_dir() { | ||
Bootloader::Efi | ||
} else { | ||
Bootloader::Bios | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use crate::fs::FileSystem; | ||
use std::io; | ||
use std::path::Path; | ||
use std::process::{Command, ExitStatus, Stdio}; | ||
|
||
pub trait Fscker { | ||
fn fsck(path: &Path, fs: FileSystem) -> Result<(), FsckError>; | ||
} | ||
|
||
#[derive(Debug, Error)] | ||
pub enum FsckError { | ||
#[error(display = "fsck I/O error: {:?}", _0)] | ||
Io(io::Error), | ||
#[error(display = "command failed with exit status: {}", _0)] | ||
BadStatus(ExitStatus), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
use std::{ | ||
cell::RefCell, | ||
fmt::Debug, | ||
fs::File, | ||
io::{self, Read}, | ||
path::{Path, PathBuf}, | ||
str::FromStr, | ||
}; | ||
use sysfs_class::{Block, SysClass}; | ||
|
||
/// Methods that all block devices share, whether they are partitions or disks. | ||
/// | ||
/// This trait is required to implement other disk traits. | ||
pub trait BlockDeviceExt { | ||
/// The sys path of the block device. | ||
fn sys_block_path(&self) -> PathBuf { sys_block_path(self.get_device_name(), "") } | ||
|
||
fn is_partition(&self) -> bool { | ||
sys_block_path(self.get_device_name(), "partition").exists() | ||
} | ||
|
||
/// Checks if the device is a read-only device. | ||
fn is_read_only(&self) -> bool { | ||
Block::from_path(&self.sys_block_path()) | ||
.ok() | ||
.map_or(false, |block| block.ro().ok() == Some(1)) | ||
} | ||
|
||
/// Checks if the device is a removable device. | ||
/// | ||
/// # Notes | ||
/// This is only applicable for disk devices. | ||
fn is_removable(&self) -> bool { | ||
Block::from_path(&self.sys_block_path()) | ||
.ok() | ||
.map_or(false, |block| block.removable().ok() == Some(1)) | ||
} | ||
|
||
/// Checks if the device is a rotational device. | ||
/// | ||
/// # Notes | ||
/// This is only applicable for disk devices. | ||
fn is_rotational(&self) -> bool { | ||
Block::from_path(&self.sys_block_path()) | ||
.ok() | ||
.map_or(false, |block| block.queue_rotational().ok() == Some(1)) | ||
} | ||
|
||
/// The path to the block device, such as `/dev/sda1`, or `/dev/data/root`. | ||
fn get_device_path(&self) -> &Path; | ||
|
||
/// The mount point of this block device, if it is mounted. | ||
fn get_mount_point(&self) -> Option<&Path> { None } | ||
|
||
/// The name of the device, such as `sda1`. | ||
fn get_device_name(&self) -> &str { | ||
self.get_device_path() | ||
.file_name() | ||
.expect("BlockDeviceExt::get_device_path missing file_name") | ||
.to_str() | ||
.expect("BlockDeviceExt::get_device_path invalid file_name") | ||
} | ||
|
||
/// The combined total number of sectors on the disk. | ||
fn get_sectors(&self) -> u64 { | ||
let size_file = sys_block_path(self.get_device_name(), "/size"); | ||
read_file::<u64>(&size_file).expect("no sector count found") | ||
} | ||
|
||
/// The size of each logical sector, in bytes. | ||
fn get_logical_block_size(&self) -> u64 { | ||
eprintln!("get block size for {:?}", self.sys_block_path()); | ||
|
||
let block = Block::from_path(&self.sys_block_path()) | ||
.expect("device lacks block"); | ||
|
||
match block.queue_logical_block_size() { | ||
Ok(size) => return size, | ||
Err(_) => { | ||
return Block::from_path(&self.sys_block_path()) | ||
.expect("partition does not have a block device") | ||
.parent_device() | ||
.expect("partition lacks parent block device") | ||
.queue_logical_block_size() | ||
.expect("parent of partition lacks logical block size"); | ||
} | ||
} | ||
} | ||
|
||
/// The size of each logical sector, in bytes. | ||
fn get_physical_block_size(&self) -> u64 { | ||
let path = sys_block_path(self.get_device_name(), "/queue/physical_block_size"); | ||
read_file::<u64>(&path).expect("physical block size not found") | ||
} | ||
} | ||
|
||
fn sys_block_path(name: &str, ppath: &str) -> PathBuf { | ||
PathBuf::from(["/sys/class/block/", name, ppath].concat()) | ||
} | ||
|
||
thread_local! { | ||
static BUFFER: RefCell<String> = String::with_capacity(256).into(); | ||
} | ||
|
||
fn read_file<T: FromStr>(path: &Path) -> io::Result<T> | ||
where | ||
<T as FromStr>::Err: Debug, | ||
{ | ||
BUFFER.with(|buffer| { | ||
let mut buffer = buffer.borrow_mut(); | ||
File::open(path)?.read_to_string(&mut buffer)?; | ||
let value = buffer.trim().parse::<T>(); | ||
buffer.clear(); | ||
value.map_err(|why| io::Error::new(io::ErrorKind::Other, format!("{:?}", why))) | ||
}) | ||
} |
Oops, something went wrong.