summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ibm/locks.hpp140
-rw-r--r--include/ibm/management_console_rest.hpp85
2 files changed, 220 insertions, 5 deletions
diff --git a/include/ibm/locks.hpp b/include/ibm/locks.hpp
index 60c55bffa4..dcd110f8dc 100644
--- a/include/ibm/locks.hpp
+++ b/include/ibm/locks.hpp
@@ -23,16 +23,17 @@ using SegmentFlags = std::vector<std::pair<SType, uint32_t>>;
// Lockrequest = session-id | hmc-id | locktype | resourceid | segmentinfo
using LockRequest = std::tuple<SType, SType, SType, uint64_t, SegmentFlags>;
-
using LockRequests = std::vector<LockRequest>;
using Rc =
std::pair<bool, std::variant<uint32_t, std::pair<uint32_t, LockRequest>>>;
-using RcRelaseLock = std::pair<bool, LockRequest>;
+using RcRelaseLock = std::pair<bool, std::pair<uint32_t, LockRequest>>;
using RcGetLocklist = std::pair<
bool,
std::variant<std::string, std::vector<std::pair<uint32_t, LockRequests>>>>;
-
+using ListOfTransactionIds = std::vector<uint32_t>;
using RcAcquireLock = std::pair<bool, std::variant<Rc, std::pair<bool, int>>>;
+using RcReleaseLockApi = std::pair<bool, std::variant<bool, RcRelaseLock>>;
+using SessionFlags = std::pair<SType, SType>;
class Lock
{
@@ -78,6 +79,29 @@ class Lock
*/
Rc isConflictWithTable(const LockRequests);
+ /*
+ * This function implements the logic of checking the ownership of the
+ * lock from the releaselock request.
+ *
+ * Returns : True (if the requesting HMC & Session owns the lock(s))
+ * Returns : False (if the request HMC or Session does not own the lock(s))
+ */
+
+ RcRelaseLock isItMyLock(const ListOfTransactionIds &, const SessionFlags &);
+
+ /*
+ * This function validates the the list of transactionID's and returns false
+ * if the transaction ID is not valid & not present in the lock table
+ */
+
+ bool validateRids(const ListOfTransactionIds &);
+
+ /*
+ * This function releases the locks that are already obtained by the
+ * requesting Management console.
+ */
+
+ void releaseLock(const ListOfTransactionIds &);
/*
* This function implements the algorithm for checking the respective
@@ -104,7 +128,20 @@ class Lock
RcAcquireLock acquireLock(const LockRequests);
- public:
+ /*
+ * This function implements the logic for releasing the lock that are
+ * owned by a management console session.
+ *
+ * The locks can be released by two ways
+ * - Using list of transaction ID's
+ * - Using a Session ID
+ *
+ * Client can choose either of the ways by using `Type` JSON key.
+ *
+ */
+ RcReleaseLockApi releaseLock(const ListOfTransactionIds &,
+ const SessionFlags &);
+
Lock()
{
transactionId = 0;
@@ -112,6 +149,34 @@ class Lock
} lockObject;
+RcReleaseLockApi Lock::releaseLock(const ListOfTransactionIds &p,
+ const SessionFlags &ids)
+{
+
+ bool status = validateRids(p);
+
+ if (!status)
+ {
+ // Validation of rids failed
+ BMCWEB_LOG_DEBUG << "Not a Valid request id";
+ return std::make_pair(false, status);
+ }
+ else
+ {
+ // Validation passed, check if all the locks are owned by the
+ // requesting HMC
+ auto status = isItMyLock(p, ids);
+ if (status.first)
+ {
+ // The current hmc owns all the locks, so we can release
+ // them
+ releaseLock(p);
+ }
+ return std::make_pair(true, status);
+ }
+ return std::make_pair(false, status);
+}
+
RcAcquireLock Lock::acquireLock(const LockRequests lockRequestStructure)
{
@@ -152,6 +217,72 @@ RcAcquireLock Lock::acquireLock(const LockRequests lockRequestStructure)
return std::make_pair(true, std::make_pair(true, 1));
}
+void Lock::releaseLock(const ListOfTransactionIds &refRids)
+{
+ for (const auto &id : refRids)
+ {
+ if (lockTable.erase(id))
+ {
+ BMCWEB_LOG_DEBUG << "Removing the locks with transaction ID : "
+ << id;
+ }
+
+ else
+ {
+ BMCWEB_LOG_DEBUG << "Removing the locks from the lock table "
+ "failed, tranasction ID: "
+ << id;
+ }
+ }
+}
+
+RcRelaseLock Lock::isItMyLock(const ListOfTransactionIds &refRids,
+ const SessionFlags &ids)
+{
+ for (const auto &id : refRids)
+ {
+ // Just need to compare the client id of the first lock records in the
+ // complete lock row(in the map), because the rest of the lock records
+ // would have the same client id
+
+ std::string expectedClientId = std::get<1>(lockTable[id][0]);
+ std::string expectedSessionId = std::get<0>(lockTable[id][0]);
+
+ if ((expectedClientId == ids.first) &&
+ (expectedSessionId == ids.second))
+ {
+ // It is owned by the currently request hmc
+ BMCWEB_LOG_DEBUG << "Lock is owned by the current hmc";
+ }
+ else
+ {
+ BMCWEB_LOG_DEBUG << "Lock is not owned by the current hmc";
+ return std::make_pair(false, std::make_pair(id, lockTable[id][0]));
+ }
+ }
+ return std::make_pair(true, std::make_pair(0, LockRequest()));
+}
+
+bool Lock::validateRids(const ListOfTransactionIds &refRids)
+{
+ for (const auto &id : refRids)
+ {
+ auto search = lockTable.find(id);
+
+ if (search != lockTable.end())
+ {
+ BMCWEB_LOG_DEBUG << "Valid Transaction id";
+ // continue for the next rid
+ }
+ else
+ {
+ BMCWEB_LOG_DEBUG << "Atleast 1 inValid Request id";
+ return false;
+ }
+ }
+ return true;
+}
+
bool Lock::isValidLockRequest(const LockRequest refLockRecord)
{
@@ -217,7 +348,6 @@ bool Lock::isValidLockRequest(const LockRequest refLockRecord)
}
}
- // validate the segment length
return true;
}
diff --git a/include/ibm/management_console_rest.hpp b/include/ibm/management_console_rest.hpp
index a4dcf4a61c..a4bf31ea72 100644
--- a/include/ibm/management_console_rest.hpp
+++ b/include/ibm/management_console_rest.hpp
@@ -406,6 +406,74 @@ void handleAcquireLockAPI(const crow::Request &req, crow::Response &res,
}
}
+void handleReleaseLockAPI(const crow::Request &req, crow::Response &res,
+ const std::vector<uint32_t> &listTransactionIds)
+{
+ BMCWEB_LOG_DEBUG << listTransactionIds.size();
+ BMCWEB_LOG_DEBUG << "Data is present";
+ for (uint32_t i = 0; i < listTransactionIds.size(); i++)
+ {
+ BMCWEB_LOG_DEBUG << listTransactionIds[i];
+ }
+
+ std::string clientId = "hmc-id";
+ std::string sessionId = req.session->uniqueId;
+
+ // validate the request ids
+
+ auto varReleaselock = crow::ibm_mc_lock::lockObject.releaseLock(
+ listTransactionIds, std::make_pair(clientId, sessionId));
+
+ if (!varReleaselock.first)
+ {
+ // validation Failed
+ res.result(boost::beast::http::status::bad_request);
+ res.end();
+ return;
+ }
+ else
+ {
+ auto statusRelease =
+ std::get<crow::ibm_mc_lock::RcRelaseLock>(varReleaselock.second);
+ if (statusRelease.first)
+ {
+ // The current hmc owns all the locks, so we already released
+ // them
+ res.result(boost::beast::http::status::ok);
+ res.end();
+ return;
+ }
+
+ else
+ {
+ // valid rid, but the current hmc does not own all the locks
+ BMCWEB_LOG_DEBUG << "Current HMC does not own all the locks";
+ res.result(boost::beast::http::status::unauthorized);
+
+ auto var = statusRelease.second;
+ nlohmann::json returnJson, segments;
+ nlohmann::json myArray = nlohmann::json::array();
+ returnJson["TransactionID"] = var.first;
+ returnJson["SessionID"] = std::get<0>(var.second);
+ returnJson["HMCID"] = std::get<1>(var.second);
+ returnJson["LockType"] = std::get<2>(var.second);
+ returnJson["ResourceID"] = std::get<3>(var.second);
+
+ for (uint32_t i = 0; i < std::get<4>(var.second).size(); i++)
+ {
+ segments["LockFlag"] = std::get<4>(var.second)[i].first;
+ segments["SegmentLength"] = std::get<4>(var.second)[i].second;
+ myArray.push_back(segments);
+ }
+
+ returnJson["SegmentFlags"] = myArray;
+ res.jsonValue["Record"] = returnJson;
+ res.end();
+ return;
+ }
+ }
+}
+
template <typename... Middlewares> void requestRoutes(Crow<Middlewares...> &app)
{
@@ -469,6 +537,23 @@ template <typename... Middlewares> void requestRoutes(Crow<Middlewares...> &app)
}
handleAcquireLockAPI(req, res, body);
});
+
+ BMCWEB_ROUTE(app, "/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock")
+ .requires({"ConfigureComponents", "ConfigureManager"})
+ .methods("POST"_method)(
+ [](const crow::Request &req, crow::Response &res) {
+ std::vector<uint32_t> listTransactionIds;
+
+ if (!redfish::json_util::readJson(req, res, "TransactionIDs",
+ listTransactionIds))
+ {
+ res.result(boost::beast::http::status::bad_request);
+ res.end();
+ return;
+ }
+
+ handleReleaseLockAPI(req, res, listTransactionIds);
+ });
}
} // namespace ibm_mc