From: Dietmar Maurer <dietmar@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup] pbs-api-types: new MaintenanceType::Unmount, implement and use set_maintenance_mode
Date: Thu, 18 Apr 2024 10:27:31 +0200 [thread overview]
Message-ID: <20240418082731.124193-1-dietmar@proxmox.com> (raw)
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
pbs-api-types/src/datastore.rs | 49 ++++++++++++++++++++++++++++----
pbs-api-types/src/maintenance.rs | 11 ++++---
pbs-datastore/src/datastore.rs | 8 ++++--
src/api2/config/datastore.rs | 13 +++++++--
4 files changed, 66 insertions(+), 15 deletions(-)
diff --git a/pbs-api-types/src/datastore.rs b/pbs-api-types/src/datastore.rs
index 5e13c157..9fe45bc0 100644
--- a/pbs-api-types/src/datastore.rs
+++ b/pbs-api-types/src/datastore.rs
@@ -11,8 +11,8 @@ use proxmox_schema::{
};
use crate::{
- Authid, CryptMode, Fingerprint, GroupFilter, MaintenanceMode, Userid, BACKUP_ID_RE,
- BACKUP_NS_RE, BACKUP_TIME_RE, BACKUP_TYPE_RE, DATASTORE_NOTIFY_STRING_SCHEMA,
+ Authid, CryptMode, Fingerprint, GroupFilter, MaintenanceMode, MaintenanceType, Userid,
+ BACKUP_ID_RE, BACKUP_NS_RE, BACKUP_TIME_RE, BACKUP_TYPE_RE, DATASTORE_NOTIFY_STRING_SCHEMA,
GC_SCHEDULE_SCHEMA, GROUP_OR_SNAPSHOT_PATH_REGEX_STR, PROXMOX_SAFE_ID_FORMAT,
PROXMOX_SAFE_ID_REGEX_STR, PRUNE_SCHEDULE_SCHEMA, SHA256_HEX_REGEX, SINGLE_LINE_COMMENT_SCHEMA,
SNAPSHOT_PATH_REGEX_STR, UPID,
@@ -336,10 +336,47 @@ impl DataStoreConfig {
}
pub fn get_maintenance_mode(&self) -> Option<MaintenanceMode> {
- self.maintenance_mode
- .as_ref()
- .and_then(|str| MaintenanceMode::API_SCHEMA.parse_property_string(str).ok())
- .and_then(|value| MaintenanceMode::deserialize(value).ok())
+ self.maintenance_mode.as_ref().and_then(|str| {
+ MaintenanceMode::deserialize(proxmox_schema::de::SchemaDeserializer::new(
+ str,
+ &MaintenanceMode::API_SCHEMA,
+ ))
+ .ok()
+ })
+ }
+
+ pub fn set_maintenance_mode(&mut self, new_mode: Option<MaintenanceMode>) -> Result<(), Error> {
+ let current_type = self.get_maintenance_mode().map(|mode| mode.ty);
+ let new_type = new_mode.as_ref().map(|mode| mode.ty);
+
+ match current_type {
+ Some(MaintenanceType::ReadOnly) => { /* always OK */ }
+ Some(MaintenanceType::Offline) => { /* always OK */ }
+ Some(MaintenanceType::Unmount) => {
+ bail!("datastore is being unmounted");
+ }
+ Some(MaintenanceType::Delete) => {
+ match new_type {
+ Some(MaintenanceType::Delete) => { /* allow to delete a deleted storage */ }
+ _ => {
+ bail!("datastore is being deleted")
+ }
+ }
+ }
+ None => { /* always OK */ }
+ }
+
+ let new_mode = match new_mode {
+ Some(new_mode) => Some(
+ proxmox_schema::property_string::PropertyString::new(new_mode)
+ .to_property_string()?,
+ ),
+ None => None,
+ };
+
+ self.maintenance_mode = new_mode;
+
+ Ok(())
}
}
diff --git a/pbs-api-types/src/maintenance.rs b/pbs-api-types/src/maintenance.rs
index a605cc17..fd4d3416 100644
--- a/pbs-api-types/src/maintenance.rs
+++ b/pbs-api-types/src/maintenance.rs
@@ -33,12 +33,11 @@ pub enum Operation {
}
#[api]
-#[derive(Deserialize, Serialize, PartialEq, Eq)]
+#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
/// Maintenance type.
pub enum MaintenanceType {
// TODO:
- // - Add "unmounting" once we got pluggable datastores
// - Add "GarbageCollection" or "DeleteOnly" as type and track GC (or all deletes) as separate
// operation, so that one can enable a mode where nothing new can be added but stuff can be
// cleaned
@@ -48,6 +47,8 @@ pub enum MaintenanceType {
Offline,
/// The datastore is being deleted.
Delete,
+ /// The (removable) datastore is being unmounted.
+ Unmount,
}
serde_plain::derive_display_from_serialize!(MaintenanceType);
serde_plain::derive_fromstr_from_deserialize!(MaintenanceType);
@@ -69,11 +70,11 @@ serde_plain::derive_fromstr_from_deserialize!(MaintenanceType);
pub struct MaintenanceMode {
/// Type of maintenance ("read-only" or "offline").
#[serde(rename = "type")]
- ty: MaintenanceType,
+ pub ty: MaintenanceType,
/// Reason for maintenance.
#[serde(skip_serializing_if = "Option::is_none")]
- message: Option<String>,
+ pub message: Option<String>,
}
impl MaintenanceMode {
@@ -94,6 +95,8 @@ impl MaintenanceMode {
if let Some(Operation::Lookup) = operation {
return Ok(());
+ } else if self.ty == MaintenanceType::Unmount {
+ bail!("datastore is being unmounted");
} else if self.ty == MaintenanceType::Offline {
bail!("offline maintenance mode: {}", message);
} else if self.ty == MaintenanceType::ReadOnly {
diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs
index 0685cc84..f95da761 100644
--- a/pbs-datastore/src/datastore.rs
+++ b/pbs-datastore/src/datastore.rs
@@ -20,7 +20,7 @@ use proxmox_sys::{task_log, task_warn};
use pbs_api_types::{
Authid, BackupNamespace, BackupType, ChunkOrder, DataStoreConfig, DatastoreFSyncLevel,
- DatastoreTuning, GarbageCollectionStatus, Operation, UPID,
+ DatastoreTuning, GarbageCollectionStatus, MaintenanceMode, MaintenanceType, Operation, UPID,
};
use crate::backup_info::{BackupDir, BackupGroup, BackupGroupDeleteStats};
@@ -1390,7 +1390,11 @@ impl DataStore {
let (mut config, _digest) = pbs_config::datastore::config()?;
let mut datastore_config: DataStoreConfig = config.lookup("datastore", name)?;
- datastore_config.maintenance_mode = Some("type=delete".to_string());
+ datastore_config.set_maintenance_mode(Some(MaintenanceMode {
+ ty: MaintenanceType::Delete,
+ message: None,
+ }))?;
+
config.set_data(name, "datastore", &datastore_config)?;
pbs_config::datastore::save_config(&config)?;
drop(config_lock);
diff --git a/src/api2/config/datastore.rs b/src/api2/config/datastore.rs
index 3081e1f4..87425ff5 100644
--- a/src/api2/config/datastore.rs
+++ b/src/api2/config/datastore.rs
@@ -13,7 +13,7 @@ use proxmox_uuid::Uuid;
use pbs_api_types::{
Authid, DataStoreConfig, DataStoreConfigUpdater, DatastoreNotify, DatastoreTuning, KeepOptions,
- PruneJobConfig, PruneJobOptions, DATASTORE_SCHEMA, PRIV_DATASTORE_ALLOCATE,
+ MaintenanceMode, PruneJobConfig, PruneJobOptions, DATASTORE_SCHEMA, PRIV_DATASTORE_ALLOCATE,
PRIV_DATASTORE_AUDIT, PRIV_DATASTORE_MODIFY, PROXMOX_CONFIG_DIGEST_SCHEMA, UPID_SCHEMA,
};
use pbs_config::BackupLockGuard;
@@ -319,7 +319,7 @@ pub fn update_datastore(
data.tuning = None;
}
DeletableProperty::MaintenanceMode => {
- data.maintenance_mode = None;
+ data.set_maintenance_mode(None)?;
}
}
}
@@ -392,7 +392,14 @@ pub fn update_datastore(
let mut maintenance_mode_changed = false;
if update.maintenance_mode.is_some() {
maintenance_mode_changed = data.maintenance_mode != update.maintenance_mode;
- data.maintenance_mode = update.maintenance_mode;
+
+ let maintenance_mode = match update.maintenance_mode {
+ Some(mode_str) => Some(MaintenanceMode::deserialize(
+ proxmox_schema::de::SchemaDeserializer::new(mode_str, &MaintenanceMode::API_SCHEMA),
+ )?),
+ None => None,
+ };
+ data.set_maintenance_mode(maintenance_mode)?;
}
config.set_data(&name, "datastore", &data)?;
--
2.39.2
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
reply other threads:[~2024-04-18 8:28 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240418082731.124193-1-dietmar@proxmox.com \
--to=dietmar@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.