Skip to content

Commit 1909245

Browse files
committed
disks: Add discovery of virtual devices (/dev/vd*)
We've used the name `virt` because `virtual` is reserved. Signed-off-by: Ikey Doherty <[email protected]>
1 parent 53f48b7 commit 1909245

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

crates/disks/src/disk.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::{
99
path::{Path, PathBuf},
1010
};
1111

12-
use crate::{mmc, nvme, partition::Partition, scsi, sysfs, DEVFS_DIR};
12+
use crate::{mmc, nvme, partition::Partition, scsi, sysfs, virt, DEVFS_DIR};
1313

1414
/// Represents the type of disk device.
1515
#[derive(Debug)]
@@ -20,6 +20,8 @@ pub enum Disk {
2020
Mmc(mmc::Disk),
2121
/// NVMe disk device (e.g. nvme0n1)
2222
Nvme(nvme::Disk),
23+
/// Virtual disk device
24+
Virtual(virt::Disk),
2325
}
2426

2527
impl Deref for Disk {
@@ -31,6 +33,7 @@ impl Deref for Disk {
3133
Disk::Mmc(disk) => disk,
3234
Disk::Nvme(disk) => disk,
3335
Disk::Scsi(disk) => disk,
36+
Disk::Virtual(disk) => disk,
3437
}
3538
}
3639
}

crates/disks/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub mod nvme;
1515
pub mod partition;
1616
pub mod scsi;
1717
mod sysfs;
18+
pub mod virt;
1819

1920
const SYSFS_DIR: &str = "/sys/class/block";
2021
const DEVFS_DIR: &str = "/dev";
@@ -83,6 +84,8 @@ impl BlockDevice {
8384
BlockDevice::Disk(Box::new(Disk::Nvme(disk)))
8485
} else if let Some(disk) = mmc::Disk::from_sysfs_path(&sysfs_dir, &entry) {
8586
BlockDevice::Disk(Box::new(Disk::Mmc(disk)))
87+
} else if let Some(device) = virt::Disk::from_sysfs_path(&sysfs_dir, &entry) {
88+
BlockDevice::Disk(Box::new(Disk::Virtual(device)))
8689
} else if let Some(device) = loopback::Device::from_sysfs_path(&sysfs_dir, &entry) {
8790
BlockDevice::Loopback(Box::new(device))
8891
} else {

crates/disks/src/virt.rs

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// SPDX-FileCopyrightText: Copyright © 2025 Serpent OS Developers
2+
//
3+
// SPDX-License-Identifier: MPL-2.0
4+
5+
//! Virtual disk device enumeration and handling.
6+
//!
7+
//! In Linux systems, virtual disk devices are exposed through
8+
//! the block subsystem. This module handles enumeration and management of these devices,
9+
//! which appear as `/dev/vd*` block devices.
10+
11+
use std::{ops::Deref, path::Path};
12+
13+
use crate::{BasicDisk, DiskInit};
14+
15+
/// Represents a virtual disk device.
16+
///
17+
/// This struct wraps a BasicDisk to provide virtual disk-specific functionality.
18+
#[derive(Debug)]
19+
pub struct Disk(pub BasicDisk);
20+
21+
impl Deref for Disk {
22+
type Target = BasicDisk;
23+
24+
fn deref(&self) -> &Self::Target {
25+
&self.0
26+
}
27+
}
28+
29+
impl DiskInit for Disk {
30+
/// Creates a new Disk instance from a sysfs path if the device name matches virtual disk naming pattern.
31+
///
32+
/// # Arguments
33+
///
34+
/// * `sysroot` - The root path of the sysfs filesystem
35+
/// * `name` - The device name to check (e.g. "vda", "vdb")
36+
///
37+
/// # Returns
38+
///
39+
/// * `Some(Disk)` if the name matches virtual disk pattern (starts with "vd" followed by letters)
40+
/// * `None` if the name doesn't match or the device can't be initialized
41+
fn from_sysfs_path(sysroot: &Path, name: &str) -> Option<Self> {
42+
let matching = name.starts_with("vd") && name[2..].chars().all(char::is_alphabetic);
43+
if matching {
44+
Some(Self(BasicDisk::from_sysfs_path(sysroot, name)?))
45+
} else {
46+
None
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)