/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
CondCore/CondDB/src/IOVEditor.cc
377 строк
17 KB
Giacomo Govi
Fix for bug concerning lock cleaning up at session closing time
30 апр 2021, 17:53
30 апр 2021, 17:53
435e38b
Код
Авторство
О чём код?
#include "CondCore/CondDB/interface/IOVEditor.h" #include "CondCore/CondDB/interface/Auth.h" #include "CondCore/CondDB/interface/Utils.h" #include "SessionImpl.h" // namespace cond { namespace persistency { // implementation details. holds only data. class IOVEditorData { public: explicit IOVEditorData() : tag(""), timeType(cond::invalid), payloadType(""), synchronizationType(cond::SYNCH_ANY), description(""), iovBuffer(), deleteBuffer(), changes() {} std::string tag; cond::TimeType timeType; std::string payloadType; cond::SynchronizationType synchronizationType; std::string description; cond::Time_t endOfValidity = cond::time::MAX_VAL; cond::Time_t lastValidatedTime = cond::time::MIN_VAL; boost::posix_time::ptime creationTime; bool change = false; bool metadataChange = false; bool exists = false; // buffer for the iov sequence std::vector<std::tuple<cond::Time_t, cond::Hash, boost::posix_time::ptime> > iovBuffer; std::vector<std::tuple<cond::Time_t, cond::Hash> > deleteBuffer; std::set<std::string> changes; int protectionCode = 0; }; IOVEditor::IOVEditor() : m_data(), m_session() {} IOVEditor::IOVEditor(const std::shared_ptr<SessionImpl>& session) : m_data(new IOVEditorData), m_session(session) {} IOVEditor::IOVEditor(const std::shared_ptr<SessionImpl>& session, const std::string& tag, cond::TimeType timeType, const std::string& payloadObjectType, cond::SynchronizationType synchronizationType, const boost::posix_time::ptime& creationTime) : m_data(new IOVEditorData), m_session(session) { m_data->tag = tag; m_data->timeType = timeType; m_data->payloadType = payloadObjectType; m_data->synchronizationType = synchronizationType; m_data->creationTime = creationTime; m_data->change = true; m_data->metadataChange = true; } IOVEditor::IOVEditor(const IOVEditor& rhs) : m_data(rhs.m_data), m_session(rhs.m_session) {} IOVEditor::~IOVEditor() {} IOVEditor& IOVEditor::operator=(const IOVEditor& rhs) { m_data = rhs.m_data; m_session = rhs.m_session; return *this; } void IOVEditor::load(const std::string& tag) { checkTransaction("IOVEditor::load"); // loads the current header data in memory if (!m_session->iovSchema().tagTable().select(tag, m_data->timeType, m_data->payloadType, m_data->synchronizationType, m_data->endOfValidity, m_data->lastValidatedTime, m_data->protectionCode)) { cond::throwException("Tag \"" + tag + "\" has not been found in the database.", "IOVEditor::load"); } if (m_data->protectionCode) { if (m_data->protectionCode & cond::auth::COND_DBTAG_WRITE_ACCESS_CODE) { bool writeAllowed = m_session->iovSchema().tagAccessPermissionTable().getAccessPermission( tag, m_session->principalName, cond::auth::COND_DBKEY_CREDENTIAL_CODE, cond::auth::COND_DBTAG_WRITE_ACCESS_CODE); if (!writeAllowed) cond::throwException( "Tag \"" + tag + "\" can't be accessed for update by db-user \"" + m_session->principalName + "\".", "IOVEditor::load"); } if (m_data->protectionCode & cond::auth::COND_DBTAG_LOCK_ACCESS_CODE) { bool mylock = m_session->iovSchema().tagAccessPermissionTable().getAccessPermission( tag, m_session->sessionHash, cond::auth::COND_SESSION_HASH_CODE, cond::auth::COND_DBTAG_LOCK_ACCESS_CODE); if (!mylock) cond::throwException( "Tag \"" + tag + "\" can't be accessed for update, because it has been locked by an other session.", "IOVEditor::load"); } } m_data->tag = tag; m_data->exists = true; m_data->change = false; } std::string IOVEditor::tag() const { return m_data.get() ? m_data->tag : ""; } cond::TimeType IOVEditor::timeType() const { return m_data.get() ? m_data->timeType : cond::invalid; } std::string IOVEditor::payloadType() const { return m_data.get() ? m_data->payloadType : ""; } cond::SynchronizationType IOVEditor::synchronizationType() const { return m_data.get() ? m_data->synchronizationType : cond::SYNCH_ANY; } void IOVEditor::setSynchronizationType(cond::SynchronizationType synchronizationType) { if (m_data.get()) { m_data->synchronizationType = synchronizationType; m_data->change = true; m_data->changes.insert("SynchronizationType"); } } cond::Time_t IOVEditor::endOfValidity() const { return m_data.get() ? m_data->endOfValidity : cond::time::MIN_VAL; } void IOVEditor::setEndOfValidity(cond::Time_t time) { if (m_data.get()) { m_data->endOfValidity = time; m_data->change = true; m_data->changes.insert("EndOfValidity"); } } std::string IOVEditor::description() const { return m_data.get() ? m_data->description : ""; } void IOVEditor::setDescription(const std::string& description) { if (m_data.get()) { m_data->description = description; m_data->metadataChange = true; m_data->changes.insert("Description"); } } cond::Time_t IOVEditor::lastValidatedTime() const { return m_data.get() ? m_data->lastValidatedTime : cond::time::MIN_VAL; } void IOVEditor::setLastValidatedTime(cond::Time_t time) { if (m_data.get()) { m_data->lastValidatedTime = time; m_data->change = true; m_data->changes.insert("LastValidatedTime"); } } void IOVEditor::insert(cond::Time_t since, const cond::Hash& payloadHash, bool checkType) { boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); insert(since, payloadHash, now, checkType); } void IOVEditor::insert(cond::Time_t since, const cond::Hash& payloadHash, const boost::posix_time::ptime& insertionTime, bool) { if (m_data.get()) { // here the type check could be added m_data->iovBuffer.push_back(std::tie(since, payloadHash, insertionTime)); } } void IOVEditor::erase(cond::Time_t since, const cond::Hash& payloadHash) { if (m_data.get()) { m_data->deleteBuffer.push_back(std::tie(since, payloadHash)); } } bool iovSorter(const std::tuple<cond::Time_t, cond::Hash, boost::posix_time::ptime>& f, const std::tuple<cond::Time_t, cond::Hash, boost::posix_time::ptime>& s) { return std::get<0>(f) < std::get<0>(s); } bool IOVEditor::flush(const std::string& logText, const boost::posix_time::ptime& operationTime, bool forceInsertion) { bool ret = false; checkTransaction("IOVEditor::flush"); std::string lt = logText; if (lt.empty()) lt = "-"; if (m_data->change || m_data->metadataChange) { if (m_data->metadataChange && m_data->description.empty()) throwException("A non-empty description string is mandatory.", "IOVEditor::flush"); //if (m_data->validationMode) // m_session->iovSchema().tagTable().setValidationMode(); if (!m_data->exists) { // set the creation time ( only available in the migration from v1...) if (m_data->creationTime.is_not_a_date_time()) m_data->creationTime = operationTime; m_session->iovSchema().tagTable().insert(m_data->tag, m_data->timeType, m_data->payloadType, m_data->synchronizationType, m_data->endOfValidity, m_data->description, m_data->lastValidatedTime, m_data->creationTime); if (m_session->iovSchema().tagLogTable().exists()) m_session->iovSchema().tagLogTable().insert(m_data->tag, m_data->creationTime, cond::getUserName(), cond::getHostName(), cond::getCommand(), std::string("New tag created."), lt); m_data->exists = true; ret = true; } else { if (m_data->change) { m_session->iovSchema().tagTable().update(m_data->tag, m_data->synchronizationType, m_data->endOfValidity, m_data->lastValidatedTime, operationTime); } if (m_data->metadataChange) { m_session->iovSchema().tagTable().updateMetadata(m_data->tag, m_data->description, operationTime); } if (m_session->iovSchema().tagLogTable().exists()) { std::string action("Tag header updated. Changes involve: "); size_t i = 0; for (const auto& c : m_data->changes) { action += c; if (i == (m_data->changes.size() - 1)) action += "."; else action += ", "; i++; } m_session->iovSchema().tagLogTable().insert( m_data->tag, operationTime, cond::getUserName(), cond::getHostName(), cond::getCommand(), action, lt); } ret = true; } m_data->change = false; } if (!m_data->iovBuffer.empty()) { std::sort(m_data->iovBuffer.begin(), m_data->iovBuffer.end(), iovSorter); cond::Time_t l = std::get<0>(m_data->iovBuffer.front()); //We do not allow for IOV updates (i.e. insertion in the past or overriding) on tags whose syncrosization is not "ANY" or "VALIDATION". //This policy is stricter than the one deployed in the Condition Upload service, //which allows insertions in the past or overriding for IOVs larger than the first condition safe run for HLT ("HLT"/"EXPRESS" synchronizations) and Tier0 ("PROMPT"/"PCL"). //This is intended: in the C++ API we have no way to determine the first condition safe runs. if (!forceInsertion && m_data->synchronizationType != cond::SYNCH_ANY && m_data->synchronizationType != cond::SYNCH_VALIDATION) { // retrieve the last since cond::Time_t last = 0; cond::Hash h; boost::posix_time::ptime no_time; m_session->iovSchema().iovTable().getLastIov(m_data->tag, no_time, last, h); // check if the min iov is greater then the last since if (l <= last) { std::stringstream msg; msg << "Can't insert iov since " << l << " on the tag " << m_data->tag << ": last since is " << last << " and synchronization is \"" << cond::synchronizationTypeNames(m_data->synchronizationType) << "\""; throwException(msg.str(), "IOVEditor::flush"); } } // set the insertion time ( only for the migration from v1 will be available... ) for (auto& iov : m_data->iovBuffer) { boost::posix_time::ptime& insertionTime = std::get<2>(iov); if (insertionTime.is_not_a_date_time()) insertionTime = operationTime; } // insert the new iovs m_session->iovSchema().iovTable().insertMany(m_data->tag, m_data->iovBuffer); ret = true; } if (!m_data->deleteBuffer.empty()) { // delete the specified iovs m_session->iovSchema().iovTable().eraseMany(m_data->tag, m_data->deleteBuffer); ret = true; } if (m_session->iovSchema().tagLogTable().exists()) { std::stringstream msg; if (!m_data->iovBuffer.empty()) msg << m_data->iovBuffer.size() << " iov(s) inserted"; if (!msg.str().empty()) msg << "; "; else msg << "."; if (!m_data->deleteBuffer.empty()) msg << m_data->deleteBuffer.size() << " iov(s) deleted."; if (ret) { m_session->iovSchema().tagLogTable().insert( m_data->tag, operationTime, cond::getUserName(), cond::getHostName(), cond::getCommand(), msg.str(), lt); } } m_data->iovBuffer.clear(); m_data->deleteBuffer.clear(); m_data->changes.clear(); return ret; } bool IOVEditor::flush(const std::string& logText) { return flush(logText, boost::posix_time::microsec_clock::universal_time(), false); } bool IOVEditor::flush(const boost::posix_time::ptime& operationTime) { return flush(std::string("-"), operationTime, false); } bool IOVEditor::flush() { return flush(std::string("-"), boost::posix_time::microsec_clock::universal_time(), false); } bool IOVEditor::flush(const std::string& logText, bool forceInsertion) { return flush(logText, boost::posix_time::microsec_clock::universal_time(), forceInsertion); } bool IOVEditor::isLocked() const { return m_data->protectionCode & cond::auth::COND_DBTAG_LOCK_ACCESS_CODE; } void IOVEditor::lock() { if (isLocked()) return; checkTransaction("IOVEditor::lock"); m_session->iovSchema().tagAccessPermissionTable().setAccessPermission(m_data->tag, m_session->sessionHash, cond::auth::COND_SESSION_HASH_CODE, cond::auth::COND_DBTAG_LOCK_ACCESS_CODE); m_data->protectionCode |= cond::auth::COND_DBTAG_LOCK_ACCESS_CODE; m_session->iovSchema().tagTable().setProtectionCode(m_data->tag, cond::auth::COND_DBTAG_LOCK_ACCESS_CODE); m_session->lockedTags.insert(m_data->tag); std::string lt("-"); std::string action("Lock set by session "); action += m_session->sessionHash; m_session->iovSchema().tagLogTable().insert(m_data->tag, boost::posix_time::microsec_clock::universal_time(), cond::getUserName(), cond::getHostName(), cond::getCommand(), action, lt); } void IOVEditor::unlock() { if (!isLocked()) return; checkTransaction("IOVEditor::unlock"); m_session->iovSchema().tagAccessPermissionTable().removeAccessPermission( m_data->tag, m_session->sessionHash, cond::auth::COND_SESSION_HASH_CODE); m_data->protectionCode &= cond::auth::COND_DBTAG_WRITE_ACCESS_CODE; m_session->iovSchema().tagTable().unsetProtectionCode(m_data->tag, cond::auth::COND_DBTAG_LOCK_ACCESS_CODE); m_session->lockedTags.erase(m_data->tag); std::string lt("-"); std::string action("Lock released by session "); action += m_session->sessionHash; m_session->iovSchema().tagLogTable().insert(m_data->tag, boost::posix_time::microsec_clock::universal_time(), cond::getUserName(), cond::getHostName(), cond::getCommand(), action, lt); } void IOVEditor::checkTransaction(const std::string& ctx) { if (!m_session.get()) throwException("The session is not active.", ctx); if (!m_session->isTransactionActive(false)) throwException("The transaction is not active.", ctx); } } // namespace persistency } // namespace cond