SHA256
Work on making partitions start-end calculate properly. Specifically 2mb at start and -33 sectors GPT reserved at the end.
This commit is contained in:
+75
-21
@@ -20,7 +20,7 @@
|
||||
|
||||
use crate::kira_size::KiraSize;
|
||||
use log;
|
||||
use std::{collections::HashMap};
|
||||
use std::collections::HashMap;
|
||||
///
|
||||
/// size - device size in bytes
|
||||
/// sector size - default 4096
|
||||
@@ -124,13 +124,18 @@ pub struct BcachefsProp {
|
||||
|
||||
impl BcachefsProp {
|
||||
pub fn new(password: Option<String>, comp_alg: Option<String>) -> Self {
|
||||
Self { password:password, comp_alg: comp_alg }
|
||||
Self {
|
||||
password: password,
|
||||
comp_alg: comp_alg,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default() -> Self {
|
||||
Self { password: None, comp_alg: None }
|
||||
Self {
|
||||
password: None,
|
||||
comp_alg: None,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@@ -208,7 +213,7 @@ impl FSType {
|
||||
pub enum PartRole {
|
||||
EFI,
|
||||
ROOT,
|
||||
SWAP
|
||||
SWAP,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@@ -230,6 +235,22 @@ impl std::fmt::Display for PartInfo {
|
||||
}
|
||||
|
||||
impl PartInfo {
|
||||
///
|
||||
/// calculate par end byte as 0 starting bytes index (for parted and such)
|
||||
///
|
||||
pub fn part_end(&self) -> KiraSize {
|
||||
// important to shift here by 1 because disk index is starting from 0, and part end pointing to last byte of the partition.
|
||||
(self.start + self.size) - KiraSize::new_b(1)
|
||||
}
|
||||
|
||||
///
|
||||
/// Returns zero based byte index of start of next (right after this one) partition
|
||||
///
|
||||
pub fn next_part_start(&self) -> KiraSize {
|
||||
// important to shift here by 1 because disk index is starting from 0, and part end pointing to last byte of the partition.
|
||||
self.start + self.size
|
||||
}
|
||||
|
||||
pub fn from_hash_map(data: &HashMap<String, String>) -> Option<Self> {
|
||||
Some(Self {
|
||||
name: data.get("NAME")?.clone(),
|
||||
@@ -250,7 +271,9 @@ impl PartInfo {
|
||||
}
|
||||
|
||||
pub fn partlabel_dev(&self) -> Option<String> {
|
||||
self.gpt_label.as_ref().and_then(|l| Some(format!("/dev/disk/by-partlabel/{}", l)))
|
||||
self.gpt_label
|
||||
.as_ref()
|
||||
.and_then(|l| Some(format!("/dev/disk/by-partlabel/{}", l)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,7 +352,7 @@ pub fn align_part(size: u64, start: u64, align: u64) -> Option<(u64, u64, u64)>
|
||||
// decreasing end if not align
|
||||
let part_end = align_start + size;
|
||||
let end_mod = part_end % align;
|
||||
log::debug!("part_end: {} end_mod: {}", part_end, end_mod);
|
||||
|
||||
let align_end = part_end - end_mod - 1;
|
||||
|
||||
let align_size = align_end - align_start + 1;
|
||||
@@ -342,7 +365,13 @@ pub fn align_part(size: u64, start: u64, align: u64) -> Option<(u64, u64, u64)>
|
||||
);
|
||||
return None;
|
||||
}
|
||||
|
||||
log::debug!(
|
||||
"align_size: {}, align_start:{}, align_end: {} end_mod: {}",
|
||||
align_size,
|
||||
align_start,
|
||||
align_end,
|
||||
end_mod
|
||||
);
|
||||
Some((align_size, align_start, align_end))
|
||||
}
|
||||
|
||||
@@ -353,10 +382,16 @@ pub struct PartLayout {
|
||||
pub part_list: Vec<PartInfo>,
|
||||
}
|
||||
|
||||
///
|
||||
/// GPT requires 33x512 sectors at the very end of the disk (16,896 bytes = 16.5 KiB):
|
||||
/// 32 sectors — backup Partition Entry Array (128 entries × 128 bytes = 16,384 bytes)
|
||||
/// 1 sector — backup GPT header
|
||||
impl PartLayout {
|
||||
pub fn new(dev: BlkDev) -> Self {
|
||||
// 16896 - reserved space at the dev end for gpt
|
||||
let usable_space = dev.size - KiraSize::new_b(16896);
|
||||
Self {
|
||||
empty_space: dev.size,
|
||||
empty_space: usable_space,
|
||||
dev: dev,
|
||||
part_list: Vec::new(),
|
||||
}
|
||||
@@ -374,11 +409,11 @@ impl PartLayout {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new_table(mut self) -> Self {
|
||||
self.empty_space = self.dev.size;
|
||||
self.part_list = Vec::new();
|
||||
self
|
||||
}
|
||||
// pub fn new_table(mut self) -> Self {
|
||||
// self.empty_space = self.dev.size;
|
||||
// self.part_list = Vec::new();
|
||||
// self
|
||||
// }
|
||||
|
||||
pub fn add_part(
|
||||
mut self,
|
||||
@@ -390,19 +425,29 @@ impl PartLayout {
|
||||
role: Option<PartRole>,
|
||||
) -> Self {
|
||||
let part_start = if self.part_list.is_empty() {
|
||||
// need to substract 2 mb offset from disk start.
|
||||
self.empty_space = self.empty_space - KiraSize::new_mb(2);
|
||||
KiraSize::new_mb(2)
|
||||
} else {
|
||||
self.dev.size - self.empty_space
|
||||
// last part end + 1
|
||||
self.part_list.last().unwrap().next_part_start()
|
||||
};
|
||||
|
||||
let (size, start, _) =
|
||||
let (a_size, a_start, _) =
|
||||
align_part(part_size.b(), part_start.b(), self.dev.sector_size.b()).unwrap();
|
||||
|
||||
log::debug!(
|
||||
"PartLayout.add_part gpt_label{:?}, size_asked:{}, size_al:{}",
|
||||
gpt_label,
|
||||
part_size,
|
||||
a_size
|
||||
);
|
||||
|
||||
let part_name = format!("{}p{}", self.dev.name, self.part_list.len() + 1);
|
||||
self.part_list.push(PartInfo {
|
||||
name: part_name,
|
||||
size: KiraSize::new_b(size),
|
||||
start: KiraSize::new_b(start),
|
||||
size: KiraSize::new_b(a_size),
|
||||
start: KiraSize::new_b(a_start),
|
||||
fs_type: fs_type,
|
||||
gpt_label: gpt_label,
|
||||
fs_label: fs_label,
|
||||
@@ -410,10 +455,14 @@ impl PartLayout {
|
||||
role: role,
|
||||
});
|
||||
|
||||
self.empty_space = self.empty_space - KiraSize::new_b(size);
|
||||
self.empty_space = self.empty_space - KiraSize::new_b(a_size);
|
||||
|
||||
self
|
||||
}
|
||||
///
|
||||
/// Use this to add partition of (disk_empty_space - reserve_space)
|
||||
/// Specifically to leave some space at the end for SWAP and such
|
||||
///
|
||||
pub fn add_part_reserve(
|
||||
self,
|
||||
reserve_space: KiraSize,
|
||||
@@ -427,7 +476,13 @@ impl PartLayout {
|
||||
self.add_part(p_size, fs_type, gpt_label, fs_label, mount_point, role)
|
||||
}
|
||||
|
||||
pub fn gen_kira_layout(dev: BlkDev, efi_size: KiraSize, swap_size: KiraSize, maybe_password: Option<String>, maybe_compr: Option<String>) -> Self {
|
||||
pub fn gen_kira_layout(
|
||||
dev: BlkDev,
|
||||
efi_size: KiraSize,
|
||||
swap_size: KiraSize,
|
||||
maybe_password: Option<String>,
|
||||
maybe_compr: Option<String>,
|
||||
) -> Self {
|
||||
let mut res: PartLayout = PartLayout::new(dev);
|
||||
|
||||
// UEFI partition
|
||||
@@ -465,7 +520,6 @@ impl PartLayout {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rand::RngExt;
|
||||
|
||||
+24
-13
@@ -19,8 +19,9 @@
|
||||
*/
|
||||
|
||||
use crate::kira_disk_layout::*;
|
||||
use std::process::Command;
|
||||
use crate::kira_size::KiraSize;
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CommandFailed {
|
||||
@@ -30,7 +31,13 @@ pub struct CommandFailed{
|
||||
|
||||
impl std::fmt::Display for CommandFailed {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "Command failed! Command: {}; Stderr: {}", self.cmd, String::from_utf8(self.stderr.clone()).unwrap_or_else(|_|{"STDEER IS NOT VALID UTF-8".to_string()}))
|
||||
write!(
|
||||
f,
|
||||
"Command failed! Command: {}; Stderr: {}",
|
||||
self.cmd,
|
||||
String::from_utf8(self.stderr.clone())
|
||||
.unwrap_or_else(|_| { "STDEER IS NOT VALID UTF-8".to_string() })
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +131,10 @@ pub fn dinit_sync_time_chrony() -> Result<(), ExecCommandError> {
|
||||
/// Install base system
|
||||
/// basestrap /mnt base base-devel dinit elogind-dinit
|
||||
pub fn basestrap_dinit(root_dir: &str) -> Result<(), ExecCommandError> {
|
||||
exec_command("basestrap", &vec![root_dir, "base", "base-devel", "dinit", "elogind-dinit"])
|
||||
exec_command(
|
||||
"basestrap",
|
||||
&vec![root_dir, "base", "base-devel", "dinit", "elogind-dinit"],
|
||||
)
|
||||
}
|
||||
|
||||
/// Executes parted command with given arguments
|
||||
@@ -151,12 +161,7 @@ fn parted_get_last_part_num(dev: &BlkDev) -> Result<u32, ExecCommandError> {
|
||||
/// Its blocking function
|
||||
pub fn parted_init_gpt_part_table(dev: &BlkDev) -> Result<(), ExecCommandError> {
|
||||
let dev_full_name = dev.full_name();
|
||||
let args = vec![
|
||||
"--script",
|
||||
&dev_full_name,
|
||||
"mklabel",
|
||||
"gpt",
|
||||
];
|
||||
let args = vec!["--script", &dev_full_name, "mklabel", "gpt"];
|
||||
exec_command("parted", &args)
|
||||
}
|
||||
|
||||
@@ -166,7 +171,8 @@ const LINUX_ROOT_X86_64_TYPE: &str = "4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709";
|
||||
/// It assumes that we add partitions sequentially to empty space (for part attributes settings)
|
||||
/// Otherwise can produce bonkers layout
|
||||
pub fn parted_mkpart(dev: &BlkDev, part: &PartInfo) -> Result<(), ExecCommandError> {
|
||||
let part_end = part.start + part.size;
|
||||
// important to shift here by 1 because disk index is starting from 0, and part end pointing to last byte of the partition.
|
||||
let part_end = part.part_end();
|
||||
|
||||
// gpt label should be in double qutes
|
||||
let gpt_label = if let Some(s) = &part.gpt_label {
|
||||
@@ -174,6 +180,14 @@ pub fn parted_mkpart(dev: &BlkDev, part: &PartInfo) -> Result<(), ExecCommandErr
|
||||
} else {
|
||||
"\"\"".to_string()
|
||||
};
|
||||
log::debug!(
|
||||
"Creatin partition dev:{}, label:{}, fs_type:{}, start:{}, end:{}",
|
||||
dev.full_name(),
|
||||
gpt_label,
|
||||
part.fs_type.to_parted_str(),
|
||||
part.start.to_parted_bytes_str(),
|
||||
part_end.to_parted_bytes_str()
|
||||
);
|
||||
// creating partition
|
||||
exec_parted(&vec![
|
||||
"--script",
|
||||
@@ -255,13 +269,11 @@ pub fn bcachefs_format(
|
||||
|
||||
/// unlok encrypted bcache volume
|
||||
pub fn bcachefs_unlock(dev_name: &str, pass: &str) -> Result<(), ExecCommandError> {
|
||||
|
||||
// bcachefs unlock --file=/tmp/bzzpsspass.txt /dev/loop0
|
||||
let arg = vec!["unlock", "--file=/tmp/bzzpsspass.txt ", dev_name];
|
||||
// creating tmp file with password
|
||||
fs::write("/tmp/bzzpsspass.txt", &pass)?;
|
||||
|
||||
|
||||
let out = exec_command("bcachefs", &arg);
|
||||
// ignore any errors while deleting pass tmp file
|
||||
let _ = fs::remove_file("/tmp/bzzpsspass.txt");
|
||||
@@ -304,7 +316,6 @@ pub fn mkfs_esp(dev: &str) -> Result<(), ExecCommandError> {
|
||||
mkfs_fat32(dev, Some("ESP"))
|
||||
}
|
||||
|
||||
|
||||
pub fn mkswap(dev: &str) -> Result<(), ExecCommandError> {
|
||||
//mkswap -L SWAP /dev/sda4
|
||||
exec_command("mkswap", &vec!["L", "SWAP", dev])
|
||||
|
||||
Reference in New Issue
Block a user