Skip to main content

btrfs_cli/subvolume/
get_default.rs

1use crate::{
2    Format, RunContext, Runnable,
3    util::{open_path, print_json},
4};
5use anyhow::{Context, Result};
6use btrfs_uapi::subvolume::{FS_TREE_OBJECTID, subvolume_default_get};
7use clap::Parser;
8use serde::Serialize;
9use std::{os::unix::io::AsFd, path::PathBuf};
10
11/// Show the default subvolume of a filesystem
12#[derive(Parser, Debug)]
13pub struct SubvolumeGetDefaultCommand {
14    /// Path to a mounted btrfs filesystem
15    pub path: PathBuf,
16}
17
18#[derive(Serialize)]
19struct DefaultSubvolJson {
20    id: u64,
21    name: String,
22}
23
24impl Runnable for SubvolumeGetDefaultCommand {
25    fn supported_formats(&self) -> &[Format] {
26        &[Format::Text, Format::Json, Format::Modern]
27    }
28
29    fn run(&self, ctx: &RunContext) -> Result<()> {
30        let file = open_path(&self.path)?;
31
32        let default_id =
33            subvolume_default_get(file.as_fd()).with_context(|| {
34                format!(
35                    "failed to get default subvolume for '{}'",
36                    self.path.display()
37                )
38            })?;
39
40        let name = if default_id == FS_TREE_OBJECTID {
41            "FS_TREE".to_string()
42        } else {
43            format!("{default_id}")
44        };
45
46        match ctx.format {
47            Format::Modern | Format::Text => {
48                if default_id == FS_TREE_OBJECTID {
49                    println!("ID 5 (FS_TREE)");
50                } else {
51                    println!("ID {default_id}");
52                }
53            }
54            Format::Json => {
55                print_json(
56                    "default-subvolume",
57                    &DefaultSubvolJson {
58                        id: default_id,
59                        name,
60                    },
61                )?;
62            }
63        }
64
65        Ok(())
66    }
67}