KUDU-2395 (part 1): cache logged-in user The name of the current logged-in user is not expected to change over time once the process is running. If it did change this could cause strange effects with ACL enforcement, for one, or result in outbound RPC connections switching credentials during the process lifetime.
Additionally, as pointed at in KUDU-2395, the lookup of the user name from the UID sometimes needs to go to external services which may be slow and incur lock contention. This patch switches to computing the local username only once and reusing the result on all subsequent lookups. Change-Id: Ib4500d89dd91e8eed6e4ae0661b886ab3c105130 Reviewed-on: http://gerrit.cloudera.org:8080/9895 Tested-by: Kudu Jenkins Reviewed-by: Todd Lipcon <t...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/kudu/repo Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/52b50b7a Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/52b50b7a Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/52b50b7a Branch: refs/heads/master Commit: 52b50b7a91c61925a7bc42992fe1001e74425d4d Parents: 161c25c Author: Todd Lipcon <t...@apache.org> Authored: Mon Apr 2 16:12:33 2018 -0700 Committer: Todd Lipcon <t...@apache.org> Committed: Wed Apr 4 00:21:27 2018 +0000 ---------------------------------------------------------------------- src/kudu/util/user.cc | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kudu/blob/52b50b7a/src/kudu/util/user.cc ---------------------------------------------------------------------- diff --git a/src/kudu/util/user.cc b/src/kudu/util/user.cc index 1b73e53..2d12267 100644 --- a/src/kudu/util/user.cc +++ b/src/kudu/util/user.cc @@ -22,19 +22,23 @@ #include <cerrno> #include <cstdlib> +#include <mutex> #include <string> +#include <utility> #include <glog/logging.h> #include "kudu/gutil/gscoped_ptr.h" +#include "kudu/util/debug/leakcheck_disabler.h" #include "kudu/util/errno.h" #include "kudu/util/status.h" using std::string; namespace kudu { +namespace { -Status GetLoggedInUser(string* user_name) { +Status DoGetLoggedInUser(string* user_name) { DCHECK(user_name != nullptr); struct passwd pwd; @@ -59,9 +63,26 @@ Status GetLoggedInUser(string* user_name) { return Status::RuntimeError("Error calling getpwuid_r()", ErrnoToString(ret), ret); } } - *user_name = pwd.pw_name; + return Status::OK(); +} + +} // anonymous namespace + +Status GetLoggedInUser(string* user_name) { + static std::once_flag once; + static string* once_user_name; + static Status* once_status; + std::call_once(once, [](){ + string u; + Status s = DoGetLoggedInUser(&u); + debug::ScopedLeakCheckDisabler ignore_leaks; + once_status = new Status(std::move(s)); + once_user_name = new string(std::move(u)); + }); + RETURN_NOT_OK(*once_status); + *user_name = *once_user_name; return Status::OK(); }