Skip to main content

btrfs_cli/balance/
status.rs

1use super::open_path;
2use crate::{Format, 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, _format: Format, _dry_run: bool) -> 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                let pct_left = if progress.expected > 0 {
35                    100.0
36                        * (1.0
37                            - progress.completed as f64
38                                / progress.expected as f64)
39                } else {
40                    0.0
41                };
42
43                println!(
44                    "{} out of about {} chunks balanced ({} considered), {:3.0}% left",
45                    progress.completed,
46                    progress.expected,
47                    progress.considered,
48                    pct_left
49                );
50
51                Ok(())
52            }
53            Err(e) if e == Errno::ENOTCONN => {
54                println!("No balance found on '{}'", self.path.display());
55                Ok(())
56            }
57            Err(e) => Err(e).with_context(|| {
58                format!("balance status on '{}' failed", self.path.display())
59            }),
60        }
61    }
62}