aboutsummaryrefslogtreecommitdiff
path: root/src/rpc/system.rs
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2023-09-11 20:00:02 +0200
committerAlex Auvolat <alex@adnab.me>2023-09-11 20:00:02 +0200
commit51abbb02d8b77529c2e3db079d527d0f28c737bc (patch)
tree5dbc1611f968214ba103c73cd0cf2cc966696eef /src/rpc/system.rs
parentad6b1cc0bed8a01ebeb2aacf995a69ced785b5a6 (diff)
parent2548a247f22a6404a2f447e9f9c47fe18e10f67a (diff)
downloadgarage-51abbb02d8b77529c2e3db079d527d0f28c737bc.tar.gz
garage-51abbb02d8b77529c2e3db079d527d0f28c737bc.zip
Merge branch 'main' into next
Diffstat (limited to 'src/rpc/system.rs')
-rw-r--r--src/rpc/system.rs66
1 files changed, 30 insertions, 36 deletions
diff --git a/src/rpc/system.rs b/src/rpc/system.rs
index cf480549..b76e6d4a 100644
--- a/src/rpc/system.rs
+++ b/src/rpc/system.rs
@@ -896,46 +896,40 @@ impl NodeStatus {
data_dir: &DataDirEnum,
metrics: &SystemMetrics,
) {
- use systemstat::{Platform, System};
- let mounts = System::new().mounts().unwrap_or_default();
-
- let mount_avail = |path: &Path| {
- mounts
- .iter()
- .filter(|x| path.starts_with(&x.fs_mounted_on))
- .max_by_key(|x| x.fs_mounted_on.len())
- .map(|x| (x.avail.as_u64(), x.total.as_u64()))
+ use nix::sys::statvfs::statvfs;
+ let mount_avail = |path: &Path| match statvfs(path) {
+ Ok(x) => {
+ let avail = x.blocks_available() * x.fragment_size();
+ let total = x.blocks() * x.fragment_size();
+ Some((x.filesystem_id(), avail, total))
+ }
+ Err(_) => None,
};
- self.meta_disk_avail = mount_avail(meta_dir);
+ self.meta_disk_avail = mount_avail(meta_dir).map(|(_, a, t)| (a, t));
self.data_disk_avail = match data_dir {
- DataDirEnum::Single(dir) => mount_avail(dir),
- DataDirEnum::Multiple(dirs) => {
- // Take mounts corresponding to all specified data directories that
- // can be used for writing data
- let mounts = dirs
- .iter()
- .filter(|dir| dir.capacity.is_some())
- .map(|dir| {
- mounts
- .iter()
- .filter(|mnt| dir.path.starts_with(&mnt.fs_mounted_on))
- .max_by_key(|mnt| mnt.fs_mounted_on.len())
- })
- .collect::<Vec<_>>();
- if mounts.iter().any(|x| x.is_none()) {
- None // could not get info for at least one mount
- } else {
- // dedup mounts in case several data directories are on the same filesystem
- let mut mounts = mounts.iter().map(|x| x.unwrap()).collect::<Vec<_>>();
- mounts.sort_by(|x, y| x.fs_mounted_on.cmp(&y.fs_mounted_on));
- mounts.dedup_by(|x, y| x.fs_mounted_on == y.fs_mounted_on);
- // calculate sum of available and total space
- Some(mounts.iter().fold((0, 0), |(x, y), mnt| {
- (x + mnt.avail.as_u64(), y + mnt.total.as_u64())
- }))
+ DataDirEnum::Single(dir) => mount_avail(dir).map(|(_, a, t)| (a, t)),
+ DataDirEnum::Multiple(dirs) => (|| {
+ // TODO: more precise calculation that takes into account
+ // how data is going to be spread among partitions
+ let mut mounts = HashMap::new();
+ for dir in dirs.iter() {
+ if dir.capacity.is_none() {
+ continue;
+ }
+ match mount_avail(&dir.path) {
+ Some((fsid, avail, total)) => {
+ mounts.insert(fsid, (avail, total));
+ }
+ None => return None,
+ }
}
- }
+ Some(
+ mounts
+ .into_iter()
+ .fold((0, 0), |(x, y), (_, (a, b))| (x + a, y + b)),
+ )
+ })(),
};
if let Some((avail, total)) = self.meta_disk_avail {