summaryrefslogtreecommitdiff
path: root/include/ibm/locks.hpp
diff options
context:
space:
mode:
authormanojkiraneda <manojkiran.eda@gmail.com>2019-12-13 14:35:36 +0300
committerManojKiran Eda <manojkiran.eda@gmail.com>2020-04-28 06:51:24 +0300
commit3b6dea601ede930c4596b0160b5a8d328b92b0c4 (patch)
treecdf82e7527ffe38d5f26c1b2af7d7b6c4798954b /include/ibm/locks.hpp
parentb52664e2f47512c4eb7ce8f036eacf7a4b161320 (diff)
downloadbmcweb-3b6dea601ede930c4596b0160b5a8d328b92b0c4.tar.xz
Implement Release Lock in Lock Service
- This commit implements the Release Lock rest API, so that any external client(having admin-privelege) can release the locks owned by it. Tested By: 1.curl -k -H "X-Auth-Token:$bmc_tokens" -XPOST -H "Content-type: application/json" -d '{ "Request" :[ { "LockType":"Read", "SegmentFlags": [ {"LockFlag":"LockSame","SegmentLength":3}, {"LockFlag":"DontLock","SegmentLength":4} ], "ResourceID": 256 } ] }' https://<ip>/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock { "TransactionID": 1 } 2.curl -k -H "X-Auth-Token:$bmc_tokens" -XPOST -H "Content-type: application/json" -d '{ "Request" :[ { "LockType":"Read", "SegmentFlags": [ {"LockFlag":"LockSame","SegmentLength":3}, {"LockFlag":"DontLock","SegmentLength":4} ], "ResourceID": 256 } ] }' https://<ip>/ibm/v1/HMC/LockService/Actions/LockService.AcquireLock { "TransactionID": 2 } 3. Try releasing the lock owned by it curl -k -H "X-Auth-Token:$bmc_tokens" -XPOST -H "Content-type: application/json" -d '{"TransactionIDs": [1]}' https://<ip>/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock 4. Try releasing the lock, which is not owned by the same session curl -k -H "X-Auth-Token:$bmc_tokens" -XPOST -H "Content-type: application/json" -d '{"TransactionIDs": [2]}' https://127.0.0.1:2443/ibm/v1/HMC/LockService/Actions/LockService.ReleaseLock { "Record": { "HMCID": "hmc-id", "LockType": "Read", "ResourceID": 256, "SegmentFlags": [ { "LockFlag": "LockSame", "SegmentLength": 3 }, { "LockFlag": "DontLock", "SegmentLength": 4 } ], "SessionID": "qM4D0VfZt3", "TransactionID": 2 } } Signed-off-by: manojkiraneda <manojkiran.eda@gmail.com> Change-Id: I5d75d44ce805358b25dc293db4dc0f44f4317c06
Diffstat (limited to 'include/ibm/locks.hpp')
-rw-r--r--include/ibm/locks.hpp140
1 files changed, 135 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;
}