diff options
author | manojkiraneda <manojkiran.eda@gmail.com> | 2019-12-13 14:35:36 +0300 |
---|---|---|
committer | ManojKiran Eda <manojkiran.eda@gmail.com> | 2020-04-28 06:51:24 +0300 |
commit | 3b6dea601ede930c4596b0160b5a8d328b92b0c4 (patch) | |
tree | cdf82e7527ffe38d5f26c1b2af7d7b6c4798954b /include/ibm/locks.hpp | |
parent | b52664e2f47512c4eb7ce8f036eacf7a4b161320 (diff) | |
download | bmcweb-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.hpp | 140 |
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; } |