diff --git a/mgmtd/src/config.rs b/mgmtd/src/config.rs index 341a8d5..245228b 100644 --- a/mgmtd/src/config.rs +++ b/mgmtd/src/config.rs @@ -11,6 +11,7 @@ use std::fmt::Debug; use std::ops::RangeInclusive; use std::path::PathBuf; use std::time::Duration; +use uuid::Uuid; /// Generates `Config` to be filled by the functions below and exported to be used by the program. /// @@ -107,6 +108,16 @@ generate_structs! { #[serde(skip)] init: bool = false, + /// Optionally specifies the FsUuid when initializing the database. + /// + /// If not provided, a new FsUuid will be generated. + #[arg(long)] + #[arg(num_args = 1)] + #[arg(hide = true)] + #[arg(value_name = "UUID")] + #[serde(skip)] + fs_uuid: Option = None, + /// Upgrades an outdated management database to the current version, then exits. /// /// Automatically creates a backup of the existing database file in the same directory. @@ -393,6 +404,12 @@ generate_structs! { impl Config { pub fn check_validity(&self) -> Result<()> { + if let Some(ref uuid) = self.fs_uuid { + if uuid.get_version_num() != 4 { + bail!("Provided file system UUID is not a valid v4 UUID"); + } + } + if self.quota_enforce && !self.quota_enable { bail!("Quota enforcement requires quota being enabled"); } diff --git a/mgmtd/src/db.rs b/mgmtd/src/db.rs index 327287a..e6fb0ab 100644 --- a/mgmtd/src/db.rs +++ b/mgmtd/src/db.rs @@ -37,8 +37,10 @@ pub const MIGRATIONS: &[sqlite::Migration] = include!(concat!(env!("OUT_DIR"), " /// Inserts initial entries into a new database. Remember to commit the transaction after calling /// this function. -pub fn initial_entries(tx: &Transaction) -> Result<()> { - config::set(tx, Config::FsUuid, Uuid::new_v4().to_string())?; +/// +/// If `fs_uuid` is provided, it will be used. Otherwise, a new FsUUID will be generated. +pub fn initial_entries(tx: &Transaction, fs_uuid: Option) -> Result<()> { + config::set(tx, Config::FsUuid, fs_uuid.unwrap_or_else(Uuid::new_v4))?; config::set( tx, Config::FsInitDateSecs, diff --git a/mgmtd/src/main.rs b/mgmtd/src/main.rs index 0a85b41..385d0a7 100644 --- a/mgmtd/src/main.rs +++ b/mgmtd/src/main.rs @@ -11,6 +11,7 @@ use std::fmt::Write; use std::path::Path; use std::{fs, panic}; use tokio::signal::ctrl_c; +use uuid::Uuid; fn main() -> Result<(), i32> { inner_main().map_err(|err| { @@ -62,7 +63,11 @@ fn inner_main() -> Result<()> { } if user_config.init || user_config.import_from_v7.is_some() { - init_db(&user_config.db_file, user_config.import_from_v7.as_deref())?; + init_db( + &user_config.db_file, + user_config.import_from_v7.as_deref(), + user_config.fs_uuid, + )?; return Ok(()); } @@ -149,10 +154,11 @@ doc.beegfs.io.", }) } -/// Create and initialize a new database. Optionally import v7 data from the given path. +/// Create and initialize a new database. /// -/// The database file is only written to disk if the initialization succeeds. -fn init_db(db_file: &Path, v7_path: Option<&Path>) -> Result<()> { +/// Optionally import v7 data from the given path. Optionally the FsUUID can be specified otherwise +/// it will be autogenerated. The database file is only written to disk if initialization succeeds. +fn init_db(db_file: &Path, v7_path: Option<&Path>, fs_uuid: Option) -> Result<()> { if db_file.try_exists()? { bail!("Database file {db_file:?} already exists"); } @@ -165,7 +171,7 @@ fn init_db(db_file: &Path, v7_path: Option<&Path>) -> Result<()> { let version = sqlite::migrate_schema(&tx, db::MIGRATIONS).context("Creating schema failed")?; - db::initial_entries(&tx).context("Creating initial entries failed")?; + db::initial_entries(&tx, fs_uuid).context("Creating initial entries failed")?; if let Some(v7_path) = v7_path { db::import_v7(&tx, v7_path).context("v7 management data import failed")?;