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