GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/receiver/catalog_merge_tool_impl.h
Date: 2026-08-23 02:40:52
Exec Total Coverage
Lines: 137 191 71.7%
Branches: 130 339 38.3%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_RECEIVER_CATALOG_MERGE_TOOL_IMPL_H_
6 #define CVMFS_RECEIVER_CATALOG_MERGE_TOOL_IMPL_H_
7
8 #include <memory>
9 #include <string>
10
11 #include "catalog.h"
12 #include "catalog_merge_tool.h"
13 #include "crypto/hash.h"
14 #include "manifest.h"
15 #include "options.h"
16 #include "shortstring.h"
17 #include "upload.h"
18 #include "util/exception.h"
19 #include "util/logging.h"
20 #include "util/posix.h"
21 #include "util/raii_temp_dir.h"
22
23 1591 inline PathString MakeRelative(const PathString &path) {
24 1591 std::string rel_path;
25
1/2
✓ Branch 1 taken 1591 times.
✗ Branch 2 not taken.
1591 std::string abs_path = path.ToString();
26
3/4
✓ Branch 1 taken 1591 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1517 times.
✓ Branch 4 taken 74 times.
1591 if (abs_path[0] == '/') {
27
1/2
✓ Branch 1 taken 1517 times.
✗ Branch 2 not taken.
1517 rel_path = abs_path.substr(1);
28 } else {
29
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 rel_path = abs_path;
30 }
31
1/2
✓ Branch 1 taken 1591 times.
✗ Branch 2 not taken.
3182 return PathString(rel_path);
32 1591 }
33
34 111 inline void SplitHardlink(catalog::DirectoryEntry *entry) {
35
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 111 times.
111 if (entry->linkcount() > 1) {
36 LogCvmfs(kLogReceiver, kLogSyslogErr,
37 "CatalogMergeTool - Hardlink found: %s. Hardlinks are not "
38 "supported when publishing through repository gateway and "
39 "will be split.",
40 entry->name().c_str());
41 entry->set_linkcount(1);
42 }
43 111 }
44
45 111 inline void AbortIfHardlinked(const catalog::DirectoryEntry &entry) {
46
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 111 times.
111 if (entry.linkcount() > 1) {
47 PANIC(kLogSyslogErr,
48 "CatalogMergeTool - Removal of file %s with linkcount > 1 is "
49 "not supported. Aborting",
50 entry.name().c_str());
51 }
52 111 }
53
54 namespace receiver {
55
56 template<typename RwCatalogMgr, typename RoCatalogMgr>
57 74 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::Run(
58 const Params &params, std::string *new_manifest_path,
59 shash::Any *new_manifest_hash, uint64_t *final_rev) {
60 74 std::unique_ptr<upload::Spooler> spooler;
61
2/4
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 74 times.
✗ Branch 6 not taken.
148 perf::StatisticsTemplate stats_tmpl("publish", statistics_);
62
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
148 counters_ = std::unique_ptr<perf::FsCounters>(
63
2/4
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
74 new perf::FsCounters(stats_tmpl));
64
65 74 std::unique_ptr<RaiiTempDir> raii_temp_dir(
66
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 RaiiTempDir::Create(temp_dir_prefix_));
67
1/2
✓ Branch 0 taken 74 times.
✗ Branch 1 not taken.
74 if (needs_setup_) {
68
2/4
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 74 times.
✗ Branch 7 not taken.
148 upload::SpoolerDefinition definition(
69 74 params.spooler_configuration, params.hash_alg, params.compression_alg,
70 74 params.generate_legacy_bulk_chunks, params.use_file_chunking,
71
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 params.min_chunk_size, params.avg_chunk_size, params.max_chunk_size,
72 "dummy_token", "dummy_key");
73
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 spooler = std::unique_ptr<upload::Spooler>(
74 upload::Spooler::Construct(definition, &stats_tmpl));
75
1/2
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
74 const std::string temp_dir = raii_temp_dir->dir();
76
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
148 output_catalog_mgr_ = std::unique_ptr<RwCatalogMgr>(new RwCatalogMgr(
77 74 manifest_->catalog_hash(), repo_path_, temp_dir, spooler.get(),
78 74 download_manager_, params.enforce_limits, params.nested_kcatalog_limit,
79 74 params.root_kcatalog_limit, params.file_mbyte_limit, statistics_,
80 74 params.use_autocatalogs, params.max_weight, params.min_weight,
81
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 cache_dir_));
82
1/2
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
74 output_catalog_mgr_->Init();
83 74 }
84
85
3/6
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 74 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 74 times.
✗ Branch 9 not taken.
74 bool ret = CatalogDiffTool<RoCatalogMgr>::Run(PathString(""));
86
87
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 ret &= CreateNewManifest(new_manifest_path);
88 74 *new_manifest_hash = manifest_->catalog_hash();
89 74 *final_rev = manifest_->revision();
90
91 74 output_catalog_mgr_.reset();
92
93 74 return ret;
94 74 }
95
96 template<typename RwCatalogMgr, typename RoCatalogMgr>
97 296 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::IsIgnoredPath(
98 const PathString &path) {
99
1/2
✓ Branch 1 taken 296 times.
✗ Branch 2 not taken.
296 const PathString rel_path = MakeRelative(path);
100
101 // Ignore any paths that are not either within the lease path or
102 // above the lease path
103
1/2
✓ Branch 1 taken 296 times.
✗ Branch 2 not taken.
296 return !(IsSubPath(lease_path_, rel_path)
104
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 296 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
592 || IsSubPath(rel_path, lease_path_));
105 296 }
106
107 template<typename RwCatalogMgr, typename RoCatalogMgr>
108 999 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::IsReportablePath(
109 const PathString &path) {
110
1/2
✓ Branch 1 taken 999 times.
✗ Branch 2 not taken.
999 const PathString rel_path = MakeRelative(path);
111
112 // Do not report any changes occurring outside the lease path (which
113 // will be due to other concurrent writers)
114
1/2
✓ Branch 1 taken 999 times.
✗ Branch 2 not taken.
1998 return IsSubPath(lease_path_, rel_path);
115 999 }
116
117 template<typename RwCatalogMgr, typename RoCatalogMgr>
118 74 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::ReportAddition(
119 const PathString &path, const catalog::DirectoryEntry &entry,
120 const XattrList &xattrs, const FileChunkList &chunks) {
121
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 const PathString rel_path = MakeRelative(path);
122
123
2/4
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 74 times.
✗ Branch 6 not taken.
148 const std::string parent_path = std::strchr(rel_path.c_str(), '/')
124
2/6
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
222 ? GetParentPath(rel_path).c_str()
125 : "";
126
127
2/2
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 37 times.
74 if (entry.IsDirectory()) {
128
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
37 if (entry.IsNestedCatalogMountpoint()) {
129 // Install the provided nested catalog in the output catalog manager
130 RoCatalogMgr
131 *new_catalog_mgr = CatalogDiffTool<RoCatalogMgr>::GetNewCatalogMgr();
132 PathString mountpoint;
133 shash::Any nested_hash;
134 uint64_t nested_size;
135 const bool found = new_catalog_mgr->LookupNested(
136 path, &mountpoint, &nested_hash, &nested_size);
137 if (!found || !nested_size) {
138 PANIC(kLogSyslogErr,
139 "CatalogMergeTool - nested catalog %s not found. Aborting",
140 rel_path.c_str());
141 }
142 output_catalog_mgr_->GraftNestedCatalog(rel_path.ToString(), nested_hash,
143 nested_size);
144 return false;
145 } else {
146
1/2
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
37 output_catalog_mgr_->AddDirectory(entry, xattrs, parent_path);
147 }
148 37 perf::Inc(counters_->n_directories_added);
149
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 37 times.
✗ Branch 7 not taken.
37 } else if (entry.IsRegular() || entry.IsLink()) {
150
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 catalog::DirectoryEntry modified_entry = entry;
151
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 SplitHardlink(&modified_entry);
152 const catalog::DirectoryEntryBase
153 37 *base_entry = static_cast<const catalog::DirectoryEntryBase *>(
154 &modified_entry);
155
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
37 if (entry.IsChunkedFile()) {
156 assert(!chunks.IsEmpty());
157 output_catalog_mgr_->AddChunkedFile(*base_entry, xattrs, parent_path,
158 chunks);
159 } else {
160
1/2
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
37 output_catalog_mgr_->AddFile(*base_entry, xattrs, parent_path);
161 }
162
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
37 if (entry.IsLink()) {
163 perf::Inc(counters_->n_symlinks_added);
164 } else {
165 37 perf::Inc(counters_->n_files_added);
166 }
167
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 perf::Xadd(counters_->sz_added_bytes, static_cast<int64_t>(entry.size()));
168 37 }
169 74 return true;
170 74 }
171
172 template<typename RwCatalogMgr, typename RoCatalogMgr>
173 111 void CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::ReportRemoval(
174 const PathString &path, const catalog::DirectoryEntry &entry) {
175
1/2
✓ Branch 1 taken 111 times.
✗ Branch 2 not taken.
111 const PathString rel_path = MakeRelative(path);
176
177
2/2
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 74 times.
111 if (entry.IsDirectory()) {
178
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
37 if (entry.IsNestedCatalogMountpoint()) {
179 output_catalog_mgr_->RemoveNestedCatalog(std::string(rel_path.c_str()),
180 false);
181 }
182
183
2/4
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 37 times.
✗ Branch 8 not taken.
37 output_catalog_mgr_->RemoveDirectory(rel_path.c_str());
184 37 perf::Inc(counters_->n_directories_removed);
185
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 74 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 74 times.
✗ Branch 7 not taken.
74 } else if (entry.IsRegular() || entry.IsLink()) {
186
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 AbortIfHardlinked(entry);
187
2/4
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 74 times.
✗ Branch 8 not taken.
74 output_catalog_mgr_->RemoveFile(rel_path.c_str());
188
189
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 74 times.
74 if (entry.IsLink()) {
190 perf::Inc(counters_->n_symlinks_removed);
191 } else {
192 74 perf::Inc(counters_->n_files_removed);
193 }
194
195
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 perf::Xadd(counters_->sz_removed_bytes, static_cast<int64_t>(entry.size()));
196 }
197 111 }
198
199 template<typename RwCatalogMgr, typename RoCatalogMgr>
200 111 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::ReportModification(
201 const PathString &path, const catalog::DirectoryEntry &entry1,
202 const catalog::DirectoryEntry &entry2, const XattrList &xattrs,
203 const FileChunkList &chunks) {
204
1/2
✓ Branch 1 taken 111 times.
✗ Branch 2 not taken.
111 const PathString rel_path = MakeRelative(path);
205
206
3/4
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 37 times.
✓ Branch 5 taken 111 times.
✗ Branch 6 not taken.
185 const std::string parent_path = std::strchr(rel_path.c_str(), '/')
207
3/6
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 74 times.
✓ Branch 5 taken 37 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
259 ? GetParentPath(rel_path).c_str()
208 : "";
209
210 111 if (entry1.IsNestedCatalogMountpoint()
211
4/6
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 74 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 111 times.
111 && entry2.IsNestedCatalogMountpoint()) {
212 // From nested catalog to nested catalog
213 RoCatalogMgr
214 *new_catalog_mgr = CatalogDiffTool<RoCatalogMgr>::GetNewCatalogMgr();
215 PathString mountpoint;
216 shash::Any new_hash;
217 uint64_t new_size;
218 const bool found = new_catalog_mgr->LookupNested(path, &mountpoint,
219 &new_hash, &new_size);
220 if (!found || !new_size) {
221 PANIC(kLogSyslogErr,
222 "CatalogMergeTool - nested catalog %s not found. Aborting",
223 rel_path.c_str());
224 }
225 output_catalog_mgr_->SwapNestedCatalog(rel_path.ToString(), new_hash,
226 new_size);
227 return false; // skip recursion into nested catalog mountpoints
228
6/6
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 37 times.
✓ Branch 5 taken 37 times.
✓ Branch 6 taken 37 times.
✓ Branch 7 taken 37 times.
✓ Branch 8 taken 74 times.
111 } else if (entry1.IsDirectory() && entry2.IsDirectory()) {
229 // From directory to directory
230 const catalog::DirectoryEntryBase
231 37 *base_entry = static_cast<const catalog::DirectoryEntryBase *>(&entry2);
232
2/4
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 37 times.
✗ Branch 8 not taken.
37 output_catalog_mgr_->TouchDirectory(*base_entry, xattrs, rel_path.c_str());
233 37 if (!entry1.IsNestedCatalogMountpoint()
234
3/6
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37 times.
37 && entry2.IsNestedCatalogMountpoint()) {
235 output_catalog_mgr_->CreateNestedCatalog(std::string(rel_path.c_str()));
236 37 } else if (entry1.IsNestedCatalogMountpoint()
237
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 37 times.
37 && !entry2.IsNestedCatalogMountpoint()) {
238 output_catalog_mgr_->RemoveNestedCatalog(std::string(rel_path.c_str()));
239 }
240 37 perf::Inc(counters_->n_directories_changed);
241
5/8
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 37 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 37 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 37 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 74 times.
74 } else if ((entry1.IsRegular() || entry1.IsLink()) && entry2.IsDirectory()) {
242 // From file to directory
243 AbortIfHardlinked(entry1);
244 output_catalog_mgr_->RemoveFile(rel_path.c_str());
245 output_catalog_mgr_->AddDirectory(entry2, xattrs, parent_path);
246 if (entry2.IsNestedCatalogMountpoint()) {
247 output_catalog_mgr_->CreateNestedCatalog(std::string(rel_path.c_str()));
248 }
249 if (entry1.IsLink()) {
250 perf::Inc(counters_->n_symlinks_removed);
251 } else {
252 perf::Inc(counters_->n_files_removed);
253 }
254 perf::Xadd(counters_->sz_removed_bytes,
255 static_cast<int64_t>(entry1.size()));
256 perf::Inc(counters_->n_directories_added);
257
258
6/8
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 37 times.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 37 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 37 times.
✓ Branch 10 taken 37 times.
74 } else if (entry1.IsDirectory() && (entry2.IsRegular() || entry2.IsLink())) {
259 // From directory to file
260
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 if (entry1.IsNestedCatalogMountpoint()) {
261 // we merge the nested catalog with its parent, it will be the recursive
262 // procedure that will take care of deleting all the files.
263
2/4
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 37 times.
✗ Branch 8 not taken.
37 output_catalog_mgr_->RemoveNestedCatalog(std::string(rel_path.c_str()),
264 /* merge = */ true);
265 }
266
267
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 catalog::DirectoryEntry modified_entry = entry2;
268
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 SplitHardlink(&modified_entry);
269 const catalog::DirectoryEntryBase
270 37 *base_entry = static_cast<const catalog::DirectoryEntryBase *>(
271 &modified_entry);
272
273
2/4
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 37 times.
✗ Branch 8 not taken.
37 output_catalog_mgr_->RemoveDirectory(rel_path.c_str());
274
275
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
37 if (entry2.IsChunkedFile()) {
276 assert(!chunks.IsEmpty());
277 output_catalog_mgr_->AddChunkedFile(*base_entry, xattrs, parent_path,
278 chunks);
279 } else {
280
1/2
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
37 output_catalog_mgr_->AddFile(*base_entry, xattrs, parent_path);
281 }
282
283 37 perf::Inc(counters_->n_directories_removed);
284
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 if (entry2.IsLink()) {
285 37 perf::Inc(counters_->n_symlinks_added);
286 } else {
287 perf::Inc(counters_->n_files_added);
288 }
289
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 perf::Xadd(counters_->sz_added_bytes, static_cast<int64_t>(entry2.size()));
290
291
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
74 } else if ((entry1.IsRegular() || entry1.IsLink())
292
3/8
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 37 times.
✗ Branch 9 not taken.
37 && (entry2.IsRegular() || entry2.IsLink())) {
293 // From file to file
294
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 AbortIfHardlinked(entry1);
295
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 catalog::DirectoryEntry modified_entry = entry2;
296
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 SplitHardlink(&modified_entry);
297 const catalog::DirectoryEntryBase
298 37 *base_entry = static_cast<const catalog::DirectoryEntryBase *>(
299 &modified_entry);
300
2/4
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 37 times.
✗ Branch 8 not taken.
37 output_catalog_mgr_->RemoveFile(rel_path.c_str());
301
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 37 times.
37 if (entry2.IsChunkedFile()) {
302 assert(!chunks.IsEmpty());
303 output_catalog_mgr_->AddChunkedFile(*base_entry, xattrs, parent_path,
304 chunks);
305 } else {
306
1/2
✓ Branch 2 taken 37 times.
✗ Branch 3 not taken.
37 output_catalog_mgr_->AddFile(*base_entry, xattrs, parent_path);
307 }
308
309
3/6
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37 times.
✗ Branch 7 not taken.
37 if (entry1.IsRegular() && entry2.IsRegular()) {
310 37 perf::Inc(counters_->n_files_changed);
311 } else if (entry1.IsRegular() && entry2.IsLink()) {
312 perf::Inc(counters_->n_files_removed);
313 perf::Inc(counters_->n_symlinks_added);
314 } else if (entry1.IsLink() && entry2.IsRegular()) {
315 perf::Inc(counters_->n_symlinks_removed);
316 perf::Inc(counters_->n_files_added);
317 } else {
318 perf::Inc(counters_->n_symlinks_changed);
319 }
320 37 perf::Xadd(counters_->sz_removed_bytes,
321
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 static_cast<int64_t>(entry1.size()));
322
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 perf::Xadd(counters_->sz_added_bytes, static_cast<int64_t>(entry2.size()));
323 37 }
324 111 return true;
325 111 }
326
327 template<typename RwCatalogMgr, typename RoCatalogMgr>
328 74 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::CreateNewManifest(
329 std::string *new_manifest_path) {
330
2/4
✓ Branch 2 taken 74 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 74 times.
74 if (!output_catalog_mgr_->Commit(false, 0, manifest_)) {
331 LogCvmfs(kLogReceiver, kLogSyslogErr,
332 "CatalogMergeTool - Could not commit output catalog");
333 return false;
334 }
335
336
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 const std::string new_path = CreateTempPath(temp_dir_prefix_, 0600);
337
338
2/4
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 74 times.
74 if (!manifest_->Export(new_path)) {
339 LogCvmfs(kLogReceiver, kLogSyslogErr,
340 "CatalogMergeTool - Could not export new manifest");
341 }
342
343
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
74 *new_manifest_path = new_path;
344
345 74 return true;
346 74 }
347
348 } // namespace receiver
349
350 #endif // CVMFS_RECEIVER_CATALOG_MERGE_TOOL_IMPL_H_
351