GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/receiver/catalog_merge_tool_impl.h
Date: 2025-08-31 02:39:21
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 "catalog_merge_tool.h"
12 #include "crypto/hash.h"
13 #include "manifest.h"
14 #include "options.h"
15 #include "shortstring.h"
16 #include "upload.h"
17 #include "util/exception.h"
18 #include "util/logging.h"
19 #include "util/posix.h"
20 #include "util/raii_temp_dir.h"
21
22 2064 inline PathString MakeRelative(const PathString &path) {
23 2064 std::string rel_path;
24
1/2
✓ Branch 1 taken 2064 times.
✗ Branch 2 not taken.
2064 std::string abs_path = path.ToString();
25
3/4
✓ Branch 1 taken 2064 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1968 times.
✓ Branch 4 taken 96 times.
2064 if (abs_path[0] == '/') {
26
1/2
✓ Branch 1 taken 1968 times.
✗ Branch 2 not taken.
1968 rel_path = abs_path.substr(1);
27 } else {
28
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 rel_path = abs_path;
29 }
30
1/2
✓ Branch 1 taken 2064 times.
✗ Branch 2 not taken.
4128 return PathString(rel_path);
31 2064 }
32
33 144 inline void SplitHardlink(catalog::DirectoryEntry *entry) {
34
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
144 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 144 }
43
44 144 inline void AbortIfHardlinked(const catalog::DirectoryEntry &entry) {
45
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
144 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 144 }
52
53 namespace receiver {
54
55 template<typename RwCatalogMgr, typename RoCatalogMgr>
56 96 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 96 times.
✗ Branch 2 not taken.
96 UniquePtr<upload::Spooler> spooler;
60
2/4
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 96 times.
✗ Branch 6 not taken.
192 perf::StatisticsTemplate stats_tmpl("publish", statistics_);
61
4/8
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 96 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 96 times.
✗ Branch 11 not taken.
96 counters_ = new perf::FsCounters(stats_tmpl);
62
63
2/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
96 UniquePtr<RaiiTempDir> raii_temp_dir(RaiiTempDir::Create(temp_dir_prefix_));
64
1/2
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
96 if (needs_setup_) {
65
2/4
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 96 times.
✗ Branch 7 not taken.
192 upload::SpoolerDefinition definition(
66 96 params.spooler_configuration, params.hash_alg, params.compression_alg,
67 96 params.generate_legacy_bulk_chunks, params.use_file_chunking,
68
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 params.min_chunk_size, params.avg_chunk_size, params.max_chunk_size,
69 "dummy_token", "dummy_key");
70
2/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
96 spooler = upload::Spooler::Construct(definition, &stats_tmpl);
71
1/2
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
96 const std::string temp_dir = raii_temp_dir->dir();
72
2/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
192 output_catalog_mgr_ = new RwCatalogMgr(
73 96 manifest_->catalog_hash(), repo_path_, temp_dir, spooler.weak_ref(),
74 96 download_manager_, params.enforce_limits, params.nested_kcatalog_limit,
75 96 params.root_kcatalog_limit, params.file_mbyte_limit, statistics_,
76 96 params.use_autocatalogs, params.max_weight, params.min_weight,
77
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 cache_dir_);
78
1/2
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
96 output_catalog_mgr_->Init();
79 96 }
80
81
3/6
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 96 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 96 times.
✗ Branch 9 not taken.
96 bool ret = CatalogDiffTool<RoCatalogMgr>::Run(PathString(""));
82
83
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 ret &= CreateNewManifest(new_manifest_path);
84 96 *new_manifest_hash = manifest_->catalog_hash();
85 96 *final_rev = manifest_->revision();
86
87
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 output_catalog_mgr_.Destroy();
88
89 96 return ret;
90 96 }
91
92 template<typename RwCatalogMgr, typename RoCatalogMgr>
93 384 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::IsIgnoredPath(
94 const PathString &path) {
95
1/2
✓ Branch 1 taken 384 times.
✗ Branch 2 not taken.
384 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 384 times.
✗ Branch 2 not taken.
384 return !(IsSubPath(lease_path_, rel_path)
100
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 384 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
768 || IsSubPath(rel_path, lease_path_));
101 384 }
102
103 template<typename RwCatalogMgr, typename RoCatalogMgr>
104 1296 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::IsReportablePath(
105 const PathString &path) {
106
1/2
✓ Branch 1 taken 1296 times.
✗ Branch 2 not taken.
1296 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 1296 times.
✗ Branch 2 not taken.
2592 return IsSubPath(lease_path_, rel_path);
111 1296 }
112
113 template<typename RwCatalogMgr, typename RoCatalogMgr>
114 96 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 96 times.
✗ Branch 2 not taken.
96 const PathString rel_path = MakeRelative(path);
118
119
2/4
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 96 times.
✗ Branch 6 not taken.
192 const std::string parent_path = std::strchr(rel_path.c_str(), '/')
120
2/6
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
288 ? GetParentPath(rel_path).c_str()
121 : "";
122
123
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 48 times.
96 if (entry.IsDirectory()) {
124
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 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 48 times.
✗ Branch 3 not taken.
48 output_catalog_mgr_->AddDirectory(entry, xattrs, parent_path);
143 }
144 48 perf::Inc(counters_->n_directories_added);
145
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 48 times.
✗ Branch 7 not taken.
48 } else if (entry.IsRegular() || entry.IsLink()) {
146
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 catalog::DirectoryEntry modified_entry = entry;
147
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 SplitHardlink(&modified_entry);
148 const catalog::DirectoryEntryBase
149 48 *base_entry = static_cast<const catalog::DirectoryEntryBase *>(
150 &modified_entry);
151
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 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 48 times.
✗ Branch 3 not taken.
48 output_catalog_mgr_->AddFile(*base_entry, xattrs, parent_path);
157 }
158
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 if (entry.IsLink()) {
159 perf::Inc(counters_->n_symlinks_added);
160 } else {
161 48 perf::Inc(counters_->n_files_added);
162 }
163
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 perf::Xadd(counters_->sz_added_bytes, static_cast<int64_t>(entry.size()));
164 48 }
165 96 return true;
166 96 }
167
168 template<typename RwCatalogMgr, typename RoCatalogMgr>
169 144 void CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::ReportRemoval(
170 const PathString &path, const catalog::DirectoryEntry &entry) {
171
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
144 const PathString rel_path = MakeRelative(path);
172
173
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 96 times.
144 if (entry.IsDirectory()) {
174
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 if (entry.IsNestedCatalogMountpoint()) {
175 output_catalog_mgr_->RemoveNestedCatalog(std::string(rel_path.c_str()),
176 false);
177 }
178
179
2/4
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 8 not taken.
48 output_catalog_mgr_->RemoveDirectory(rel_path.c_str());
180 48 perf::Inc(counters_->n_directories_removed);
181
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 96 times.
✗ Branch 7 not taken.
96 } else if (entry.IsRegular() || entry.IsLink()) {
182
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 AbortIfHardlinked(entry);
183
2/4
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 96 times.
✗ Branch 8 not taken.
96 output_catalog_mgr_->RemoveFile(rel_path.c_str());
184
185
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
96 if (entry.IsLink()) {
186 perf::Inc(counters_->n_symlinks_removed);
187 } else {
188 96 perf::Inc(counters_->n_files_removed);
189 }
190
191
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 perf::Xadd(counters_->sz_removed_bytes, static_cast<int64_t>(entry.size()));
192 }
193 144 }
194
195 template<typename RwCatalogMgr, typename RoCatalogMgr>
196 144 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 144 times.
✗ Branch 2 not taken.
144 const PathString rel_path = MakeRelative(path);
201
202
3/4
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 48 times.
✓ Branch 5 taken 144 times.
✗ Branch 6 not taken.
240 const std::string parent_path = std::strchr(rel_path.c_str(), '/')
203
3/6
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✓ Branch 5 taken 48 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
336 ? GetParentPath(rel_path).c_str()
204 : "";
205
206 144 if (entry1.IsNestedCatalogMountpoint()
207
4/6
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 144 times.
144 && 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 96 times.
✓ Branch 3 taken 48 times.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 48 times.
✓ Branch 7 taken 48 times.
✓ Branch 8 taken 96 times.
144 } else if (entry1.IsDirectory() && entry2.IsDirectory()) {
225 // From directory to directory
226 const catalog::DirectoryEntryBase
227 48 *base_entry = static_cast<const catalog::DirectoryEntryBase *>(&entry2);
228
2/4
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 8 not taken.
48 output_catalog_mgr_->TouchDirectory(*base_entry, xattrs, rel_path.c_str());
229 48 if (!entry1.IsNestedCatalogMountpoint()
230
3/6
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 48 times.
48 && entry2.IsNestedCatalogMountpoint()) {
231 output_catalog_mgr_->CreateNestedCatalog(std::string(rel_path.c_str()));
232 48 } else if (entry1.IsNestedCatalogMountpoint()
233
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 48 times.
48 && !entry2.IsNestedCatalogMountpoint()) {
234 output_catalog_mgr_->RemoveNestedCatalog(std::string(rel_path.c_str()));
235 }
236 48 perf::Inc(counters_->n_directories_changed);
237
5/8
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 48 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 48 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 48 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 96 times.
96 } 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 48 times.
✓ Branch 2 taken 48 times.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 48 times.
✓ Branch 10 taken 48 times.
96 } else if (entry1.IsDirectory() && (entry2.IsRegular() || entry2.IsLink())) {
255 // From directory to file
256
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 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 48 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 8 not taken.
48 output_catalog_mgr_->RemoveNestedCatalog(std::string(rel_path.c_str()),
260 /* merge = */ true);
261 }
262
263
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 catalog::DirectoryEntry modified_entry = entry2;
264
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 SplitHardlink(&modified_entry);
265 const catalog::DirectoryEntryBase
266 48 *base_entry = static_cast<const catalog::DirectoryEntryBase *>(
267 &modified_entry);
268
269
2/4
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 8 not taken.
48 output_catalog_mgr_->RemoveDirectory(rel_path.c_str());
270
271
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 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 48 times.
✗ Branch 3 not taken.
48 output_catalog_mgr_->AddFile(*base_entry, xattrs, parent_path);
277 }
278
279 48 perf::Inc(counters_->n_directories_removed);
280
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 if (entry2.IsLink()) {
281 48 perf::Inc(counters_->n_symlinks_added);
282 } else {
283 perf::Inc(counters_->n_files_added);
284 }
285
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 perf::Xadd(counters_->sz_added_bytes, static_cast<int64_t>(entry2.size()));
286
287
0/2
✗ Branch 3 not taken.
✗ Branch 4 not taken.
96 } else if ((entry1.IsRegular() || entry1.IsLink())
288
3/8
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 48 times.
✗ Branch 9 not taken.
48 && (entry2.IsRegular() || entry2.IsLink())) {
289 // From file to file
290
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 AbortIfHardlinked(entry1);
291
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 catalog::DirectoryEntry modified_entry = entry2;
292
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 SplitHardlink(&modified_entry);
293 const catalog::DirectoryEntryBase
294 48 *base_entry = static_cast<const catalog::DirectoryEntryBase *>(
295 &modified_entry);
296
2/4
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 48 times.
✗ Branch 8 not taken.
48 output_catalog_mgr_->RemoveFile(rel_path.c_str());
297
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 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 48 times.
✗ Branch 3 not taken.
48 output_catalog_mgr_->AddFile(*base_entry, xattrs, parent_path);
303 }
304
305
3/6
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 48 times.
✗ Branch 7 not taken.
48 if (entry1.IsRegular() && entry2.IsRegular()) {
306 48 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 48 perf::Xadd(counters_->sz_removed_bytes,
317
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 static_cast<int64_t>(entry1.size()));
318
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 perf::Xadd(counters_->sz_added_bytes, static_cast<int64_t>(entry2.size()));
319 48 }
320 144 return true;
321 144 }
322
323 template<typename RwCatalogMgr, typename RoCatalogMgr>
324 96 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::CreateNewManifest(
325 std::string *new_manifest_path) {
326
2/4
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 96 times.
96 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 96 times.
✗ Branch 2 not taken.
96 const std::string new_path = CreateTempPath(temp_dir_prefix_, 0600);
333
334
2/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 96 times.
96 if (!manifest_->Export(new_path)) {
335 LogCvmfs(kLogReceiver, kLogSyslogErr,
336 "CatalogMergeTool - Could not export new manifest");
337 }
338
339
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 *new_manifest_path = new_path;
340
341 96 return true;
342 96 }
343
344 } // namespace receiver
345
346 #endif // CVMFS_RECEIVER_CATALOG_MERGE_TOOL_IMPL_H_
347