From 0ea1a9bb3f83072c1325fa6e8ca2ac1d3a8b26704ffe88adee033e5d5f58d449 Mon Sep 17 00:00:00 2001 From: Kira Date: Wed, 29 Jul 2026 15:34:52 +0200 Subject: [PATCH] Using blkid utility to determine dev name by gpt partlabel. --- src/main.rs | 28 ++++++++++++++++++---------- src/nyan_system.rs | 30 +++++++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/main.rs b/src/main.rs index fbe6648..d2cc0ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,7 +39,7 @@ use nyan_system::ExecCommandError; const BEE_CAT: &str = include_str!("bee_cat.txt"); //const ROOT_PARTLABEL: &str = "bee-root"; -const ROOT_DEV: &str = "/dev/disk/by-partlabel/bee-root"; +const ROOT_PARTLABEL: &str = "bee-root"; const TMP_ROOT: &str = "/mnt/bee_root"; const TMP_ROOT_SNAPS: &str = "/mnt/bee-root/bzz_snaps"; const SYS_INIT: &str = "/sbin/init"; @@ -74,9 +74,9 @@ enum NyanitState { } /// Mounting bee-root and chiking if there any snapshots -fn mount_and_check_snaps() -> Result { +fn mount_and_check_snaps(bee_root_dev: &str) -> Result { // mount bee-root - nyan_system::mount_bee_root(TMP_ROOT, ROOT_DEV)?; + nyan_system::mount_bee_root(TMP_ROOT, bee_root_dev)?; // list snaps if any let mut snaps_list = nyan_system::list_bzzpss_snaps(TMP_ROOT_SNAPS)?; @@ -90,23 +90,27 @@ fn mount_and_check_snaps() -> Result { Ok(NyanitState::HandOff(TMP_ROOT.into())) } -fn init_stage() -> Result { +fn init_stage() -> 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 + let bee_root_dev = nyan_system::find_partlabel(ROOT_PARTLABEL)?; // check if device is encrypted - if nyan_system::bzzpss_dev_encrypted(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(NyanitState::EnterPassword); + return Ok((bee_root_dev, NyanitState::EnterPassword)); } // if unencrypted - mount_and_check_snaps() + let check_res = mount_and_check_snaps(&bee_root_dev)?; + Ok((bee_root_dev, check_res)) } struct NyanitTUI<'a> { exit: bool, state: NyanitState, + bee_root_dev: String, list_state: ListState, time_counter: u32, textarea: Option>, @@ -117,6 +121,7 @@ impl NyanitTUI<'_> { Ok(Self { exit: false, state: NyanitState::Init, + bee_root_dev: String::new(), list_state: ListState::default().with_selected(Some(0)), time_counter: 0, textarea: None, @@ -126,7 +131,10 @@ impl NyanitTUI<'_> { /// runs the application's main loop until the user quits pub fn run(&mut self) -> io::Result<()> { self.state = match init_stage() { - Ok(st) => st, + Ok(res) => { + self.bee_root_dev = res.0; + res.1 + }, Err(ex) => { NyanitState::Error(format!("Error while trying to bzzz-pss things:\n{}", ex)) }, @@ -276,11 +284,11 @@ impl NyanitTUI<'_> { // try to unlock if enter pressed Event::Key(event::Key::Char('\n')) => { let password = self.textarea.as_ref().unwrap().lines()[0].clone(); - match nyan_system::bcachefs_unlock(password, ROOT_DEV) { + match nyan_system::bcachefs_unlock(password, &self.bee_root_dev) { Ok(unlocked) => { if unlocked { // need to check for subvolumes and stuff - self.state = match mount_and_check_snaps() { + self.state = match mount_and_check_snaps(&self.bee_root_dev) { Ok(st) => { self.time_counter = 0; st diff --git a/src/nyan_system.rs b/src/nyan_system.rs index a74f856..2b84a8a 100644 --- a/src/nyan_system.rs +++ b/src/nyan_system.rs @@ -110,6 +110,34 @@ pub fn exec_command(cmd: &str, args: &Vec<&str>) -> Result<(), ExecCommandError> } } +/// Gets device node aka /dev/sda1 from gpr partition label +/// blkid -s PARTLABEL --match-token "PARTLABEL=primary" +pub fn find_partlabel(partlabel: &str) -> Result { + let out = Command::new("/usr/bin/blkid") + .args([ + "-s", + "PARTLABEL", + "--match-token", + format!("\"PARTLABEL={}\"", partlabel).as_str(), + ]) + .output()?; + if out.status.success() { + let out_text = String::from_utf8(out.stdout)?; + + let split_res = out_text.split_once(':').ok_or_else(|| { + ExecCommandError::Other(format!("Unexpected blkid output format: \"{}\"", out_text)) + })?; + + Ok(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()) + ))) + } +} + /// exec given command with arguments, returning stdout parsed to UTF-8 string /// capturing stderr in case or failure // pub fn exec_command_out(cmd: &str, args: &Vec<&str>) -> Result { @@ -224,7 +252,7 @@ pub fn list_bzzpss_snaps(snaps_dir: &str) -> Result, ExecCommandErro // mount -t sysfs none /sys // modprobe bcachefs pub fn prepare_env() -> Result<(), String> { - use nix::mount::{mount, MsFlags}; + use nix::mount::{MsFlags, mount}; use std::path::Path;