GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/catalog_mgr_client.cc
Date: 2025-06-22 02:36:02
Exec Total Coverage
Lines: 208 229 90.8%
Branches: 185 323 57.3%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM file system.
3 */
4
5
6 #include "catalog_mgr_client.h"
7
8 #include <string>
9 #include <vector>
10
11 #include "cache_posix.h"
12 #include "crypto/signature.h"
13 #include "fetch.h"
14 #include "manifest.h"
15 #include "mountpoint.h"
16 #include "network/download.h"
17 #include "quota.h"
18 #include "statistics.h"
19 #include "util/posix.h"
20 #include "util/string.h"
21
22 using namespace std; // NOLINT
23
24 namespace catalog {
25
26 /**
27 * Triggered when the catalog is attached (db file opened)
28 */
29 1316 void ClientCatalogManager::ActivateCatalog(Catalog *catalog) {
30 const Counters &counters = const_cast<const Catalog *>(catalog)
31 1316 ->GetCounters();
32
2/2
✓ Branch 1 taken 1122 times.
✓ Branch 2 taken 194 times.
1316 if (catalog->IsRoot()) {
33 1122 all_inodes_ = counters.GetAllEntries();
34 }
35 1316 loaded_inodes_ += counters.GetSelfEntries();
36 1316 }
37
38
39 1510 ClientCatalogManager::ClientCatalogManager(MountPoint *mountpoint)
40 : AbstractCatalogManager<Catalog>(mountpoint->statistics())
41
1/2
✓ Branch 1 taken 1510 times.
✗ Branch 2 not taken.
1510 , repo_name_(mountpoint->fqrn())
42 1510 , fetcher_(mountpoint->fetcher())
43 1510 , signature_mgr_(mountpoint->signature_mgr())
44
1/2
✓ Branch 2 taken 1510 times.
✗ Branch 3 not taken.
1510 , workspace_(mountpoint->file_system()->workspace())
45 1510 , offline_mode_(false)
46 1510 , all_inodes_(0)
47 1510 , loaded_inodes_(0)
48
1/2
✓ Branch 1 taken 1510 times.
✗ Branch 2 not taken.
1510 , fixed_root_catalog_()
49 1510 , fixed_alt_root_catalog_(false)
50
2/4
✓ Branch 5 taken 1510 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1510 times.
✗ Branch 9 not taken.
3020 , root_fd_(-1) {
51
1/2
✓ Branch 1 taken 1510 times.
✗ Branch 2 not taken.
1510 LogCvmfs(kLogCatalog, kLogDebug, "constructing client catalog manager");
52
3/6
✓ Branch 3 taken 1510 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1510 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1510 times.
✗ Branch 11 not taken.
1510 n_certificate_hits_ = mountpoint->statistics()->Register(
53 "cache.n_certificate_hits", "Number of certificate hits");
54
3/6
✓ Branch 3 taken 1510 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1510 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1510 times.
✗ Branch 11 not taken.
1510 n_certificate_misses_ = mountpoint->statistics()->Register(
55 "cache.n_certificate_misses", "Number of certificate misses");
56 1510 }
57
58
59 6040 ClientCatalogManager::~ClientCatalogManager() {
60 3020 LogCvmfs(kLogCache, kLogDebug, "unpinning / unloading all catalogs");
61
62 6040 for (map<PathString, shash::Any>::iterator i = mounted_catalogs_.begin(),
63 3020 iend = mounted_catalogs_.end();
64
2/2
✓ Branch 1 taken 1314 times.
✓ Branch 2 taken 1510 times.
5648 i != iend;
65 2628 ++i) {
66 2628 fetcher_->cache_mgr()->quota_mgr()->Unpin(i->second);
67 }
68 6040 }
69
70
71 1316 Catalog *ClientCatalogManager::CreateCatalog(const PathString &mountpoint,
72 const shash::Any &catalog_hash,
73 catalog::Catalog *parent_catalog) {
74 1316 mounted_catalogs_[mountpoint] = loaded_catalogs_[mountpoint];
75 1316 loaded_catalogs_.erase(mountpoint);
76
1/2
✓ Branch 2 taken 1316 times.
✗ Branch 3 not taken.
1316 return new Catalog(mountpoint, catalog_hash, parent_catalog);
77 }
78
79
80 290 shash::Any ClientCatalogManager::GetRootHash() {
81 290 ReadLock();
82
1/2
✓ Branch 2 taken 290 times.
✗ Branch 3 not taken.
290 shash::Any result = mounted_catalogs_[PathString("", 0)];
83 290 Unlock();
84 290 return result;
85 }
86
87
88 /**
89 * Specialized initialization that uses a fixed root hash.
90 *
91 * @returns true - root catalog was successfully mounted
92 * false - otherwise
93 */
94 730 bool ClientCatalogManager::InitFixed(const shash::Any &root_hash,
95 bool alternative_path) {
96
1/2
✓ Branch 2 taken 730 times.
✗ Branch 3 not taken.
730 LogCvmfs(kLogCatalog, kLogDebug, "Initialize catalog with fixed root hash %s",
97 1460 root_hash.ToString().c_str());
98 730 WriteLock();
99 730 fixed_alt_root_catalog_ = alternative_path;
100 730 fixed_root_catalog_ = root_hash;
101
102
1/2
✓ Branch 2 taken 730 times.
✗ Branch 3 not taken.
730 const bool attached = MountCatalog(PathString("", 0), root_hash, NULL);
103 730 Unlock();
104
105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 730 times.
730 if (!attached) {
106 LogCvmfs(kLogCatalog, kLogDebug, "failed to initialize fixed root catalog");
107 }
108
109 730 return attached;
110 }
111
112 /**
113 * Gets information about the most recent root catalog, including even if it is
114 * a fixed root catalog. This is needed as Remount() does not know what kind of
115 * root catalog will be remounted.
116 *
117 * Checks the locations: mounted, alien cache and remote (server) and sets the
118 * fields of variable "result". For the most recent catalog the location, hash
119 * and revision number are set.
120 *
121 *
122 * @param [out] result All fields but sqlite_path will be set:
123 * mountpoint, root_ctl_location, root_ctlg_revision, hash
124 * @return kLoadUp2Date - if most recent root catalog is already mounted
125 * kLoadNew - otherwise
126 */
127 733 LoadReturn ClientCatalogManager::GetNewRootCatalogContext(
128 CatalogContext *result) {
129
2/4
✓ Branch 1 taken 733 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 733 times.
✗ Branch 5 not taken.
733 result->SetMountpoint(PathString("", 0));
130
131 // quick escape if we have a fixed catalog
132
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 733 times.
733 if (!fixed_root_catalog_.IsNull()) {
133 result->SetHash(fixed_root_catalog_);
134 result->SetRootCtlgRevision(GetRevisionNoLock());
135
136 // it might or might not be already mounted, but we do not care
137 // as we do no need to download and save the manifest
138 // (see LoadCatalogByHash()) as such we must set the location to this
139 result->SetRootCtlgLocation(kCtlgLocationMounted);
140 offline_mode_ = false;
141
142 // we can do this here as the very first time fixed catalog is loaded it
143 // call directly MountCatalog() and will skip the call to this function
144 // here
145 return catalog::kLoadUp2Date;
146 }
147
148 // 1) Get alien cache root catalog (local)
149
150 // Happens only on init/remount, i.e. quota won't delete a cached catalog
151
1/2
✓ Branch 1 taken 733 times.
✗ Branch 2 not taken.
733 shash::Any local_newest_hash(shash::kSha1, shash::kSuffixCatalog);
152
1/2
✓ Branch 1 taken 733 times.
✗ Branch 2 not taken.
733 shash::Any mounted_hash(shash::kSha1, shash::kSuffixCatalog);
153 733 uint64_t local_newest_timestamp = 0;
154 733 uint64_t local_newest_revision = manifest::Breadcrumb::kInvalidRevision;
155
156 const manifest::Breadcrumb breadcrumb =
157
1/2
✓ Branch 2 taken 733 times.
✗ Branch 3 not taken.
733 fetcher_->cache_mgr()->LoadBreadcrumb(repo_name_);
158
3/4
✓ Branch 1 taken 733 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 149 times.
✓ Branch 4 taken 584 times.
733 if (breadcrumb.IsValid()) {
159 149 local_newest_hash = breadcrumb.catalog_hash;
160 149 local_newest_timestamp = breadcrumb.timestamp;
161 149 local_newest_revision = breadcrumb.revision;
162
1/2
✓ Branch 3 taken 149 times.
✗ Branch 4 not taken.
298 LogCvmfs(kLogCache, kLogDebug,
163 "Cached copy publish date %s (hash %s, revision %" PRIu64 ")",
164
1/2
✓ Branch 1 taken 149 times.
✗ Branch 2 not taken.
298 StringifyTime(static_cast<int64_t>(local_newest_timestamp), true)
165 .c_str(),
166
1/2
✓ Branch 1 taken 149 times.
✗ Branch 2 not taken.
298 local_newest_hash.ToString().c_str(), breadcrumb.revision);
167 } else {
168
1/2
✓ Branch 2 taken 584 times.
✗ Branch 3 not taken.
584 LogCvmfs(kLogCache, kLogDebug, "Unable to read local checksum %s",
169
1/2
✓ Branch 1 taken 584 times.
✗ Branch 2 not taken.
1168 breadcrumb.ToString().c_str());
170 }
171
172 // 2) Select local newest catalog: mounted vs alien
173
174 733 result->SetRootCtlgLocation(kCtlgLocationBreadcrumb);
175 733 LoadReturn success_code = catalog::kLoadNew;
176
177
2/2
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 633 times.
733 if (mounted_catalogs_.size() > 0) {
178 const std::map<PathString, shash::Any>::iterator
179
2/4
✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
100 curr_hash_itr = mounted_catalogs_.find(PathString("", 0));
180 100 mounted_hash = curr_hash_itr->second;
181 }
182
183 // We only look for currently loaded catalog if the revision is newer than
184 // the breadcrumb revision and both revision numbers are valid (!= -1ul).
185 733 if ((local_newest_revision <= GetRevisionNoLock()
186
1/2
✓ Branch 0 taken 584 times.
✗ Branch 1 not taken.
584 || local_newest_revision == manifest::Breadcrumb::kInvalidRevision)
187
6/6
✓ Branch 0 taken 584 times.
✓ Branch 1 taken 149 times.
✓ Branch 3 taken 100 times.
✓ Branch 4 taken 633 times.
✓ Branch 5 taken 100 times.
✓ Branch 6 taken 633 times.
1317 && mounted_catalogs_.size() > 0) {
188 100 local_newest_hash = mounted_hash;
189 100 local_newest_revision = GetRevisionNoLock();
190 // if needed for integration test 707: breadcrumb_timestamp_newer()
191 100 local_newest_timestamp = GetTimestampNoLock() > local_newest_timestamp
192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 100 times.
100 ? GetTimestampNoLock()
193 : local_newest_timestamp;
194 100 result->SetRootCtlgLocation(kCtlgLocationMounted);
195 100 success_code = catalog::kLoadUp2Date;
196
4/6
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 584 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 633 times.
633 } else if (local_newest_revision == 0 && mounted_catalogs_.size() > 0) {
197 // breadcrumb has no revision
198 // TODO(heretherebedragons) this branch can be removed in future versions
199
200 // revisions are better, but if we dont have any we need to compare by
201 // timestamp (you can have multiple revisions in the same timestamp)
202 if (local_newest_timestamp < GetTimestampNoLock()) {
203 local_newest_hash = mounted_hash;
204 local_newest_revision = GetRevisionNoLock();
205 local_newest_timestamp = GetTimestampNoLock();
206 result->SetRootCtlgLocation(kCtlgLocationMounted);
207 success_code = catalog::kLoadUp2Date;
208 }
209 }
210
211 // 3) Get remote root catalog (fails if remote catalog is older)
212 manifest::Failures manifest_failure;
213 UniquePtr<CachedManifestEnsemble> ensemble(
214
2/4
✓ Branch 2 taken 733 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 733 times.
✗ Branch 7 not taken.
733 new CachedManifestEnsemble(fetcher_->cache_mgr(), this));
215
2/4
✓ Branch 1 taken 733 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 733 times.
✗ Branch 5 not taken.
733 manifest_failure = manifest::Fetch(
216 733 "", repo_name_, local_newest_timestamp, &local_newest_hash,
217 733 signature_mgr_, fetcher_->download_mgr(), ensemble.weak_ref());
218
219
2/2
✓ Branch 0 taken 442 times.
✓ Branch 1 taken 291 times.
733 if (manifest_failure == manifest::kFailOk) {
220 // server has newest revision or no valid local revision
221 442 if (ensemble->manifest->revision() > local_newest_revision
222
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 341 times.
440 || local_newest_revision == manifest::Breadcrumb::kInvalidRevision
223 // if revision is 0 both local and server, load catalog from server
224 // as local is most likely just "initialized" without valid value
225
6/6
✓ Branch 0 taken 440 times.
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 51 times.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 394 times.
✓ Branch 7 taken 48 times.
933 || (ensemble->manifest->revision() == 0
226
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 && local_newest_revision == 0)) {
227 394 result->SetHash(ensemble->manifest->catalog_hash());
228 394 result->SetRootCtlgRevision(ensemble->manifest->revision());
229 394 result->SetRootCtlgLocation(kCtlgLocationServer);
230 394 fixed_alt_root_catalog_ = ensemble->manifest->has_alt_catalog_path();
231
232
1/2
✓ Branch 1 taken 394 times.
✗ Branch 2 not taken.
394 result->TakeManifestEnsemble(
233 394 static_cast<manifest::ManifestEnsemble *>(ensemble.Release()));
234 394 offline_mode_ = false;
235
236 394 return catalog::kLoadNew;
237 }
238 }
239
1/2
✓ Branch 2 taken 339 times.
✗ Branch 3 not taken.
339 LogCvmfs(kLogCache, kLogDebug,
240 "Failed fetch manifest from server: "
241 "manifest too old or server unreachable (%d - %s)",
242 manifest_failure, manifest::Code2Ascii(manifest_failure));
243
244 // total failure: server not reachable and no valid local hash
245
6/6
✓ Branch 0 taken 291 times.
✓ Branch 1 taken 48 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 243 times.
✓ Branch 6 taken 96 times.
339 if ((manifest_failure != manifest::kFailOk) && local_newest_hash.IsNull()) {
246
1/2
✓ Branch 1 taken 243 times.
✗ Branch 2 not taken.
243 LogCvmfs(kLogCache, kLogDebug, "No valid root catalog found!");
247 243 return catalog::kLoadFail;
248 }
249
250 96 if (manifest_failure == manifest::kFailOk
251
5/6
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 48 times.
✓ Branch 7 taken 48 times.
96 && ensemble->manifest->revision() == local_newest_revision) {
252 48 offline_mode_ = false;
253 } else {
254 48 offline_mode_ = true;
255 }
256 96 result->SetHash(local_newest_hash);
257 96 result->SetRootCtlgRevision(local_newest_revision);
258
259 // for integration test 707: breadcrumb_revision_large()
260
4/8
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 96 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 96 times.
✗ Branch 9 not taken.
96 if (breadcrumb.IsValid() && breadcrumb.catalog_hash == mounted_hash) {
261 96 success_code = catalog::kLoadUp2Date;
262 }
263
264 96 return success_code;
265 733 }
266
267 1797 std::string ClientCatalogManager::GetCatalogDescription(
268 const PathString &mountpoint, const shash::Any &hash) {
269
2/4
✓ Branch 1 taken 1797 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1797 times.
✗ Branch 5 not taken.
3594 return "file catalog at " + repo_name_ + ":"
270
2/4
✓ Branch 1 taken 1797 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1797 times.
✗ Branch 5 not taken.
5391 + (mountpoint.IsEmpty()
271
8/14
✓ Branch 0 taken 1218 times.
✓ Branch 1 taken 579 times.
✓ Branch 4 taken 1218 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 579 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 579 times.
✓ Branch 13 taken 1218 times.
✓ Branch 15 taken 1218 times.
✓ Branch 16 taken 579 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
4173 ? "/"
272 579 : string(mountpoint.GetChars(), mountpoint.GetLength()))
273
3/6
✓ Branch 2 taken 1797 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1797 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1797 times.
✗ Branch 9 not taken.
7188 + " (" + hash.ToString() + ")";
274 }
275
276 /**
277 * Loads (and fetches) a catalog by hash for a given mountpoint.
278 *
279 * Special case for root catalog: ctlg_context->root_ctlg_location must be
280 * given.
281 *
282 * @param [in, out] ctlg_context mandatory fields (input): mountpoint, hash
283 * additional mandatory fields for root catalog: root_ctlg_location
284 * output: sqlite_path is set if catalog fetch successful
285 * @return kLoadUp2Date for root catalog that is already mounted
286 * kLoadNew for any other successful load
287 * kLoadFail on failure
288 */
289 1700 LoadReturn ClientCatalogManager::LoadCatalogByHash(
290 CatalogContext *ctlg_context) {
291 const string catalog_descr =
292
2/4
✓ Branch 2 taken 1700 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1700 times.
✗ Branch 6 not taken.
1700 GetCatalogDescription(ctlg_context->mountpoint(), ctlg_context->hash());
293
1/2
✓ Branch 2 taken 1700 times.
✗ Branch 3 not taken.
1700 string alt_root_catalog_path = "";
294
295 // root catalog needs special handling because of alt_root_catalog_path
296
5/8
✓ Branch 1 taken 1700 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1218 times.
✓ Branch 4 taken 482 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1218 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1700 times.
1700 if (ctlg_context->IsRootCatalog() && fixed_alt_root_catalog_) {
297 alt_root_catalog_path = ctlg_context->hash().MakeAlternativePath();
298 }
299
300
1/2
✓ Branch 2 taken 1700 times.
✗ Branch 3 not taken.
3400 const LoadReturn load_ret = FetchCatalogByHash(
301 1700 ctlg_context->hash(), catalog_descr, alt_root_catalog_path,
302 ctlg_context->GetSqlitePathPtr());
303
2/2
✓ Branch 0 taken 1652 times.
✓ Branch 1 taken 48 times.
1700 if (load_ret == catalog::kLoadNew) {
304
2/4
✓ Branch 2 taken 1652 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1652 times.
✗ Branch 6 not taken.
1652 loaded_catalogs_[ctlg_context->mountpoint()] = ctlg_context->hash();
305
306
3/4
✓ Branch 1 taken 1652 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1218 times.
✓ Branch 4 taken 434 times.
1652 if (ctlg_context->IsRootCatalog()) {
307
2/2
✓ Branch 1 taken 826 times.
✓ Branch 2 taken 392 times.
1218 if (ctlg_context->root_ctlg_location() == kCtlgLocationMounted) {
308 826 return kLoadUp2Date;
309 }
310
311 // if coming from server: update breadcrumb
312
1/2
✓ Branch 1 taken 392 times.
✗ Branch 2 not taken.
392 if (ctlg_context->root_ctlg_location() == kCtlgLocationServer) {
313 // Store new manifest and certificate
314 392 CacheManager::Label label;
315
1/2
✓ Branch 1 taken 392 times.
✗ Branch 2 not taken.
392 label.path = repo_name_;
316 392 label.flags |= CacheManager::kLabelCertificate;
317
3/4
✓ Branch 1 taken 392 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 342 times.
✓ Branch 4 taken 50 times.
392 if (ctlg_context->manifest_ensemble()->cert_size > 0) {
318
1/2
✓ Branch 2 taken 342 times.
✗ Branch 3 not taken.
684 fetcher_->cache_mgr()->CommitFromMem(
319
1/2
✓ Branch 1 taken 342 times.
✗ Branch 2 not taken.
684 CacheManager::LabeledObject(
320 684 ctlg_context->manifest_ensemble()->manifest->certificate(),
321 label),
322
1/2
✓ Branch 1 taken 342 times.
✗ Branch 2 not taken.
342 ctlg_context->manifest_ensemble()->cert_buf,
323
2/4
✓ Branch 1 taken 342 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 342 times.
✗ Branch 5 not taken.
342 ctlg_context->manifest_ensemble()->cert_size);
324 }
325 392 fetcher_->cache_mgr()->StoreBreadcrumb(
326
2/4
✓ Branch 1 taken 392 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 392 times.
✗ Branch 5 not taken.
392 *ctlg_context->manifest_ensemble()->manifest);
327 392 }
328 }
329 }
330
331 874 return load_ret;
332 1700 }
333
334 /**
335 * Fetch a catalog by hash either from cache or from remote.
336 * Successful load always returns kLoadNew (independent of the location) and
337 * sets the sqlite_path variable.
338 *
339 * @param [out] sqlite_path of the catalog if successfully fetched
340 * @return kLoadNew on success
341 * kLoadNoSpace out of space, no room on the device to open the catalog
342 * kLoadFail on all other failures
343 */
344 1700 LoadReturn ClientCatalogManager::FetchCatalogByHash(
345 const shash::Any &hash,
346 const string &name,
347 const std::string &alt_root_catalog_path,
348 std::string *sqlite_path) {
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1700 times.
1700 assert(hash.suffix == shash::kSuffixCatalog);
350 1700 CacheManager::Label label;
351
1/2
✓ Branch 1 taken 1700 times.
✗ Branch 2 not taken.
1700 label.path = name;
352 1700 label.flags = CacheManager::kLabelCatalog;
353
2/4
✓ Branch 1 taken 1700 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1700 times.
✗ Branch 5 not taken.
1700 const int fd = fetcher_->Fetch(CacheManager::LabeledObject(hash, label),
354 alt_root_catalog_path);
355
2/2
✓ Branch 0 taken 1652 times.
✓ Branch 1 taken 48 times.
1700 if (fd >= 0) {
356
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 532 times.
1652 if (root_fd_ < 0) {
357 1120 root_fd_ = fd;
358 }
359
360
1/2
✓ Branch 1 taken 1652 times.
✗ Branch 2 not taken.
1652 LogCvmfs(kLogCatalog, kLogDebug, "FetchCatalogByHash filedescriptor %d",
361 fd);
362
2/4
✓ Branch 1 taken 1652 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1652 times.
✗ Branch 5 not taken.
1652 *sqlite_path = "@" + StringifyInt(fd);
363 1652 return kLoadNew;
364 }
365
366
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 if (fd == -ENOSPC)
367 return kLoadNoSpace;
368
369 48 return kLoadFail;
370 1700 }
371
372 97 void ClientCatalogManager::StageNestedCatalogByHash(
373 const shash::Any &hash, const PathString &mountpoint) {
374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
97 assert(hash.suffix == shash::kSuffixCatalog);
375
376 97 CacheManager::Label label;
377
1/2
✓ Branch 1 taken 97 times.
✗ Branch 2 not taken.
97 label.path = GetCatalogDescription(mountpoint, hash);
378 97 label.flags = CacheManager::kLabelCatalog;
379
3/6
✓ Branch 2 taken 97 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 97 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 97 times.
✗ Branch 9 not taken.
97 const int fd = fetcher_->Fetch(CacheManager::LabeledObject(hash, label));
380
1/2
✓ Branch 0 taken 97 times.
✗ Branch 1 not taken.
97 if (fd >= 0)
381
1/2
✓ Branch 2 taken 97 times.
✗ Branch 3 not taken.
97 fetcher_->cache_mgr()->Close(fd);
382 97 }
383
384 2 void ClientCatalogManager::UnloadCatalog(const Catalog *catalog) {
385
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 LogCvmfs(kLogCache, kLogDebug, "unloading catalog %s",
386
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
4 catalog->mountpoint().c_str());
387
388 const map<PathString, shash::Any>::iterator iter =
389
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 mounted_catalogs_.find(catalog->mountpoint());
390
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 assert(iter != mounted_catalogs_.end());
391
1/2
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 fetcher_->cache_mgr()->quota_mgr()->Unpin(iter->second);
392
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 mounted_catalogs_.erase(iter);
393 2 const catalog::Counters &counters = catalog->GetCounters();
394
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 loaded_inodes_ -= counters.GetSelfEntries();
395 2 }
396
397
398 /**
399 * Checks if the current repository revision is blacklisted. The format
400 * of the blacklist lines is '<REPO N' where REPO is the repository name,
401 * N is the revision number, and the two parts are separated by whitespace.
402 * Any revision of REPO less than N is blacklisted.
403 * Note: no extra characters are allowed after N, not even whitespace.
404 * @return true if it is blacklisted, false otherwise
405 */
406 1120 bool ClientCatalogManager::IsRevisionBlacklisted() {
407 1120 const uint64_t revision = GetRevision();
408
409
1/2
✓ Branch 2 taken 1120 times.
✗ Branch 3 not taken.
1120 LogCvmfs(kLogCache, kLogDebug,
410 "checking if %s revision %" PRIu64 " is blacklisted",
411 repo_name_.c_str(), revision);
412
413
1/2
✓ Branch 1 taken 1120 times.
✗ Branch 2 not taken.
1120 vector<string> blacklist = signature_mgr_->GetBlacklist();
414
2/2
✓ Branch 1 taken 49 times.
✓ Branch 2 taken 1071 times.
1120 for (unsigned i = 0; i < blacklist.size(); ++i) {
415
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
49 std::string line = blacklist[i];
416
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 49 times.
49 if (line[0] != '<')
417 continue;
418 49 unsigned idx = repo_name_.length() + 1;
419
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
49 if (line.length() <= idx)
420 continue;
421
3/10
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 49 times.
49 if ((line[idx] != ' ') && (line[idx] != '\t'))
422 continue;
423
2/4
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 49 times.
49 if (line.substr(1, idx - 1) != repo_name_)
424 continue;
425 49 ++idx;
426
5/10
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 49 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 49 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 49 times.
49 while ((line[idx] == ' ') || (line[idx] == '\t'))
427 ++idx;
428
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
49 if (idx >= line.length())
429 continue;
430 uint64_t rev;
431
3/6
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 49 times.
49 if (!String2Uint64Parse(line.substr(idx), &rev))
432 continue;
433
1/2
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
49 if (revision < rev)
434 49 return true;
435
1/3
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
49 }
436
437 1071 return false;
438 1120 }
439
440
441 //------------------------------------------------------------------------------
442
443
444 441 void CachedManifestEnsemble::FetchCertificate(const shash::Any &hash) {
445 441 CacheManager::Label label;
446 441 label.flags |= CacheManager::kLabelCertificate;
447
1/2
✓ Branch 1 taken 441 times.
✗ Branch 2 not taken.
441 label.path = catalog_mgr_->repo_name();
448 uint64_t size;
449
1/2
✓ Branch 1 taken 441 times.
✗ Branch 2 not taken.
441 const bool retval = cache_mgr_->Open2Mem(
450
1/2
✓ Branch 1 taken 441 times.
✗ Branch 2 not taken.
882 CacheManager::LabeledObject(hash, label), &cert_buf, &size);
451 441 cert_size = size;
452
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 439 times.
441 if (retval)
453 2 perf::Inc(catalog_mgr_->n_certificate_hits_);
454 else
455 439 perf::Inc(catalog_mgr_->n_certificate_misses_);
456 441 }
457
458 } // namespace catalog
459