5
0
mirror of git://git.proxmox.com/git/proxmox-backup.git synced 2025-01-18 06:03:59 +03:00

datastore: extract nesting check into helper

and improve the variable namign while we are at it. this allows the check to be
re-used in other code paths, like when starting a garbage collection.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
Fabian Grünbichler 2024-11-27 15:11:27 +01:00 committed by Thomas Lamprecht
parent 93bdba1ac6
commit 4d5e14c07e
2 changed files with 42 additions and 26 deletions

View File

@ -441,6 +441,45 @@ impl DataStoreConfig {
Ok(())
}
pub fn ensure_not_nested(&self, stores: &[DataStoreConfig]) -> Result<(), Error> {
let our_absolute_path = PathBuf::from(self.absolute_path());
let removable = self.backing_device.is_some();
for other_store in stores {
if self == other_store {
continue;
};
// Relative paths must not be nested on the backing device of removable datastores
if removable && other_store.backing_device == self.backing_device {
let our_relative_path = Path::new(&self.path);
let other_relative_path = Path::new(&other_store.path);
if our_relative_path.starts_with(other_relative_path)
|| other_relative_path.starts_with(our_relative_path)
{
bail!(
"paths on backing device must not be nested - {path:?} already used by '{store}'!",
path = other_relative_path,
store = other_store.name,
);
}
}
// No two datastores should have a nested absolute path
let other_absolute_path = PathBuf::from(other_store.absolute_path());
if other_absolute_path.starts_with(&our_absolute_path)
|| our_absolute_path.starts_with(&other_absolute_path)
{
bail!(
"nested datastores not allowed: '{}' already in {:?}",
other_store.name,
other_absolute_path,
);
}
}
Ok(())
}
}
#[api(

View File

@ -82,32 +82,9 @@ pub(crate) fn do_create_datastore(
bail!("cannot create datastore in root path");
}
let new_store_path = PathBuf::from(&datastore.absolute_path());
let removable = datastore.backing_device.is_some();
for store in config.convert_to_typed_array::<DataStoreConfig>("datastore")? {
// Relative paths must not be nested on the backing device of removable datastores
if removable && store.backing_device == datastore.backing_device {
let new_path = Path::new(&datastore.path);
let path = Path::new(&store.path);
if new_path.starts_with(path) || path.starts_with(new_path) {
param_bail!(
"path",
"paths on backing device must not be nested - {path:?} already used by '{store}'!",
store = store.name
);
}
}
// No two datastores should have a nested absolute path
let store_path = PathBuf::from(store.absolute_path());
if store_path.starts_with(&new_store_path) || new_store_path.starts_with(&store_path) {
param_bail!(
"path",
"nested datastores not allowed: '{}' already in {:?}",
store.name,
store_path,
);
}
let existing_stores = config.convert_to_typed_array("datastore")?;
if let Err(err) = datastore.ensure_not_nested(&existing_stores) {
param_bail!("path", err);
}
let need_unmount = datastore.backing_device.is_some();