]> git.proxmox.com Git - proxmox-backup.git/commitdiff
remove src/tools/procfs.rs, use proxmox::sys::linux::procfs instead
authorDietmar Maurer <dietmar@proxmox.com>
Sat, 3 Aug 2019 14:26:44 +0000 (16:26 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Sat, 3 Aug 2019 14:26:44 +0000 (16:26 +0200)
src/server/upid.rs
src/server/worker_task.rs
src/tools.rs
src/tools/procfs.rs [deleted file]

index c27ccdf57401c5fbc47d47acd1807388ac100e90..969ea371702f92f6705c6fad0962a8bec8cc7503 100644 (file)
@@ -62,7 +62,7 @@ impl UPID {
 
         Ok(UPID {
             pid,
-            pstart: tools::procfs::read_proc_starttime(pid)?,
+            pstart: proxmox::sys::linux::procfs::read_proc_starttime(pid)?,
             starttime: Local::now().timestamp(),
             task_id,
             worker_type: worker_type.to_owned(),
index df1e71e0cb6a48bbda3b61c65c31fd18536c0636..a31b0f347968ca8b40516d359e24bff80919bba4 100644 (file)
@@ -36,7 +36,7 @@ lazy_static! {
     static ref WORKER_TASK_LIST: Mutex<HashMap<usize, Arc<WorkerTask>>> = Mutex::new(HashMap::new());
 
     static ref MY_PID: i32 = unsafe { libc::getpid() };
-    static ref MY_PID_PSTART: u64 = crate::tools::procfs::read_proc_pid_stat(*MY_PID).unwrap().starttime;
+    static ref MY_PID_PSTART: u64 = proxmox::sys::linux::procfs::read_proc_pid_stat(*MY_PID).unwrap().starttime;
 }
 
 /// Test if the task is still running
@@ -49,7 +49,7 @@ pub fn worker_is_active(upid: &UPID) -> bool {
             false
         }
     } else {
-        match crate::tools::procfs::check_process_running_pstart(upid.pid, upid.pstart) {
+        match proxmox::sys::linux::procfs::check_process_running_pstart(upid.pid, upid.pstart) {
             Some(_) => true,
             _ => false,
         }
index 520d0d192badcf06e2e1c024305885bf0522095b..fcd11e31aeff80ca852ea94a2e763d0d6667ea29 100644 (file)
@@ -30,7 +30,6 @@ pub mod fs;
 pub mod tty;
 pub mod signalfd;
 pub mod daemon;
-pub mod procfs;
 pub mod acl;
 pub mod xattr;
 pub mod futures;
diff --git a/src/tools/procfs.rs b/src/tools/procfs.rs
deleted file mode 100644 (file)
index 655a489..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-use failure::*;
-
-use std::u32;
-use std::fs::OpenOptions;
-use std::io::{BufRead, BufReader};
-use std::collections::HashSet;
-use std::process;
-use std::net::{Ipv4Addr, Ipv6Addr};
-use proxmox::tools::fs::file_read_firstline;
-use lazy_static::lazy_static;
-use regex::Regex;
-use libc;
-
-/// POSIX sysconf call
-pub fn sysconf(name: i32) -> i64 {
-    extern { fn sysconf(name: i32) -> i64; }
-    unsafe { sysconf(name) }
-}
-
-lazy_static! {
-    static ref CLOCK_TICKS: f64 = sysconf(libc::_SC_CLK_TCK) as f64;
-}
-
-pub struct ProcFsPidStat {
-    pub status: u8,
-    pub utime: u64,
-    pub stime: u64,
-    pub starttime: u64,
-    pub vsize: u64,
-    pub rss: i64,
-}
-
-pub fn read_proc_pid_stat(pid: libc::pid_t) -> Result<ProcFsPidStat, Error> {
-
-    let statstr = file_read_firstline(format!("/proc/{}/stat", pid))?;
-
-    lazy_static! {
-        static ref REGEX: Regex = Regex::new(concat!(
-            r"^(?P<pid>\d+) \(.*\) (?P<status>\S) -?\d+ -?\d+ -?\d+ -?\d+ -?\d+ \d+ \d+ \d+ \d+ \d+ ",
-            r"(?P<utime>\d+) (?P<stime>\d+) -?\d+ -?\d+ -?\d+ -?\d+ -?\d+ 0 ",
-            r"(?P<starttime>\d+) (?P<vsize>\d+) (?P<rss>-?\d+) ",
-            r"\d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ -?\d+ -?\d+ \d+ \d+ \d+"
-        )).unwrap();
-    }
-
-    if let Some(cap) = REGEX.captures(&statstr) {
-        if pid != cap["pid"].parse::<i32>().unwrap() {
-            bail!("unable to read pid stat for process '{}' - got wrong pid", pid);
-        }
-
-        return Ok(ProcFsPidStat {
-            status: cap["status"].as_bytes()[0],
-            utime: cap["utime"].parse::<u64>().unwrap(),
-            stime: cap["stime"].parse::<u64>().unwrap(),
-            starttime: cap["starttime"].parse::<u64>().unwrap(),
-            vsize: cap["vsize"].parse::<u64>().unwrap(),
-            rss: cap["rss"].parse::<i64>().unwrap() * 4096,
-        });
-
-    }
-
-    bail!("unable to read pid stat for process '{}'", pid);
-}
-
-pub fn read_proc_starttime(pid: libc::pid_t) -> Result<u64, Error> {
-
-    let info = read_proc_pid_stat(pid)?;
-
-    Ok(info.starttime)
-}
-
-pub fn check_process_running(pid: libc::pid_t) -> Option<ProcFsPidStat> {
-    if let Ok(info) = read_proc_pid_stat(pid) {
-        if info.status != 'Z' as u8 {
-            return Some(info);
-        }
-    }
-    None
-}
-
-pub fn check_process_running_pstart(pid: libc::pid_t, pstart: u64) -> Option<ProcFsPidStat> {
-    if let Some(info) = check_process_running(pid) {
-        if info.starttime == pstart {
-            return Some(info);
-        }
-    }
-    None
-}
-
-pub fn read_proc_uptime() -> Result<(f64, f64), Error> {
-    let path = "/proc/uptime";
-    let line = file_read_firstline(&path)?;
-    let mut values = line.split_whitespace().map(|v| v.parse::<f64>());
-
-    match (values.next(), values.next()) {
-        (Some(Ok(up)), Some(Ok(idle))) => return Ok((up, idle)),
-        _ => bail!("Error while parsing '{}'", path),
-    }
-}
-
-pub fn read_proc_uptime_ticks() -> Result<(u64, u64), Error> {
-    let (mut up, mut idle) = read_proc_uptime()?;
-    up *= *CLOCK_TICKS;
-    idle *= *CLOCK_TICKS;
-    Ok((up as u64, idle as u64))
-}
-
-#[derive(Debug)]
-pub struct ProcFsMemInfo {
-    pub memtotal: u64,
-    pub memfree: u64,
-    pub memused: u64,
-    pub memshared: u64,
-    pub swaptotal: u64,
-    pub swapfree: u64,
-    pub swapused: u64,
-}
-
-pub fn read_meminfo() -> Result<ProcFsMemInfo, Error> {
-    let path = "/proc/meminfo";
-    let file = OpenOptions::new().read(true).open(&path)?;
-
-    let mut meminfo = ProcFsMemInfo {
-        memtotal: 0,
-        memfree: 0,
-        memused: 0,
-        memshared: 0,
-        swaptotal: 0,
-        swapfree: 0,
-        swapused: 0,
-    };
-
-    let (mut buffers, mut cached) = (0, 0);
-    for line in BufReader::new(&file).lines() {
-        let content = line?;
-        let mut content_iter = content.split_whitespace();
-        if let (Some(key), Some(value)) = (content_iter.next(), content_iter.next()) {
-            match key {
-                "MemTotal:" => meminfo.memtotal = value.parse::<u64>()? * 1024,
-                "MemFree:" => meminfo.memfree = value.parse::<u64>()? * 1024,
-                "SwapTotal:" => meminfo.swaptotal = value.parse::<u64>()? * 1024,
-                "SwapFree:" => meminfo.swapfree = value.parse::<u64>()? * 1024,
-                "Buffers:" => buffers = value.parse::<u64>()? * 1024,
-                "Cached:" => cached = value.parse::<u64>()? * 1024,
-                _ => continue,
-            }
-        }
-    }
-
-    meminfo.memfree += buffers + cached;
-    meminfo.memused = meminfo.memtotal - meminfo.memfree;
-
-    meminfo.swapused = meminfo.swaptotal - meminfo.swapfree;
-
-    let spages_line = file_read_firstline("/sys/kernel/mm/ksm/pages_sharing")?;
-    meminfo.memshared = spages_line.trim_end().parse::<u64>()? * 4096;
-
-    Ok(meminfo)
-}
-
-#[derive(Clone, Debug)]
-pub struct ProcFsCPUInfo {
-    pub user_hz: f64,
-    pub mhz: f64,
-    pub model: String,
-    pub hvm: bool,
-    pub sockets: usize,
-    pub cpus: usize,
-}
-
-static CPU_INFO: Option<ProcFsCPUInfo> = None;
-
-pub fn read_cpuinfo() -> Result<ProcFsCPUInfo, Error> {
-    if let Some(cpu_info) = &CPU_INFO { return Ok(cpu_info.clone()); }
-
-    let path = "/proc/cpuinfo";
-    let file = OpenOptions::new().read(true).open(&path)?;
-
-    let mut cpuinfo = ProcFsCPUInfo {
-        user_hz: *CLOCK_TICKS,
-        mhz: 0.0,
-        model: String::new(),
-        hvm: false,
-        sockets: 0,
-        cpus: 0,
-    };
-
-    let mut socket_ids = HashSet::new();
-    for line in BufReader::new(&file).lines() {
-        let content = line?;
-        if content.is_empty() { continue; }
-        let mut content_iter = content.split(":");
-        match (content_iter.next(), content_iter.next()) {
-            (Some(key), Some(value)) => {
-                match key.trim_end() {
-                    "processor" => cpuinfo.cpus += 1,
-                    "model name" => cpuinfo.model = value.trim().to_string(),
-                    "cpu MHz" => cpuinfo.mhz = value.trim().parse::<f64>()?,
-                    "flags" => cpuinfo.hvm = value.contains(" vmx ") || value.contains(" svm "),
-                    "physical id" => {
-                        let id = value.trim().parse::<u8>()?;
-                        socket_ids.insert(id);
-                    },
-                    _ => continue,
-                }
-            },
-            _ => bail!("Error while parsing '{}'", path),
-        }
-    }
-    cpuinfo.sockets = socket_ids.len();
-
-    Ok(cpuinfo)
-}
-
-#[derive(Debug)]
-pub struct ProcFsMemUsage {
-    pub size: u64,
-    pub resident: u64,
-    pub shared: u64,
-}
-
-pub fn read_memory_usage() -> Result<ProcFsMemUsage, Error> {
-    let path = format!("/proc/{}/statm", process::id());
-    let line = file_read_firstline(&path)?;
-    let mut values = line.split_whitespace().map(|v| v.parse::<u64>());
-
-    let ps = 4096;
-    match (values.next(), values.next(), values.next()) {
-        (Some(Ok(size)), Some(Ok(resident)), Some(Ok(shared))) =>
-            Ok(ProcFsMemUsage {
-                size: size * ps,
-                resident: resident * ps,
-                shared: shared * ps,
-            }),
-        _ => bail!("Error while parsing '{}'", path),
-    }
-}
-
-#[derive(Debug)]
-pub struct ProcFsNetDev {
-    pub device: String,
-    pub receive: u64,
-    pub send: u64,
-}
-
-pub fn read_proc_net_dev() -> Result<Vec<ProcFsNetDev>, Error> {
-    let path = "/proc/net/dev";
-    let file = OpenOptions::new().read(true).open(&path)?;
-
-    let mut result = Vec::new();
-    for line in BufReader::new(&file).lines().skip(2) {
-        let content = line?;
-        let mut iter = content.split_whitespace();
-        match (iter.next(), iter.next(), iter.skip(7).next()) {
-            (Some(device), Some(receive), Some(send)) => {
-                result.push(ProcFsNetDev {
-                    device: device[..device.len()-1].to_string(),
-                    receive: receive.parse::<u64>()?,
-                    send: send.parse::<u64>()?,
-                });
-            },
-            _ => bail!("Error while parsing '{}'", path),
-        }
-    }
-
-    Ok(result)
-}
-
-fn hex_nibble(c: u8) -> Result<u8, Error> {
-    Ok(match c {
-        b'0'..=b'9' => c - b'0',
-        b'a'..=b'f' => c - b'a' + 0xa,
-        b'A'..=b'F' => c - b'A' + 0xa,
-        _ => bail!("not a hex digit: {}", c as char),
-    })
-}
-
-fn hexstr_to_ipv4addr<T: AsRef<[u8]>>(hex: T) -> Result<Ipv4Addr, Error> {
-    let hex = hex.as_ref();
-    if hex.len() != 8 {
-        bail!("Error while converting hex string to IPv4 address: unexpected string length");
-    }
-
-    let mut addr: [u8; 4] = unsafe { std::mem::uninitialized() };
-    for i in 0..4 {
-        addr[3 - i] = (hex_nibble(hex[i * 2])? << 4) + hex_nibble(hex[i * 2 + 1])?;
-    }
-
-    Ok(Ipv4Addr::from(addr))
-}
-
-#[derive(Debug)]
-pub struct ProcFsNetRoute {
-    pub dest: Ipv4Addr,
-    pub gateway: Ipv4Addr,
-    pub mask: Ipv4Addr,
-    pub metric: u32,
-    pub mtu: u32,
-    pub iface: String,
-}
-
-pub fn read_proc_net_route() -> Result<Vec<ProcFsNetRoute>, Error> {
-    let path = "/proc/net/route";
-    let file = OpenOptions::new().read(true).open(&path)?;
-
-    let mut result = Vec::new();
-    for line in BufReader::new(&file).lines().skip(1) {
-        let content = line?;
-        if content.is_empty() { continue; }
-        let mut iter = content.split_whitespace();
-
-        let mut next = || iter.next()
-            .ok_or(format_err!("Error while parsing '{}'", path));
-
-        let (iface, dest, gateway) = (next()?, next()?, next()?);
-        for _ in 0..3 { next()?; }
-        let (metric, mask, mtu) = (next()?, next()?, next()?);
-
-        result.push(ProcFsNetRoute {
-            dest: hexstr_to_ipv4addr(dest)?,
-            gateway: hexstr_to_ipv4addr(gateway)?,
-            mask: hexstr_to_ipv4addr(mask)?,
-            metric: metric.parse()?,
-            mtu: mtu.parse()?,
-            iface: iface.to_string(),
-        });
-    }
-
-    Ok(result)
-}
-
-fn hexstr_to_ipv6addr<T: AsRef<[u8]>>(hex: T) -> Result<Ipv6Addr, Error> {
-    let hex = hex.as_ref();
-    if hex.len() != 32 {
-        bail!("Error while converting hex string to IPv6 address: unexpected string length");
-    }
-
-    let mut addr: [u8; 16] = unsafe { std::mem::uninitialized() };
-    for i in 0..16 {
-        addr[i] = (hex_nibble(hex[i * 2])? << 4) + hex_nibble(hex[i * 2 + 1])?;
-    }
-
-    Ok(Ipv6Addr::from(addr))
-}
-
-fn hexstr_to_u8<T: AsRef<[u8]>>(hex: T) -> Result<u8, Error> {
-    let hex = hex.as_ref();
-    if hex.len() != 2 {
-        bail!("Error while converting hex string to u8: unexpected string length");
-    }
-
-    Ok((hex_nibble(hex[0])? << 4) + hex_nibble(hex[1])?)
-}
-
-fn hexstr_to_u32<T: AsRef<[u8]>>(hex: T) -> Result<u32, Error> {
-    let hex = hex.as_ref();
-    if hex.len() != 8 {
-        bail!("Error while converting hex string to u32: unexpected string length");
-    }
-
-    let mut bytes: [u8; 4] = unsafe { std::mem::uninitialized() };
-    for i in 0..4 {
-        bytes[i] = (hex_nibble(hex[i * 2])? << 4) + hex_nibble(hex[i * 2 + 1])?;
-    }
-
-    Ok(u32::from_be_bytes(bytes))
-}
-
-#[derive(Debug)]
-pub struct ProcFsNetIPv6Route {
-    pub dest: Ipv6Addr,
-    pub prefix: u8,
-    pub gateway: Ipv6Addr,
-    pub metric: u32,
-    pub iface: String,
-}
-
-pub fn read_proc_net_ipv6_route() -> Result<Vec<ProcFsNetIPv6Route>, Error> {
-    let path = "/proc/net/ipv6_route";
-    let file = OpenOptions::new().read(true).open(&path)?;
-
-    let mut result = Vec::new();
-    for line in BufReader::new(&file).lines() {
-        let content = line?;
-        if content.is_empty() { continue; }
-        let mut iter = content.split_whitespace();
-
-        let mut next = || iter.next()
-            .ok_or_else(|| format_err!("Error while parsing '{}'", path));
-
-        let (dest, prefix) = (next()?, next()?);
-        for _ in 0..2 { next()?; }
-        let (nexthop, metric) = (next()?, next()?);
-        for _ in 0..3 { next()?; }
-        let iface = next()?;
-
-        result.push(ProcFsNetIPv6Route {
-            dest: hexstr_to_ipv6addr(dest)?,
-            prefix: hexstr_to_u8(prefix)?,
-            gateway: hexstr_to_ipv6addr(nexthop)?,
-            metric: hexstr_to_u32(metric)?,
-            iface: iface.to_string(),
-        });
-    }
-
-    Ok(result)
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_read_proc_net_route() {
-        read_proc_net_route().unwrap();
-    }
-    
-    #[test]
-    fn test_read_proc_net_ipv6_route() {
-        read_proc_net_ipv6_route().unwrap();
-    }
-}