byteor_runtime/
host.rs

1use std::path::Path;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
6pub struct ShmRuntimeContext {
7    pub path: String,
8    pub mount_fstype: Option<String>,
9    pub hugetlbfs: bool,
10}
11
12pub(crate) fn shm_runtime_context(path: &Path) -> ShmRuntimeContext {
13    let mount_fstype = find_mount_fstype(path);
14    let hugetlbfs = mount_fstype.as_deref() == Some("hugetlbfs");
15    ShmRuntimeContext {
16        path: path.display().to_string(),
17        mount_fstype,
18        hugetlbfs,
19    }
20}
21
22pub(crate) fn find_mount_fstype(path: &Path) -> Option<String> {
23    let mounts = std::fs::read_to_string("/proc/mounts").ok()?;
24    let canonical = std::fs::canonicalize(path).ok()?;
25
26    let mut best: Option<(usize, String)> = None;
27    for line in mounts.lines() {
28        let parts: Vec<&str> = line.split_whitespace().collect();
29        if parts.len() < 3 {
30            continue;
31        }
32        let mount_point = parts[1];
33        let fstype = parts[2];
34
35        let mp = Path::new(mount_point);
36        if canonical.starts_with(mp) {
37            let len = mount_point.len();
38            let is_better = best.as_ref().map(|(l, _)| len > *l).unwrap_or(true);
39            if is_better {
40                best = Some((len, fstype.to_string()));
41            }
42        }
43    }
44
45    best.map(|(_, t)| t)
46}
47
48pub(crate) fn probe_shm_dir_writable(dir: &Path) -> Result<(), String> {
49    #[cfg(target_os = "linux")]
50    {
51        indexbus_platform_ops::linux::fs::probe_dir_writable(dir).map_err(|e| e.to_string())
52    }
53
54    #[cfg(not(target_os = "linux"))]
55    {
56        use std::io::Write;
57
58        let path = dir.join(format!(".byteor_shm_probe_{}", std::process::id()));
59        let res = (|| -> Result<(), String> {
60            let mut f = std::fs::OpenOptions::new()
61                .create(true)
62                .write(true)
63                .truncate(true)
64                .open(&path)
65                .map_err(|e| format!("dir not writable (open {}): {e}", path.display()))?;
66            f.write_all(b"probe")
67                .map_err(|e| format!("dir not writable (write {}): {e}", path.display()))?;
68            Ok(())
69        })();
70
71        let _ = std::fs::remove_file(&path);
72        res
73    }
74}