From a50759c50dff135956a96e0339d4dc06ce2a8a5e Mon Sep 17 00:00:00 2001 From: Gianmaria Del Monte Date: Mon, 27 Jan 2025 13:35:09 +0100 Subject: [PATCH] MGM: add possibility to run a script after the slave to master transition --- mgm/QdbMaster.cc | 34 +++++++++++++++++++++++++++++++--- mgm/QdbMaster.hh | 7 +++++++ mgm/XrdMgmOfs.hh | 12 ++++++++---- mgm/XrdMgmOfsConfigure.cc | 10 ++++++++++ misc/etc/eos/config/mgm/mgm | 3 +++ 5 files changed, 59 insertions(+), 7 deletions(-) diff --git a/mgm/QdbMaster.cc b/mgm/QdbMaster.cc index e867f36dcf..e5f318ffca 100644 --- a/mgm/QdbMaster.cc +++ b/mgm/QdbMaster.cc @@ -42,6 +42,7 @@ #include "common/plugin_manager/PluginManager.hh" #include "common/IntervalStopwatch.hh" #include +#include "common/ShellCmd.hh" EOSMGMNAMESPACE_BEGIN @@ -110,6 +111,7 @@ QdbMaster::BootNamespace() namespaceConfig["qdb_password"] = gOFS->mQdbPassword; namespaceConfig["qdb_flusher_md"] = SSTR(instance_id << "_md"); namespaceConfig["qdb_flusher_quota"] = SSTR(instance_id << "_quota"); + if (!gOFS->mQClientFlusherType.empty()) { namespaceConfig["qclient_flusher_type"] = gOFS->mQClientFlusherType; } @@ -118,7 +120,6 @@ QdbMaster::BootNamespace() namespaceConfig["qclient_rocksdb_options"] = gOFS->mQClientRocksDBOptions; } - FillNsCacheConfig(gOFS->ConfEngine, namespaceConfig); if (!gOFS->namespaceGroup->initialize(&gOFS->eosViewRWMutex, namespaceConfig, @@ -319,6 +320,7 @@ QdbMaster::Supervisor(ThreadAssistant& assistant) noexcept MasterLog(eos_log(LOG_ERR, "%s", "msg=\"acquired the master lease\"")); SlaveToMaster(); + PostSlaveToMaster(old_master_id, GetMasterId()); } } else { std::string new_master_id = GetMasterId(); @@ -337,8 +339,7 @@ QdbMaster::Supervisor(ThreadAssistant& assistant) noexcept eos_static_info("%s", "msg=\"follow up master-to-slave transition\""); Access::SetMasterToSlaveRules(new_master_id); gOFS->mTracker.SetAcceptingRequests(true); - } - else { + } else { if (new_master_id == mIdentity) { if (mDoMasterDelay) { if (mMasterDelayDeadline < std::chrono::system_clock::now()) { @@ -367,6 +368,33 @@ QdbMaster::Supervisor(ThreadAssistant& assistant) noexcept RemoveStatusFile(EOSMGMMASTER_SUBSYS_RW_LOCKFILE); } +//------------------------------------------------------------------------------ +// PostSlaveToMaster runs a custom hook. It is invoked after the SlaveToMaster +// transition. It only runs if configured in the mgmofs.postslavetomaster option. +//------------------------------------------------------------------------------ +void QdbMaster::PostSlaveToMaster(std::string old_master, + std::string new_master) +{ + if (gOFS->mPostSlaveToMaster.length() == 0) { + return; + } + + eos_static_info("msg=\"running post slave to master script\" path=\"%s\"", + gOFS->mPostSlaveToMaster.c_str()); + std::string script = std::string(gOFS->mPostSlaveToMaster.c_str()) + + " '" + old_master + "'" + + " '" + new_master + "'"; + eos::common::ShellCmd cmd(script); + auto status = cmd.wait(POST_SLAVE_TO_MASTER_TIMEOUT); + + if (status.exit_code) { + eos_static_warning("msg=\"post slave to master script failed\" script=\"%s\" retcode=%d", + script, status.exit_code); + } else { + eos_static_info("msg=\"post slave to master script run successfully\""); + } +} + //------------------------------------------------------------------------------ // Slave to master transition //------------------------------------------------------------------------------ diff --git a/mgm/QdbMaster.hh b/mgm/QdbMaster.hh index 958aba2ab6..19b67e768c 100644 --- a/mgm/QdbMaster.hh +++ b/mgm/QdbMaster.hh @@ -37,6 +37,8 @@ class QClient; EOSMGMNAMESPACE_BEGIN +#define POST_SLAVE_TO_MASTER_TIMEOUT 60 + //------------------------------------------------------------------------------ //! Class IMaster //------------------------------------------------------------------------------ @@ -214,6 +216,11 @@ private: //---------------------------------------------------------------------------- void SlaveToMaster(); + //---------------------------------------------------------------------------- + //! Run a post slave to master hook, if configured + //---------------------------------------------------------------------------- + void PostSlaveToMaster(std::string old_master, std::string new_master); + //---------------------------------------------------------------------------- //! Master to slave transition //---------------------------------------------------------------------------- diff --git a/mgm/XrdMgmOfs.hh b/mgm/XrdMgmOfs.hh index e46de71b52..ea4e273bd0 100644 --- a/mgm/XrdMgmOfs.hh +++ b/mgm/XrdMgmOfs.hh @@ -830,8 +830,8 @@ public: //! container and the file individually before checking their access with the //! AccessChecker. //---------------------------------------------------------------------------- - int _access(const char*, int mode, XrdOucErrInfo&, - eos::common::VirtualIdentity& vid, const char*); + int _access(const char*, int mode, XrdOucErrInfo&, + eos::common::VirtualIdentity& vid, const char*); //---------------------------------------------------------------------------- //! @brief define access permissions for files/directories @@ -1759,6 +1759,8 @@ public: XrdOucString MgmAuthDir; ///< Directory containing exported authentication token XrdOucString ManagerId; ///< manager id in : format XrdOucString ManagerIp; ///< manager ip in format + XrdOucString + mPostSlaveToMaster; ///< Path of the script running after the Slave to Master transition int ManagerPort; ///< manager port as number e.g. 1094 uint16_t XrdHttpPort; ///< The port on which the XrdHttp server is running std::string @@ -1795,8 +1797,10 @@ public: bool mAuthorize; ///< Determine if the authorization should be applied or not std::string mAuthLib; ///< Path to authorization library bool mTapeEnabled; ///< True if support for tape is enabled - std::string mPrepareDestSpace; ///< Space to be used when retrieving files from tape - unsigned int mReqIdMax; ///< Maximum number of request IDs on a single retrieving file + std::string + mPrepareDestSpace; ///< Space to be used when retrieving files from tape + unsigned int + mReqIdMax; ///< Maximum number of request IDs on a single retrieving file //! Acts only as a redirector, disables many components in the MGM bool MgmRedirector; //! Writes error log with cluster wide collected errors in diff --git a/mgm/XrdMgmOfsConfigure.cc b/mgm/XrdMgmOfsConfigure.cc index e453e937e4..697552e73f 100644 --- a/mgm/XrdMgmOfsConfigure.cc +++ b/mgm/XrdMgmOfsConfigure.cc @@ -1067,6 +1067,16 @@ XrdMgmOfs::Configure(XrdSysError& Eroute) } } + if (!strcmp("postslavetomaster", var)) { + if (!(val = Config.GetWord())) { + Eroute.Emsg("Config", "argument for postslavetomaster invalid."); + NoGo = 1; + } else { + Eroute.Say("=====> mgmofs.postslavetomaster: ", val, ""); + mPostSlaveToMaster = val; + } + } + if (!strcmp("protowfendpoint", var)) { val = Config.GetWord(); diff --git a/misc/etc/eos/config/mgm/mgm b/misc/etc/eos/config/mgm/mgm index b73a7d97f4..49402c38e4 100644 --- a/misc/etc/eos/config/mgm/mgm +++ b/misc/etc/eos/config/mgm/mgm @@ -54,6 +54,9 @@ mgmofs.autoloadconfig default # QoS configuration file mgmofs.qoscfg /var/eos/qos/qos.conf +# Post slave to master transition script +# mgmofs.postslavetomaster /usr/bin/true + #------------------------------------------------------------------------------- # Configuration for the authentication plugin EosAuth #-------------------------------------------------------------------------------