| Directory: | cvmfs/ |
|---|---|
| File: | cvmfs/authz/authz_session.cc |
| Date: | 2025-11-02 02:35:35 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 177 | 189 | 93.7% |
| Branches: | 110 | 186 | 59.1% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /** | ||
| 2 | * This file is part of the CernVM File System. | ||
| 3 | */ | ||
| 4 | |||
| 5 | #define __STDC_FORMAT_MACROS | ||
| 6 | #include "authz_session.h" | ||
| 7 | |||
| 8 | #include <errno.h> | ||
| 9 | #include <inttypes.h> | ||
| 10 | #ifdef __APPLE__ | ||
| 11 | #include <sys/sysctl.h> | ||
| 12 | #endif | ||
| 13 | |||
| 14 | #include <cassert> | ||
| 15 | #include <cstdio> | ||
| 16 | #include <cstring> | ||
| 17 | #include <vector> | ||
| 18 | |||
| 19 | #include "authz/authz_fetch.h" | ||
| 20 | #include "statistics.h" | ||
| 21 | #include "util/concurrency.h" | ||
| 22 | #include "util/logging.h" | ||
| 23 | #include "util/platform.h" | ||
| 24 | #include "util/posix.h" | ||
| 25 | |||
| 26 | using namespace std; // NOLINT | ||
| 27 | |||
| 28 | |||
| 29 | 1485 | AuthzSessionManager::AuthzSessionManager() | |
| 30 | 1485 | : deadline_sweep_pids_(0) | |
| 31 | 1485 | , deadline_sweep_creds_(0) | |
| 32 | 1485 | , authz_fetcher_(NULL) | |
| 33 | 1485 | , no_pid_(NULL) | |
| 34 | 1485 | , no_session_(NULL) | |
| 35 | 1485 | , n_fetch_(NULL) | |
| 36 | 1485 | , n_grant_(NULL) | |
| 37 |
1/2✓ Branch 3 taken 1485 times.
✗ Branch 4 not taken.
|
1485 | , n_deny_(NULL) { |
| 38 | 1485 | int retval = pthread_mutex_init(&lock_pid2session_, NULL); | |
| 39 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1485 times.
|
1485 | assert(retval == 0); |
| 40 | 1485 | retval = pthread_mutex_init(&lock_session2cred_, NULL); | |
| 41 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1485 times.
|
1485 | assert(retval == 0); |
| 42 | |||
| 43 |
1/2✓ Branch 2 taken 1485 times.
✗ Branch 3 not taken.
|
1485 | session2cred_.Init(16, SessionKey(), HashSessionKey); |
| 44 |
1/2✓ Branch 2 taken 1485 times.
✗ Branch 3 not taken.
|
1485 | pid2session_.Init(16, PidKey(), HashPidKey); |
| 45 | 1485 | } | |
| 46 | |||
| 47 | |||
| 48 | 1485 | AuthzSessionManager::~AuthzSessionManager() { | |
| 49 | 1485 | int retval = pthread_mutex_destroy(&lock_pid2session_); | |
| 50 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1485 times.
|
1485 | assert(retval == 0); |
| 51 | 1485 | retval = pthread_mutex_destroy(&lock_session2cred_); | |
| 52 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1485 times.
|
1485 | assert(retval == 0); |
| 53 | |||
| 54 | 1485 | const SessionKey empty_key; | |
| 55 |
2/2✓ Branch 1 taken 31185 times.
✓ Branch 2 taken 1485 times.
|
32670 | for (unsigned i = 0; i < session2cred_.capacity(); ++i) { |
| 56 |
2/2✓ Branch 2 taken 148 times.
✓ Branch 3 taken 31037 times.
|
31185 | if (session2cred_.keys()[i] != empty_key) { |
| 57 |
2/2✓ Branch 1 taken 37 times.
✓ Branch 2 taken 111 times.
|
148 | if ((session2cred_.values() + i)->token.data != NULL) |
| 58 | 37 | free((session2cred_.values() + i)->token.data); | |
| 59 | } | ||
| 60 | } | ||
| 61 | 1485 | } | |
| 62 | |||
| 63 | |||
| 64 | 37 | void AuthzSessionManager::ClearSessionCache() { | |
| 65 | 37 | const MutexLockGuard m(&lock_session2cred_); | |
| 66 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | session2cred_.Clear(); |
| 67 | 37 | no_session_->Set(0); | |
| 68 | 37 | } | |
| 69 | |||
| 70 | |||
| 71 | 1485 | AuthzSessionManager *AuthzSessionManager::Create(AuthzFetcher *authz_fetcher, | |
| 72 | perf::Statistics *statistics) { | ||
| 73 |
1/2✓ Branch 2 taken 1485 times.
✗ Branch 3 not taken.
|
1485 | AuthzSessionManager *authz_mgr = new AuthzSessionManager(); |
| 74 | 1485 | authz_mgr->authz_fetcher_ = authz_fetcher; | |
| 75 | |||
| 76 |
3/6✓ Branch 2 taken 1485 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1485 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1485 times.
✗ Branch 10 not taken.
|
1485 | authz_mgr->no_pid_ = statistics->Register("authz.no_pid", "cached pids"); |
| 77 |
3/6✓ Branch 2 taken 1485 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1485 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1485 times.
✗ Branch 10 not taken.
|
1485 | authz_mgr->no_session_ = statistics->Register("authz.no_session", |
| 78 | "cached sessions"); | ||
| 79 |
3/6✓ Branch 2 taken 1485 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1485 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1485 times.
✗ Branch 10 not taken.
|
1485 | authz_mgr->n_fetch_ = statistics->Register( |
| 80 | "authz.n_fetch", "overall number of authz helper invocations"); | ||
| 81 |
3/6✓ Branch 2 taken 1485 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1485 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1485 times.
✗ Branch 10 not taken.
|
1485 | authz_mgr->n_grant_ = statistics->Register( |
| 82 | "authz.n_grant", "overall number of granted membership queries"); | ||
| 83 |
3/6✓ Branch 2 taken 1485 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1485 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1485 times.
✗ Branch 10 not taken.
|
1485 | authz_mgr->n_deny_ = statistics->Register( |
| 84 | "authz.n_deny", "overall number of denied membership queries"); | ||
| 85 | |||
| 86 | 1485 | return authz_mgr; | |
| 87 | } | ||
| 88 | |||
| 89 | |||
| 90 | /** | ||
| 91 | * Gathers SID, birthday, uid, and gid from given PID. | ||
| 92 | */ | ||
| 93 | 703 | bool AuthzSessionManager::GetPidInfo(pid_t pid, PidKey *pid_key) { | |
| 94 | int retval; | ||
| 95 | |||
| 96 | // TODO(jblomer): better in platform.h? Maybe a bit too bulky for that? | ||
| 97 | #ifdef __APPLE__ | ||
| 98 | pid_key->sid = getsid(pid); | ||
| 99 | if (pid_key->sid == static_cast<pid_t>(-1)) { | ||
| 100 | LogCvmfs(kLogAuthz, kLogDebug, "failed to get sid (%s)", strerror(errno)); | ||
| 101 | return false; | ||
| 102 | } | ||
| 103 | |||
| 104 | int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; | ||
| 105 | struct kinfo_proc kp; | ||
| 106 | size_t len = sizeof(kp); | ||
| 107 | retval = sysctl(mib, 4, &kp, &len, NULL, 0); | ||
| 108 | if (retval == -1) { | ||
| 109 | LogCvmfs(kLogAuthz, kLogDebug, "failed to get pid info (%s)", | ||
| 110 | strerror(errno)); | ||
| 111 | return false; | ||
| 112 | } | ||
| 113 | pid_key->uid = kp.kp_eproc.e_pcred.p_ruid; | ||
| 114 | pid_key->gid = kp.kp_eproc.e_pcred.p_rgid; | ||
| 115 | int64_t usec = static_cast<int64_t>(kp.kp_proc.p_un.__p_starttime.tv_sec) | ||
| 116 | * 1000000; | ||
| 117 | usec += static_cast<int64_t>(kp.kp_proc.p_un.__p_starttime.tv_usec); | ||
| 118 | pid_key->pid_bday = usec; | ||
| 119 | pid_key->pid = pid; | ||
| 120 | return true; | ||
| 121 | #endif | ||
| 122 | |||
| 123 | 703 | const int kMaxProcPath = 64; // Enough to store /proc/PID/stat | |
| 124 | char pid_path[kMaxProcPath]; | ||
| 125 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 703 times.
|
703 | if (snprintf(pid_path, kMaxProcPath, "/proc/%d/stat", pid) >= kMaxProcPath) { |
| 126 | ✗ | return false; | |
| 127 | } | ||
| 128 | |||
| 129 |
1/2✓ Branch 1 taken 703 times.
✗ Branch 2 not taken.
|
703 | FILE *fp_stat = fopen(pid_path, "r"); |
| 130 |
2/2✓ Branch 0 taken 148 times.
✓ Branch 1 taken 555 times.
|
703 | if (fp_stat == NULL) { |
| 131 | 296 | LogCvmfs(kLogAuthz, kLogDebug, | |
| 132 | "Failed to open status file /proc/%d/stat: (errno=%d) %s", pid, | ||
| 133 |
1/2✓ Branch 2 taken 148 times.
✗ Branch 3 not taken.
|
148 | errno, strerror(errno)); |
| 134 |
1/2✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
|
148 | LogCvmfs(kLogAuthz, kLogSyslogWarn | kLogDebug, |
| 135 | "Authorization for session %d disappeared", pid); | ||
| 136 | 148 | return false; | |
| 137 | } | ||
| 138 | |||
| 139 | // The uid and gid can be gathered from /proc/$PID/stat file ownership | ||
| 140 | 555 | const int fd_stat = fileno(fp_stat); | |
| 141 | platform_stat64 info; | ||
| 142 | 555 | retval = platform_fstat(fd_stat, &info); | |
| 143 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 555 times.
|
555 | if (retval != 0) { |
| 144 | ✗ | fclose(fp_stat); | |
| 145 | ✗ | LogCvmfs(kLogAuthz, kLogDebug, | |
| 146 | "Failed to get stat information of running process."); | ||
| 147 | ✗ | return false; | |
| 148 | } | ||
| 149 | 555 | pid_key->uid = info.st_uid; | |
| 150 | 555 | pid_key->gid = info.st_gid; | |
| 151 | |||
| 152 | // TODO(bbockelm): EINTR handling | ||
| 153 |
1/2✓ Branch 1 taken 555 times.
✗ Branch 2 not taken.
|
555 | retval = fscanf(fp_stat, |
| 154 | "%*d %*s %*c %*d %*d %d %*d %*d %*u %*u %*u %*u " | ||
| 155 | "%*u %*u %*u %*d %*d %*d %*d %*d %*d %" SCNu64, | ||
| 156 | &(pid_key->sid), &(pid_key->pid_bday)); | ||
| 157 |
1/2✓ Branch 1 taken 555 times.
✗ Branch 2 not taken.
|
555 | fclose(fp_stat); |
| 158 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 555 times.
|
555 | if (retval != 2) { |
| 159 | ✗ | if (errno == 0) { | |
| 160 | ✗ | errno = EINVAL; | |
| 161 | } | ||
| 162 | ✗ | LogCvmfs(kLogAuthz, kLogDebug, | |
| 163 | "Failed to parse status file for " | ||
| 164 | "pid %d: (errno=%d) %s, fscanf result %d", | ||
| 165 | ✗ | pid, errno, strerror(errno), retval); | |
| 166 | ✗ | return false; | |
| 167 | } | ||
| 168 | |||
| 169 | 555 | pid_key->pid = pid; | |
| 170 | 555 | return true; | |
| 171 | } | ||
| 172 | |||
| 173 | |||
| 174 | /** | ||
| 175 | * Caller is responsible for freeing the returned token. | ||
| 176 | */ | ||
| 177 | 111 | AuthzToken *AuthzSessionManager::GetTokenCopy(const pid_t pid, | |
| 178 | const std::string &membership) { | ||
| 179 | 111 | SessionKey session_key; | |
| 180 | 111 | PidKey pid_key; | |
| 181 |
1/2✓ Branch 1 taken 111 times.
✗ Branch 2 not taken.
|
111 | const bool retval = LookupSessionKey(pid, &pid_key, &session_key); |
| 182 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 74 times.
|
111 | if (!retval) |
| 183 | 37 | return NULL; | |
| 184 | |||
| 185 | 74 | AuthzData authz_data; | |
| 186 |
1/2✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
|
74 | const bool granted = LookupAuthzData(pid_key, session_key, membership, |
| 187 | &authz_data); | ||
| 188 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 74 times.
|
74 | if (!granted) |
| 189 | ✗ | return NULL; | |
| 190 |
1/2✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
|
74 | return authz_data.token.DeepCopy(); |
| 191 | 74 | } | |
| 192 | |||
| 193 | |||
| 194 | 259 | bool AuthzSessionManager::IsMemberOf(const pid_t pid, | |
| 195 | const std::string &membership) { | ||
| 196 | 259 | SessionKey session_key; | |
| 197 | 259 | PidKey pid_key; | |
| 198 |
1/2✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
|
259 | const bool retval = LookupSessionKey(pid, &pid_key, &session_key); |
| 199 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 222 times.
|
259 | if (!retval) |
| 200 | 37 | return false; | |
| 201 | |||
| 202 | 222 | AuthzData authz_data; | |
| 203 |
1/2✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
|
222 | return LookupAuthzData(pid_key, session_key, membership, &authz_data); |
| 204 | 222 | } | |
| 205 | |||
| 206 | |||
| 207 | /** | ||
| 208 | * Calls out to the AuthzFetcher if the data is not cached. Verifies the | ||
| 209 | * membership. | ||
| 210 | */ | ||
| 211 | 518 | bool AuthzSessionManager::LookupAuthzData(const PidKey &pid_key, | |
| 212 | const SessionKey &session_key, | ||
| 213 | const std::string &membership, | ||
| 214 | AuthzData *authz_data) { | ||
| 215 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 518 times.
|
518 | assert(authz_data != NULL); |
| 216 | |||
| 217 | bool found; | ||
| 218 | { | ||
| 219 | 518 | const MutexLockGuard m(&lock_session2cred_); | |
| 220 |
1/2✓ Branch 1 taken 518 times.
✗ Branch 2 not taken.
|
518 | MaySweepCreds(); |
| 221 |
1/2✓ Branch 1 taken 518 times.
✗ Branch 2 not taken.
|
518 | found = session2cred_.Lookup(session_key, authz_data); |
| 222 | 518 | } | |
| 223 |
2/2✓ Branch 0 taken 259 times.
✓ Branch 1 taken 259 times.
|
518 | if (found) { |
| 224 | 518 | LogCvmfs(kLogAuthz, kLogDebug, | |
| 225 | "cached authz data for sid %d, membership %s, status %d", | ||
| 226 |
1/2✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
|
259 | session_key.sid, authz_data->membership.c_str(), |
| 227 | 259 | authz_data->status); | |
| 228 | 259 | const bool granted = authz_data->IsGranted(membership); | |
| 229 |
2/2✓ Branch 0 taken 74 times.
✓ Branch 1 taken 185 times.
|
259 | if (granted) |
| 230 | 74 | perf::Inc(n_grant_); | |
| 231 | else | ||
| 232 | 185 | perf::Inc(n_deny_); | |
| 233 | 259 | return granted; | |
| 234 | } | ||
| 235 | |||
| 236 | // Not found in cache, ask for help | ||
| 237 | 259 | perf::Inc(n_fetch_); | |
| 238 | unsigned ttl; | ||
| 239 |
1/2✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
|
259 | authz_data->status = authz_fetcher_->Fetch( |
| 240 |
1/2✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
|
518 | AuthzFetcher::QueryInfo(pid_key.pid, pid_key.uid, pid_key.gid, |
| 241 | membership), | ||
| 242 | &(authz_data->token), &ttl); | ||
| 243 | 259 | authz_data->deadline = platform_monotonic_time() + ttl; | |
| 244 |
2/2✓ Branch 0 taken 222 times.
✓ Branch 1 taken 37 times.
|
259 | if (authz_data->status == kAuthzOk) |
| 245 |
1/2✓ Branch 1 taken 222 times.
✗ Branch 2 not taken.
|
222 | authz_data->membership = membership; |
| 246 | 518 | LogCvmfs(kLogAuthz, kLogDebug, | |
| 247 | "fetched authz data for sid %d (pid %d), membership %s, status %d, " | ||
| 248 | "ttl %u", | ||
| 249 |
1/2✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
|
259 | session_key.sid, pid_key.pid, authz_data->membership.c_str(), |
| 250 | 259 | authz_data->status, ttl); | |
| 251 | |||
| 252 | { | ||
| 253 | 259 | const MutexLockGuard m(&lock_session2cred_); | |
| 254 |
2/4✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 259 times.
✗ Branch 4 not taken.
|
259 | if (!session2cred_.Contains(session_key)) |
| 255 | 259 | perf::Inc(no_session_); | |
| 256 |
1/2✓ Branch 1 taken 259 times.
✗ Branch 2 not taken.
|
259 | session2cred_.Insert(session_key, *authz_data); |
| 257 | 259 | } | |
| 258 | 259 | const bool granted = authz_data->status == kAuthzOk; | |
| 259 |
2/2✓ Branch 0 taken 222 times.
✓ Branch 1 taken 37 times.
|
259 | if (granted) |
| 260 | 222 | perf::Inc(n_grant_); | |
| 261 | else | ||
| 262 | 37 | perf::Inc(n_deny_); | |
| 263 | 259 | return granted; | |
| 264 | } | ||
| 265 | |||
| 266 | |||
| 267 | /** | ||
| 268 | * Translate a PID and its birthday into an SID and its birthday. The Session | ||
| 269 | * ID and its birthday together with UID and GID make the Session Key. The | ||
| 270 | * translation result is cached in pid2session_. | ||
| 271 | */ | ||
| 272 | 444 | bool AuthzSessionManager::LookupSessionKey(pid_t pid, | |
| 273 | PidKey *pid_key, | ||
| 274 | SessionKey *session_key) { | ||
| 275 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 444 times.
|
444 | assert(pid_key != NULL); |
| 276 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 444 times.
|
444 | assert(session_key != NULL); |
| 277 |
3/4✓ Branch 1 taken 444 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 111 times.
✓ Branch 4 taken 333 times.
|
444 | if (!GetPidInfo(pid, pid_key)) |
| 278 | 111 | return false; | |
| 279 | |||
| 280 | bool found; | ||
| 281 | { | ||
| 282 | 333 | const MutexLockGuard m(&lock_pid2session_); | |
| 283 |
1/2✓ Branch 1 taken 333 times.
✗ Branch 2 not taken.
|
333 | found = pid2session_.Lookup(*pid_key, session_key); |
| 284 |
1/2✓ Branch 1 taken 333 times.
✗ Branch 2 not taken.
|
333 | MaySweepPids(); |
| 285 | 333 | } | |
| 286 |
2/2✓ Branch 0 taken 185 times.
✓ Branch 1 taken 148 times.
|
333 | if (found) { |
| 287 |
1/2✓ Branch 1 taken 185 times.
✗ Branch 2 not taken.
|
185 | LogCvmfs(kLogAuthz, kLogDebug, |
| 288 | "Session key %d/%" PRIu64 " in cache; sid=%d, bday=%" PRIu64, | ||
| 289 | pid_key->pid, pid_key->pid_bday, session_key->sid, | ||
| 290 | session_key->sid_bday); | ||
| 291 | 185 | return true; | |
| 292 | } | ||
| 293 | |||
| 294 |
1/2✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
|
148 | LogCvmfs(kLogAuthz, kLogDebug, |
| 295 | "Session key not found in cache, getting information from OS"); | ||
| 296 | 148 | PidKey sid_key; | |
| 297 | 148 | pid_t sid = pid_key->sid; | |
| 298 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 148 times.
|
148 | if (sid == 0) { |
| 299 | // This can happen inside process namespaces such as those used by | ||
| 300 | // singularity and cvmfsexec. Use init process id instead. | ||
| 301 | ✗ | sid = 1; | |
| 302 | } | ||
| 303 |
2/4✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 148 times.
|
148 | if (!GetPidInfo(sid, &sid_key)) |
| 304 | ✗ | return false; | |
| 305 | |||
| 306 | 148 | session_key->sid = sid_key.pid; | |
| 307 | 148 | session_key->sid_bday = sid_key.pid_bday; | |
| 308 | { | ||
| 309 | 148 | const MutexLockGuard m(&lock_pid2session_); | |
| 310 | 148 | pid_key->deadline = platform_monotonic_time() + kPidLifetime; | |
| 311 |
2/4✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 148 times.
✗ Branch 4 not taken.
|
148 | if (!pid2session_.Contains(*pid_key)) |
| 312 | 148 | perf::Inc(no_pid_); | |
| 313 |
1/2✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
|
148 | pid2session_.Insert(*pid_key, *session_key); |
| 314 | 148 | } | |
| 315 | |||
| 316 |
1/2✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
|
148 | LogCvmfs(kLogAuthz, kLogDebug, "Lookup key %d/%" PRIu64 "; sid=%d, bday=%lu", |
| 317 | pid_key->pid, pid_key->pid_bday, session_key->sid, | ||
| 318 | session_key->sid_bday); | ||
| 319 | 148 | return true; | |
| 320 | } | ||
| 321 | |||
| 322 | |||
| 323 | /** | ||
| 324 | * Scan through old sessions only every so often. | ||
| 325 | */ | ||
| 326 | 518 | void AuthzSessionManager::MaySweepCreds() { | |
| 327 | 518 | const uint64_t now = platform_monotonic_time(); | |
| 328 |
2/2✓ Branch 0 taken 148 times.
✓ Branch 1 taken 370 times.
|
518 | if (now >= deadline_sweep_creds_) { |
| 329 | 148 | SweepCreds(now); | |
| 330 | 148 | deadline_sweep_creds_ = now + kSweepInterval; | |
| 331 | } | ||
| 332 | 518 | } | |
| 333 | |||
| 334 | |||
| 335 | /** | ||
| 336 | * Scan through old PIDs only every so often. | ||
| 337 | */ | ||
| 338 | 333 | void AuthzSessionManager::MaySweepPids() { | |
| 339 | 333 | const uint64_t now = platform_monotonic_time(); | |
| 340 |
2/2✓ Branch 0 taken 148 times.
✓ Branch 1 taken 185 times.
|
333 | if (now >= deadline_sweep_pids_) { |
| 341 | 148 | SweepPids(now); | |
| 342 | 148 | deadline_sweep_pids_ = now + kSweepInterval; | |
| 343 | } | ||
| 344 | 333 | } | |
| 345 | |||
| 346 | |||
| 347 | /** | ||
| 348 | * Remove cache PIDs with expired cache life time. | ||
| 349 | * TODO(jblomer): a generalized sweeping can become part of smallhash | ||
| 350 | */ | ||
| 351 | 185 | void AuthzSessionManager::SweepCreds(uint64_t now) { | |
| 352 | 185 | const SessionKey empty_key; | |
| 353 | 185 | vector<SessionKey> trash_bin; | |
| 354 |
2/2✓ Branch 1 taken 3885 times.
✓ Branch 2 taken 185 times.
|
4070 | for (unsigned i = 0; i < session2cred_.capacity(); ++i) { |
| 355 | 3885 | const SessionKey this_key = session2cred_.keys()[i]; | |
| 356 |
2/2✓ Branch 1 taken 74 times.
✓ Branch 2 taken 3811 times.
|
3885 | if (this_key != empty_key) { |
| 357 |
1/2✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
|
74 | if (now >= (session2cred_.values() + i)->deadline) |
| 358 |
1/2✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
|
74 | trash_bin.push_back(this_key); |
| 359 | } | ||
| 360 | } | ||
| 361 | |||
| 362 |
2/2✓ Branch 1 taken 74 times.
✓ Branch 2 taken 185 times.
|
259 | for (unsigned i = 0; i < trash_bin.size(); ++i) { |
| 363 |
1/2✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
|
74 | session2cred_.Erase(trash_bin[i]); |
| 364 | 74 | perf::Dec(no_session_); | |
| 365 | } | ||
| 366 | 185 | } | |
| 367 | |||
| 368 | |||
| 369 | /** | ||
| 370 | * Remove cache PIDs with expired cache life time. | ||
| 371 | * TODO(jblomer): a generalized sweeping can become part of smallhash | ||
| 372 | */ | ||
| 373 | 222 | void AuthzSessionManager::SweepPids(uint64_t now) { | |
| 374 | 222 | const PidKey empty_key; | |
| 375 | 222 | vector<PidKey> trash_bin; | |
| 376 |
2/2✓ Branch 1 taken 4662 times.
✓ Branch 2 taken 222 times.
|
4884 | for (unsigned i = 0; i < pid2session_.capacity(); ++i) { |
| 377 | 4662 | const PidKey this_key = pid2session_.keys()[i]; | |
| 378 |
2/2✓ Branch 1 taken 74 times.
✓ Branch 2 taken 4588 times.
|
4662 | if (this_key != empty_key) { |
| 379 |
2/2✓ Branch 0 taken 37 times.
✓ Branch 1 taken 37 times.
|
74 | if (now >= this_key.deadline) |
| 380 |
1/2✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
|
37 | trash_bin.push_back(this_key); |
| 381 | } | ||
| 382 | } | ||
| 383 | |||
| 384 |
2/2✓ Branch 1 taken 37 times.
✓ Branch 2 taken 222 times.
|
259 | for (unsigned i = 0; i < trash_bin.size(); ++i) { |
| 385 |
1/2✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
|
37 | pid2session_.Erase(trash_bin[i]); |
| 386 | 37 | perf::Dec(no_pid_); | |
| 387 | } | ||
| 388 | 222 | } | |
| 389 |