aboutsummaryrefslogtreecommitdiff
path: root/src/garage/repair/offline.rs
blob: ef56cc5cf2406df13b8106c2de59d4f0412e1140 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use std::path::PathBuf;

use tokio::sync::watch;

use garage_util::background::*;
use garage_util::config::*;
use garage_util::error::*;

use garage_model::garage::Garage;

use crate::cli::structs::*;

pub async fn offline_repair(config_file: PathBuf, opt: OfflineRepairOpt) -> Result<(), Error> {
	if !opt.yes {
		return Err(Error::Message(
			"Please add the --yes flag to launch repair operation".into(),
		));
	}

	info!("Loading configuration...");
	let config = read_config(config_file)?;

	info!("Initializing background runner...");
	let (done_tx, done_rx) = watch::channel(false);
	let (background, await_background_done) = BackgroundRunner::new(16, done_rx);

	info!("Initializing Garage main data store...");
	let garage = Garage::new(config.clone(), background)?;

	info!("Launching repair operation...");
	match opt.what {
		OfflineRepairWhat::K2VItemCounters => {
			#[cfg(feature = "k2v")]
			garage
				.k2v
				.counter_table
				.offline_recount_all(&garage.k2v.item_table)?;
			#[cfg(not(feature = "k2v"))]
			error!("K2V not enabled in this build.");
		}
		OfflineRepairWhat::ObjectCounters => {
			garage
				.object_counter_table
				.offline_recount_all(&garage.object_table)?;
		}
	}

	info!("Repair operation finished, shutting down Garage internals...");
	done_tx.send(true).unwrap();
	drop(garage);

	await_background_done.await?;

	info!("Cleaning up...");

	Ok(())
}