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 crate::kira_size::KiraSize;
|
||||||
use log;
|
use log;
|
||||||
use std::{collections::HashMap};
|
use std::collections::HashMap;
|
||||||
///
|
///
|
||||||
/// size - device size in bytes
|
/// size - device size in bytes
|
||||||
/// sector size - default 4096
|
/// sector size - default 4096
|
||||||
@@ -124,13 +124,18 @@ pub struct BcachefsProp {
|
|||||||
|
|
||||||
impl BcachefsProp {
|
impl BcachefsProp {
|
||||||
pub fn new(password: Option<String>, comp_alg: Option<String>) -> Self {
|
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 {
|
pub fn default() -> Self {
|
||||||
Self { password: None, comp_alg: None }
|
Self {
|
||||||
|
password: None,
|
||||||
|
comp_alg: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
@@ -208,7 +213,7 @@ impl FSType {
|
|||||||
pub enum PartRole {
|
pub enum PartRole {
|
||||||
EFI,
|
EFI,
|
||||||
ROOT,
|
ROOT,
|
||||||
SWAP
|
SWAP,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
@@ -230,6 +235,22 @@ impl std::fmt::Display for PartInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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> {
|
pub fn from_hash_map(data: &HashMap<String, String>) -> Option<Self> {
|
||||||
Some(Self {
|
Some(Self {
|
||||||
name: data.get("NAME")?.clone(),
|
name: data.get("NAME")?.clone(),
|
||||||
@@ -250,7 +271,9 @@ impl PartInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn partlabel_dev(&self) -> Option<String> {
|
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
|
// decreasing end if not align
|
||||||
let part_end = align_start + size;
|
let part_end = align_start + size;
|
||||||
let end_mod = part_end % align;
|
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_end = part_end - end_mod - 1;
|
||||||
|
|
||||||
let align_size = align_end - align_start + 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;
|
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))
|
Some((align_size, align_start, align_end))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,10 +382,16 @@ pub struct PartLayout {
|
|||||||
pub part_list: Vec<PartInfo>,
|
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 {
|
impl PartLayout {
|
||||||
pub fn new(dev: BlkDev) -> Self {
|
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 {
|
Self {
|
||||||
empty_space: dev.size,
|
empty_space: usable_space,
|
||||||
dev: dev,
|
dev: dev,
|
||||||
part_list: Vec::new(),
|
part_list: Vec::new(),
|
||||||
}
|
}
|
||||||
@@ -374,11 +409,11 @@ impl PartLayout {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_table(mut self) -> Self {
|
// pub fn new_table(mut self) -> Self {
|
||||||
self.empty_space = self.dev.size;
|
// self.empty_space = self.dev.size;
|
||||||
self.part_list = Vec::new();
|
// self.part_list = Vec::new();
|
||||||
self
|
// self
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn add_part(
|
pub fn add_part(
|
||||||
mut self,
|
mut self,
|
||||||
@@ -390,19 +425,29 @@ impl PartLayout {
|
|||||||
role: Option<PartRole>,
|
role: Option<PartRole>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let part_start = if self.part_list.is_empty() {
|
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)
|
KiraSize::new_mb(2)
|
||||||
} else {
|
} 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();
|
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);
|
let part_name = format!("{}p{}", self.dev.name, self.part_list.len() + 1);
|
||||||
self.part_list.push(PartInfo {
|
self.part_list.push(PartInfo {
|
||||||
name: part_name,
|
name: part_name,
|
||||||
size: KiraSize::new_b(size),
|
size: KiraSize::new_b(a_size),
|
||||||
start: KiraSize::new_b(start),
|
start: KiraSize::new_b(a_start),
|
||||||
fs_type: fs_type,
|
fs_type: fs_type,
|
||||||
gpt_label: gpt_label,
|
gpt_label: gpt_label,
|
||||||
fs_label: fs_label,
|
fs_label: fs_label,
|
||||||
@@ -410,10 +455,14 @@ impl PartLayout {
|
|||||||
role: role,
|
role: role,
|
||||||
});
|
});
|
||||||
|
|
||||||
self.empty_space = self.empty_space - KiraSize::new_b(size);
|
self.empty_space = self.empty_space - KiraSize::new_b(a_size);
|
||||||
|
|
||||||
self
|
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(
|
pub fn add_part_reserve(
|
||||||
self,
|
self,
|
||||||
reserve_space: KiraSize,
|
reserve_space: KiraSize,
|
||||||
@@ -427,7 +476,13 @@ impl PartLayout {
|
|||||||
self.add_part(p_size, fs_type, gpt_label, fs_label, mount_point, role)
|
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);
|
let mut res: PartLayout = PartLayout::new(dev);
|
||||||
|
|
||||||
// UEFI partition
|
// UEFI partition
|
||||||
@@ -465,7 +520,6 @@ impl PartLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use rand::RngExt;
|
use rand::RngExt;
|
||||||
|
|||||||
+25
-14
@@ -19,18 +19,25 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::kira_disk_layout::*;
|
use crate::kira_disk_layout::*;
|
||||||
use std::process::Command;
|
use crate::kira_size::KiraSize;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CommandFailed{
|
pub struct CommandFailed {
|
||||||
stderr: Vec<u8>,
|
stderr: Vec<u8>,
|
||||||
cmd: String,
|
cmd: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for CommandFailed {
|
impl std::fmt::Display for CommandFailed {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
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
|
/// Install base system
|
||||||
/// basestrap /mnt base base-devel dinit elogind-dinit
|
/// basestrap /mnt base base-devel dinit elogind-dinit
|
||||||
pub fn basestrap_dinit(root_dir: &str) -> Result<(), ExecCommandError> {
|
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
|
/// Executes parted command with given arguments
|
||||||
@@ -151,12 +161,7 @@ fn parted_get_last_part_num(dev: &BlkDev) -> Result<u32, ExecCommandError> {
|
|||||||
/// Its blocking function
|
/// Its blocking function
|
||||||
pub fn parted_init_gpt_part_table(dev: &BlkDev) -> Result<(), ExecCommandError> {
|
pub fn parted_init_gpt_part_table(dev: &BlkDev) -> Result<(), ExecCommandError> {
|
||||||
let dev_full_name = dev.full_name();
|
let dev_full_name = dev.full_name();
|
||||||
let args = vec![
|
let args = vec!["--script", &dev_full_name, "mklabel", "gpt"];
|
||||||
"--script",
|
|
||||||
&dev_full_name,
|
|
||||||
"mklabel",
|
|
||||||
"gpt",
|
|
||||||
];
|
|
||||||
exec_command("parted", &args)
|
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)
|
/// It assumes that we add partitions sequentially to empty space (for part attributes settings)
|
||||||
/// Otherwise can produce bonkers layout
|
/// Otherwise can produce bonkers layout
|
||||||
pub fn parted_mkpart(dev: &BlkDev, part: &PartInfo) -> Result<(), ExecCommandError> {
|
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
|
// gpt label should be in double qutes
|
||||||
let gpt_label = if let Some(s) = &part.gpt_label {
|
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 {
|
} else {
|
||||||
"\"\"".to_string()
|
"\"\"".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
|
// creating partition
|
||||||
exec_parted(&vec![
|
exec_parted(&vec![
|
||||||
"--script",
|
"--script",
|
||||||
@@ -255,13 +269,11 @@ pub fn bcachefs_format(
|
|||||||
|
|
||||||
/// unlok encrypted bcache volume
|
/// unlok encrypted bcache volume
|
||||||
pub fn bcachefs_unlock(dev_name: &str, pass: &str) -> Result<(), ExecCommandError> {
|
pub fn bcachefs_unlock(dev_name: &str, pass: &str) -> Result<(), ExecCommandError> {
|
||||||
|
|
||||||
// bcachefs unlock --file=/tmp/bzzpsspass.txt /dev/loop0
|
// bcachefs unlock --file=/tmp/bzzpsspass.txt /dev/loop0
|
||||||
let arg = vec!["unlock", "--file=/tmp/bzzpsspass.txt ", dev_name];
|
let arg = vec!["unlock", "--file=/tmp/bzzpsspass.txt ", dev_name];
|
||||||
// creating tmp file with password
|
// creating tmp file with password
|
||||||
fs::write("/tmp/bzzpsspass.txt", &pass)?;
|
fs::write("/tmp/bzzpsspass.txt", &pass)?;
|
||||||
|
|
||||||
|
|
||||||
let out = exec_command("bcachefs", &arg);
|
let out = exec_command("bcachefs", &arg);
|
||||||
// ignore any errors while deleting pass tmp file
|
// ignore any errors while deleting pass tmp file
|
||||||
let _ = fs::remove_file("/tmp/bzzpsspass.txt");
|
let _ = fs::remove_file("/tmp/bzzpsspass.txt");
|
||||||
@@ -304,7 +316,6 @@ pub fn mkfs_esp(dev: &str) -> Result<(), ExecCommandError> {
|
|||||||
mkfs_fat32(dev, Some("ESP"))
|
mkfs_fat32(dev, Some("ESP"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn mkswap(dev: &str) -> Result<(), ExecCommandError> {
|
pub fn mkswap(dev: &str) -> Result<(), ExecCommandError> {
|
||||||
//mkswap -L SWAP /dev/sda4
|
//mkswap -L SWAP /dev/sda4
|
||||||
exec_command("mkswap", &vec!["L", "SWAP", dev])
|
exec_command("mkswap", &vec!["L", "SWAP", dev])
|
||||||
|
|||||||
Reference in New Issue
Block a user