From 84d210d07c58e2f664e46248eafae1a6cd539094d37e2be1df85dfb156875378 Mon Sep 17 00:00:00 2001 From: Kira Date: Fri, 31 Jul 2026 15:54:54 +0200 Subject: [PATCH] blkid partlabel discovery now working. Also some cleanups. --- src/main.rs | 35 ++++------- src/nyan_system.rs | 146 ++++++++++++++++++++++++--------------------- 2 files changed, 90 insertions(+), 91 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1d0d09f..74a14b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,28 +90,20 @@ fn mount_and_check_snaps(bee_root_dev: &str) -> Result Result<(String, NyanitState), ExecCommandError> { // mount sysfss nyan_system::prepare_env().map_err(|ex| format!("prepare_env error: {}", ex))?; // get bee-root device name aka /dev/sda1 + // trying for max 3 sec + let bee_root_dev = nyan_system::try_find_partlabel(ROOT_PARTLABEL, 3) + .ok_or_else(|| "Timed out trying to find dev by partlabel.".to_string())?; - let mut maybe_bee_root_dev = nyan_system::find_partlabel(ROOT_PARTLABEL); - if maybe_bee_root_dev.is_err() { - for _i in 0u32..5 { - thread::sleep(Duration::from_millis(100)); - maybe_bee_root_dev = nyan_system::find_partlabel(ROOT_PARTLABEL); - if maybe_bee_root_dev.is_ok() { - break ; - } - } - } - - let bee_root_dev= maybe_bee_root_dev?; - + // works until this point!!!! // check if device is encrypted - if nyan_system::bzzpss_dev_encrypted(&bee_root_dev).map_err(|ex| format!("Error checking if device is encrypted: {}", ex))? { + if nyan_system::bzzpss_dev_encrypted(&bee_root_dev) + .map_err(|ex| format!("Error checking if device is encrypted: {}", ex))? + { // if encrypted return EnterPassword so used get promted for pass return Ok((bee_root_dev, NyanitState::EnterPassword)); } @@ -119,7 +111,6 @@ fn init_stage() -> Result<(String, NyanitState), ExecCommandError> { // if unencrypted let check_res = mount_and_check_snaps(&bee_root_dev)?; Ok((bee_root_dev, check_res)) - } struct NyanitTUI<'a> { @@ -148,12 +139,11 @@ impl NyanitTUI<'_> { self.state = match init_stage() { Ok(res) => { self.bee_root_dev = res.0; - //res.1 - NyanitState::Error(format!("bee_root_dev={} END EVERYTHING IS READY", self.bee_root_dev)) - }, + res.1 + } Err(ex) => { NyanitState::Error(format!("Error while trying to bzzz-pss things:\n{}", ex)) - }, + } }; // if drive unencrypted and there is no root snapshots finish boot @@ -304,7 +294,8 @@ impl NyanitTUI<'_> { Ok(unlocked) => { if unlocked { // need to check for subvolumes and stuff - self.state = match mount_and_check_snaps(&self.bee_root_dev) { + self.state = match mount_and_check_snaps(&self.bee_root_dev) + { Ok(st) => { self.time_counter = 0; st @@ -358,8 +349,6 @@ impl NyanitTUI<'_> { } } - - fn main() -> ExitCode { // nyan_system::set_env_vars_unsafe(); let mut app = NyanitTUI::new().unwrap(); diff --git a/src/nyan_system.rs b/src/nyan_system.rs index a758ebc..66fb991 100644 --- a/src/nyan_system.rs +++ b/src/nyan_system.rs @@ -22,7 +22,6 @@ use nix; use std::fs; use std::process::Command; - // timeout for block deices population const WAIT_FOR_BLK_DEVS: u64 = 5u64; @@ -114,16 +113,28 @@ pub fn exec_command(cmd: &str, args: &Vec<&str>) -> Result<(), ExecCommandError> } } +pub fn try_find_partlabel(partlabel: &str, timeout_secs: u64) -> Option { + use std::{thread, time::Duration}; + + let start = std::time::Instant::now(); + while start.elapsed().as_secs() < timeout_secs { + if let Ok(Some(label)) = find_partlabel(partlabel) { + return Some(label); + } + thread::sleep(Duration::from_millis(100)); + } + None +} + /// Gets device node aka /dev/sda1 from gpr partition label -/// blkid -s PARTLABEL --match-token "PARTLABEL=primary" -pub fn find_partlabel(partlabel: &str) -> Result { +/// blkid -s PARTLABEL --match-token PARTLABEL="bzz-primary" +pub fn find_partlabel(partlabel: &str) -> Result, ExecCommandError> { let out = Command::new("/usr/bin/blkid") .args([ - "--probe", "-s", "PARTLABEL", - "--match-token", - format!("\"PARTLABEL={}\"", partlabel).as_str(), + "-t", + format!("PARTLABEL=\"{}\"", partlabel).as_str(), ]) .output()?; if out.status.success() { @@ -133,28 +144,31 @@ pub fn find_partlabel(partlabel: &str) -> Result { ExecCommandError::Other(format!("Unexpected blkid output format: \"{}\"", out_text)) })?; - Ok(split_res.0.to_string()) + Ok(Some(split_res.0.to_string())) } else { - Err(ExecCommandError::Other(format!( - "Connot find device with partlabel={} or something other is wrong: \"{}\"", - partlabel, - String::from_utf8(out.stderr).unwrap_or_else(|_| String::new()) - ))) + if let Some(code) = out.status.code() + && code == 2 + { + Ok(None) + } else { + Err(ExecCommandError::Other(format!( + "Error while looking for partlabel={}: \"{}\"", + partlabel, + String::from_utf8(out.stderr).unwrap_or_else(|ex| ex.to_string()) + ))) + } } } +// pub fn list_dir(dirname: &str) -> Result { +// let res: String = fs::read_dir(dirname)? +// .filter_map(|entry| entry.ok()) +// .map(|entry| entry.file_name().to_string_lossy().to_string()) +// .collect::>() +// .join("\n"); -pub fn list_partlabel() -> Result { - let out = Command::new("/usr/bin/blkid") - .args(["--probe", "-s", "PARTLABEL"]) - .output()?; - if out.status.success() { - let out_text = String::from_utf8(out.stdout)?; - Ok(out_text) - } else { - Err(ExecCommandError::Other("Oh no".to_string())) - } -} +// Ok(res) +// } /// exec given command with arguments, returning stdout parsed to UTF-8 string /// capturing stderr in case or failure @@ -167,21 +181,6 @@ pub fn list_partlabel() -> Result { // } // } -// ls /dev/disk/by-partlabel/ -// here we can find gpt part labels -// pub fn list_gpt_labeled_devs() -> Result, ExecCommandError> { -// use std::os::unix::fs::FileTypeExt; -// let mut res: Vec = Vec::new(); -// for maybe_entry in fs::read_dir("/dev/disk/by-partlabel/")? { -// let entry = maybe_entry?; -// if entry.file_type()?.is_block_device() { -// res.push(entry.path().to_str().unwrap().to_string()); -// } -// } - -// Ok(res) -// } - /// bcachefs unlock --file=/tmp/bzzpsspass.txt /dev/loop0somedev /// Ok so. It is stupid, because bcacheutils far from ideal. /// But if we provide wrong password from file or stdin this stuff plays stupid and asks for right password. @@ -247,10 +246,17 @@ pub fn bzzpss_dev_encrypted(dev_name: &str) -> Result { //const TMP_ROOT: &str = "/mnt/bee-root"; pub fn list_bzzpss_snaps(snaps_dir: &str) -> Result, ExecCommandError> { use regex::Regex; + use std::path::Path; + // root snapshoot in a form of bzz-yyyy-mm-ddTHH-MM-SS let re = Regex::new(r"^bzz-[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}-[0-9]{2}-[0-9]{2}$").unwrap(); let mut res: Vec = Vec::new(); + // if snaps dir path do not exist return empty list + if !Path::new(snaps_dir).exists() { + return Ok(res); + } + for maybe_entry in fs::read_dir(snaps_dir)? { let entry = maybe_entry?; if entry.file_type()?.is_dir() { @@ -264,7 +270,6 @@ pub fn list_bzzpss_snaps(snaps_dir: &str) -> Result, ExecCommandErro Ok(res) } - // pulls /sys/class/block fn wait_for_block_devices(timeout_secs: u64) -> bool { use std::path::Path; @@ -274,7 +279,9 @@ fn wait_for_block_devices(timeout_secs: u64) -> bool { while start.elapsed().as_secs() < timeout_secs { // Check if any block device exists (e.g., sda, nvme0n1, vda) // You can refine this to check for a specific device needed for root - if Path::new("/sys/class/block").read_dir().ok() + if Path::new("/sys/class/block") + .read_dir() + .ok() .and_then(|mut d| d.next().is_some().then_some(true)) .unwrap_or(false) { @@ -299,25 +306,30 @@ pub fn prepare_env() -> Result<(), String> { // Mount proc filesystem // mount -t proc none /proc + let proc_mount_flags = + MsFlags::MS_NOSUID | MsFlags::MS_NODEV | MsFlags::MS_NOEXEC | MsFlags::MS_RELATIME; mount( Some("proc"), Path::new("/proc"), Some("proc"), - MsFlags::empty(), - None::<&str>, + proc_mount_flags, + Some("mode=0555"), ) .map_err(|ex| format!("Error mounting /proc: {}", ex.to_string()))?; // mount -t sysfs none /sys + let sys_mount_flags = + MsFlags::MS_NOSUID | MsFlags::MS_NODEV | MsFlags::MS_NOEXEC | MsFlags::MS_RELATIME; mount( Some("sysfs"), Path::new("/sys"), Some("sysfs"), - MsFlags::empty(), - None::<&str>, + sys_mount_flags, + Some("mode=0555"), ) .map_err(|ex| format!("Error mounting /sys: {}", ex.to_string()))?; + //waiting for block devs population if wait_for_block_devices(WAIT_FOR_BLK_DEVS) == false { return Err("Waiting for block devices to get populated timed out.".to_string()); } @@ -332,8 +344,6 @@ pub fn prepare_env() -> Result<(), String> { ) .map_err(|ex| format!("Error mounting /dev: {}", ex.to_string()))?; - - // modprobe bcachefs // exec_command("modprobe", &vec!["bcachefs"])?; Ok(()) @@ -341,31 +351,31 @@ pub fn prepare_env() -> Result<(), String> { /// /// MUST be done before spawning any threads or async runtimes -pub fn set_env_vars_unsafe() -> () { - use std::env; - // 1. Define your custom paths - let custom_bin = "/usr/bin"; - let custom_lib = "/usr/lib"; +// pub fn set_env_vars_unsafe() -> () { +// use std::env; +// // 1. Define your custom paths +// let custom_bin = "/usr/bin"; +// let custom_lib = "/usr/lib"; - // 2. Retrieve existing paths to append/prepend (optional but recommended) - // 3. Construct new path strings - let new_path = match env::var("PATH") { - Err(_) => custom_bin.to_string(), - Ok(v) => format!("{}:{}", custom_bin, v), - }; +// // 2. Retrieve existing paths to append/prepend (optional but recommended) +// // 3. Construct new path strings +// let new_path = match env::var("PATH") { +// Err(_) => custom_bin.to_string(), +// Ok(v) => format!("{}:{}", custom_bin, v), +// }; - let new_ld_path = match env::var("LD_LIBRARY_PATH") { - Err(_) => custom_lib.to_string(), - Ok(v) => format!("{}:{}", custom_lib, v), - }; +// let new_ld_path = match env::var("LD_LIBRARY_PATH") { +// Err(_) => custom_lib.to_string(), +// Ok(v) => format!("{}:{}", custom_lib, v), +// }; - // 4. Set environment variables (UNSAFE in Rust 2024+) - // MUST be done before spawning any threads or async runtimes - unsafe { - env::set_var("PATH", new_path); - env::set_var("LD_LIBRARY_PATH", new_ld_path); - } -} +// // 4. Set environment variables (UNSAFE in Rust 2024+) +// // MUST be done before spawning any threads or async runtimes +// unsafe { +// env::set_var("PATH", new_path); +// env::set_var("LD_LIBRARY_PATH", new_ld_path); +// } +// } // # Mount the real root filesystem pub fn mount_bee_root(mount_point: &str, dev_name: &str) -> Result<(), ExecCommandError> {