btrfs_cli/balance/
status.rs1use 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#[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 #[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}