api: create_datastore: fix nesting checks

there two kinds of overlap we need to check here:
- two removable datastores backed by the same device must not have nested
  relative paths on the device
- any two datastores must not have nested absolute paths

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
Fabian Grünbichler 2024-11-27 14:05:21 +01:00 committed by Thomas Lamprecht
parent 13fe842041
commit 4948864a07

View File

@ -82,21 +82,30 @@ pub(crate) fn do_create_datastore(
bail!("cannot create datastore in root path"); bail!("cannot create datastore in root path");
} }
let new_store_path = Path::new(&datastore.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")? { for store in config.convert_to_typed_array::<DataStoreConfig>("datastore")? {
if store.backing_device != datastore.backing_device { // Relative paths must not be nested on the backing device of removable datastores
continue; 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
);
}
} }
// Since we check for that on creation, we assume all removable datastore // No two datastores should have a nested absolute path
// paths are relative, so don't have a leading `/`. let store_path = PathBuf::from(store.absolute_path());
let store_path = Path::new(&store.path);
if store_path.starts_with(&new_store_path) || new_store_path.starts_with(&store_path) { if store_path.starts_with(&new_store_path) || new_store_path.starts_with(&store_path) {
param_bail!( param_bail!(
"path", "path",
"nested datastores not allowed: '{}' already in '{}'", "nested datastores not allowed: '{}' already in {:?}",
store.name, store.name,
store.path store_path,
); );
} }
} }