proxmox-backup-proxy: fix leftover references on datastore removal

when we remove a datastore via api/cli, the proxy
has sometimes leftover references to that datastore in its
DATASTORE_MAP which includes an open filehandle on the
'.lock' file

this prevents unmounting/exporting the datastore even after removal,
only a reload/restart of the proxy did help

add a command to our command socket, which removes all non
configured datastores from the map, dropping the open filehandle

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
This commit is contained in:
Dominik Csapak 2021-06-02 13:27:01 +02:00 committed by Dietmar Maurer
parent e5950360ca
commit 062cf75cdf
4 changed files with 34 additions and 1 deletions

View File

@ -403,7 +403,7 @@ pub fn update_datastore(
},
)]
/// Remove a datastore configuration.
pub fn delete_datastore(name: String, digest: Option<String>) -> Result<(), Error> {
pub async fn delete_datastore(name: String, digest: Option<String>) -> Result<(), Error> {
let _lock = open_file_locked(datastore::DATASTORE_CFG_LOCKFILE, std::time::Duration::new(10, 0), true)?;
@ -425,6 +425,8 @@ pub fn delete_datastore(name: String, digest: Option<String>) -> Result<(), Erro
let _ = jobstate::remove_state_file("prune", &name);
let _ = jobstate::remove_state_file("garbage_collection", &name);
crate::server::notify_datastore_removed().await?;
Ok(())
}

View File

@ -69,6 +69,18 @@ impl DataStore {
Ok(datastore)
}
/// removes all datastores that are not configured anymore
pub fn remove_unused_datastores() -> Result<(), Error>{
let (config, _digest) = datastore::config()?;
let mut map = DATASTORE_MAP.lock().unwrap();
// removes all elements that are not in the config
map.retain(|key, _| {
config.sections.contains_key(key)
});
Ok(())
}
fn open_with_path(store_name: &str, path: &Path, config: DataStoreConfig) -> Result<Self, Error> {
let chunk_store = ChunkStore::open(store_name, path)?;

View File

@ -136,6 +136,17 @@ async fn run() -> Result<(), Error> {
},
)?;
// to remove references for not configured datastores
commando_sock.register_command(
"datastore-removed".to_string(),
|_value| {
if let Err(err) = proxmox_backup::backup::DataStore::remove_unused_datastores() {
log::error!("could not refresh datastores: {}", err);
}
Ok(Value::Null)
}
)?;
let server = daemon::create_daemon(
([0,0,0,0,0,0,0,0], 8007).into(),
move |listener, ready| {

View File

@ -100,3 +100,11 @@ pub(crate) async fn reload_proxy_certificate() -> Result<(), Error> {
.await?;
Ok(())
}
pub(crate) async fn notify_datastore_removed() -> Result<(), Error> {
let proxy_pid = crate::server::read_pid(buildcfg::PROXMOX_BACKUP_PROXY_PID_FN)?;
let sock = crate::server::ctrl_sock_from_pid(proxy_pid);
let _: Value = crate::server::send_raw_command(sock, "{\"command\":\"datastore-removed\"}\n")
.await?;
Ok(())
}