sysfs_rs/
node.rs

1use std::io::prelude::*;
2use std::fs::File;
3
4use cpu::Cpu;
5use util;
6
7#[derive(Clone, Debug)]
8pub struct Node {
9    id: usize,
10    cpus: Vec<Cpu>,
11    cpumask: Vec<bool>,
12    mem_free: u64,
13    mem_total: u64,
14    mem_used: u64,
15    hugepages_2m_free: usize,
16    hugepages_2m_total: usize,
17    hugepages_1g_free: usize,
18    hugepages_1g_total: usize,
19}
20
21impl Node {
22    pub fn new(id: usize) -> Result<Node, &'static str> {
23        let node = Node {
24            id: id,
25            cpus: Vec::new(),
26            cpumask: Vec::new(),
27            mem_free: 0, // TODO: implement
28            mem_total: 0, // TODO: implement
29            mem_used: 0, // TODO: implement
30            hugepages_1g_total: 0,
31            hugepages_1g_free: 0,
32            hugepages_2m_total: 0,
33            hugepages_2m_free: 0,
34        };
35        node.init()
36    }
37
38    fn init(mut self) -> Result<Self, &'static str> {
39        if let Ok(cpumask) = util::bitmask_from_hex_file(format!("/sys/devices/system/node/node{}/cpumap",
40                                                                 self.id)) {
41            self.cpumask = cpumask.clone();
42            for i in 0..4096 {
43                if let Ok(mut cpu) = Cpu::new(self.id, i) {
44                    cpu.set_node_id(self.id);
45                    self.cpus.push(cpu);
46                }
47            }
48            self.mem_init();
49            Ok(self)
50        } else {
51            Err("no node found")
52        }
53    }
54
55    fn mem_init(&mut self) {
56        let path = format!("/sys/devices/system/node/node{}/meminfo", self.id);
57        if let Ok(mut f) = File::open(&path) {
58            let mut s = String::new();
59            if let Ok(_) = f.read_to_string(&mut s) {
60                for l in s.lines() {
61                    let tokens: Vec<&str> = l.split_whitespace().collect();
62                    match tokens[2] {
63                        "MemTotal:" => {
64                            self.mem_total = tokens[3].parse().unwrap_or(0);
65                        }
66                        "MemUsed:" => {
67                            self.mem_used = tokens[3].parse().unwrap_or(0);
68                        }
69                        "MemFree:" => {
70                            self.mem_free = tokens[3].parse().unwrap_or(0);
71                        }
72                        _ => {}
73                    }
74                }
75            }
76        }
77        self.hugepages_2m_free = util::usize_from_file(format!("/sys/devices/system/node/node{}/hugepages/hugepages-2048kB/free_hugepages", self.id)).unwrap_or(0);
78        self.hugepages_2m_total = util::usize_from_file(format!("/sys/devices/system/node/node{}/hugepages/hugepages-2048kB/nr_hugepages", self.id)).unwrap_or(0);
79        self.hugepages_1g_free = util::usize_from_file(format!("/sys/devices/system/node/node{}/hugepages/hugepages-1048576kB/free_hugepages", self.id)).unwrap_or(0);
80        self.hugepages_1g_total = util::usize_from_file(format!("/sys/devices/system/node/node{}/hugepages/hugepages-1048576kB/nr_hugepages", self.id)).unwrap_or(0);
81    }
82
83    pub fn id(&self) -> usize {
84        self.id
85    }
86
87    pub fn cpus(&self) -> &Vec<Cpu> {
88        &self.cpus
89    }
90
91    pub fn cpumask(&self) -> &Vec<bool> {
92        &self.cpumask
93    }
94
95    pub fn mem_free(&self) -> u64 {
96        self.mem_free
97    }
98
99    pub fn mem_total(&self) -> u64 {
100        self.mem_total
101    }
102
103    pub fn mem_used(&self) -> u64 {
104        self.mem_used
105    }
106
107    pub fn hugepages_2m_free(&self) -> usize {
108        self.hugepages_2m_free
109    }
110
111    pub fn hugepages_2m_total(&self) -> usize {
112        self.hugepages_2m_total
113    }
114
115    pub fn hugepages_1g_free(&self) -> usize {
116        self.hugepages_1g_free
117    }
118
119    pub fn hugepages_1g_total(&self) -> usize {
120        self.hugepages_1g_total
121    }
122}