GCC Code Coverage Report


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