GCC Code Coverage Report


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