Files
RedBear-OS/local/patches/base/P60-lived-dynamic-scheme-discovery.patch
T

119 lines
5.8 KiB
Diff

--- a/drivers/storage/lived/src/main.rs
+++ b/drivers/storage/lived/src/main.rs
@@ -45 +45 @@
- disk_file: RefCell<Option<File>>,
+ disk_path: RefCell<Option<String>>,
@@ -90 +90 @@
- disk_file: RefCell::new(None),
+ disk_path: RefCell::new(None),
@@ -96 +96 @@
- if self.disk_file.borrow().is_some() {
+ if self.disk_path.borrow().is_some() {
@@ -100,2 +100,2 @@
- Ok(file) => {
- *self.disk_file.borrow_mut() = Some(file);
+ Ok(path) => {
+ *self.disk_path.borrow_mut() = Some(path);
@@ -111,10 +111 @@
- fn try_open_disk(&self) -> Result<File, String> {
- // Try common disk scheme paths. USB boot appears as /scheme/disk/0 or /scheme/usbscsi/0.
- // AHCI boot appears as /scheme/disk/0. NVMe appears as /scheme/disk/0.
- let candidates = [
- "/scheme/disk/0",
- "/scheme/usbscsi/0",
- "/scheme/disk/1",
- "/scheme/usbscsi/1",
- ];
-
+ fn try_open_disk(&self) -> Result<String, String> {
@@ -122,4 +113,70 @@
- for path in &candidates {
- if let Ok(file) = File::open(path) {
- eprintln!("lived: opened physical disk at {} (attempt {})", path, attempt + 1);
- return Ok(file);
+ if let Ok(entries) = std::fs::read_dir("/scheme") {
+ let all_schemes: Vec<String> = entries
+ .flatten()
+ .map(|e| e.file_name().to_string_lossy().to_string())
+ .collect();
+ let has_disk = all_schemes
+ .iter()
+ .any(|s| s.starts_with("disk.") && s != "disk.live");
+ if attempt == 0 || attempt == DISK_OPEN_MAX_RETRIES - 1 || has_disk {
+ eprintln!(
+ "lived: attempt {} /scheme/ = {:?} (has_disk={})",
+ attempt + 1,
+ all_schemes,
+ has_disk
+ );
+ }
+ for name_str in &all_schemes {
+ if name_str.starts_with("disk.") && name_str != "disk.live" {
+ for idx in [0u32, 2, 1, 3, 4, 5] {
+ let path = format!("/scheme/{}/{}", name_str, idx);
+ if let Ok(mut file) = File::open(&path) {
+ use std::io::{Read, Seek, SeekFrom};
+ let test_offset = self.disk_phys_offset + self.full_size - 4096;
+ let mut probe = vec![0u8; 4096];
+ if file.seek(SeekFrom::Start(test_offset)).is_err() {
+ eprintln!(
+ "lived: skipping {} — seek to {:#x} failed",
+ path, test_offset
+ );
+ continue;
+ }
+ match file.read_exact(&mut probe) {
+ Ok(()) => {
+ eprintln!(
+ "lived: validated physical disk at {} (attempt {}, verified at end {:#x})",
+ path,
+ attempt + 1,
+ test_offset
+ );
+ return Ok(path);
+ }
+ Err(e) => {
+ eprintln!(
+ "lived: skipping {} — read at {:#x}: {}",
+ path, test_offset, e
+ );
+ continue;
+ }
+ }
+ } else if attempt == 0 {
+ eprintln!("lived: {} not openable", path);
+ }
+ }
+ let path_root = format!("/scheme/{}", name_str);
+ if let Ok(mut file) = File::open(&path_root) {
+ use std::io::{Read, Seek, SeekFrom};
+ let test_offset = self.disk_phys_offset + self.full_size - 4096;
+ let mut probe = vec![0u8; 4096];
+ if file.seek(SeekFrom::Start(test_offset)).is_ok()
+ && file.read_exact(&mut probe).is_ok()
+ {
+ eprintln!(
+ "lived: validated physical disk at {} (attempt {})",
+ path_root,
+ attempt + 1
+ );
+ return Ok(path_root);
+ }
+ }
+ }
@@ -152,0 +210,4 @@
+ let path = self.disk_path.borrow();
+ let disk_path = path.as_ref().unwrap();
+ let mut file = File::open(disk_path).map_err(|_| syscall::Error::new(EIO))?;
+
@@ -154,2 +214,0 @@
- let mut disk = self.disk_file.borrow_mut();
- let file = disk.as_mut().unwrap();
@@ -319,2 +378,4 @@
- libredox::call::setrens(0, 0).expect("lived: failed to enter null namespace");
-
+ // Lived must NOT call setrens(0, 0). The null namespace only contains
+ // "memory" and "pipe" (see relibc redox_setrens_v1). Lived needs
+ // ongoing access to /scheme/ for disk scheme discovery after storage
+ // drivers register their schemes asynchronously.