Skip to content

Commit

Permalink
Fix memory and swap values reported by 'iotedge check' and edge agent (
Browse files Browse the repository at this point in the history
…#6943)

Fixes several bugs related to reported system RAM and swap values:
1. Units conversion bug introduced by a recent upgrade from sysinfo v0.25 to v0.27, resulting in edgeAgent_total_memory_bytes and edgeAgent_used_memory_bytes for "module_name=host" being 1024 times higher than the value previously reported in iotedge v1.4.3.
2. Long-standing bug in edgeAgent_total_memory_bytes and edgeAgent_used_memory_bytes for "module_name=host", where the reported values were 1.024 times higher than the actual values. This was caused by incorrectly treating the values returned by sysinfo v0.25 as KiB instead of KB.
3. Long-standing bug in system info reported by 'iotedge check', where the total_ram, total_swap, used_ram, and used_swap values were 1.024 times higher than the actual values. This was also caused by incorrectly treating the value returned by sysinfo v0.25 as KiB instead of KB.

The changes in this PR have been tested by building an aziot-edge package using the CI pipeline and installing it on a VM device. The 'iotedge check' and edgeAgent metrics were then checked to confirm that the values are now correct.

## Azure IoT Edge PR checklist:
  • Loading branch information
nlcamp authored Mar 10, 2023
1 parent 907eef1 commit b29d736
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 8 deletions.
4 changes: 2 additions & 2 deletions edgelet/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion edgelet/edgelet-docker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ nix = "0.26"
serde = "1"
serde_json = "1"
serial_test = "1"
sysinfo = "0.27"
sysinfo = "0.28"
thiserror = "1"
tokio = { version = "1", features = ["parking_lot", "sync"] }
url = "2"
Expand Down
53 changes: 50 additions & 3 deletions edgelet/edgelet-docker/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ where
let total_memory = {
let mut system_resources = self.system_resources.as_ref().lock().await;
system_resources.refresh_memory();
system_resources.total_memory() * 1024
total_memory_bytes(&system_resources)
};

let mut system_info = CoreSystemInfo::default();
Expand Down Expand Up @@ -616,8 +616,8 @@ where
.as_secs();

let used_cpu = system_resources.global_cpu_info().cpu_usage();
let total_memory = system_resources.total_memory() * 1024;
let used_memory = system_resources.used_memory() * 1024;
let total_memory = total_memory_bytes(&system_resources);
let used_memory = used_memory_bytes(&system_resources);

let disks = system_resources
.disks()
Expand Down Expand Up @@ -852,6 +852,14 @@ where
}
}

fn total_memory_bytes(system_resources: &System) -> u64 {
system_resources.total_memory()
}

fn used_memory_bytes(system_resources: &System) -> u64 {
system_resources.used_memory()
}

fn parse_top_response<'de, D>(resp: &InlineResponse2001) -> Result<Vec<i32>, D::Error>
where
D: serde::Deserializer<'de>,
Expand Down Expand Up @@ -952,6 +960,8 @@ fn drop_unsafe_privileges(

#[cfg(test)]
mod tests {
use std::process::{Command, Stdio};

use super::*;

#[test]
Expand Down Expand Up @@ -1082,4 +1092,41 @@ mod tests {
Some(&vec!["SETUID".to_owned()])
);
}

// Compare the total memory returned by the 'total_memory_bytes()' helper method
// to the value in /proc/meminfo
#[test]
fn test_total_memory_bytes() {
// Use 'total_memory_bytes()' helper method to get total memory
let system_resources = System::new_all();
let total_memory_bytes = total_memory_bytes(&system_resources);

// Get expected total memory directly from /proc/meminfo
let cat_proc_meminfo = Command::new("cat")
.arg("/proc/meminfo")
.stdout(Stdio::piped())
.spawn()
.expect("Failed to execute 'cat /proc/meminfo'");
let grep_memtotal = Command::new("grep")
.arg("-i")
.arg("memtotal")
.stdin(Stdio::from(cat_proc_meminfo.stdout.unwrap()))
.stdout(Stdio::piped())
.spawn()
.expect("Failed to execute 'grep -i memtotal'");
let grep_value = Command::new("grep")
.arg("-o")
.arg("[0-9]*")
.stdin(Stdio::from(grep_memtotal.stdout.unwrap()))
.stdout(Stdio::piped())
.spawn()
.expect("Failed to execute 'grep -o [0-9]*'");
let output = grep_value.wait_with_output().unwrap();
let expected_total_memory_kilobytes_str = str::from_utf8(&output.stdout).unwrap().trim();
let expected_total_memory_bytes =
expected_total_memory_kilobytes_str.parse::<u64>().unwrap() * 1024;

// Compare
assert_eq!(total_memory_bytes, expected_total_memory_bytes);
}
}
2 changes: 1 addition & 1 deletion edgelet/iotedge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ nix = "0.26"
regex = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
sysinfo = "0.27"
sysinfo = "0.28"
tabwriter = "1"
termcolor = "1"
thiserror = "1"
Expand Down
2 changes: 1 addition & 1 deletion edgelet/iotedge/src/check/additional_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ impl DiskInfo {
#[cfg(unix)]
fn pretty_kbyte(bytes: u64) -> String {
#[allow(clippy::cast_precision_loss)]
match Byte::from_unit(bytes as f64, ByteUnit::KiB) {
match Byte::from_unit(bytes as f64, ByteUnit::B) {
Ok(b) => b.get_appropriate_unit(true).format(2),
Err(err) => format!("could not parse bytes value: {:?}", err),
}
Expand Down

0 comments on commit b29d736

Please sign in to comment.