lfs_core/
label.rs

1#[cfg(target_os = "linux")]
2use {
3    super::*,
4    snafu::prelude::*,
5    std::fs,
6};
7
8/// the labelling of a file-system, that is the pair (label, fs)
9#[derive(Debug, Clone)]
10pub struct Labelling {
11    pub label: String,
12    pub fs_name: String,
13}
14
15pub fn get_label(
16    fs_name: &str,
17    labellings: Option<&[Labelling]>,
18) -> Option<String> {
19    labellings.as_ref().and_then(|labels| {
20        labels
21            .iter()
22            .find(|label| label.fs_name == fs_name)
23            .map(|label| label.label.clone())
24    })
25}
26
27/// try to read all mappings defined in /dev/disk/by-<by_kind>,
28/// where by_kind is one of "label", "uuid", "partuuid", "diskseq", etc.
29///
30/// An error can't be excluded as not all systems expose
31/// this information the way lfs-core reads it.
32#[cfg(target_os = "linux")]
33pub fn read_by(by_kind: &str) -> Result<Vec<Labelling>, Error> {
34    let path = format!("/dev/disk/by-{by_kind}");
35    let entries = fs::read_dir(&path).context(CantReadDirSnafu { path })?;
36    let labels = entries
37        .filter_map(|entry| entry.ok())
38        .filter_map(|entry| {
39            let md = entry.metadata().ok()?;
40            let file_type = md.file_type();
41            if !file_type.is_symlink() {
42                return None;
43            }
44            let label = sys::decode_string(entry.file_name().to_string_lossy());
45            let linked_path = fs::read_link(entry.path())
46                .map(|path| path.to_string_lossy().to_string())
47                .ok()?;
48            let fs_name = format!("/dev/{}", linked_path.strip_prefix("../../")?,);
49            Some(Labelling { label, fs_name })
50        })
51        .collect();
52    Ok(labels)
53}