Skip to content

Commit

Permalink
disks: Add discovery of virtual devices (/dev/vd*)
Browse files Browse the repository at this point in the history
We've used the name `virt` because `virtual` is reserved.

Signed-off-by: Ikey Doherty <[email protected]>
  • Loading branch information
ikeycode committed Jan 22, 2025
1 parent 53f48b7 commit 1909245
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
5 changes: 4 additions & 1 deletion crates/disks/src/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::{
path::{Path, PathBuf},
};

use crate::{mmc, nvme, partition::Partition, scsi, sysfs, DEVFS_DIR};
use crate::{mmc, nvme, partition::Partition, scsi, sysfs, virt, DEVFS_DIR};

/// Represents the type of disk device.
#[derive(Debug)]
Expand All @@ -20,6 +20,8 @@ pub enum Disk {
Mmc(mmc::Disk),
/// NVMe disk device (e.g. nvme0n1)
Nvme(nvme::Disk),
/// Virtual disk device
Virtual(virt::Disk),
}

impl Deref for Disk {
Expand All @@ -31,6 +33,7 @@ impl Deref for Disk {
Disk::Mmc(disk) => disk,
Disk::Nvme(disk) => disk,
Disk::Scsi(disk) => disk,
Disk::Virtual(disk) => disk,
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/disks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod nvme;
pub mod partition;
pub mod scsi;
mod sysfs;
pub mod virt;

const SYSFS_DIR: &str = "/sys/class/block";
const DEVFS_DIR: &str = "/dev";
Expand Down Expand Up @@ -83,6 +84,8 @@ impl BlockDevice {
BlockDevice::Disk(Box::new(Disk::Nvme(disk)))
} else if let Some(disk) = mmc::Disk::from_sysfs_path(&sysfs_dir, &entry) {
BlockDevice::Disk(Box::new(Disk::Mmc(disk)))
} else if let Some(device) = virt::Disk::from_sysfs_path(&sysfs_dir, &entry) {
BlockDevice::Disk(Box::new(Disk::Virtual(device)))
} else if let Some(device) = loopback::Device::from_sysfs_path(&sysfs_dir, &entry) {
BlockDevice::Loopback(Box::new(device))
} else {
Expand Down
49 changes: 49 additions & 0 deletions crates/disks/src/virt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-FileCopyrightText: Copyright © 2025 Serpent OS Developers
//
// SPDX-License-Identifier: MPL-2.0

//! Virtual disk device enumeration and handling.
//!
//! In Linux systems, virtual disk devices are exposed through
//! the block subsystem. This module handles enumeration and management of these devices,
//! which appear as `/dev/vd*` block devices.
use std::{ops::Deref, path::Path};

use crate::{BasicDisk, DiskInit};

/// Represents a virtual disk device.
///
/// This struct wraps a BasicDisk to provide virtual disk-specific functionality.
#[derive(Debug)]
pub struct Disk(pub BasicDisk);

impl Deref for Disk {
type Target = BasicDisk;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl DiskInit for Disk {
/// Creates a new Disk instance from a sysfs path if the device name matches virtual disk naming pattern.
///
/// # Arguments
///
/// * `sysroot` - The root path of the sysfs filesystem
/// * `name` - The device name to check (e.g. "vda", "vdb")
///
/// # Returns
///
/// * `Some(Disk)` if the name matches virtual disk pattern (starts with "vd" followed by letters)
/// * `None` if the name doesn't match or the device can't be initialized
fn from_sysfs_path(sysroot: &Path, name: &str) -> Option<Self> {
let matching = name.starts_with("vd") && name[2..].chars().all(char::is_alphabetic);
if matching {
Some(Self(BasicDisk::from_sysfs_path(sysroot, name)?))
} else {
None
}
}
}

0 comments on commit 1909245

Please sign in to comment.