Skip to content

Commit

Permalink
mount: Fix updating user groups in master after its restart
Browse files Browse the repository at this point in the history
The bug originated from clearing mount's group cache on master disconnected
event and using the same cache to register user's groups in the master later on.
The cache was already empty when attempting the registration so there were no
groups to tell master about so the operation performed on the mounted filesystem
failed.

This fix changes the registration part in the client so that it uses client
context to populate the cache and update credentials (groups) in master if
the group cache is empty, for example due to disconnection from master.

Context references were made non-const because updating groups in group cache
requires assigning a new gid value in the client context.

Fixes bug introduced by 7e7ad72

Change-Id: Idac2ebc74e73ca306462e07bd3b943c2efa73a0d
  • Loading branch information
przemekpjski authored and AmokHuginnsson committed Dec 15, 2020
1 parent cead0a0 commit d61a93e
Show file tree
Hide file tree
Showing 9 changed files with 434 additions and 364 deletions.
41 changes: 41 additions & 0 deletions src/common/user_groups.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
Copyright 2013-2020 Lizard sp. z o.o.
This file is part of LizardFS.
LizardFS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3.
LizardFS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LizardFS. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "common/platform.h"

#include <cstdint>

namespace user_groups {

constexpr std::uint32_t kSecondaryGroupsBit = (std::uint32_t)1 << 31;

constexpr bool isGroupCacheId(std::uint32_t groupsId) noexcept {
return static_cast<bool>(groupsId & kSecondaryGroupsBit);
}

constexpr std::uint32_t encodeGroupCacheId(std::uint32_t groupsId) noexcept {
return groupsId | kSecondaryGroupsBit;
}

constexpr std::uint32_t decodeGroupCacheId(std::uint32_t groupsId) noexcept {
return groupsId & ~kSecondaryGroupsBit;
}

} // namespace user_groups
13 changes: 5 additions & 8 deletions src/master/matoclserv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "common/serialized_goal.h"
#include "common/slogger.h"
#include "common/sockets.h"
#include "common/user_groups.h"
#include "master/changelog.h"
#include "master/chartsdata.h"
#include "master/chunks.h"
Expand Down Expand Up @@ -948,14 +949,12 @@ static inline void matoclserv_ugid_remap(matoclserventry *eptr,uint32_t *auid,ui
}

static inline uint8_t matoclserv_check_group_cache(matoclserventry *eptr, uint32_t gid) {
static constexpr uint32_t kSecondaryGroupsBit = (uint32_t)1 << 31;

if ((gid & kSecondaryGroupsBit) == 0) {
if (!user_groups::isGroupCacheId(gid)) {
return LIZARDFS_STATUS_OK;
}

assert(eptr && eptr->sesdata);
auto it = eptr->sesdata->group_cache.find(gid ^ kSecondaryGroupsBit);
auto it = eptr->sesdata->group_cache.find(user_groups::decodeGroupCacheId(gid));
return it == eptr->sesdata->group_cache.end() ? LIZARDFS_ERROR_GROUPNOTREGISTERED : LIZARDFS_STATUS_OK;
}

Expand All @@ -971,12 +970,10 @@ static inline FsContext matoclserv_get_context(matoclserventry *eptr) {
* Returns FsContext with session data and uid/gid data
*/
static inline FsContext matoclserv_get_context(matoclserventry *eptr, uint32_t uid, uint32_t gid) {
static constexpr uint32_t kSecondaryGroupsBit = (uint32_t)1 << 31;

assert(eptr && eptr->sesdata);

if (gid & kSecondaryGroupsBit) {
auto it = eptr->sesdata->group_cache.find(gid ^ kSecondaryGroupsBit);
if (user_groups::isGroupCacheId(gid)) {
auto it = eptr->sesdata->group_cache.find(user_groups::decodeGroupCacheId(gid));
if (it == eptr->sesdata->group_cache.end()) {
throw std::runtime_error("Missing group data in session cache");
}
Expand Down
Loading

0 comments on commit d61a93e

Please sign in to comment.