Only scan one filesystem by default (can configure 'cross_filesystems' if needed)
This commit is contained in:
parent
e8fc448ace
commit
af553d1fed
|
@ -195,10 +195,10 @@ fn main() -> anyhow::Result<()> {
|
|||
unimplemented!();
|
||||
}
|
||||
DatmanCommand::InteractiveLabelling { source_name } => {
|
||||
interactive_labelling_session(Path::new("."), source_name).unwrap();
|
||||
interactive_labelling_session(Path::new("."), source_name)?;
|
||||
}
|
||||
DatmanCommand::InteractiveBrowsing { source_name } => {
|
||||
datman::commands::ibrowse::session(Path::new("."), source_name).unwrap();
|
||||
datman::commands::ibrowse::session(Path::new("."), source_name)?;
|
||||
}
|
||||
DatmanCommand::BackupOne {
|
||||
source_name,
|
||||
|
@ -317,7 +317,7 @@ fn main() -> anyhow::Result<()> {
|
|||
let descriptor = load_descriptor(Path::new(".")).unwrap();
|
||||
let destination = &descriptor.piles[&pile_name];
|
||||
let report = datman::commands::report::generate_report(destination, &descriptor)?;
|
||||
|
||||
|
||||
datman::commands::report::print_report(&report)?;
|
||||
datman::commands::report::print_filesystem_space(&destination.path)?;
|
||||
}
|
||||
|
|
|
@ -147,10 +147,12 @@ pub fn backup_source_to_destination<PT: ProgressTracker>(
|
|||
SourceDescriptor::DirectorySource {
|
||||
hostname: _,
|
||||
directory,
|
||||
cross_filesystems,
|
||||
} => {
|
||||
info!("Looking to backup {} to {}", source_name, dest_name);
|
||||
info!("Scanning.");
|
||||
let tree = scan(directory)?.ok_or_else(|| anyhow!("Source does not exist."))?;
|
||||
let tree = scan(directory, !*cross_filesystems)?
|
||||
.ok_or_else(|| anyhow!("Source does not exist."))?;
|
||||
|
||||
let absolute_source_path = desc_path.join(directory);
|
||||
let absolute_dest_path = desc_path.join(&dest.path);
|
||||
|
|
|
@ -68,15 +68,19 @@ pub fn session(path: &Path, source_name: String) -> anyhow::Result<()> {
|
|||
.get(&source_name)
|
||||
.ok_or_else(|| anyhow!("Could not find source {:?}!", source_name))?;
|
||||
|
||||
let directory = match source_descriptor {
|
||||
SourceDescriptor::DirectorySource { directory, .. } => directory,
|
||||
let (directory, one_filesystem) = match source_descriptor {
|
||||
SourceDescriptor::DirectorySource {
|
||||
directory,
|
||||
cross_filesystems,
|
||||
..
|
||||
} => (directory, !*cross_filesystems),
|
||||
SourceDescriptor::VirtualSource { .. } => {
|
||||
bail!("Cannot browse virtual source.");
|
||||
}
|
||||
};
|
||||
|
||||
println!("Scanning source; this might take a little while...");
|
||||
let mut dir_scan: FileTree1<Option<State>> = scan(directory)?
|
||||
let mut dir_scan: FileTree1<Option<State>> = scan(directory, one_filesystem)?
|
||||
.ok_or_else(|| anyhow!("Empty source."))?
|
||||
.replace_meta(&None);
|
||||
|
||||
|
|
|
@ -186,12 +186,13 @@ pub fn interactive_labelling_session(path: &Path, source_name: String) -> anyhow
|
|||
if let SourceDescriptor::DirectorySource {
|
||||
hostname,
|
||||
directory,
|
||||
cross_filesystems,
|
||||
} = source
|
||||
{
|
||||
let my_hostname = get_hostname();
|
||||
let mut dir_scan = if &my_hostname == hostname {
|
||||
info!("Scanning source; this might take a little while...");
|
||||
scan(directory)?
|
||||
scan(directory, !*cross_filesystems)?
|
||||
.ok_or_else(|| anyhow!("Empty source."))?
|
||||
.replace_meta(&None)
|
||||
} else {
|
||||
|
@ -206,10 +207,14 @@ pub fn interactive_labelling_session(path: &Path, source_name: String) -> anyhow
|
|||
|
||||
// then request to scan
|
||||
info!("Requesting scan from remote source... (this may take some time)");
|
||||
let scan =
|
||||
backup_source_requester::scanning(&mut read, &mut write, directory.as_ref())?
|
||||
.ok_or_else(|| anyhow!("Remote scan failed (does the directory exist?)"))?
|
||||
.replace_meta(&None);
|
||||
let scan = backup_source_requester::scanning(
|
||||
&mut read,
|
||||
&mut write,
|
||||
directory.as_ref(),
|
||||
!*cross_filesystems,
|
||||
)?
|
||||
.ok_or_else(|| anyhow!("Remote scan failed (does the directory exist?)"))?
|
||||
.replace_meta(&None);
|
||||
|
||||
backup_source_requester::quit(&mut read, &mut write)?;
|
||||
|
||||
|
|
|
@ -52,6 +52,8 @@ pub enum SourceDescriptor {
|
|||
DirectorySource {
|
||||
hostname: String,
|
||||
directory: PathBuf,
|
||||
#[serde(default)]
|
||||
cross_filesystems: bool,
|
||||
},
|
||||
VirtualSource {
|
||||
/// The name of the helper program that will be used to do this backup.
|
||||
|
|
|
@ -47,10 +47,12 @@ pub fn scanning<R: Read, W: Write>(
|
|||
read: &mut R,
|
||||
write: &mut W,
|
||||
path: &Path,
|
||||
one_filesystem: bool,
|
||||
) -> anyhow::Result<Option<FileTree<(), (), (), ()>>> {
|
||||
info!("Scanning.");
|
||||
write_message(write, &"scan")?;
|
||||
write_message(write, &path)?;
|
||||
write_message(write, &one_filesystem)?;
|
||||
write.flush()?;
|
||||
let scan_result: Option<FileTree<(), (), (), ()>> = read_message(read)?;
|
||||
|
||||
|
@ -177,6 +179,7 @@ pub fn backup_remote_source_to_destination<PT: ProgressTracker + Send + 'static>
|
|||
SourceDescriptor::DirectorySource {
|
||||
hostname,
|
||||
directory,
|
||||
cross_filesystems,
|
||||
} => {
|
||||
let remote_host_descriptor = descriptor
|
||||
.remote_hosts
|
||||
|
@ -198,8 +201,13 @@ pub fn backup_remote_source_to_destination<PT: ProgressTracker + Send + 'static>
|
|||
|
||||
// then request to scan
|
||||
info!("Requesting scan... (this may take some time)");
|
||||
let scan_result = scanning(&mut read, &mut write, directory.as_ref())?
|
||||
.ok_or_else(|| anyhow!("Remote scan failed (does the directory exist?)"))?;
|
||||
let scan_result = scanning(
|
||||
&mut read,
|
||||
&mut write,
|
||||
directory.as_ref(),
|
||||
!*cross_filesystems,
|
||||
)?
|
||||
.ok_or_else(|| anyhow!("Remote scan failed (does the directory exist?)"))?;
|
||||
|
||||
let mut root =
|
||||
label_filter_and_convert(scan_result, descriptor, desc_path, source_name, dest)?
|
||||
|
|
|
@ -42,7 +42,8 @@ pub fn introduction<R: Read, W: Write>(read: &mut R, write: &mut W) -> anyhow::R
|
|||
|
||||
pub fn scanning<R: Read, W: Write>(read: &mut R, write: &mut W) -> anyhow::Result<()> {
|
||||
let path: PathBuf = read_message(read)?;
|
||||
let scan_result = scan(&path)?;
|
||||
let one_filesystem: bool = read_message(read)?;
|
||||
let scan_result = scan(&path, one_filesystem)?;
|
||||
write_message(write, &scan_result)?;
|
||||
write.flush()?;
|
||||
Ok(())
|
||||
|
|
|
@ -24,7 +24,7 @@ use std::path::Path;
|
|||
|
||||
use anyhow::anyhow;
|
||||
use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle};
|
||||
use log::warn;
|
||||
use log::{info, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub use yama::definitions::FilesystemOwnership;
|
||||
|
@ -216,12 +216,14 @@ pub fn mtime_msec(metadata: &Metadata) -> u64 {
|
|||
}
|
||||
|
||||
/// Scan the filesystem to produce a Tree, using a default progress bar.
|
||||
pub fn scan(path: &Path) -> anyhow::Result<Option<FileTree<(), (), (), ()>>> {
|
||||
pub fn scan(path: &Path, one_filesystem: bool) -> anyhow::Result<Option<FileTree<(), (), (), ()>>> {
|
||||
let pbar = ProgressBar::with_draw_target(0, ProgressDrawTarget::stdout_with_hz(2));
|
||||
pbar.set_style(ProgressStyle::default_spinner().template("{spinner} {pos:7} {msg}"));
|
||||
pbar.set_message("dir scan");
|
||||
|
||||
let result = scan_with_progress_bar(path, &pbar);
|
||||
let one_filesystem = if one_filesystem { Some(None) } else { None };
|
||||
|
||||
let result = scan_with_progress_bar(path, &pbar, one_filesystem);
|
||||
pbar.finish_at_current_pos();
|
||||
result
|
||||
}
|
||||
|
@ -230,6 +232,7 @@ pub fn scan(path: &Path) -> anyhow::Result<Option<FileTree<(), (), (), ()>>> {
|
|||
pub fn scan_with_progress_bar(
|
||||
path: &Path,
|
||||
progress_bar: &ProgressBar,
|
||||
mut one_filesystem: Option<Option<u64>>,
|
||||
) -> anyhow::Result<Option<FileTree<(), (), (), ()>>> {
|
||||
let metadata_res = symlink_metadata(path);
|
||||
progress_bar.inc(1);
|
||||
|
@ -249,6 +252,14 @@ pub fn scan_with_progress_bar(
|
|||
let metadata = metadata_res?;
|
||||
let filetype = metadata.file_type();
|
||||
|
||||
if let Some(one_filesystem) = one_filesystem.as_mut() {
|
||||
let this_fs = metadata.dev();
|
||||
if *one_filesystem.get_or_insert(this_fs) != this_fs {
|
||||
info!("Stopping at filesystem boundary: {:?}", path);
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
|
||||
/*let name = path
|
||||
.file_name()
|
||||
.ok_or(anyhow!("No filename, wat"))?
|
||||
|
@ -294,7 +305,7 @@ pub fn scan_with_progress_bar(
|
|||
|
||||
for entry in dir_read? {
|
||||
let entry: DirEntry = entry?;
|
||||
let scanned = scan_with_progress_bar(&entry.path(), progress_bar)?;
|
||||
let scanned = scan_with_progress_bar(&entry.path(), progress_bar, one_filesystem)?;
|
||||
if let Some(scanned) = scanned {
|
||||
children.insert(
|
||||
entry
|
||||
|
|
Loading…
Reference in New Issue