Merge UID and GID tables when integrating

This commit is contained in:
Olivier 'reivilibre' 2021-06-15 14:49:55 +01:00
parent 7f77a47f5f
commit f5afcb9205
2 changed files with 46 additions and 4 deletions

View File

@ -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<RP: RawPile>(
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(())

View File

@ -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<u16, Option<String>>,
source: &BTreeMap<u16, Option<String>>,
) -> 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::{