microsoft/openvmm

Public

mirrored from https://github.com/microsoft/openvmmAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
release/2411-fork

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

openhcl/hcl/src/stats.rs

59lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Code for getting kernel stats from /proc/mshv.
5
6use std::io::BufRead;
7use std::io::BufReader;
8use thiserror::Error;
9
10/// Error returned by [`vp_stats`].
11#[derive(Debug, Error)]
12#[allow(missing_docs)]
13pub enum VpStatsError {
14 #[error("failed to read /proc/mshv")]
15 Read(#[source] std::io::Error),
16 #[error("failed to parse stats string")]
17 ParseString(#[source] std::io::Error),
18 #[error("failed to parse stats line")]
19 ParseLine,
20 #[error("a cpu was missing from the stats file")]
21 MissingCpu,
22}
23
24/// The per-VP stats from the kernel.
25#[derive(Debug)]
26pub struct HclVpStats {
27 /// The number of VTL transitions.
28 pub vtl_transitions: u64,
29}
30
31/// Gets the per-VP stats from the kernel.
32pub fn vp_stats() -> Result<Vec<HclVpStats>, VpStatsError> {
33 let v = std::fs::read("/proc/mshv").map_err(VpStatsError::Read)?;
34 // Skip the first two lines (version and header).
35 let lines = BufReader::new(v.as_slice()).lines().skip(2);
36 let mut stats = Vec::new();
37 for line in lines {
38 let line = line.map_err(VpStatsError::ParseString)?;
39 let (cpu, rest) = line.split_once(' ').ok_or(VpStatsError::ParseLine)?;
40 let n: usize = cpu
41 .strip_prefix("cpu")
42 .ok_or(VpStatsError::ParseLine)?
43 .parse()
44 .map_err(|_| VpStatsError::ParseLine)?;
45
46 if n != stats.len() {
47 return Err(VpStatsError::MissingCpu);
48 }
49 let vtl_transitions = rest
50 .split(' ')
51 .next()
52 .ok_or(VpStatsError::ParseLine)?
53 .parse()
54 .map_err(|_| VpStatsError::ParseLine)?;
55
56 stats.push(HclVpStats { vtl_transitions })
57 }
58 Ok(stats)
59}
60