Skip to main content

btrfs_cli/balance/
resume.rs

1use super::open_path;
2use crate::{Format, Runnable};
3use anyhow::{Context, Result};
4use btrfs_uapi::balance::{BalanceFlags, balance};
5use clap::Parser;
6use nix::errno::Errno;
7use std::{os::unix::io::AsFd, path::PathBuf};
8
9/// Resume a paused balance operation
10#[derive(Parser, Debug)]
11pub struct BalanceResumeCommand {
12    pub path: PathBuf,
13}
14
15impl Runnable for BalanceResumeCommand {
16    fn run(&self, _format: Format, _dry_run: bool) -> Result<()> {
17        let file = open_path(&self.path)?;
18
19        // Resume is just a balance start with the RESUME flag and no type
20        // filters; the kernel picks up where it left off.
21        match balance(file.as_fd(), BalanceFlags::RESUME, None, None, None) {
22            Ok(progress) => {
23                println!(
24                    "Done, had to relocate {} out of {} chunks",
25                    progress.completed, progress.considered
26                );
27                Ok(())
28            }
29            Err(e) if e == Errno::ECANCELED => {
30                eprintln!("Balance was paused or cancelled by user.");
31                Ok(())
32            }
33            Err(e) if e == Errno::ENOTCONN => {
34                anyhow::bail!(
35                    "balance resume on '{}' failed: Not in progress",
36                    self.path.display()
37                )
38            }
39            Err(e) if e == Errno::EINPROGRESS => {
40                anyhow::bail!(
41                    "balance resume on '{}' failed: Already running",
42                    self.path.display()
43                )
44            }
45            Err(e) => Err(e).with_context(|| {
46                format!(
47                    "error during balance resume on '{}'\n\
48                     There may be more info in syslog - try dmesg | tail",
49                    self.path.display()
50                )
51            }),
52        }
53    }
54}