btrfs_cli/scrub/
status.rs1use crate::{
2 Format, Runnable,
3 filesystem::UnitMode,
4 util::{fmt_size, open_path},
5};
6use anyhow::{Context, Result};
7use btrfs_uapi::{
8 device::device_info_all, filesystem::filesystem_info, scrub::scrub_progress,
9};
10use clap::Parser;
11use std::{os::unix::io::AsFd, path::PathBuf};
12
13#[derive(Parser, Debug)]
15pub struct ScrubStatusCommand {
16 #[clap(long, short)]
18 pub device: bool,
19
20 #[clap(short = 'R', long = "raw-data")]
22 pub raw_data: bool,
23
24 #[clap(flatten)]
25 pub units: UnitMode,
26
27 pub path: PathBuf,
29}
30
31impl Runnable for ScrubStatusCommand {
32 fn run(&self, _format: Format, _dry_run: bool) -> Result<()> {
33 let mode = self.units.resolve();
34 let file = open_path(&self.path)?;
35 let fd = file.as_fd();
36
37 let fs = filesystem_info(fd).with_context(|| {
38 format!(
39 "failed to get filesystem info for '{}'",
40 self.path.display()
41 )
42 })?;
43 let devices = device_info_all(fd, &fs).with_context(|| {
44 format!("failed to get device info for '{}'", self.path.display())
45 })?;
46
47 println!("UUID: {}", fs.uuid.as_hyphenated());
48
49 let mut any_running = false;
50 let mut fs_totals = btrfs_uapi::scrub::ScrubProgress::default();
51
52 for dev in &devices {
53 match scrub_progress(fd, dev.devid).with_context(|| {
54 format!("failed to get scrub progress for device {}", dev.devid)
55 })? {
56 None => {
57 if self.device {
58 println!(
59 "device {} ({}): no scrub in progress",
60 dev.devid, dev.path
61 );
62 }
63 }
64 Some(progress) => {
65 any_running = true;
66 super::accumulate(&mut fs_totals, &progress);
67 if self.device {
68 super::print_device_progress(
69 &progress,
70 dev.devid,
71 &dev.path,
72 self.raw_data,
73 &mode,
74 );
75 }
76 }
77 }
78 }
79
80 if !any_running {
81 println!("\tno scrub in progress");
82 } else if !self.device {
83 if self.raw_data {
84 super::print_raw_progress(&fs_totals, 0, "filesystem totals");
85 } else {
86 println!(
87 "Bytes scrubbed: {}",
88 fmt_size(fs_totals.bytes_scrubbed(), &mode)
89 );
90 super::print_error_summary(&fs_totals);
91 }
92 }
93
94 Ok(())
95 }
96}