Crate rsblkid

source
Expand description

§Table of Contents

  1. Description
  2. API structure
  3. From libblkid to rsblkid
    1. High-Level functions
      1. Tag and spec evaluation
      2. Cache basic routines
      3. Search and iterate over devices in the cache
    2. Low-Level functions
      1. Library initialization
      2. Low-level probing
      3. Low-level tags
      4. Superblocks probing
      5. Partitions probing
      6. Topology information
    3. Common utils
      1. Encoding utils
      2. Miscellaneous utils

§Description

The rsblkid library is a safe Rust wrapper around util-linux/libblkid.

The libblkid library helps identify disks (block devices), the file systems they use to store content, as well as extracting additional information such as:

  • File system labels,
  • Volume names,
  • Unique identifiers,
  • Serial numbers,
  • etc.

rsblkid presents the data it gathers as key/value pairs (tags), where the keys can be for example a device’s LABEL, UUID, file system TYPE, etc. (see FsProperty for the list of keys supported by rsblkid).

§API structure

rsblkid’s API is roughly divided into two parts, a high-level API that keeps information about block devices in a cache file, and a low-level API that offers more fine grained methods to extract data about file systems, device partitions, and disk topology.

Provided it has permission to read raw block devices, the high-level part of the library checks that device information is always up-to-date before returning it to the user. The cache file allows unprivileged users, i.e. anyone other than root or a member of the disk user group, to locate devices by label or id.

use std::path::PathBuf;
use rsblkid::core::device::Tag;
use rsblkid::cache::Cache;

fn main() -> rsblkid::Result<()> {
    let mut cache = Cache::builder()
        .discard_changes_on_drop()
        .build()?;

    cache.probe_all_devices()?;

    // Find the absolute path to the device with the UUID.
    let uuid: Tag = r#"UUID="ac4f36bf-191b-4fb0-b808-6d7fc9fc88be""#.parse()?;
    let actual = cache.find_canonical_device_name_from_tag(&uuid);
    let device_name = PathBuf::from("/dev/vda");
    let expected = Some(device_name);

    assert_eq!(actual, expected);

    Ok(())
}

To determine the values of the LABEL or UUID tags of a block device, the high-level API supports two methods:

  • extracting data directly by scanning a block device,
  • or reading information from udev’s /dev/disk/by-* symlinks (method used by default).

The low-level API, on the other hand, always scans a block device directly. It offers more fine-grained control over the data collected.

use rsblkid::probe::{Probe, ScanResult};

fn main() -> rsblkid::Result<()> {
    let mut probe = Probe::builder()
        .scan_device("/dev/vda")
        // Superblocks scanning is active by default, setting this option to `true` here
        // is redundant.
        .scan_device_superblocks(true)
        // Activate partition search functions.
        .scan_device_partitions(true)
        // Search for partition entries ONLY in DOS or GPT partition tables
        .scan_partitions_for_partition_tables(Filter::In,
            vec![
                PartitionTableType::DOS,
                PartitionTableType::GPT,
            ])
        // Activate topology search functions.
        .scan_device_topology(true)
        .build()?;

    match probe.find_device_properties() {
        ScanResult::FoundProperties => {
            // Print collected file system properties
            for property in probe.iter_device_properties() {
                println!("{property}")
            }

            println!();

            // Print metadata about partition table entries
            // Header
            println!("Partition table");
            println!("{} {:>10} {:>10}  {:>10}\n----", "number", "start", "size", "part_type");

            for partition in probe.iter_partitions() {
                let number = partition.number();
                let start = partition.location_in_sectors();
                let size = partition.size_in_sectors();
                let part_type = partition.partition_type();

                // Row
                println!("#{}: {:>10} {:>10}  0x{:x}", number, start, size, part_type)
            }

            println!();

            // Print metadata about device topology
            let topology = probe.topology()?;

            let alignment_offset = topology.alignment_offset_in_bytes();
            let dax_support = if topology.supports_dax() { "yes" } else { "no" };
            let minimum_io_size = topology.minimum_io_size();
            let optimal_io_size = topology.optimal_io_size();
            let logical_sector_size = topology.logical_sector_size();
            let physical_sector_size = topology.physical_sector_size();


            println!("Alignment offset (bytes): {}", alignment_offset);
            println!("Direct Access support (DAX): {}", dax_support);
            println!("Minimum I/O size (bytes): {}", minimum_io_size);
            println!("Optimal I/O size (bytes): {}", optimal_io_size);
            println!("Logical sector size (bytes): {}", logical_sector_size);
            println!("Physical sector size (bytes): {}", physical_sector_size);
        }
        _ => eprintln!("could not find device properties"),
    }

    // Example output
    //
    // LABEL="nixos"
    // UUID="ac4f36bf-191b-4fb0-b808-6d7fc9fc88be"
    // BLOCK_SIZE="1024"
    // TYPE="ext4"
    //
    // Partition table
    // number    start      size  part_type
    // ----
    // #1:          34      2014        0x0
    // #2:        2048      2048        0x0
    // #3:        4096      2048        0x0
    // #4:        6144      2048        0x0
    // #5:        8192      2048        0x0
    //
    // Alignment offset (bytes): 0
    // Direct Access support (DAX): no
    // Minimum I/O size (bytes): 512
    // Optimal I/O size (bytes): 0
    // Logical sector size (bytes): 512
    // Physical sector size (bytes): 512

    Ok(())
}

