Adding function to perform bcachfs unlock.

This commit is contained in:
2026-06-23 18:34:46 +02:00
parent c758c68f23
commit 76a04b7d3e
+46
View File
@@ -135,6 +135,52 @@ pub fn list_gpt_labeled_devs() -> Result<Vec<String>, ExecCommandError> {
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.
/// Sooo.. In order to know if unlock was sucessfull we need to check if program exited with Ok status,
/// or it shits to STDERR still waiting for stdin
/// Returns true if unlock successful, and false otherwise
pub fn bcachefs_unlock(pass: String, dev: &str) -> Result<bool, ExecCommandError> {
use std::io::Read;
use std::io::Write;
use std::process::Stdio;
let mut child = Command::new("bcachefs")
.arg("unlock")
.arg(dev)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
let mut c_stderr = child.stderr.take().ok_or_else(||{"Unable to get child process STDERR".to_string()})?;
// Write password to STDIN in a limited scope
{
let mut c_stdin = child.stdin.take().ok_or_else(||{"Unable to get child process STDIN".to_string()})?;
// neccessery to use thread or we may be deadlocking
c_stdin.write_all(pass.as_bytes())?;
let bytes_written = c_stdin.write(b"\n")?;
println!("bytes_written: {}", bytes_written);
// stdin is dropped here automatically when the block ends
}
let mut buffer = [0u8; 10];
// This blocks.
// if unlok fails it reads 10 bytes (piece of err message)
// if sucess it reads 0 bytes and exit
let read_b = c_stderr.read(&mut buffer)?;
if read_b > 0 {
println!("STDERR error not empty, password incorrect! Try to kill a child.");
child.kill()?;
}
// Safe to wait now; child will see EOF
let exit_status = child.wait()?;
// if exit status is SUCCESS - unloking is successful
Ok(exit_status.success())
}
/// Cheking if device is encripted
pub fn bzzpss_dev_encrypted(dev_name: &str) -> Result<bool, ExecCommandError> {
match exec_command("bcachefs", &vec!["unlock", "--check"]) {