GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/receiver/catalog_merge_tool_impl.h
Date: 2025-02-09 02:34:19
Exec Total Coverage
Lines: 133 180 73.9%
Branches: 136 345 39.4%

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 void 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 2 taken 1 times.
✗ Branch 3 not taken.
1 output_catalog_mgr_->AddDirectory(entry, xattrs, parent_path);
121
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (entry.IsNestedCatalogMountpoint()) {
122 output_catalog_mgr_->CreateNestedCatalog(std::string(rel_path.c_str()));
123 }
124 1 perf::Inc(counters_->n_directories_added);
125
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()) {
126
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 catalog::DirectoryEntry modified_entry = entry;
127
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 SplitHardlink(&modified_entry);
128 1 const catalog::DirectoryEntryBase* base_entry =
129 static_cast<const catalog::DirectoryEntryBase*>(&modified_entry);
130
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (entry.IsChunkedFile()) {
131 assert(!chunks.IsEmpty());
132 output_catalog_mgr_->AddChunkedFile(*base_entry, xattrs, parent_path,
133 chunks);
134 } else {
135
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 output_catalog_mgr_->AddFile(*base_entry, xattrs, parent_path);
136 }
137
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (entry.IsLink()) {
138 perf::Inc(counters_->n_symlinks_added);
139 } else {
140 1 perf::Inc(counters_->n_files_added);
141 }
142
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 perf::Xadd(counters_->sz_added_bytes, static_cast<int64_t>(entry.size()));
143 1 }
144 2 }
145
146 template <typename RwCatalogMgr, typename RoCatalogMgr>
147 3 void CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::ReportRemoval(
148 const PathString& path, const catalog::DirectoryEntry& entry) {
149
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 const PathString rel_path = MakeRelative(path);
150
151
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 if (entry.IsDirectory()) {
152
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (entry.IsNestedCatalogMountpoint()) {
153 output_catalog_mgr_->RemoveNestedCatalog(std::string(rel_path.c_str()),
154 false);
155 }
156
157
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());
158 1 perf::Inc(counters_->n_directories_removed);
159
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()) {
160
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 AbortIfHardlinked(entry);
161
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());
162
163
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (entry.IsLink()) {
164 perf::Inc(counters_->n_symlinks_removed);
165 } else {
166 2 perf::Inc(counters_->n_files_removed);
167 }
168
169
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 perf::Xadd(counters_->sz_removed_bytes, static_cast<int64_t>(entry.size()));
170 }
171 3 }
172
173 template <typename RwCatalogMgr, typename RoCatalogMgr>
174 3 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::ReportModification(
175 const PathString& path, const catalog::DirectoryEntry& entry1,
176 const catalog::DirectoryEntry& entry2, const XattrList& xattrs,
177 const FileChunkList& chunks) {
178
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 const PathString rel_path = MakeRelative(path);
179
180
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 const std::string parent_path =
181
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() : "";
182
183
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() &&
184 1 entry2.IsNestedCatalogMountpoint()) {
185 // From nested catalog to nested catalog
186 RoCatalogMgr *new_catalog_mgr =
187 CatalogDiffTool<RoCatalogMgr>::GetNewCatalogMgr();
188 PathString mountpoint;
189 shash::Any new_hash;
190 uint64_t new_size;
191 const bool found = new_catalog_mgr->LookupNested(path, &mountpoint,
192 &new_hash, &new_size);
193 if (!found || !new_size) {
194 PANIC(kLogSyslogErr,
195 "CatalogMergeTool - nested catalog %s not found. Aborting",
196 rel_path.c_str());
197 }
198 output_catalog_mgr_->SwapNestedCatalog(rel_path.ToString(), new_hash,
199 new_size);
200 return false; // skip recursion into nested catalog mountpoints
201
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()) {
202 // From directory to directory
203 1 const catalog::DirectoryEntryBase* base_entry =
204 static_cast<const catalog::DirectoryEntryBase*>(&entry2);
205
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());
206
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() &&
207 1 entry2.IsNestedCatalogMountpoint()) {
208 output_catalog_mgr_->CreateNestedCatalog(std::string(rel_path.c_str()));
209
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() &&
210 !entry2.IsNestedCatalogMountpoint()) {
211 output_catalog_mgr_->RemoveNestedCatalog(std::string(rel_path.c_str()));
212 }
213 1 perf::Inc(counters_->n_directories_changed);
214
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()) {
215 // From file to directory
216 AbortIfHardlinked(entry1);
217 output_catalog_mgr_->RemoveFile(rel_path.c_str());
218 output_catalog_mgr_->AddDirectory(entry2, xattrs, parent_path);
219 if (entry2.IsNestedCatalogMountpoint()) {
220 output_catalog_mgr_->CreateNestedCatalog(std::string(rel_path.c_str()));
221 }
222 if (entry1.IsLink()) {
223 perf::Inc(counters_->n_symlinks_removed);
224 } else {
225 perf::Inc(counters_->n_files_removed);
226 }
227 perf::Xadd(counters_->sz_removed_bytes,
228 static_cast<int64_t>(entry1.size()));
229 perf::Inc(counters_->n_directories_added);
230
231
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())) {
232 // From directory to file
233
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (entry1.IsNestedCatalogMountpoint()) {
234 // we merge the nested catalog with its parent, it will be the recursive
235 // procedure that will take care of deleting all the files.
236
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()),
237 /* merge = */ true);
238 }
239
240
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 catalog::DirectoryEntry modified_entry = entry2;
241
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 SplitHardlink(&modified_entry);
242 1 const catalog::DirectoryEntryBase* base_entry =
243 static_cast<const catalog::DirectoryEntryBase*>(&modified_entry);
244
245
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());
246
247
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (entry2.IsChunkedFile()) {
248 assert(!chunks.IsEmpty());
249 output_catalog_mgr_->AddChunkedFile(*base_entry, xattrs, parent_path,
250 chunks);
251 } else {
252
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 output_catalog_mgr_->AddFile(*base_entry, xattrs, parent_path);
253 }
254
255 1 perf::Inc(counters_->n_directories_removed);
256
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (entry2.IsLink()) {
257 1 perf::Inc(counters_->n_symlinks_added);
258 } else {
259 perf::Inc(counters_->n_files_added);
260 }
261
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 perf::Xadd(counters_->sz_added_bytes, static_cast<int64_t>(entry2.size()));
262
263
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()) &&
264
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 (entry2.IsRegular() || entry2.IsLink())) {
265 // From file to file
266
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 AbortIfHardlinked(entry1);
267
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 catalog::DirectoryEntry modified_entry = entry2;
268
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 SplitHardlink(&modified_entry);
269 1 const catalog::DirectoryEntryBase* base_entry =
270 static_cast<const catalog::DirectoryEntryBase*>(&modified_entry);
271
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());
272
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (entry2.IsChunkedFile()) {
273 assert(!chunks.IsEmpty());
274 output_catalog_mgr_->AddChunkedFile(*base_entry, xattrs, parent_path,
275 chunks);
276 } else {
277
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 output_catalog_mgr_->AddFile(*base_entry, xattrs, parent_path);
278 }
279
280
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()) {
281 1 perf::Inc(counters_->n_files_changed);
282 } else if (entry1.IsRegular() && entry2.IsLink()) {
283 perf::Inc(counters_->n_files_removed);
284 perf::Inc(counters_->n_symlinks_added);
285 } else if (entry1.IsLink() && entry2.IsRegular()) {
286 perf::Inc(counters_->n_symlinks_removed);
287 perf::Inc(counters_->n_files_added);
288 } else {
289 perf::Inc(counters_->n_symlinks_changed);
290 }
291 1 perf::Xadd(counters_->sz_removed_bytes,
292
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 static_cast<int64_t>(entry1.size()));
293
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 perf::Xadd(counters_->sz_added_bytes, static_cast<int64_t>(entry2.size()));
294 1 }
295 3 return true;
296 3 }
297
298 template <typename RwCatalogMgr, typename RoCatalogMgr>
299 2 bool CatalogMergeTool<RwCatalogMgr, RoCatalogMgr>::CreateNewManifest(
300 std::string* new_manifest_path) {
301
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_)) {
302 LogCvmfs(kLogReceiver, kLogSyslogErr,
303 "CatalogMergeTool - Could not commit output catalog");
304 return false;
305 }
306
307
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 const std::string new_path = CreateTempPath(temp_dir_prefix_, 0600);
308
309
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)) {
310 LogCvmfs(kLogReceiver, kLogSyslogErr,
311 "CatalogMergeTool - Could not export new manifest");
312 }
313
314
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 *new_manifest_path = new_path;
315
316 2 return true;
317 2 }
318
319 } // namespace receiver
320
321 #endif // CVMFS_RECEIVER_CATALOG_MERGE_TOOL_IMPL_H_
322