Directory: | cvmfs/ |
---|---|
File: | cvmfs/authz/authz_session.cc |
Date: | 2025-06-29 02:35:41 |
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 | 1034 | AuthzSessionManager::AuthzSessionManager() | |
30 | 1034 | : deadline_sweep_pids_(0) | |
31 | 1034 | , deadline_sweep_creds_(0) | |
32 | 1034 | , authz_fetcher_(NULL) | |
33 | 1034 | , no_pid_(NULL) | |
34 | 1034 | , no_session_(NULL) | |
35 | 1034 | , n_fetch_(NULL) | |
36 | 1034 | , n_grant_(NULL) | |
37 |
1/2✓ Branch 3 taken 1034 times.
✗ Branch 4 not taken.
|
1034 | , n_deny_(NULL) { |
38 | 1034 | int retval = pthread_mutex_init(&lock_pid2session_, NULL); | |
39 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1034 times.
|
1034 | assert(retval == 0); |
40 | 1034 | retval = pthread_mutex_init(&lock_session2cred_, NULL); | |
41 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1034 times.
|
1034 | assert(retval == 0); |
42 | |||
43 |
1/2✓ Branch 2 taken 1034 times.
✗ Branch 3 not taken.
|
1034 | session2cred_.Init(16, SessionKey(), HashSessionKey); |
44 |
1/2✓ Branch 2 taken 1034 times.
✗ Branch 3 not taken.
|
1034 | pid2session_.Init(16, PidKey(), HashPidKey); |
45 | 1034 | } | |
46 | |||
47 | |||
48 | 1034 | AuthzSessionManager::~AuthzSessionManager() { | |
49 | 1034 | int retval = pthread_mutex_destroy(&lock_pid2session_); | |
50 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1034 times.
|
1034 | assert(retval == 0); |
51 | 1034 | retval = pthread_mutex_destroy(&lock_session2cred_); | |
52 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1034 times.
|
1034 | assert(retval == 0); |
53 | |||
54 | 1034 | const SessionKey empty_key; | |
55 |
2/2✓ Branch 1 taken 21714 times.
✓ Branch 2 taken 1034 times.
|
22748 | for (unsigned i = 0; i < session2cred_.capacity(); ++i) { |
56 |
2/2✓ Branch 2 taken 8 times.
✓ Branch 3 taken 21706 times.
|
21714 | if (session2cred_.keys()[i] != empty_key) { |
57 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
|
8 | if ((session2cred_.values() + i)->token.data != NULL) |
58 | 2 | free((session2cred_.values() + i)->token.data); | |
59 | } | ||
60 | } | ||
61 | 1034 | } | |
62 | |||
63 | |||
64 | 2 | void AuthzSessionManager::ClearSessionCache() { | |
65 | 2 | const MutexLockGuard m(&lock_session2cred_); | |
66 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | session2cred_.Clear(); |
67 | 2 | no_session_->Set(0); | |
68 | 2 | } | |
69 | |||
70 | |||
71 | 1034 | AuthzSessionManager *AuthzSessionManager::Create(AuthzFetcher *authz_fetcher, | |
72 | perf::Statistics *statistics) { | ||
73 |
1/2✓ Branch 2 taken 1034 times.
✗ Branch 3 not taken.
|
1034 | AuthzSessionManager *authz_mgr = new AuthzSessionManager(); |
74 | 1034 | authz_mgr->authz_fetcher_ = authz_fetcher; | |
75 | |||
76 |
3/6✓ Branch 2 taken 1034 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1034 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1034 times.
✗ Branch 10 not taken.
|
1034 | authz_mgr->no_pid_ = statistics->Register("authz.no_pid", "cached pids"); |
77 |
3/6✓ Branch 2 taken 1034 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1034 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1034 times.
✗ Branch 10 not taken.
|
1034 | authz_mgr->no_session_ = statistics->Register("authz.no_session", |
78 | "cached sessions"); | ||
79 |
3/6✓ Branch 2 taken 1034 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1034 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1034 times.
✗ Branch 10 not taken.
|
1034 | authz_mgr->n_fetch_ = statistics->Register( |
80 | "authz.n_fetch", "overall number of authz helper invocations"); | ||
81 |
3/6✓ Branch 2 taken 1034 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1034 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1034 times.
✗ Branch 10 not taken.
|
1034 | authz_mgr->n_grant_ = statistics->Register( |
82 | "authz.n_grant", "overall number of granted membership queries"); | ||
83 |
3/6✓ Branch 2 taken 1034 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1034 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1034 times.
✗ Branch 10 not taken.
|
1034 | authz_mgr->n_deny_ = statistics->Register( |
84 | "authz.n_deny", "overall number of denied membership queries"); | ||
85 | |||
86 | 1034 | return authz_mgr; | |
87 | } | ||
88 | |||
89 | |||
90 | /** | ||
91 | * Gathers SID, birthday, uid, and gid from given PID. | ||
92 | */ | ||
93 | 38 | 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 | 38 | 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 38 times.
|
38 | if (snprintf(pid_path, kMaxProcPath, "/proc/%d/stat", pid) >= kMaxProcPath) { |
126 | ✗ | return false; | |
127 | } | ||
128 | |||
129 |
1/2✓ Branch 1 taken 38 times.
✗ Branch 2 not taken.
|
38 | FILE *fp_stat = fopen(pid_path, "r"); |
130 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 30 times.
|
38 | if (fp_stat == NULL) { |
131 | 16 | LogCvmfs(kLogAuthz, kLogDebug, | |
132 | "Failed to open status file /proc/%d/stat: (errno=%d) %s", pid, | ||
133 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | errno, strerror(errno)); |
134 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | LogCvmfs(kLogAuthz, kLogSyslogWarn | kLogDebug, |
135 | "Authorization for session %d disappeared", pid); | ||
136 | 8 | return false; | |
137 | } | ||
138 | |||
139 | // The uid and gid can be gathered from /proc/$PID/stat file ownership | ||
140 | 30 | const int fd_stat = fileno(fp_stat); | |
141 | platform_stat64 info; | ||
142 | 30 | retval = platform_fstat(fd_stat, &info); | |
143 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
|
30 | 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 | 30 | pid_key->uid = info.st_uid; | |
150 | 30 | pid_key->gid = info.st_gid; | |
151 | |||
152 | // TODO(bbockelm): EINTR handling | ||
153 |
1/2✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
|
30 | 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 30 times.
✗ Branch 2 not taken.
|
30 | fclose(fp_stat); |
158 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
|
30 | 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 | 30 | pid_key->pid = pid; | |
170 | 30 | return true; | |
171 | } | ||
172 | |||
173 | |||
174 | /** | ||
175 | * Caller is responsible for freeing the returned token. | ||
176 | */ | ||
177 | 6 | AuthzToken *AuthzSessionManager::GetTokenCopy(const pid_t pid, | |
178 | const std::string &membership) { | ||
179 | 6 | SessionKey session_key; | |
180 | 6 | PidKey pid_key; | |
181 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
6 | const bool retval = LookupSessionKey(pid, &pid_key, &session_key); |
182 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
|
6 | if (!retval) |
183 | 2 | return NULL; | |
184 | |||
185 | 4 | AuthzData authz_data; | |
186 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | const bool granted = LookupAuthzData(pid_key, session_key, membership, |
187 | &authz_data); | ||
188 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!granted) |
189 | ✗ | return NULL; | |
190 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | return authz_data.token.DeepCopy(); |
191 | 4 | } | |
192 | |||
193 | |||
194 | 14 | bool AuthzSessionManager::IsMemberOf(const pid_t pid, | |
195 | const std::string &membership) { | ||
196 | 14 | SessionKey session_key; | |
197 | 14 | PidKey pid_key; | |
198 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | const bool retval = LookupSessionKey(pid, &pid_key, &session_key); |
199 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
|
14 | if (!retval) |
200 | 2 | return false; | |
201 | |||
202 | 12 | AuthzData authz_data; | |
203 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | return LookupAuthzData(pid_key, session_key, membership, &authz_data); |
204 | 12 | } | |
205 | |||
206 | |||
207 | /** | ||
208 | * Calls out to the AuthzFetcher if the data is not cached. Verifies the | ||
209 | * membership. | ||
210 | */ | ||
211 | 28 | 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 28 times.
|
28 | assert(authz_data != NULL); |
216 | |||
217 | bool found; | ||
218 | { | ||
219 | 28 | const MutexLockGuard m(&lock_session2cred_); | |
220 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | MaySweepCreds(); |
221 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | found = session2cred_.Lookup(session_key, authz_data); |
222 | 28 | } | |
223 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 14 times.
|
28 | if (found) { |
224 | 28 | LogCvmfs(kLogAuthz, kLogDebug, | |
225 | "cached authz data for sid %d, membership %s, status %d", | ||
226 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | session_key.sid, authz_data->membership.c_str(), |
227 | 14 | authz_data->status); | |
228 | 14 | const bool granted = authz_data->IsGranted(membership); | |
229 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 10 times.
|
14 | if (granted) |
230 | 4 | perf::Inc(n_grant_); | |
231 | else | ||
232 | 10 | perf::Inc(n_deny_); | |
233 | 14 | return granted; | |
234 | } | ||
235 | |||
236 | // Not found in cache, ask for help | ||
237 | 14 | perf::Inc(n_fetch_); | |
238 | unsigned ttl; | ||
239 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | authz_data->status = authz_fetcher_->Fetch( |
240 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | AuthzFetcher::QueryInfo(pid_key.pid, pid_key.uid, pid_key.gid, |
241 | membership), | ||
242 | &(authz_data->token), &ttl); | ||
243 | 14 | authz_data->deadline = platform_monotonic_time() + ttl; | |
244 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
14 | if (authz_data->status == kAuthzOk) |
245 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | authz_data->membership = membership; |
246 | 28 | 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 14 times.
✗ Branch 2 not taken.
|
14 | session_key.sid, pid_key.pid, authz_data->membership.c_str(), |
250 | 14 | authz_data->status, ttl); | |
251 | |||
252 | { | ||
253 | 14 | const MutexLockGuard m(&lock_session2cred_); | |
254 |
2/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
|
14 | if (!session2cred_.Contains(session_key)) |
255 | 14 | perf::Inc(no_session_); | |
256 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
14 | session2cred_.Insert(session_key, *authz_data); |
257 | 14 | } | |
258 | 14 | const bool granted = authz_data->status == kAuthzOk; | |
259 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
|
14 | if (granted) |
260 | 12 | perf::Inc(n_grant_); | |
261 | else | ||
262 | 2 | perf::Inc(n_deny_); | |
263 | 14 | 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 | 24 | bool AuthzSessionManager::LookupSessionKey(pid_t pid, | |
273 | PidKey *pid_key, | ||
274 | SessionKey *session_key) { | ||
275 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | assert(pid_key != NULL); |
276 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | assert(session_key != NULL); |
277 |
3/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 18 times.
|
24 | if (!GetPidInfo(pid, pid_key)) |
278 | 6 | return false; | |
279 | |||
280 | bool found; | ||
281 | { | ||
282 | 18 | const MutexLockGuard m(&lock_pid2session_); | |
283 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | found = pid2session_.Lookup(*pid_key, session_key); |
284 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
18 | MaySweepPids(); |
285 | 18 | } | |
286 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 8 times.
|
18 | if (found) { |
287 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
10 | 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 | 10 | return true; | |
292 | } | ||
293 | |||
294 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | LogCvmfs(kLogAuthz, kLogDebug, |
295 | "Session key not found in cache, getting information from OS"); | ||
296 | 8 | PidKey sid_key; | |
297 | 8 | pid_t sid = pid_key->sid; | |
298 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
8 | 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 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
|
8 | if (!GetPidInfo(sid, &sid_key)) |
304 | ✗ | return false; | |
305 | |||
306 | 8 | session_key->sid = sid_key.pid; | |
307 | 8 | session_key->sid_bday = sid_key.pid_bday; | |
308 | { | ||
309 | 8 | const MutexLockGuard m(&lock_pid2session_); | |
310 | 8 | pid_key->deadline = platform_monotonic_time() + kPidLifetime; | |
311 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
8 | if (!pid2session_.Contains(*pid_key)) |
312 | 8 | perf::Inc(no_pid_); | |
313 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | pid2session_.Insert(*pid_key, *session_key); |
314 | 8 | } | |
315 | |||
316 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | 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 | 8 | return true; | |
320 | } | ||
321 | |||
322 | |||
323 | /** | ||
324 | * Scan through old sessions only every so often. | ||
325 | */ | ||
326 | 28 | void AuthzSessionManager::MaySweepCreds() { | |
327 | 28 | const uint64_t now = platform_monotonic_time(); | |
328 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 20 times.
|
28 | if (now >= deadline_sweep_creds_) { |
329 | 8 | SweepCreds(now); | |
330 | 8 | deadline_sweep_creds_ = now + kSweepInterval; | |
331 | } | ||
332 | 28 | } | |
333 | |||
334 | |||
335 | /** | ||
336 | * Scan through old PIDs only every so often. | ||
337 | */ | ||
338 | 18 | void AuthzSessionManager::MaySweepPids() { | |
339 | 18 | const uint64_t now = platform_monotonic_time(); | |
340 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 10 times.
|
18 | if (now >= deadline_sweep_pids_) { |
341 | 8 | SweepPids(now); | |
342 | 8 | deadline_sweep_pids_ = now + kSweepInterval; | |
343 | } | ||
344 | 18 | } | |
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 | 10 | void AuthzSessionManager::SweepCreds(uint64_t now) { | |
352 | 10 | const SessionKey empty_key; | |
353 | 10 | vector<SessionKey> trash_bin; | |
354 |
2/2✓ Branch 1 taken 210 times.
✓ Branch 2 taken 10 times.
|
220 | for (unsigned i = 0; i < session2cred_.capacity(); ++i) { |
355 | 210 | const SessionKey this_key = session2cred_.keys()[i]; | |
356 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 206 times.
|
210 | if (this_key != empty_key) { |
357 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | if (now >= (session2cred_.values() + i)->deadline) |
358 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | trash_bin.push_back(this_key); |
359 | } | ||
360 | } | ||
361 | |||
362 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 10 times.
|
14 | for (unsigned i = 0; i < trash_bin.size(); ++i) { |
363 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | session2cred_.Erase(trash_bin[i]); |
364 | 4 | perf::Dec(no_session_); | |
365 | } | ||
366 | 10 | } | |
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 | 12 | void AuthzSessionManager::SweepPids(uint64_t now) { | |
374 | 12 | const PidKey empty_key; | |
375 | 12 | vector<PidKey> trash_bin; | |
376 |
2/2✓ Branch 1 taken 252 times.
✓ Branch 2 taken 12 times.
|
264 | for (unsigned i = 0; i < pid2session_.capacity(); ++i) { |
377 | 252 | const PidKey this_key = pid2session_.keys()[i]; | |
378 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 248 times.
|
252 | if (this_key != empty_key) { |
379 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (now >= this_key.deadline) |
380 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | trash_bin.push_back(this_key); |
381 | } | ||
382 | } | ||
383 | |||
384 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 12 times.
|
14 | for (unsigned i = 0; i < trash_bin.size(); ++i) { |
385 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | pid2session_.Erase(trash_bin[i]); |
386 | 2 | perf::Dec(no_pid_); | |
387 | } | ||
388 | 12 | } | |
389 |