From f5afcb9205ef02adbea9f080ef6d39094e3e28d3 Mon Sep 17 00:00:00 2001 From: Olivier 'reivilibre Date: Tue, 15 Jun 2021 14:49:55 +0100 Subject: [PATCH] Merge UID and GID tables when integrating --- yama/src/commands.rs | 24 ++++++++++++++++++++---- yama/src/tree.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/yama/src/commands.rs b/yama/src/commands.rs index 339aa2e..fe485fc 100644 --- a/yama/src/commands.rs +++ b/yama/src/commands.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use anyhow::{anyhow, bail, Context}; use clap::crate_version; +use log::warn; use crate::chunking::{RecursiveChunker, RecursiveUnchunker, SENSIBLE_THRESHOLD}; use crate::definitions::{PointerData, RecursiveChunkRef, RootTreeNode, TreeNode}; @@ -14,7 +15,7 @@ use crate::pile::integrity::RawPileIntegrityChecker; use crate::pile::local_sled::LocalSledRawPile; use crate::pile::local_sqlitebloblogs::SqliteBloblogPile; use crate::pile::{Pile, PileDescriptor, PileStorage, RawPile}; -use crate::tree::integrate_node_in_place; +use crate::tree::{integrate_node_in_place, merge_uid_or_gid_tables}; pub fn init(dir: &Path) -> anyhow::Result<()> { let yama_toml = dir.join("yama.toml"); @@ -142,14 +143,29 @@ pub fn fully_integrate_pointer_node( tree_node: &mut TreeNode, pointer: &mut PointerData, ) -> anyhow::Result<()> { - if let Some(parent) = &pointer.parent_pointer { + if let Some(parent_name) = &pointer.parent_pointer { let mut parent = pile - .read_pointer(parent.as_str())? - .ok_or_else(|| anyhow!("Parent pointer {:?} not found.", parent))?; + .read_pointer(parent_name.as_str())? + .ok_or_else(|| anyhow!("Parent pointer {:?} not found.", parent_name))?; let mut parent_node = retrieve_tree_node(pile, parent.chunk_ref.clone())?.node; fully_integrate_pointer_node(pile, &mut parent_node, &mut parent)?; integrate_node_in_place(tree_node, &mut parent_node)?; + + // merge in the UID and GID tables when integrating. + if merge_uid_or_gid_tables(&mut pointer.uid_lookup, &parent.uid_lookup) { + warn!( + "Overlap when merging parent:{:?}'s UID table into child.", + parent_name + ); + } + if merge_uid_or_gid_tables(&mut pointer.gid_lookup, &parent.gid_lookup) { + warn!( + "Overlap when merging parent:{:?}'s GID table into child.", + parent_name + ); + } + pointer.parent_pointer = None; } Ok(()) diff --git a/yama/src/tree.rs b/yama/src/tree.rs index 4432e54..8d2a60c 100644 --- a/yama/src/tree.rs +++ b/yama/src/tree.rs @@ -299,6 +299,32 @@ pub fn create_uidgid_lookup_tables( Ok(()) } +#[must_use] +/// Accepts a target UID/GID map and a source UID/GID map. +/// Merges source into target. +/// Returns true if everything is OK, false if there is a warning (overlap!). +/// In the event of an overlap, the pre-existing entry wins. +pub fn merge_uid_or_gid_tables( + target: &mut BTreeMap>, + source: &BTreeMap>, +) -> bool { + let mut warn = false; + for (uid_or_gid, name) in source.iter() { + match target.entry(*uid_or_gid) { + Entry::Vacant(entry) => { + entry.insert(name.clone()); + } + Entry::Occupied(entry) => { + if entry.get() != name { + // Conflicting IDs + warn = true; + } + } + } + } + !warn +} + #[cfg(test)] mod tests { use crate::definitions::{