§From libblkid to rsblkid

This section maps libblkid functions to rsblkid methods. It follows the same layout as libblkid’s documentation. You can use it as a reference to ease the transition from one API to the other.

§High-Level functions

§Tag and spec evaluation
§Cache basic routines
§Search and iterate over devices in the cache

§Low-Level functions

§Library initialization
§Low-level probing
libblkidrsblkid
blkid_free_probeProbe is automatically deallocated when it goes out of scope.
blkid_new_probeProbe::builder
blkid_new_probe_from_filenameProbeBuilder::scan_device
blkid_probe_get_devnoProbe::device_number
blkid_probe_get_fdProbe::device_file
blkid_probe_get_offsetProbe::scanned_device_segment_location
blkid_probe_get_sectorsProbe::device_size_in_sectors
blkid_probe_get_sectorsizeProbe::device_logical_sector_size
blkid_probe_get_sizeProbe::scanned_device_segment_size
blkid_probe_get_wholedisk_devnoProbe::device_whole_disk_number
blkid_probe_hide_rangeProbe::device_skip_bytes
blkid_probe_is_wholediskProbe::is_device_whole_disk
blkid_probe_reset_buffersProbe::empty_buffers
blkid_probe_reset_hintsProbe::discard_hints
blkid_probe_set_deviceNot implemented.
blkid_probe_set_hintProbe::set_hint
blkid_probe_set_sectorsizeProbeBuilder::bytes_per_sector
blkid_probe_step_backProbe::backtrack
blkid_reset_probeProbe::reset
§Low-level tags
§Superblocks probing
libblkidrsblkid
blkid_probe_enable_superblocksProbeBuilder::scan_device_superblocks
blkid_known_fstypeNot implemented. FileSystem lists all supported file systems.
blkid_superblocks_get_nameProbe::iter_supported_file_systems
blkid_probe_filter_superblocks_typeProbeBuilder::scan_superblocks_for_file_systems
Probe::scan_superblocks_for_file_systems
blkid_probe_filter_superblocks_usageProbeBuilder::scan_superblocks_with_usage_flags
Probe::scan_superblocks_with_usage_flags
blkid_probe_invert_superblocks_filterProbe::invert_superblocks_scanning_filter
blkid_probe_reset_superblocks_filterProbe::reset_superblocks_scanning_filter
blkid_probe_set_superblocks_flagsProbe::collect_fs_properties
blkid_probe_reset_filterDeprecated.
blkid_probe_filter_typesDeprecated.
blkid_probe_filter_usageDeprecated.
blkid_probe_invert_filterDeprecated.
blkid_probe_set_requestDeprecated.
§Partitions probing
libblkidrsblkid
blkid_probe_enable_partitionsProbeBuilder::scan_device_partitions
blkid_probe_set_partitions_flagsProbeBuilder::partitions_scanning_options
Probe::set_partitions_scanning_options
blkid_probe_filter_partitions_typeProbeBuilder::scan_partitions_for_partition_tables
Probe::scan_partitions_for_partition_tables
blkid_probe_invert_partitions_filterProbe::invert_partitions_scanning_filter
blkid_probe_reset_partitions_filterProbe::reset_partitions_scanning_filter
blkid_known_pttypeNot implemented. PartitionTableType lists all supported partition table types.
blkid_partitions_get_nameProbe::iter_supported_partition_tables
blkid_partition_get_namePartition::name
blkid_partition_get_flagsPartition::flags
blkid_partition_get_partnoPartition::number
blkid_partition_get_sizePartition::size_in_sectors
blkid_partition_get_startPartition::location_in_sectors
blkid_partition_get_tablePartition::partition_table
blkid_partition_get_typePartition::partition_type
blkid_partition_get_type_stringPartition::partition_type_string
blkid_partition_get_uuidPartition::uuid
blkid_partition_is_extendedPartition::is_extended
blkid_partition_is_logicalPartition::is_logical
blkid_partition_is_primaryPartition::is_primary
blkid_partlist_get_partitionPartitionIter::nth
blkid_partlist_get_partition_by_partnoPartitionIter::nth_by_partition_number
blkid_partlist_numof_partitionsPartitionIter::count
blkid_partlist_devno_to_partitionPartitionIter::partition_from_device_number
blkid_partlist_get_tablePartitionIter::partition_table
blkid_parttable_get_idPartitionTable::id
blkid_parttable_get_offsetPartitionTable::location_in_bytes
blkid_parttable_get_parentPartitionTable::parent
blkid_parttable_get_typePartitionTable::partition_table_type
blkid_probe_get_partitionsProbe::iter_partitions
§Topology information

§Common Utils

§Encoding utils
§Miscellaneous utils

Modules§

  • High-level API to handle device identification and tag extraction.
  • Shared objects and helper functions.
  • Activate debug message output.
  • Low-level API to probe block devices.

Enums§

Type Aliases§