GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/catalog_mgr_ro.cc
Date: 2025-02-02 02:34:22
Exec Total Coverage
Lines: 42 74 56.8%
Branches: 23 96 24.0%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM file system.
3 */
4
5
6 #include "catalog_mgr_ro.h"
7
8 #include "compression/compression.h"
9 #include "network/download.h"
10 #include "util/exception.h"
11 #include "util/posix.h"
12
13 using namespace std; // NOLINT
14
15 namespace catalog {
16
17 32 SimpleCatalogManager::SimpleCatalogManager(
18 const shash::Any &base_hash,
19 const std::string &stratum0,
20 const std::string &dir_temp,
21 download::DownloadManager *download_manager,
22 perf::Statistics *statistics,
23 const bool manage_catalog_files,
24 const std::string &dir_cache,
25 32 const bool copy_to_tmp_dir)
26 : AbstractCatalogManager<Catalog>(statistics)
27 32 , dir_cache_(dir_cache)
28 32 , copy_to_tmp_dir_(copy_to_tmp_dir)
29 32 , base_hash_(base_hash)
30
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 , stratum0_(stratum0)
31
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 , dir_temp_(dir_temp)
32 32 , download_manager_(download_manager)
33
1/2
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 , manage_catalog_files_(manage_catalog_files) {
34
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
32 if (!dir_cache.empty()) {
35 const bool success = MakeCacheDirectories(dir_cache_, 0755);
36
37 if (!success) {
38 PANIC(kLogStderr,
39 "Failure during creation of local cache directory for server. "
40 "Local cache directory: %s", dir_cache_.c_str());
41 }
42 } else {
43 32 copy_to_tmp_dir_ = false;
44 }
45 32 }
46
47 32 LoadReturn SimpleCatalogManager::GetNewRootCatalogContext(
48 CatalogContext *result) {
49
1/2
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 if (result->hash().IsNull()) {
50 32 result->SetHash(base_hash_);
51 }
52 32 result->SetRootCtlgLocation(kCtlgLocationServer);
53
1/2
✓ Branch 2 taken 32 times.
✗ Branch 3 not taken.
32 result->SetMountpoint(PathString("", 0));
54
55 32 return kLoadNew;
56 }
57
58 std::string SimpleCatalogManager::CopyCatalogToTempFile(
59 const std::string &cache_path) {
60 std::string tmp_path;
61 FILE *fcatalog = CreateTempFile(dir_temp_ + "/catalog", 0666, "w", &tmp_path);
62 if (!fcatalog) {
63 PANIC(kLogStderr, "failed to create temp file when loading %s",
64 cache_path.c_str());
65 }
66
67 const bool retval = CopyPath2File(cache_path, fcatalog);
68 if (!retval) {
69 unlink(tmp_path.c_str());
70 PANIC(kLogStderr, "failed to read %s", cache_path.c_str());
71 }
72 (void) fclose(fcatalog);
73
74 return tmp_path;
75 }
76
77 /**
78 * Loads a catalog via HTTP from Statum 0 into a temporary file.
79 * See CatalogContext class description for correct usage
80 *
81 * Depending on the initialization of SimpleCatalogManager, it can locally
82 * cache catalogs.
83 *
84 * Independent of the catalog being downloaded or being already locally cached,
85 * for WriteableCatalog it creates a new copy of the catalog in a tmp dir.
86 * This is due to write actions having to be transaction-based and therefore
87 * cannot work on standard file locations for cvmfs - someone else could try to
88 * access them in a non-clean state.
89 *
90 * @return kLoadNew on success
91 */
92 51 LoadReturn SimpleCatalogManager::LoadCatalogByHash(
93 CatalogContext *ctlg_context) {
94 51 const shash::Any effective_hash = ctlg_context->hash();
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 assert(shash::kSuffixCatalog == effective_hash.suffix);
96
3/6
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 51 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 51 times.
✗ Branch 8 not taken.
102 const string url = stratum0_ + "/data/" + effective_hash.MakePath();
97
98 FILE *fcatalog;
99
100
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
51 if (UseLocalCache()) {
101 std::string cache_path = dir_cache_ + "/"
102 + effective_hash.MakePathWithoutSuffix();
103
104 ctlg_context->SetSqlitePath(cache_path);
105
106 // catalog is cached in "cache_dir/" + standard cvmfs file hierarchy
107 if (FileExists(cache_path.c_str())) {
108 if (!copy_to_tmp_dir_) {
109 return kLoadNew;
110 } else { // for writable catalog create copy in dir_temp_
111 std::string tmp_path;
112
113 tmp_path = CopyCatalogToTempFile(cache_path);
114 ctlg_context->SetSqlitePath(tmp_path);
115
116 return kLoadNew;
117 }
118 }
119 }
120
121 // not in local cache; just create a random tmp file for download
122 51 std::string tmp_path;
123
2/4
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 51 times.
✗ Branch 5 not taken.
51 fcatalog = CreateTempFile(dir_temp_ + "/catalog", 0666, "w", &tmp_path);
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if (!fcatalog) {
125 PANIC(kLogStderr, "failed to create temp file when loading %s",
126 url.c_str());
127 }
128
1/2
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
51 ctlg_context->SetSqlitePath(tmp_path);
129
130 51 cvmfs::FileSink filesink(fcatalog);
131 download::JobInfo download_catalog(&url, true, false,
132
1/2
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
51 &effective_hash, &filesink);
133
1/2
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
51 const download::Failures retval = download_manager_->Fetch(&download_catalog);
134
1/2
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
51 fclose(fcatalog);
135
136
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 50 times.
51 if (retval != download::kFailOk) {
137 1 unlink(tmp_path.c_str());
138 1 PANIC(kLogStderr, "failed to load %s from Stratum 0 (%d - %s)",
139 url.c_str(), retval, download::Code2Ascii(retval));
140 }
141
142 // for local cache make an atomic rename call to make the file available
143 // in the local cache
144
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
50 if (UseLocalCache()) {
145 const std::string cache_path = dir_cache_ + "/"
146 + effective_hash.MakePathWithoutSuffix();
147 rename(tmp_path.c_str(), cache_path.c_str());
148 ctlg_context->SetSqlitePath(cache_path);
149
150 // for writable catalog make an extra copy that can be modified
151 if (copy_to_tmp_dir_) {
152 const std::string new_tmp_path = CopyCatalogToTempFile(cache_path);
153 ctlg_context->SetSqlitePath(new_tmp_path);
154 }
155 }
156
157 50 return kLoadNew;
158 54 }
159
160
161 5 Catalog* SimpleCatalogManager::CreateCatalog(const PathString &mountpoint,
162 const shash::Any &catalog_hash,
163 Catalog *parent_catalog)
164 {
165
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 Catalog *new_catalog = new Catalog(mountpoint, catalog_hash, parent_catalog);
166
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (manage_catalog_files_) {
167 5 new_catalog->TakeDatabaseFileOwnership();
168 }
169
170 5 return new_catalog;
171 }
172
173 } // namespace catalog
174