fix: false hdd detection on virtual devices#352
fix: false hdd detection on virtual devices#352KSXGitHub wants to merge 81 commits intoKSXGitHub:masterfrom
Conversation
The sysinfo crate reads /sys/block/*/queue/rotational to determine disk type, but virtual block devices (VirtIO, Xen, VMware PVSCSI, Hyper-V) default to rotational=1 because the kernel doesn't know the backing storage type. This caused pdu to falsely detect virtual disks as HDDs and unnecessarily limit threads to 1. The fix adds a secondary check on Linux: when sysinfo reports HDD, we read the block device's driver via /sys/block/<dev>/device/driver and reclassify known virtual drivers (virtio_blk, xen_blkfront, vmw_pvscsi, hyperv_storvsc) as Unknown instead of HDD. https://claude.ai/code/session_01MHKaZm6DcA9kjBPnW3KN5K
Apply rustfmt formatting and replace map_or with is_some_and per clippy. https://claude.ai/code/session_01MHKaZm6DcA9kjBPnW3KN5K
There was a problem hiding this comment.
Pull request overview
This PR adjusts HDD detection on Linux to avoid misclassifying virtual block devices as HDDs when sysinfo reports DiskKind::HDD due to the kernel’s rotational=1 default on some virtual devices.
Changes:
- Intercept
DiskKind::HDDon Linux and reclassify known virtual block-device drivers toDiskKind::Unknown(-1). - Add Linux-only helpers to extract a base block device name and check the sysfs driver symlink.
- Add Linux-specific tests for device-name extraction and virtual-driver detection.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| src/app/hdd.rs | Adds Linux-only correction path for HDD detection via /sys/block/<dev>/device/driver, plus device-name extraction. |
| src/app/hdd/test.rs | Adds Linux-only tests around extraction and virtual device detection (currently environment-dependent). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fix Hyper-V driver name: use 'hv_storvsc' (actual kernel name) instead of 'hyperv_storvsc' - Split extract_block_device_name into parse_block_device_name (pure parsing, no I/O) and validate_block_device (sysfs check), making the parsing logic independently testable - Update doc comments to document /dev/root handling - Make tests hermetic: test_parse_block_device_name asserts deterministically on all cases without depending on sysfs availability - Improve test_extract_and_check_real_disks to validate all disk types, not just VirtIO https://claude.ai/code/session_01MHKaZm6DcA9kjBPnW3KN5K
On macOS and FreeBSD, sysinfo reports DiskKind::Unknown because there is no reliable OS API for rotational vs solid-state detection. The HDD code path is never reached on those platforms today. Added a doc comment explaining this and noting the fragility if sysinfo improves detection. https://claude.ai/code/session_01MHKaZm6DcA9kjBPnW3KN5K
The Api trait's purpose is to enable dependency injection by delegating to sysinfo::Disk methods. get_disk_kind should only call disk.kind(), not apply platform-specific corrections. - RealApi::get_disk_kind now purely delegates to disk.kind() - Added get_disk_name to Api trait (delegates to disk.name()) - correct_hdd_detection takes (DiskKind, &str) instead of &Disk - Correction is applied in new is_in_hdd helper called from path_is_in_hdd - Updated MockedApi to implement get_disk_name https://claude.ai/code/session_01MHKaZm6DcA9kjBPnW3KN5K
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
The value passed (e.g. `/dev/vda1`) is a device path forwarded to `reclassify_virtual_hdd` as `disk_name`, not a filesystem mount point. Rename the macro parameter and doc string to match. https://claude.ai/code/session_01MHKaZm6DcA9kjBPnW3KN5K
Add the hyphenated `virtio-blk` driver name alongside the existing `virtio_blk` for consistency with the Xen dual-name treatment. Add a comment clarifying why the recursive `extract_block_device_name` call is safe (canonicalize resolves all symlinks). https://claude.ai/code/session_01MHKaZm6DcA9kjBPnW3KN5K
Replace all occurrences of `DiskKind::Unknown(-1)` with a named constant to make the intent explicit and avoid coupling to a specific numeric value across implementation and tests. https://claude.ai/code/session_01MHKaZm6DcA9kjBPnW3KN5K
…ariable `is_in_hdd` checks whether a disk IS an HDD, not whether something is IN an HDD — rename to `is_hdd`. Also rename the leftover `$mount` macro capture variable to `$disk_name` to match its parameter name. https://claude.ai/code/session_01MHKaZm6DcA9kjBPnW3KN5K
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
You can also share your feedback on Copilot code review. Take the survey.
| use super::{extract_block_device_name, is_virtual_block_device, RealFs}; | ||
|
|
||
| /// On hosts with a `/sys/block/vda` device, exercises the detection | ||
| /// pipeline without panicking. Silently skips if `vda` does not exist. | ||
| #[test] | ||
| fn real_sysfs_vda_does_not_panic() { | ||
| if std::path::Path::new("/sys/block/vda").exists() { | ||
| let _ = is_virtual_block_device::<RealFs>("vda"); | ||
| } | ||
| } | ||
|
|
||
| /// A non-existent device name must return `false` without panicking. | ||
| #[test] | ||
| fn nonexistent_device_is_not_virtual() { | ||
| assert!( | ||
| !is_virtual_block_device::<RealFs>("nonexistent_device_xyz"), | ||
| "non-existent device should not be detected as virtual" | ||
| ); | ||
| } | ||
|
|
||
| /// Runs the full detection pipeline on every mounted disk. | ||
| /// | ||
| /// Does **not** assert any specific virtual/non-virtual classification | ||
| /// because the result depends on the host hardware. Only verifies that | ||
| /// the pipeline completes without panicking. | ||
| #[test] | ||
| fn full_pipeline_does_not_panic() { | ||
| use sysinfo::Disks; | ||
| let disks = Disks::new_with_refreshed_list(); | ||
| for disk in disks.list() { | ||
| let name = disk.name().to_str().unwrap_or_default(); | ||
| if let Some(block_dev) = extract_block_device_name::<RealFs>(name) { | ||
| let _ = is_virtual_block_device::<RealFs>(&block_dev); | ||
| } | ||
| } | ||
| } |
| let name = disk.name().to_str().unwrap_or_default(); | ||
| if let Some(block_dev) = extract_block_device_name::<RealFs>(name) { |
| | "vmw_pvscsi" | ||
| | "hv_storvsc" |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
You can also share your feedback on Copilot code review. Take the survey.
Summary
Fixes virtual block devices (VirtIO, Xen, Hyper-V, VMware) on Linux being misclassified as HDDs. The kernel's
rotationalsysfs flag defaults to1for virtual devices, causingsysinfoto report them as HDDs. This PR checks the block device's driver via/sys/block/<dev>/device/driverand reclassifies known virtual drivers asDiskKind::Unknown(-1).Key Changes
Apitrait withDiskApi(&selfmethods, impl'd directly on disk types) +FsApi(static filesystem operations) for fine-grained test mockingreclassify_virtual_hdd()— checks sysfs driver and reclassifies virtual devices (Linux-only; no-op on other platforms)extract_block_device_name()— resolves/dev/mapper/,/dev/rootsymlinks and parses device paths (sd*,vd*,xvd*,nvme*,mmcblk*)is_virtual_block_device()— matches drivers:virtio_blk,xen_blkfront,xen-blkfront,vbd,vmw_pvscsi,hv_storvscpath_is_in_hddto filter by mount point first, then check disk kind/dev/dm-*) volumes are not traced to backing deviceshttps://claude.ai/code/session_01MHKaZm6DcA9kjBPnW3KN5K