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