[pbs-devel] [PATCH proxmox-backup v14 10/25] add auto-mounting for removable datastores
Hannes Laimer
h.laimer at proxmox.com
Fri Nov 22 15:46:57 CET 2024
If a device houses multiple datastore, none of them will be mounted
automatically. If a device only contains a single datastore it will be
mounted automatically. The reason for not mounting multiple datastore
automatically is that we don't know which is actually wanted, and since
mounting all means also all have to be unmounted manually, it made sense
to have the user choose which to mount.
Signed-off-by: Hannes Laimer <h.laimer at proxmox.com>
---
changes since v13:
* skip API alltogether and use mounting wrapper directly
* load datastore config directly
debian/proxmox-backup-server.install | 1 +
debian/proxmox-backup-server.udev | 3 ++
etc/Makefile | 1 +
etc/removable-device-attach at .service | 8 ++++
src/bin/proxmox_backup_manager/datastore.rs | 53 ++++++++++++++++++++-
5 files changed, 65 insertions(+), 1 deletion(-)
create mode 100644 etc/removable-device-attach at .service
diff --git a/debian/proxmox-backup-server.install b/debian/proxmox-backup-server.install
index 79757eadb..ff581e3dd 100644
--- a/debian/proxmox-backup-server.install
+++ b/debian/proxmox-backup-server.install
@@ -4,6 +4,7 @@ etc/proxmox-backup-daily-update.service /lib/systemd/system/
etc/proxmox-backup-daily-update.timer /lib/systemd/system/
etc/proxmox-backup-proxy.service /lib/systemd/system/
etc/proxmox-backup.service /lib/systemd/system/
+etc/removable-device-attach at .service /lib/systemd/system/
usr/bin/pmt
usr/bin/pmtx
usr/bin/proxmox-tape
diff --git a/debian/proxmox-backup-server.udev b/debian/proxmox-backup-server.udev
index afdfb2bc7..e21b8bc71 100644
--- a/debian/proxmox-backup-server.udev
+++ b/debian/proxmox-backup-server.udev
@@ -16,3 +16,6 @@ SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="1", ENV{ID_SCSI_SER
SYMLINK+="tape/by-id/scsi-$env{ID_SCSI_SERIAL}-sg"
LABEL="persistent_storage_tape_end"
+
+# triggers the mounting of a removable device
+ACTION=="add", SUBSYSTEM=="block", ENV{ID_FS_UUID}!="", TAG+="systemd", ENV{SYSTEMD_WANTS}="removable-device-attach@$env{ID_FS_UUID}"
\ No newline at end of file
diff --git a/etc/Makefile b/etc/Makefile
index 42f639f62..26e91684e 100644
--- a/etc/Makefile
+++ b/etc/Makefile
@@ -2,6 +2,7 @@ include ../defines.mk
UNITS := \
proxmox-backup-daily-update.timer \
+ removable-device-attach at .service
DYNAMIC_UNITS := \
proxmox-backup-banner.service \
diff --git a/etc/removable-device-attach at .service b/etc/removable-device-attach at .service
new file mode 100644
index 000000000..e10d1ea3c
--- /dev/null
+++ b/etc/removable-device-attach at .service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Try to mount the removable device of a datastore with uuid '%i'.
+After=proxmox-backup-proxy.service
+Requires=proxmox-backup-proxy.service
+
+[Service]
+Type=simple
+ExecStart=/usr/sbin/proxmox-backup-manager datastore uuid-mount %i
diff --git a/src/bin/proxmox_backup_manager/datastore.rs b/src/bin/proxmox_backup_manager/datastore.rs
index 32a55fb9c..bcfdae786 100644
--- a/src/bin/proxmox_backup_manager/datastore.rs
+++ b/src/bin/proxmox_backup_manager/datastore.rs
@@ -9,7 +9,7 @@ use proxmox_backup::api2;
use proxmox_backup::api2::config::datastore::DeletableProperty;
use proxmox_backup::client_helpers::connect_to_localhost;
-use anyhow::Error;
+use anyhow::{format_err, Error};
use serde_json::Value;
#[api(
@@ -244,6 +244,53 @@ async fn update_datastore(name: String, mut param: Value) -> Result<(), Error> {
Ok(())
}
+#[api(
+ protected: true,
+ input: {
+ properties: {
+ uuid: {
+ type: String,
+ description: "The UUID of the device that should be mounted",
+ },
+ "output-format": {
+ schema: OUTPUT_FORMAT,
+ optional: true,
+ },
+ },
+ },
+)]
+/// Try mounting a removable datastore given the UUID.
+async fn uuid_mount(param: Value, _rpcenv: &mut dyn RpcEnvironment) -> Result<Value, Error> {
+ let uuid = param["uuid"]
+ .as_str()
+ .ok_or_else(|| format_err!("uuid has to be specified"))?;
+
+ let (config, _digest) = pbs_config::datastore::config()?;
+ let list: Vec<DataStoreConfig> = config.convert_to_typed_array("datastore")?;
+ let matching_stores: Vec<DataStoreConfig> = list
+ .into_iter()
+ .filter(|store: &DataStoreConfig| {
+ store
+ .backing_device
+ .clone()
+ .map_or(false, |device| device.eq(&uuid))
+ })
+ .collect();
+
+ if matching_stores.len() != 1 {
+ return Ok(Value::Null);
+ }
+
+ if let Some(store) = matching_stores.get(0) {
+ api2::admin::datastore::do_mount_device(store.clone())?;
+ return Ok(Value::Null);
+ }
+
+ // we don't want to fail for UUIDs that are not associated with datastores, as that produces
+ // quite some noise in the logs, given this is check for every device that is plugged in.
+ Ok(Value::Null)
+}
+
pub fn datastore_commands() -> CommandLineInterface {
let cmd_def = CliCommandMap::new()
.insert("list", CliCommand::new(&API_METHOD_LIST_DATASTORES))
@@ -289,6 +336,10 @@ pub fn datastore_commands() -> CommandLineInterface {
pbs_config::datastore::complete_calendar_event,
),
)
+ .insert(
+ "uuid-mount",
+ CliCommand::new(&API_METHOD_UUID_MOUNT).arg_param(&["uuid"]),
+ )
.insert(
"remove",
CliCommand::new(&API_METHOD_DELETE_DATASTORE)
--
2.39.5
More information about the pbs-devel
mailing list