Skip to main content

btrfs_cli/balance/
status.rs

1use super::open_path;
2use crate::{RunContext, Runnable};
3use anyhow::{Context, Result};
4use btrfs_uapi::balance::{BalanceState, balance_progress};
5use clap::Parser;
6use nix::errno::Errno;
7use std::{os::unix::io::AsFd, path::PathBuf};
8
9/// Show status of running or paused balance operation.
10#[derive(Parser, Debug)]
11pub struct BalanceStatusCommand {
12    pub path: PathBuf,
13}
14
15impl Runnable for BalanceStatusCommand {
16    fn run(&self, _ctx: &RunContext) -> Result<()> {
17        let file = open_path(&self.path)?;
18
19        match balance_progress(file.as_fd()) {
20            Ok((state, progress)) => {
21                if state.contains(BalanceState::RUNNING) {
22                    print!("Balance on '{}' is running", self.path.display());
23                    if state.contains(BalanceState::CANCEL_REQ) {
24                        println!(", cancel requested");
25                    } else if state.contains(BalanceState::PAUSE_REQ) {
26                        println!(", pause requested");
27                    } else {
28                        println!();
29                    }
30                } else {
31                    println!("Balance on '{}' is paused", self.path.display());
32                }
33
34                #[allow(clippy::cast_precision_loss)]
35                let pct_left = if progress.expected > 0 {
36                    100.0
37                        * (1.0
38                            - progress.completed as f64
39                                / progress.expected as f64)
40                } else {
41                    0.0
42                };
43
44                println!(
45                    "{} out of about {} chunks balanced ({} considered), {:3.0}% left",
46                    progress.completed,
47                    progress.expected,
48                    progress.considered,
49                    pct_left
50                );
51
52                Ok(())
53            }
54            Err(Errno::ENOTCONN) => {
55                println!("No balance found on '{}'", self.path.display());
56                Ok(())
57            }
58            Err(e) => Err(e).with_context(|| {
59                format!("balance status on '{}' failed", self.path.display())
60            }),
61        }
62    }
63}