use std::collections::{HashMap, HashSet};
use sysinfo::{Disk, Disks};
pub struct DiskFilter {
excluded_prefixes: HashSet<&'static str>,
excluded_exact: HashSet<&'static str>,
docker_file_mounts: HashSet<&'static str>,
}
impl DiskFilter {
pub fn new() -> Self {
let mut excluded_prefixes = HashSet::new();
let mut excluded_exact = HashSet::new();
Self::add_macos_exclusions(&mut excluded_prefixes, &mut excluded_exact);
Self::add_linux_exclusions(&mut excluded_prefixes, &mut excluded_exact);
Self::add_common_exclusions(&mut excluded_prefixes, &mut excluded_exact);
Self::add_backendai_exclusions(&mut excluded_prefixes, &mut excluded_exact);
let mut docker_file_mounts = HashSet::new();
Self::add_docker_exclusions(&mut docker_file_mounts);
Self {
excluded_prefixes,
excluded_exact,
docker_file_mounts,
}
}
pub fn should_include(&self, mount_point: &str) -> bool {
if self.excluded_exact.contains(mount_point) {
return false;
}
if self.docker_file_mounts.contains(mount_point) {
return false;
}
for prefix in &self.excluded_prefixes {
if mount_point.starts_with(prefix) {
return false;
}
}
true
}
fn add_macos_exclusions(
prefixes: &mut HashSet<&'static str>,
exact: &mut HashSet<&'static str>,
) {
prefixes.insert("/System/Volumes/");
prefixes.insert("/Library/");
prefixes.insert("/Applications/");
prefixes.insert("/System/");
prefixes.insert("/private/");
prefixes.insert("/Volumes/VM/");
exact.insert("/Volumes"); prefixes.insert("/Network/");
prefixes.insert("/var/lib/docker/");
exact.insert("/var/lib/docker");
exact.insert("/Users/Shared");
exact.insert("/cores");
}
fn add_linux_exclusions(
prefixes: &mut HashSet<&'static str>,
exact: &mut HashSet<&'static str>,
) {
prefixes.insert("/dev/");
prefixes.insert("/proc/");
prefixes.insert("/sys/");
prefixes.insert("/run/");
prefixes.insert("/snap/");
prefixes.insert("/usr/");
prefixes.insert("/var/log/");
prefixes.insert("/var/cache/");
prefixes.insert("/var/lib/");
prefixes.insert("/var/tmp/");
prefixes.insert("/var/spool/");
prefixes.insert("/var/lib/docker/");
exact.insert("/var/lib/docker");
exact.insert("/boot");
exact.insert("/boot/efi");
exact.insert("/tmp");
exact.insert("/bin");
exact.insert("/sbin");
exact.insert("/etc");
exact.insert("/lib");
exact.insert("/lib64");
exact.insert("/opt");
exact.insert("/media");
exact.insert("/mnt");
exact.insert("/root");
exact.insert("/srv");
}
fn add_backendai_exclusions(
prefixes: &mut HashSet<&'static str>,
_exact: &mut HashSet<&'static str>,
) {
prefixes.insert("/opt/backend.ai/");
}
fn add_common_exclusions(
prefixes: &mut HashSet<&'static str>,
exact: &mut HashSet<&'static str>,
) {
prefixes.insert("/tmp/");
prefixes.insert("/var/tmp/");
prefixes.insert("/var/lib/docker/");
exact.insert("/var/lib/docker");
prefixes.insert("/var/lib/containerd/");
exact.insert("/var/lib/containerd");
}
fn add_docker_exclusions(docker_mounts: &mut HashSet<&'static str>) {
docker_mounts.insert("/etc/hosts");
docker_mounts.insert("/etc/hostname");
docker_mounts.insert("/etc/resolv.conf");
docker_mounts.insert("/etc/timezone");
docker_mounts.insert("/etc/localtime");
}
}
impl Default for DiskFilter {
fn default() -> Self {
Self::new()
}
}
use std::sync::OnceLock;
static DISK_FILTER: OnceLock<DiskFilter> = OnceLock::new();
pub fn filter_docker_aware_disks(disks: &Disks) -> Vec<&Disk> {
let filter = DISK_FILTER.get_or_init(DiskFilter::new);
let mut device_mount_count: HashMap<String, usize> = HashMap::new();
let mut device_to_disks: HashMap<String, Vec<&Disk>> = HashMap::new();
for disk in disks.list() {
let device_name = disk.name().to_string_lossy().to_string();
let mount_point = disk.mount_point().to_string_lossy().to_string();
if !filter.should_include(&mount_point) {
continue;
}
*device_mount_count.entry(device_name.clone()).or_insert(0) += 1;
device_to_disks.entry(device_name).or_default().push(disk);
}
let mut filtered_disks = Vec::new();
for (device_name, disks_for_device) in device_to_disks {
let mount_count = device_mount_count.get(&device_name).unwrap_or(&0);
if *mount_count > 5 {
for disk in disks_for_device {
let mount_point = disk.mount_point().to_string_lossy();
if is_primary_mount_point(&mount_point) {
filtered_disks.push(disk);
}
}
} else {
filtered_disks.extend(disks_for_device);
}
}
for disk in disks.list() {
let mount_point = disk.mount_point().to_string_lossy().to_string();
if (disk.file_system() == "overlay" || disk.file_system() == "overlay2")
&& filter.should_include(&mount_point)
&& !filtered_disks
.iter()
.any(|d| d.mount_point() == disk.mount_point())
{
filtered_disks.push(disk);
}
}
filtered_disks
}
fn is_primary_mount_point(mount_point: &str) -> bool {
const PRIMARY_MOUNTS: &[&str] = &[
"/",
"/home",
"/home/work",
"/data",
"/mnt",
"/opt",
"/var",
"/opt/backend.ai",
];
const DOCKER_FILE_PATTERNS: &[&str] = &[
"/usr/bin/",
"/usr/lib/",
"/opt/kernel/",
"/etc/backend.ai/jail/plugins/",
".so",
".json",
".py",
".sh",
".md",
"docker-init",
"nvidia-smi",
"cuda-mps",
];
if PRIMARY_MOUNTS.contains(&mount_point) {
return true;
}
for pattern in DOCKER_FILE_PATTERNS {
if mount_point.contains(pattern) {
return false;
}
}
for primary in PRIMARY_MOUNTS {
if mount_point.starts_with(primary) && mount_point.ends_with('/') {
return true;
}
}
if mount_point.ends_with(".so")
|| mount_point.ends_with(".json")
|| mount_point.ends_with(".py")
|| mount_point.ends_with(".sh")
|| mount_point.ends_with(".md")
{
return false;
}
if mount_point.ends_with('/') {
return true;
}
false
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_macos_exclusions() {
let filter = DiskFilter::new();
assert!(!filter.should_include("/System/Volumes/Data"));
assert!(!filter.should_include("/Library/Preferences"));
assert!(!filter.should_include("/Applications/Safari.app"));
assert!(!filter.should_include("/Users/Shared"));
assert!(!filter.should_include("/var/lib/docker"));
assert!(!filter.should_include("/var/lib/docker/volumes"));
assert!(filter.should_include("/Users/john"));
assert!(filter.should_include("/"));
assert!(filter.should_include("/Volumes/ExternalDrive"));
}
#[test]
fn test_linux_exclusions() {
let filter = DiskFilter::new();
assert!(!filter.should_include("/dev/sda1"));
assert!(!filter.should_include("/proc/meminfo"));
assert!(!filter.should_include("/sys/class"));
assert!(!filter.should_include("/run/user/1000"));
assert!(!filter.should_include("/usr/bin"));
assert!(!filter.should_include("/var/log/syslog"));
assert!(!filter.should_include("/var/lib/docker"));
assert!(!filter.should_include("/var/lib/docker/volumes"));
assert!(!filter.should_include("/boot/efi"));
assert!(filter.should_include("/home/user"));
assert!(filter.should_include("/"));
assert!(filter.should_include("/data"));
}
#[test]
fn test_docker_exclusions() {
let filter = DiskFilter::new();
assert!(!filter.should_include("/etc/hosts"));
assert!(!filter.should_include("/etc/hostname"));
assert!(!filter.should_include("/etc/resolv.conf"));
assert!(!filter.should_include("/etc/timezone"));
assert!(!filter.should_include("/etc/localtime"));
}
#[test]
fn test_is_primary_mount_point() {
assert!(is_primary_mount_point("/"));
assert!(is_primary_mount_point("/home"));
assert!(is_primary_mount_point("/home/work"));
assert!(is_primary_mount_point("/opt/backend.ai"));
assert!(is_primary_mount_point("/data"));
assert!(!is_primary_mount_point("/usr/bin/nvidia-smi"));
assert!(!is_primary_mount_point(
"/opt/kernel/libcudahook.ubuntu18.04.x86_64.so"
));
assert!(!is_primary_mount_point(
"/usr/lib/x86_64-linux-gnu/libnvidia-ml.so.575.51.03"
));
assert!(!is_primary_mount_point(
"/etc/backend.ai/jail/plugins/libcuda_jail.so"
));
assert!(is_primary_mount_point("/usr/local/"));
assert!(is_primary_mount_point("/opt/apps/"));
assert!(!is_primary_mount_point("/etc/hosts"));
}
#[test]
fn test_performance() {
let filter = DiskFilter::new();
let mount_points = [
"/",
"/home",
"/data",
"/System/Volumes/Data",
"/usr/bin",
"/var/log/messages",
"/Users/john",
"/Applications/Safari.app",
];
for mount_point in &mount_points {
filter.should_include(mount_point);
}
}
}