Skip to content

Commit

Permalink
Adds configurable path to /sys and /proc via naive global state
Browse files Browse the repository at this point in the history
Signed-off-by: Ian Henry <ianjhenry00@gmail.com>
  • Loading branch information
eeyun committed Dec 4, 2020
1 parent 6aa21b8 commit 83168f2
Show file tree
Hide file tree
Showing 26 changed files with 210 additions and 67 deletions.
4 changes: 2 additions & 2 deletions heim-cpu/src/sys/linux/count/logical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn sysconf() -> Result<u64> {

async fn cpuinfo() -> Result<u64> {
rt::spawn_blocking(|| {
let f = fs::File::open("/proc/cpuinfo")?;
let f = fs::File::open(rt::linux::procfs_root().as_path().join("cpuinfo"))?;
let reader = io::BufReader::new(f);
let mut count = 0;
for line in reader.lines() {
Expand All @@ -32,7 +32,7 @@ async fn cpuinfo() -> Result<u64> {

async fn stat() -> Result<u64> {
rt::spawn_blocking(|| {
let f = fs::File::open("/proc/stat")?;
let f = fs::File::open(rt::linux::procfs_root().as_path().join("stat"))?;
let reader = io::BufReader::new(f);
let mut count = 0;

Expand Down
17 changes: 12 additions & 5 deletions heim-cpu/src/sys/linux/count/physical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ use heim_runtime as rt;

async fn topology() -> Result<u64> {
rt::spawn_blocking(|| {
let entries = glob::glob("/sys/devices/system/cpu/cpu[0-9]/topology/core_id")
.expect("Invalid glob pattern");
let path = rt::linux::sysfs_root().join("devices/system/cpu/cpu[0-9]/topology/core_id");
let entries =
glob::glob(path.display().to_string().as_str()).expect("Invalid glob pattern");
let mut acc = HashSet::<u64>::new();

for entry in entries {
Expand Down Expand Up @@ -48,7 +49,7 @@ fn parse_line(line: &str) -> Result<u64> {
async fn cpu_info() -> Result<Option<u64>> {
rt::spawn_blocking(|| {
let mut acc = Collector::default();
let f = fs::File::open("/proc/cpuinfo")?;
let f = fs::File::open(rt::linux::procfs_root().join("cpuinfo"))?;
let reader = io::BufReader::new(f);

let lines = reader.lines();
Expand All @@ -60,7 +61,10 @@ async fn cpu_info() -> Result<Option<u64>> {
acc.physical_id = Some(core_id)
} else {
// TODO: In general it seems better to return an error
panic!("Missed the core id value in the /proc/cpuinfo, implementation bug");
panic!(
"Missed the core id value in the {:?}/cpuinfo, implementation bug",
rt::linux::procfs_root()
);
}
}
l if l.starts_with("core id") => {
Expand All @@ -71,7 +75,10 @@ async fn cpu_info() -> Result<Option<u64>> {
let _ = acc.group.insert((physical_id, core_id));
} else {
// TODO: In general it seems better to return an error
panic!("Missed the physical id value in the /proc/cpuinfo!");
panic!(
"Missed the physical id value in the {:?}/cpuinfo!",
rt::linux::procfs_root()
);
}
}
_ => continue,
Expand Down
5 changes: 3 additions & 2 deletions heim-cpu/src/sys/linux/freq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ fn _frequencies() -> impl Iterator<Item = Result<CpuFrequency>> {
// later with the thoughts and patches

// TODO: https://github.com/giampaolo/psutil/issues/1269
let entries =
glob::glob("/sys/devices/system/cpu/cpu[0-9]/cpufreq/").expect("Incorrect glob pattern");
let path = rt::linux::sysfs_root().join("devices/system/cpu/cpu[0-9]/cpufreq/");

let entries = glob::glob(path.display().to_string().as_str()).expect("Incorrect glob pattern");

entries.map(|try_path| {
let path = try_path.map_err(|e| e.into_error())?;
Expand Down
9 changes: 7 additions & 2 deletions heim-cpu/src/sys/linux/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ impl FromStr for CpuStats {
matched_lines += 1;
*field = value;
}
None => return Err(Error::missing_key(name, "/proc/stat")),
None => {
return Err(Error::missing_key(
name,
format!("{:?}/stat", rt::linux::procfs_root()),
))
}
}

if matched_lines == 3 {
Expand All @@ -57,5 +62,5 @@ impl FromStr for CpuStats {
}

pub async fn stats() -> Result<CpuStats> {
rt::fs::read_into("/proc/stat").await
rt::fs::read_into(rt::linux::procfs_root().as_path().join("stat")).await
}
11 changes: 8 additions & 3 deletions heim-cpu/src/sys/linux/times.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,21 @@ impl FromStr for CpuTime {

pub async fn time() -> Result<CpuTime> {
// cumulative time is always the first line
let lines = rt::fs::read_lines_into::<_, CpuTime, _>("/proc/stat").await?;
let lines =
rt::fs::read_lines_into::<_, CpuTime, _>(rt::linux::procfs_root().as_path().join("stat"))
.await?;
rt::pin!(lines);
match lines.next().await {
Some(line) => line,
None => Err(Error::missing_key("cumulative time line", "/proc/stat")),
None => Err(Error::missing_key(
"cumulative time line",
format!("{:?}/stat", rt::linux::procfs_root()),
)),
}
}

pub async fn times() -> Result<impl Stream<Item = Result<CpuTime>>> {
let lines = rt::fs::read_lines("/proc/stat").await?;
let lines = rt::fs::read_lines(rt::linux::procfs_root().as_path().join("stat")).await?;

let stream = lines.skip(1).filter_map(|try_line| async move {
match try_line {
Expand Down
9 changes: 7 additions & 2 deletions heim-disk/src/sys/linux/counters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ impl IoCounters {
// Based on the sysstat code:
// https://github.com/sysstat/sysstat/blob/1c711c1fd03ac638cfc1b25cdf700625c173fd2c/common.c#L200
async fn is_storage_device(&self) -> Result<bool> {
let path = CString::new(format!("/sys/block/{}", self.name.replace("/", "!")))?;
let path = CString::new(format!(
"{}/block/{}",
rt::linux::sysfs_root().as_path().display(),
self.name.replace("/", "!")
))?;

let result =
rt::spawn_blocking(move || unsafe { libc::access(path.as_ptr(), libc::F_OK) }).await;
Expand Down Expand Up @@ -111,7 +115,8 @@ impl FromStr for IoCounters {
}

pub async fn io_counters() -> Result<impl Stream<Item = Result<IoCounters>>> {
let stream = rt::fs::read_lines_into::<_, _, Error>("/proc/diskstats").await?;
let stream =
rt::fs::read_lines_into::<_, _, Error>(rt::linux::procfs_root().join("diskstats")).await?;

Ok(stream)
}
Expand Down
35 changes: 27 additions & 8 deletions heim-disk/src/sys/linux/partitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ use heim_runtime as rt;

use crate::FileSystem;

static PROC_MOUNTS: &str = "/proc/mounts";

#[derive(Debug)]
pub struct Partition {
device: Option<String>,
Expand Down Expand Up @@ -46,22 +44,43 @@ impl FromStr for Partition {
fn from_str(line: &str) -> Result<Partition> {
// Example: `/dev/sda3 /home ext4 rw,relatime,data=ordered 0 0`
let mut parts = line.splitn(5, ' ');
let mount_root = rt::linux::procfs_root().join("mounts");
let device = match parts.next() {
Some(device) if device == "none" => None,
Some(device) => Some(device.to_string()),
None => return Err(Error::missing_key("device", PROC_MOUNTS)),
None => {
return Err(Error::missing_key(
"device",
format!("{}", mount_root.display()),
))
}
};
let mount_point = match parts.next() {
Some(point) => PathBuf::from(point),
None => return Err(Error::missing_key("mount point", PROC_MOUNTS)),
None => {
return Err(Error::missing_key(
"mount point",
format!("{}", mount_root.display()),
))
}
};
let fs_type = match parts.next() {
Some(fs) => FileSystem::from_str(fs)?,
_ => return Err(Error::missing_key("file-system type", PROC_MOUNTS)),
_ => {
return Err(Error::missing_key(
"file-system type",
format!("{}", mount_root.display()),
))
}
};
let options = match parts.next() {
Some(opts) => opts.to_string(),
None => return Err(Error::missing_key("options", PROC_MOUNTS)),
None => {
return Err(Error::missing_key(
"options",
format!("{}", mount_root.display()),
))
}
};

Ok(Partition {
Expand All @@ -76,7 +95,7 @@ impl FromStr for Partition {
// Returns stream with known physical (only!) partitions
async fn known_filesystems() -> Result<HashSet<FileSystem>> {
rt::spawn_blocking(|| {
let file = fs::File::open("/proc/filesystems")?;
let file = fs::File::open(rt::linux::procfs_root().join("filesystems"))?;
let reader = io::BufReader::new(file);
let mut acc = HashSet::with_capacity(4);

Expand Down Expand Up @@ -105,7 +124,7 @@ async fn known_filesystems() -> Result<HashSet<FileSystem>> {
}

pub async fn partitions() -> Result<impl Stream<Item = Result<Partition>>> {
let lines = rt::fs::read_lines(PROC_MOUNTS).await?;
let lines = rt::fs::read_lines(rt::linux::procfs_root().join("mounts")).await?;
let stream = lines
.map_err(Error::from)
.try_filter_map(|line| async move {
Expand Down
15 changes: 10 additions & 5 deletions heim-host/src/sys/linux/boot_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ use heim_common::{
};
use heim_runtime as rt;

const PROC_STAT: &str = "/proc/stat";

pub async fn boot_time() -> Result<Time> {
let contents = rt::fs::read_to_string(PROC_STAT).await?;
let contents = rt::fs::read_to_string(rt::linux::procfs_root().join("stat")).await?;

for line in contents.lines() {
if line.starts_with("btime ") {
Expand All @@ -19,10 +17,17 @@ pub async fn boot_time() -> Result<Time> {
.parse::<f64>()
.map(Time::new::<time::second>)
.map_err(Into::into),
None => Err(Error::missing_key("btime", PROC_STAT)),
None => Err(Error::missing_key(
"btime",
format!("{}/stat", rt::linux::procfs_root().display()),
)),
//None => Err(Error::missing_key("btime", proc_stat)),
};
}
}

Err(Error::missing_key("btime", PROC_STAT))
Err(Error::missing_key(
"btime",
format!("{}/stat", rt::linux::procfs_root().display()),
))
}
9 changes: 5 additions & 4 deletions heim-host/src/sys/linux/uptime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ use heim_common::{
};
use heim_runtime as rt;

const PROC_UPTIME: &str = "/proc/uptime";

pub async fn uptime() -> Result<Time> {
let contents = rt::fs::read_to_string(PROC_UPTIME).await?;
let contents = rt::fs::read_to_string(rt::linux::procfs_root().join("uptime")).await?;

match contents.splitn(2, ' ').next() {
Some(raw_value) => {
let seconds = raw_value.parse::<f64>()?;

Ok(Time::new::<time::second>(seconds))
}
None => Err(Error::missing_key("uptime", "/proc/uptime")),
None => Err(Error::missing_key(
"uptime",
format!("{}/uptime", rt::linux::procfs_root().display()),
)),
}
}
4 changes: 2 additions & 2 deletions heim-memory/src/sys/linux/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ impl FromStr for Memory {
// but at this point we are not tracking which exact field are we missing.
// TODO: Rewrite parser and use `Error::missing_key` instead
let inner = io::Error::from(io::ErrorKind::InvalidData);
Err(Error::from(inner).with_file("/proc/meminfo"))
Err(Error::from(inner).with_file(rt::linux::procfs_root().join("meminfo")))
}
}

pub async fn memory() -> Result<Memory> {
rt::fs::read_into("/proc/meminfo").await
rt::fs::read_into(rt::linux::procfs_root().join("meminfo")).await
}
9 changes: 3 additions & 6 deletions heim-memory/src/sys/linux/swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ use heim_runtime as rt;
use heim_common::prelude::*;
use heim_common::units::{information, Information};

static PROC_VMSTAT: &str = "/proc/vmstat";
static PROC_MEMINFO: &str = "/proc/meminfo";

#[derive(Debug, Default, Clone)]
pub struct VmStat {
swap_in: Option<Information>, // pswpin
Expand Down Expand Up @@ -137,14 +134,14 @@ impl Swap {
// but at this point we are not tracking which exact field are we missing.
// TODO: Rewrite parser and use `Error::missing_key` instead
let inner = io::Error::from(io::ErrorKind::InvalidData);
Err(Error::from(inner).with_file(PROC_MEMINFO))
Err(Error::from(inner).with_file(rt::linux::procfs_root().join("meminfo")))
}
}

pub async fn swap() -> Result<Swap> {
rt::spawn_blocking(|| {
let meminfo = fs::read_to_string(PROC_MEMINFO)?;
let vmstat = fs::read_to_string(PROC_VMSTAT)?;
let meminfo = fs::read_to_string(rt::linux::procfs_root().join("meminfo"))?;
let vmstat = fs::read_to_string(rt::linux::procfs_root().join("vmstat"))?;
let vmstat = VmStat::from_str(&vmstat)?;

Swap::parse_str(&meminfo, vmstat)
Expand Down
13 changes: 10 additions & 3 deletions heim-net/src/sys/linux/counters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,12 @@ impl FromStr for IoCounters {
let mut parts = s.split_whitespace();
let interface = match parts.next() {
Some(str) => str.trim_end_matches(':').to_string(),
None => return Err(Error::missing_key("Interface", "/proc/net/dev")),
None => {
return Err(Error::missing_key(
"Interface",
format!("{}/net/dev", rt::linux::procfs_root().display()),
))
}
};

Ok(IoCounters {
Expand Down Expand Up @@ -122,11 +127,13 @@ async fn inner<T: AsRef<Path> + Send + 'static>(
}

pub async fn io_counters() -> Result<impl Stream<Item = Result<IoCounters>>> {
inner("/proc/net/dev").await
inner(rt::linux::procfs_root().join("net/dev")).await
}

pub async fn io_counters_for_pid(pid: Pid) -> Result<impl Stream<Item = Result<IoCounters>>> {
let path = format!("/proc/{}/net/dev", pid);
let path = rt::linux::procfs_root()
.join(pid.to_string())
.join("net/dev");

inner(path).await
}
2 changes: 1 addition & 1 deletion heim-process/src/sys/linux/pids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::sys::unix;
use crate::{Pid, ProcessResult};

pub async fn pids() -> Result<impl Stream<Item = Result<Pid>>> {
let entries = rt::fs::read_dir("/proc").await?;
let entries = rt::fs::read_dir(rt::linux::procfs_root().as_path()).await?;

let stream = entries
.map_err(Into::into)
Expand Down
16 changes: 14 additions & 2 deletions heim-process/src/sys/linux/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ impl Process {
}

pub async fn exe(&self) -> ProcessResult<PathBuf> {
match rt::fs::read_link(format!("/proc/{}/exe", self.pid)).await {
match rt::fs::read_link(
rt::linux::procfs_root()
.join(self.pid.to_string())
.join("exe"),
)
.await
{
Ok(path) => Ok(path),
Err(..) => {
// log::trace!() ?
Expand All @@ -88,7 +94,13 @@ impl Process {
}

pub async fn cwd(&self) -> ProcessResult<PathBuf> {
match rt::fs::read_link(format!("/proc/{}/cwd", self.pid)).await {
match rt::fs::read_link(
rt::linux::procfs_root()
.join(self.pid.to_string())
.join("cwd"),
)
.await
{
Ok(path) => Ok(path),
Err(e) if e.kind() == io::ErrorKind::PermissionDenied => {
Err(ProcessError::AccessDenied(self.pid))
Expand Down
8 changes: 7 additions & 1 deletion heim-process/src/sys/linux/process/procfs/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,13 @@ impl<'a> Iterator for CommandIter<'a> {
}

pub async fn command(pid: Pid) -> ProcessResult<Command> {
match rt::fs::read_to_string(format!("/proc/{}/cmdline", pid)).await {
match rt::fs::read_to_string(
rt::linux::procfs_root()
.join(pid.to_string())
.join("cmdline"),
)
.await
{
Ok(contents) => Ok(Command::from(contents)),
Err(e) if e.kind() == io::ErrorKind::NotFound => Err(ProcessError::NoSuchProcess(pid)),
Err(e) => Err(e.into()),
Expand Down

0 comments on commit 83168f2

Please sign in to comment.