1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
mod sys;

pub use sys::*;

use libc::statvfs;
use serde::Serialize;
use std::ffi::CString;
use std::io::Error;

/// Struct containing a disk' information.
#[derive(Debug, Clone, Serialize)]
pub struct Disks {
    pub name: String,
    pub mount_point: String,
    pub total_space: u64,
    pub avail_space: u64,
}

/// Struct containing a disk_io (bytes read/wrtn) information.
#[derive(Debug, Clone, Serialize)]
pub struct IoStats {
    pub device_name: String,
    pub bytes_read: i64,
    pub bytes_wrtn: i64,
}

/// Return the total/free space of a Disk from it's path (mount_point).
pub(crate) fn disk_usage<P>(path: P) -> Result<(u64, u64), Error>
where
    P: AsRef<[u8]>,
{
    let mut statvfs = std::mem::MaybeUninit::<statvfs>::uninit();

    if unsafe { libc::statvfs(CString::new(path.as_ref())?.as_ptr(), statvfs.as_mut_ptr()) } == -1 {
        return Err(Error::last_os_error());
    }

    let statvfs = unsafe { statvfs.assume_init() };
    let total = statvfs.f_blocks as u64 * statvfs.f_bsize as u64;
    let free = statvfs.f_bavail as u64 * statvfs.f_bsize as u64;

    Ok((total, free))
}

/// Detect if a filesysteme is for a physical drive or not.
/// This is not 100% true, but it's true enough for me.
/// The better approach would be to read the filesystems from /proc/filesystems
/// maybe construct a lazy_static array of filesystems.
pub(crate) fn is_physical_filesys(filesysteme: &str) -> bool {
    matches!(
        filesysteme,
        "ext2"
            | "ext3"
            | "ext4"
            | "vfat"
            | "ntfs"
            | "zfs"
            | "hfs"
            | "reiserfs"
            | "reiser4"
            | "exfat"
            | "f2fs"
            | "hfsplus"
            | "jfs"
            | "btrfs"
            | "minix"
            | "nilfs"
            | "xfs"
            | "apfs"
            | "fuseblk"
    )
}