blockdev 0.3.1

A Rust library for parsing and working with lsblk JSON output, providing type-safe block device representation and utilities for Linux
Documentation

blockdev

Crates.io Documentation License

A lightweight Rust library for parsing and working with lsblk --json output on Linux. Provides type-safe block device representation with utilities for inspecting device properties, filtering system devices, and iterating over device hierarchies.

Features

  • Type-safe parsing - Strongly typed structs and enums for all block device properties
  • Flexible mountpoint handling - Supports both single and multiple mountpoints per device
  • System device detection - Identify devices mounted at / (including nested children)
  • Device filtering - Helper methods to separate system and non-system devices
  • Size parsing - Handles both byte values and human-readable sizes (e.g., 500G, 3.5T)
  • Full Serde support - Serialize and deserialize block device data
  • Idiomatic iteration - Implements IntoIterator for ergonomic Rust patterns

Installation

Add blockdev to your Cargo.toml:

[dependencies]
blockdev = "0.3"

Quick Start

use blockdev::get_devices;

fn main() -> Result<(), blockdev::BlockDevError> {
    // Get all block devices from the system
    let devices = get_devices()?;

    // Iterate over devices
    for device in &devices {
        println!("{}: {} bytes, type: {:?}",
            device.name,
            device.size,
            device.device_type
        );
    }

    Ok(())
}

Usage Examples

List All Non-System Disks

use blockdev::get_devices;

fn main() -> Result<(), blockdev::BlockDevError> {
    let devices = get_devices()?;

    // Get disks that don't contain the root filesystem
    for device in devices.non_system() {
        if device.is_disk() {
            println!("Available disk: {} ({} bytes)", device.name, device.size);
        }
    }

    Ok(())
}

Find a Specific Device

use blockdev::get_devices;

fn main() -> Result<(), blockdev::BlockDevError> {
    let devices = get_devices()?;

    if let Some(device) = devices.find_by_name("sda") {
        println!("Found sda:");
        println!("  Size: {} bytes", device.size);
        println!("  Type: {:?}", device.device_type);
        println!("  Major:Minor: {}", device.maj_min);
        println!("  Removable: {}", device.rm);
        println!("  Read-only: {}", device.ro);

        // Check partitions
        if device.has_children() {
            println!("  Partitions:");
            for child in device.children_iter() {
                println!("    - {}: {} bytes", child.name, child.size);
            }
        }
    }

    Ok(())
}

Parse Pre-Existing JSON

use blockdev::parse_lsblk;

fn main() -> Result<(), serde_json::Error> {
    let json = r#"{
        "blockdevices": [{
            "name": "sda",
            "maj:min": "8:0",
            "rm": false,
            "size": 500107862016,
            "ro": false,
            "type": "disk",
            "mountpoints": [null],
            "children": [{
                "name": "sda1",
                "maj:min": "8:1",
                "rm": false,
                "size": 500106813440,
                "ro": false,
                "type": "part",
                "mountpoints": ["/data"]
            }]
        }]
    }"#;

    let devices = parse_lsblk(json)?;
    println!("Parsed {} devices", devices.len());

    Ok(())
}

Check Mountpoints

use blockdev::get_devices;

fn main() -> Result<(), blockdev::BlockDevError> {
    let devices = get_devices()?;

    for device in &devices {
        if device.is_mounted() {
            println!("{} is mounted at: {:?}",
                device.name,
                device.active_mountpoints()
            );
        }

        // Check children too
        for child in device.children_iter() {
            if child.is_mounted() {
                println!("  {} is mounted at: {:?}",
                    child.name,
                    child.active_mountpoints()
                );
            }
        }
    }

    Ok(())
}

API Reference

Functions

Function Description
get_devices() Execute lsblk --json --bytes and parse the output
parse_lsblk(json) Parse a JSON string from lsblk without executing the command

Types

BlockDevices

Container for the parsed lsblk output.

Method Description
len() Number of top-level devices
is_empty() Check if no devices exist
iter() Iterate over device references
system() Get devices containing the root mountpoint
non_system() Get devices not containing the root mountpoint
find_by_name(name) Find a device by name

BlockDevice

Represents a single block device.

Field Type Description
name String Device name (e.g., sda, nvme0n1)
maj_min MajMin Major and minor device numbers
rm bool Whether the device is removable
size u64 Size in bytes
ro bool Whether the device is read-only
device_type DeviceType Type of device
mountpoints Vec<Option<String>> Mountpoint(s) for the device
children Option<Vec<BlockDevice>> Nested devices (e.g., partitions)
Method Description
has_children() Check if the device has child devices
children_iter() Iterate over child devices
find_child(name) Find a child device by name
active_mountpoints() Get all non-null mountpoints
is_mounted() Check if the device has any mountpoint
is_system() Check if the device or children contain /
is_disk() Check if device type is Disk
is_partition() Check if device type is Part

DeviceType

Enum representing block device types:

  • Disk - Physical disk
  • Part - Partition
  • Loop - Loop device
  • Raid0, Raid1, Raid5, Raid6, Raid10 - RAID arrays
  • Lvm - LVM logical volume
  • Crypt - dm-crypt device
  • Rom - CD/DVD drive
  • Other - Unknown device type

MajMin

Represents major and minor device numbers.

Field Type Description
major u32 Major device number
minor u32 Minor device number

Implements Display to format as major:minor.

BlockDevError

Error type for library operations:

  • CommandFailed - Failed to execute lsblk
  • LsblkError - lsblk returned non-zero exit status
  • InvalidUtf8 - Output contained invalid UTF-8
  • JsonParse - Failed to parse JSON output

Requirements

  • Linux operating system (for lsblk command)
  • lsblk with JSON output support (util-linux 2.27+)

License

MIT License - see LICENSE for details.