GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/mountpoint.cc
Date: 2026-10-25 02:40:14
Exec Total Coverage
Lines: 978 1429 68.4%
Branches: 1248 3235 38.6%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #include "mountpoint.h"
6
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <inttypes.h>
10 #include <stdint.h>
11 #include <sys/stat.h>
12 #include <unistd.h>
13
14 #include <algorithm>
15 #include <cassert>
16 #include <climits>
17 #include <cstring>
18 #include <vector>
19
20 #include "duplex_fuse.h" // IWYU pragma: keep
21
22 #ifndef CVMFS_LIBCVMFS
23 #ifdef FUSE_CAP_EXPORT_SUPPORT
24 #define CVMFS_NFS_SUPPORT
25 #else
26 #warning "No NFS support, Fuse too old"
27 #endif
28 #endif
29
30 #include "authz/authz_curl.h"
31 #include "authz/authz_fetch.h"
32 #include "authz/authz_session.h"
33 #include "backoff.h"
34 #include "bundle_mgr.h"
35 #include "cache.h"
36 #include "cache_extern.h"
37 #include "cache_posix.h"
38 #include "cache_ram.h"
39 #include "cache_stream.h"
40 #include "cache_tiered.h"
41 #include "catalog.h"
42 #include "catalog_mgr_client.h"
43 #include "clientctx.h"
44 #include "crypto/signature.h"
45 #include "duplex_sqlite3.h"
46 #include "fetch.h"
47 #include "file_chunk.h"
48 #include "globals.h"
49 #include "glue_buffer.h"
50 #include "google/protobuf/stubs/common.h"
51 #include "history.h"
52 #include "history_sqlite.h"
53 #include "lru_md.h"
54 #include "manifest.h"
55 #include "manifest_fetch.h"
56 #include "network/download.h"
57 #include "network/sink_mem.h"
58 #include "nfs_maps.h"
59 #ifdef CVMFS_NFS_SUPPORT
60 #include "nfs_maps_leveldb.h"
61 #include "nfs_maps_sqlite.h"
62 #endif
63 #include <memory>
64
65 #include "options.h"
66 #include "quota_posix.h"
67 #include "resolv_conf_event_handler.h"
68 #include "sqlitemem.h"
69 #include "sqlitevfs.h"
70 #include "statistics.h"
71 #include "telemetry_aggregator.h"
72 #include "tracer.h"
73 #include "util/logging.h"
74 #include "util/posix.h"
75 #include "util/string.h"
76 #include "util/uuid.h"
77 #include "wpad.h"
78
79 using namespace std; // NOLINT
80
81
82 bool FileSystem::g_alive = false;
83 const char *FileSystem::kDefaultCacheBase = "/var/lib/cvmfs";
84 const char *FileSystem::kDefaultCacheMgrInstance = "default";
85
86
87 2752 FileSystem::IoErrorInfo::IoErrorInfo() : counter_(NULL), timestamp_last_(0) { }
88
89 ✗ void FileSystem::IoErrorInfo::Reset() {
90 ✗ counter_->Set(0);
91 ✗ timestamp_last_ = 0;
92 }
93
94 ✗ void FileSystem::IoErrorInfo::AddIoError() {
95 ✗ perf::Inc(counter_);
96 ✗ timestamp_last_ = time(NULL);
97 }
98
99 2752 void FileSystem::IoErrorInfo::SetCounter(perf::Counter *c) { counter_ = c; }
100
101 ✗ int64_t FileSystem::IoErrorInfo::count() { return counter_->Get(); }
102
103 ✗ time_t FileSystem::IoErrorInfo::timestamp_last() { return timestamp_last_; }
104
105
106 /**
107 * A cache instance name is part of a bash parameter and can only contain
108 * certain characters.
109 */
110 768 bool FileSystem::CheckInstanceName(const std::string &instance) {
111
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 720 times.
768 if (instance.length() > 24)
112 48 return false;
113
1/2
✓ Branch 1 taken 720 times.
✗ Branch 2 not taken.
720 const sanitizer::CacheInstanceSanitizer instance_sanitizer;
114
3/4
✓ Branch 1 taken 720 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
✓ Branch 4 taken 624 times.
720 if (!instance_sanitizer.IsValid(instance)) {
115
2/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
192 boot_error_ = "invalid instance name (" + instance + "), "
116
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 + "only characters a-z, A-Z, 0-9, _ are allowed";
117 96 boot_status_ = loader::kFailCacheDir;
118 96 return false;
119 }
120 624 return true;
121 720 }
122
123
124 /**
125 * Not all possible combinations of cache flags / modes are valid.
126 */
127 2694 bool FileSystem::CheckPosixCacheSettings(
128 const FileSystem::PosixCacheSettings &settings) {
129
4/4
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 2242 times.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 308 times.
2694 if (settings.is_alien && settings.is_shared) {
130 boot_error_ = "Failure: shared local disk cache and alien cache mutually "
131 144 "exclusive. Please turn off shared local disk cache.";
132 144 boot_status_ = loader::kFailOptions;
133 144 return false;
134 }
135
4/4
✓ Branch 0 taken 308 times.
✓ Branch 1 taken 2242 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 212 times.
2550 if (settings.is_alien && settings.is_managed) {
136 boot_error_ = "Failure: quota management and alien cache mutually "
137 96 "exclusive. Please turn off quota limit.";
138 96 boot_status_ = loader::kFailOptions;
139 96 return false;
140 }
141
142
2/2
✓ Branch 0 taken 263 times.
✓ Branch 1 taken 2191 times.
2454 if (type_ == kFsLibrary) {
143
3/4
✓ Branch 0 taken 215 times.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 215 times.
263 if (settings.is_shared || settings.is_managed) {
144 boot_error_ = "Failure: libcvmfs supports only unmanaged exclusive cache "
145 48 "or alien cache.";
146 48 boot_status_ = loader::kFailOptions;
147 48 return false;
148 }
149 }
150
151
4/4
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 359 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 1999 times.
2406 if (settings.cache_base_defined && settings.cache_dir_defined) {
152 boot_error_ = "'CVMFS_CACHE_BASE' and 'CVMFS_CACHE_DIR' are mutually "
153 48 "exclusive";
154 48 boot_status_ = loader::kFailOptions;
155 48 return false;
156 }
157
158 2358 return true;
159 }
160
161
162 /**
163 * Creation of state and manager classes. The destructor should mirror this
164 * method.
165 */
166 2752 FileSystem *FileSystem::Create(const FileSystem::FileSystemInfo &fs_info) {
167
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 std::unique_ptr<FileSystem> file_system(new FileSystem(fs_info));
168
169
1/2
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
2752 file_system->SetupLogging();
170
1/2
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
2752 LogCvmfs(kLogCvmfs, kLogDebug, "Options:\n%s",
171
1/2
✓ Branch 3 taken 2752 times.
✗ Branch 4 not taken.
5504 file_system->options_mgr()->Dump().c_str());
172
173
1/2
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
2752 file_system->CreateStatistics();
174
1/2
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
2752 file_system->SetupSqlite();
175
2/4
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2752 times.
2752 if (!file_system->DetermineNfsMode())
176 ✗ return file_system.release();
177
3/4
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 58 times.
✓ Branch 5 taken 2694 times.
2752 if (!file_system->SetupWorkspace())
178 58 return file_system.release();
179
180 // Redirect SQlite temp directory to workspace (global variable)
181 2694 const unsigned length_tempdir = file_system->workspace_.length() + 1;
182
1/2
✓ Branch 1 taken 2694 times.
✗ Branch 2 not taken.
2694 sqlite3_temp_directory = static_cast<char *>(sqlite3_malloc(length_tempdir));
183 2694 snprintf(sqlite3_temp_directory,
184 length_tempdir,
185 "%s",
186 2694 file_system->workspace_.c_str());
187
188
3/4
✓ Branch 2 taken 2694 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 432 times.
✓ Branch 5 taken 2262 times.
2694 if (!file_system->TriageCacheMgr())
189 432 return file_system.release();
190
1/2
✓ Branch 2 taken 2262 times.
✗ Branch 3 not taken.
2262 file_system->SetupUuid();
191
1/4
✗ Branch 2 not taken.
✓ Branch 3 taken 2262 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2262 if (!file_system->SetupNfsMaps())
192 ✗ return file_system.release();
193
1/2
✓ Branch 2 taken 2262 times.
✗ Branch 3 not taken.
2262 const bool retval = sqlite::RegisterVfsRdOnly(file_system->cache_mgr_,
194 2262 file_system->statistics_,
195 sqlite::kVfsOptDefault);
196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2262 times.
2262 assert(retval);
197 2262 file_system->has_custom_sqlitevfs_ = true;
198
199
1/2
✓ Branch 1 taken 2262 times.
✗ Branch 2 not taken.
2262 ClientCtx::GetInstance();
200
201 2262 file_system->boot_status_ = loader::kFailOk;
202 2262 return file_system.release();
203 2752 }
204
205
206 2752 void FileSystem::CreateStatistics() {
207
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 statistics_ = new perf::Statistics();
208
209 // Register the ShortString's static counters
210
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 statistics_->Register("pathstring.n_instances", "Number of instances");
211
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 statistics_->Register("pathstring.n_overflows", "Number of overflows");
212
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 statistics_->Register("namestring.n_instances", "Number of instances");
213
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 statistics_->Register("namestring.n_overflows", "Number of overflows");
214
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 statistics_->Register("linkstring.n_instances", "Number of instances");
215
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 statistics_->Register("linkstring.n_overflows", "Number of overflows");
216
217 // Callback counters
218
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_open_ = statistics_->Register("cvmfs.n_fs_open",
219 "Overall number of file open operations");
220
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_dir_open_ = statistics_->Register(
221 "cvmfs.n_fs_dir_open", "Overall number of directory open operations");
222
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_lookup_ = statistics_->Register("cvmfs.n_fs_lookup",
223 "Number of lookups");
224
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_lookup_negative_ = statistics_->Register("cvmfs.n_fs_lookup_negative",
225 "Number of negative lookups");
226
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_stat_ = statistics_->Register("cvmfs.n_fs_stat", "Number of stats");
227
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_stat_stale_ = statistics_->Register(
228 "cvmfs.n_fs_stat_stale",
229 "Number of stats for stale (open, meanwhile changed) regular files");
230
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_statfs_ = statistics_->Register("cvmfs.n_fs_statfs",
231 "Overall number of statsfs calls");
232
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_statfs_cached_ = statistics_->Register(
233 "cvmfs.n_fs_statfs_cached",
234 "Number of statsfs calls that accessed the cached statfs info");
235
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_read_ = statistics_->Register("cvmfs.n_fs_read", "Number of files read");
236
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_readlink_ = statistics_->Register("cvmfs.n_fs_readlink",
237 "Number of links read");
238
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_forget_ = statistics_->Register("cvmfs.n_fs_forget",
239 "Number of inode forgets");
240
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_fs_inode_replace_ = statistics_->Register(
241 "cvmfs.n_fs_inode_replace",
242 "Number of stale inodes that got replaced by an up-to-date version");
243
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 no_open_files_ = statistics_->Register("cvmfs.no_open_files",
244 "Number of currently opened files");
245
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 no_open_dirs_ = statistics_->Register(
246 "cvmfs.no_open_dirs", "Number of currently opened directories");
247
3/6
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2752 times.
✗ Branch 9 not taken.
2752 io_error_info_.SetCounter(
248 2752 statistics_->Register("cvmfs.n_io_error", "Number of I/O errors"));
249
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_eio_total_ = statistics_->Register(
250 "eio.total",
251 "EIO returned to calling process. Sum of individual eio counters");
252
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_eio_01_ = statistics_->Register(
253 "eio.01", "EIO returned by cvmfs.cc:cvmfs_lookup() - lookup failed");
254
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_eio_02_ = statistics_->Register("eio.02",
255 "EIO returned by cvmfs.cc:ReplyNegative() "
256 "- CVMFS-specific metadata not found");
257
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_eio_03_ = statistics_->Register(
258 "eio.03",
259 "EIO returned by cvmfs.cc:cvmfs_opendir() - failed to open directory ");
260
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_eio_04_ = statistics_->Register("eio.04",
261 "EIO returned by cvmfs.cc:cvmfs_open() "
262 "- chunked file does not have any chunks");
263
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_eio_05_ = statistics_->Register(
264 "eio.05",
265 "EIO returned by cvmfs.cc:cvmfs_read() - failed to fetch chunk");
266
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_eio_06_ = statistics_->Register(
267 "eio.06", "EIO returned by cvmfs.cc:cvmfs_open() - failed to open file");
268
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_eio_07_ = statistics_->Register(
269 "eio.07", "EIO returned by cvmfs.cc:cvmfs_read() - failed to read chunk");
270
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_eio_08_ = statistics_->Register(
271 "eio.08", "EIO returned by cvmfs.cc:cvmfs_read() - failed to read file");
272
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2752 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2752 times.
✗ Branch 10 not taken.
2752 n_emfile_ = statistics_->Register(
273 "eio.emfile",
274 "EMFILE returned by cvmfs.cc:cvmfs_read(): too many open files");
275
276 2752 string optarg;
277
3/10
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2752 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5504 if (options_mgr_->GetValue("CVMFS_INSTRUMENT_FUSE", &optarg)
278
3/10
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2752 times.
✗ Branch 12 not taken.
5504 && options_mgr_->IsOn(optarg)) {
279 ✗ HighPrecisionTimer::g_is_enabled = true;
280 }
281
282
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_lookup_ = new Log2Histogram(30);
283
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_forget_ = new Log2Histogram(30);
284
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_forget_multi_ = new Log2Histogram(30);
285
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_getattr_ = new Log2Histogram(30);
286
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_readlink_ = new Log2Histogram(30);
287
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_opendir_ = new Log2Histogram(30);
288
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_releasedir_ = new Log2Histogram(30);
289
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_readdir_ = new Log2Histogram(30);
290
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_open_ = new Log2Histogram(30);
291
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_read_ = new Log2Histogram(30);
292
2/4
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
2752 hist_fs_release_ = new Log2Histogram(30);
293 2752 }
294
295
296 /**
297 * Figure out mode of operation and cache directory. Checking options for
298 * sanity is in a separate method.
299 */
300 2310 FileSystem::PosixCacheSettings FileSystem::DeterminePosixCacheSettings(
301 const string &instance) {
302 2310 string optarg;
303 2310 PosixCacheSettings settings;
304
305
5/16
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2310 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2310 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2310 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 2310 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
4620 if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_REFCOUNT", instance),
306 &optarg)
307
3/10
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2310 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2310 times.
✗ Branch 12 not taken.
4620 && options_mgr_->IsOff(optarg)) {
308 ✗ settings.do_refcount = false;
309 }
310
311 9240 if (options_mgr_->GetValue(
312
5/16
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2310 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2310 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2310 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 2310 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
4620 MkCacheParm("CVMFS_CACHE_CLEANUP_NONOPENLRU", instance), &optarg)
313
3/10
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2310 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2310 times.
✗ Branch 12 not taken.
4620 && options_mgr_->IsOn(optarg)) {
314 // Enable this policy only in a refcounted cache.
315 // Because it's the reference counter who will say if a file is open.
316 ✗ settings.cleanup_unused_first = settings.do_refcount;
317 }
318
319
6/16
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2310 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2310 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2310 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 96 times.
✓ Branch 14 taken 2214 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
4620 if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_SHARED", instance),
320 &optarg)
321
7/10
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1855 times.
✓ Branch 5 taken 455 times.
✓ Branch 7 taken 1855 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 96 times.
✓ Branch 10 taken 1759 times.
✓ Branch 11 taken 2310 times.
✗ Branch 12 not taken.
4620 && options_mgr_->IsOn(optarg)) {
322 96 settings.is_shared = true;
323 }
324
5/16
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2310 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2310 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2310 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 2310 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
4620 if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_SERVER_MODE", instance),
325 &optarg)
326
3/10
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2310 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2310 times.
✗ Branch 12 not taken.
4620 && options_mgr_->IsOn(optarg)) {
327 ✗ settings.avoid_rename = true;
328 }
329
330
2/2
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 263 times.
2310 if (type_ == kFsFuse)
331 2047 settings.quota_limit = kDefaultQuotaLimit;
332
5/8
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2310 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2310 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 528 times.
✓ Branch 14 taken 1782 times.
2310 if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_QUOTA_LIMIT", instance),
333 &optarg)) {
334
1/2
✓ Branch 1 taken 528 times.
✗ Branch 2 not taken.
528 settings.quota_limit = String2Int64(optarg) * 1024 * 1024;
335 }
336
2/2
✓ Branch 0 taken 1663 times.
✓ Branch 1 taken 647 times.
2310 if (settings.quota_limit > 0)
337 1663 settings.is_managed = true;
338
339
1/2
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
2310 settings.cache_path = kDefaultCacheBase;
340
5/8
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2310 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2310 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 2095 times.
✓ Branch 14 taken 215 times.
2310 if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_BASE", instance),
341 &optarg)) {
342
1/2
✓ Branch 1 taken 2095 times.
✗ Branch 2 not taken.
2095 settings.cache_path = MakeCanonicalPath(optarg);
343 2095 settings.cache_base_defined = true;
344 }
345
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 2214 times.
2310 if (settings.is_shared) {
346
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 settings.cache_path += "/shared";
347 } else {
348
2/4
✓ Branch 1 taken 2214 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2214 times.
✗ Branch 5 not taken.
2214 settings.cache_path += "/" + name_;
349 }
350
351 // CheckCacheMode makes sure that CVMFS_CACHE_DIR and CVMFS_CACHE_BASE are
352 // not set at the same time.
353
5/8
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2310 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2310 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 215 times.
✓ Branch 14 taken 2095 times.
2310 if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_DIR", instance),
354 &optarg)) {
355 215 settings.cache_dir_defined = true;
356
1/2
✓ Branch 1 taken 215 times.
✗ Branch 2 not taken.
215 settings.cache_path = optarg;
357 }
358
5/8
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2310 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2310 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 308 times.
✓ Branch 14 taken 2002 times.
2310 if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_ALIEN", instance),
359 &optarg)) {
360 308 settings.is_alien = true;
361
1/2
✓ Branch 1 taken 308 times.
✗ Branch 2 not taken.
308 settings.cache_path = optarg;
362 }
363 // We already changed the cwd to the workspace
364 // Which is only done if using FUSE
365
6/6
✓ Branch 0 taken 2047 times.
✓ Branch 1 taken 263 times.
✓ Branch 3 taken 1759 times.
✓ Branch 4 taken 288 times.
✓ Branch 5 taken 1759 times.
✓ Branch 6 taken 551 times.
2310 if ((type_ == kFsFuse) && (settings.cache_path == workspace_fullpath_)) {
366
1/2
✓ Branch 1 taken 1759 times.
✗ Branch 2 not taken.
1759 settings.cache_path = ".";
367 }
368
369 // The cache workspace usually is the cache directory, unless explicitly
370 // set otherwise
371
1/2
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
2310 settings.workspace = settings.cache_path;
372
6/16
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2310 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2310 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2310 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 106 times.
✓ Branch 14 taken 2204 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
4620 if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_WORKSPACE", instance),
373 &optarg)
374
9/20
✓ Branch 2 taken 2310 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2310 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 2310 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2310 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 106 times.
✓ Branch 14 taken 2204 times.
✓ Branch 15 taken 2310 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 2310 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 2310 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
4620 || options_mgr_->GetValue("CVMFS_WORKSPACE", &optarg)) {
375 // Used for the shared quota manager
376
1/2
✓ Branch 1 taken 106 times.
✗ Branch 2 not taken.
106 settings.workspace = optarg;
377 }
378
379 4620 return settings;
380 2310 }
381
382
383 2752 bool FileSystem::DetermineNfsMode() {
384 2752 string optarg;
385
386
4/10
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 192 times.
✓ Branch 8 taken 2560 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5504 if (options_mgr_->GetValue("CVMFS_NFS_SOURCE", &optarg)
387
6/10
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 192 times.
✓ Branch 5 taken 2560 times.
✓ Branch 7 taken 192 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 192 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2752 times.
✗ Branch 12 not taken.
5504 && options_mgr_->IsOn(optarg)) {
388 192 nfs_mode_ |= kNfsMaps;
389
4/6
✓ Branch 2 taken 192 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 192 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 144 times.
✓ Branch 10 taken 48 times.
192 if (options_mgr_->GetValue("CVMFS_NFS_SHARED", &optarg)) {
390 144 nfs_mode_ |= kNfsMapsHa;
391
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
144 nfs_maps_dir_ = optarg;
392 }
393 }
394
395
3/4
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 2480 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 272 times.
2752 if ((type_ == kFsLibrary) && (nfs_mode_ != kNfsNone)) {
396 ✗ boot_error_ = "Failure: libcvmfs does not support NFS export.";
397 ✗ boot_status_ = loader::kFailOptions;
398 ✗ return false;
399 }
400 2752 return true;
401 2752 }
402
403
404 2752 FileSystem::FileSystem(const FileSystem::FileSystemInfo &fs_info)
405
1/2
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
2752 : name_(fs_info.name)
406
1/2
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
2752 , exe_path_(fs_info.exe_path)
407 2752 , type_(fs_info.type)
408 2752 , options_mgr_(fs_info.options_mgr)
409 2752 , wait_workspace_(fs_info.wait_workspace)
410 2752 , foreground_(fs_info.foreground)
411 2752 , n_fs_open_(NULL)
412 2752 , n_fs_dir_open_(NULL)
413 2752 , n_fs_lookup_(NULL)
414 2752 , n_fs_lookup_negative_(NULL)
415 2752 , n_fs_stat_(NULL)
416 2752 , n_fs_stat_stale_(NULL)
417 2752 , n_fs_statfs_(NULL)
418 2752 , n_fs_statfs_cached_(NULL)
419 2752 , n_fs_read_(NULL)
420 2752 , n_fs_readlink_(NULL)
421 2752 , n_fs_forget_(NULL)
422 2752 , n_fs_inode_replace_(NULL)
423 2752 , no_open_files_(NULL)
424 2752 , no_open_dirs_(NULL)
425 2752 , n_eio_total_(NULL)
426 2752 , n_eio_01_(NULL)
427 2752 , n_eio_02_(NULL)
428 2752 , n_eio_03_(NULL)
429 2752 , n_eio_04_(NULL)
430 2752 , n_eio_05_(NULL)
431 2752 , n_eio_06_(NULL)
432 2752 , n_eio_07_(NULL)
433 2752 , n_eio_08_(NULL)
434 2752 , n_emfile_(NULL)
435 2752 , statistics_(NULL)
436 2752 , fd_workspace_lock_(-1)
437 2752 , found_previous_crash_(false)
438 2752 , nfs_mode_(kNfsNone)
439 2752 , cache_mgr_(NULL)
440 2752 , uuid_cache_(NULL)
441 2752 , nfs_maps_(NULL)
442 5504 , has_custom_sqlitevfs_(false) {
443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2752 times.
2752 assert(!g_alive);
444 2752 g_alive = true;
445 2752 g_uid = geteuid();
446 2752 g_gid = getegid();
447
448 2752 string optarg;
449 11008 if (options_mgr_->GetValue(
450
8/26
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2752 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2752 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 2752 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 2752 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 2752 times.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 2752 times.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
5504 MkCacheParm("CVMFS_CACHE_SERVER_MODE", kDefaultCacheMgrInstance),
451 &optarg)
452
3/10
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2752 times.
✗ Branch 12 not taken.
5504 && options_mgr_->IsOn(optarg)) {
453 ✗ g_raw_symlinks = true;
454 }
455 2752 }
456
457
458 2748 FileSystem::~FileSystem() {
459 2748 ClientCtx::CleanupInstance();
460
461
2/2
✓ Branch 0 taken 2259 times.
✓ Branch 1 taken 489 times.
2748 if (has_custom_sqlitevfs_)
462 2259 sqlite::UnregisterVfsRdOnly();
463
464
2/2
✓ Branch 0 taken 2259 times.
✓ Branch 1 taken 489 times.
2748 delete uuid_cache_;
465
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2748 times.
2748 delete nfs_maps_;
466
2/2
✓ Branch 0 taken 2259 times.
✓ Branch 1 taken 489 times.
2748 delete cache_mgr_;
467
468
2/2
✓ Branch 0 taken 2691 times.
✓ Branch 1 taken 57 times.
2748 if (sqlite3_temp_directory) {
469 2691 sqlite3_free(sqlite3_temp_directory);
470 2691 sqlite3_temp_directory = NULL;
471 }
472
473
2/2
✓ Branch 1 taken 2691 times.
✓ Branch 2 taken 57 times.
2748 if (!path_crash_guard_.empty())
474 2691 unlink(path_crash_guard_.c_str());
475
2/2
✓ Branch 1 taken 2691 times.
✓ Branch 2 taken 57 times.
2748 if (!path_workspace_lock_.empty())
476 2691 unlink(path_workspace_lock_.c_str());
477
2/2
✓ Branch 0 taken 2691 times.
✓ Branch 1 taken 57 times.
2748 if (fd_workspace_lock_ >= 0)
478 2691 UnlockFile(fd_workspace_lock_);
479
480 2748 sqlite3_shutdown();
481 2748 SqliteMemoryManager::CleanupInstance();
482
483
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_lookup_;
484
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_forget_multi_;
485
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_forget_;
486
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_getattr_;
487
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_readlink_;
488
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_opendir_;
489
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_releasedir_;
490
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_readdir_;
491
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_open_;
492
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_read_;
493
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete hist_fs_release_;
494
1/2
✓ Branch 0 taken 2748 times.
✗ Branch 1 not taken.
2748 delete statistics_;
495
496 2748 SetLogSyslogPrefix("");
497 2748 SetLogMicroSyslog("");
498 2748 SetLogDebugFile("");
499 2748 google::protobuf::ShutdownProtobufLibrary();
500 2748 g_alive = false;
501 2748 }
502
503
504 2695 bool FileSystem::LockWorkspace() {
505
1/2
✓ Branch 2 taken 2695 times.
✗ Branch 3 not taken.
2695 path_workspace_lock_ = workspace_ + "/lock." + name_;
506 2695 fd_workspace_lock_ = TryLockFile(path_workspace_lock_);
507
2/2
✓ Branch 0 taken 2694 times.
✓ Branch 1 taken 1 times.
2695 if (fd_workspace_lock_ >= 0)
508 2694 return true;
509
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (fd_workspace_lock_ == -1) {
511 ✗ boot_error_ = "could not acquire workspace lock " + path_workspace_lock_
512 ✗ + " (" + strerror(errno) + ")";
513 ✗ boot_status_ = loader::kFailCacheDir;
514 ✗ return false;
515 }
516
517
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 assert(fd_workspace_lock_ == -2);
518
519
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!wait_workspace_) {
520 1 boot_status_ = loader::kFailLockWorkspace;
521 1 return false;
522 }
523
524 ✗ fd_workspace_lock_ = LockFile(path_workspace_lock_);
525 ✗ if (fd_workspace_lock_ < 0) {
526 ✗ boot_error_ = "could not acquire workspace lock " + path_workspace_lock_
527 ✗ + " (" + strerror(errno) + ")";
528 ✗ boot_status_ = loader::kFailCacheDir;
529 ✗ return false;
530 }
531 ✗ return true;
532 }
533
534
535 3296 void FileSystem::LogSqliteError(void *user_data __attribute__((unused)),
536 int sqlite_extended_error,
537 const char *message) {
538 3296 int log_dest = kLogDebug;
539 3296 const int sqlite_error = sqlite_extended_error & 0xFF;
540
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 3002 times.
3296 switch (sqlite_error) {
541 294 case SQLITE_INTERNAL:
542 case SQLITE_PERM:
543 case SQLITE_NOMEM:
544 case SQLITE_IOERR:
545 case SQLITE_CORRUPT:
546 case SQLITE_FULL:
547 case SQLITE_CANTOPEN:
548 case SQLITE_MISUSE:
549 case SQLITE_FORMAT:
550 case SQLITE_NOTADB:
551 294 log_dest |= kLogSyslogErr;
552 294 break;
553 3002 case SQLITE_WARNING:
554 case SQLITE_NOTICE:
555 default:
556 3002 break;
557 }
558
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
3296 LogCvmfs(kLogCvmfs, log_dest, "SQlite3: %s (%d)", message,
559 sqlite_extended_error);
560 3296 }
561
562
563 /**
564 * Creates the cache parameter for a specific instance of the cache. Injects
565 * the instance name such that CVMFS_CACHE_FOO_BAR becomes
566 * CVMFS_CACHE_<INSTANCE>_FOO_BAR
567 */
568 26758 string FileSystem::MkCacheParm(const string &generic_parameter,
569 const string &instance) {
570
3/6
✓ Branch 2 taken 26758 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 26758 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 26758 times.
26758 assert(HasPrefix(generic_parameter, "CVMFS_CACHE_", false));
571
572
2/2
✓ Branch 1 taken 22294 times.
✓ Branch 2 taken 4464 times.
26758 if (instance == kDefaultCacheMgrInstance) {
573 // Compatibility parameter names
574 22294 if ((generic_parameter == "CVMFS_CACHE_SHARED")
575
5/6
✓ Branch 0 taken 2166 times.
✓ Branch 1 taken 20128 times.
✓ Branch 3 taken 2166 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2166 times.
✓ Branch 6 taken 20128 times.
22294 && !options_mgr_->IsDefined(generic_parameter)) {
576
1/2
✓ Branch 2 taken 2166 times.
✗ Branch 3 not taken.
2166 return "CVMFS_SHARED_CACHE";
577 }
578 20128 if ((generic_parameter == "CVMFS_CACHE_ALIEN")
579
5/6
✓ Branch 0 taken 2166 times.
✓ Branch 1 taken 17962 times.
✓ Branch 3 taken 2166 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2166 times.
✓ Branch 6 taken 17962 times.
20128 && !options_mgr_->IsDefined(generic_parameter)) {
580
1/2
✓ Branch 2 taken 2166 times.
✗ Branch 3 not taken.
2166 return "CVMFS_ALIEN_CACHE";
581 }
582 17962 if ((generic_parameter == "CVMFS_CACHE_SERVER_MODE")
583
5/6
✓ Branch 0 taken 4918 times.
✓ Branch 1 taken 13044 times.
✓ Branch 3 taken 4918 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4918 times.
✓ Branch 6 taken 13044 times.
17962 && !options_mgr_->IsDefined(generic_parameter)) {
584
1/2
✓ Branch 2 taken 4918 times.
✗ Branch 3 not taken.
4918 return "CVMFS_SERVER_CACHE_MODE";
585 }
586 13044 if ((generic_parameter == "CVMFS_CACHE_QUOTA_LIMIT")
587
5/6
✓ Branch 0 taken 2166 times.
✓ Branch 1 taken 10878 times.
✓ Branch 3 taken 2166 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2166 times.
✓ Branch 6 taken 10878 times.
13044 && !options_mgr_->IsDefined(generic_parameter)) {
588
1/2
✓ Branch 2 taken 2166 times.
✗ Branch 3 not taken.
2166 return "CVMFS_QUOTA_LIMIT";
589 }
590 10878 return generic_parameter;
591 }
592
593
3/6
✓ Branch 2 taken 4464 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4464 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4464 times.
✗ Branch 9 not taken.
8928 return "CVMFS_CACHE_" + instance + "_" + generic_parameter.substr(12);
594 }
595
596
597 ✗ void FileSystem::ResetErrorCounters() {
598 ✗ io_error_info_.Reset();
599 ✗ n_eio_total_->Set(0);
600 ✗ n_eio_01_->Set(0);
601 ✗ n_eio_02_->Set(0);
602 ✗ n_eio_03_->Set(0);
603 ✗ n_eio_04_->Set(0);
604 ✗ n_eio_05_->Set(0);
605 ✗ n_eio_06_->Set(0);
606 ✗ n_eio_07_->Set(0);
607 ✗ n_eio_08_->Set(0);
608 ✗ n_emfile_->Set(0);
609 }
610
611
612 /**
613 * Can be recursive for the tiered cache manager.
614 */
615 3270 CacheManager *FileSystem::SetupCacheMgr(const string &instance) {
616
3/4
✓ Branch 2 taken 3270 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 3222 times.
3270 if (constructed_instances_.find(instance) != constructed_instances_.end()) {
617
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 boot_error_ = "circular cache definition: " + instance;
618 48 boot_status_ = loader::kFailCacheDir;
619 48 return NULL;
620 }
621
1/2
✓ Branch 1 taken 3222 times.
✗ Branch 2 not taken.
3222 constructed_instances_.insert(instance);
622
623
1/2
✓ Branch 2 taken 3222 times.
✗ Branch 3 not taken.
3222 LogCvmfs(kLogCvmfs, kLogDebug, "setting up cache manager instance %s",
624 instance.c_str());
625 3222 string instance_type;
626
2/2
✓ Branch 1 taken 2166 times.
✓ Branch 2 taken 1056 times.
3222 if (instance == kDefaultCacheMgrInstance) {
627
1/2
✓ Branch 1 taken 2166 times.
✗ Branch 2 not taken.
2166 instance_type = "posix";
628 } else {
629
3/6
✓ Branch 2 taken 1056 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1056 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1056 times.
✗ Branch 9 not taken.
1056 options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_TYPE", instance),
630 &instance_type);
631 }
632
2/2
✓ Branch 1 taken 2310 times.
✓ Branch 2 taken 912 times.
3222 if (instance_type == "posix") {
633
1/2
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
2310 return SetupPosixCacheMgr(instance);
634
2/2
✓ Branch 1 taken 480 times.
✓ Branch 2 taken 432 times.
912 } else if (instance_type == "ram") {
635
1/2
✓ Branch 1 taken 480 times.
✗ Branch 2 not taken.
480 return SetupRamCacheMgr(instance);
636
2/2
✓ Branch 1 taken 384 times.
✓ Branch 2 taken 48 times.
432 } else if (instance_type == "tiered") {
637
1/2
✓ Branch 1 taken 384 times.
✗ Branch 2 not taken.
384 return SetupTieredCacheMgr(instance);
638
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 } else if (instance_type == "external") {
639 ✗ return SetupExternalCacheMgr(instance);
640 } else {
641
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 boot_error_ = "invalid cache manager type for '" + instance
642
2/4
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
48 + "':" + instance_type;
643 48 boot_status_ = loader::kFailCacheDir;
644 48 return NULL;
645 }
646 3222 }
647
648
649 ✗ CacheManager *FileSystem::SetupExternalCacheMgr(const string &instance) {
650 ✗ string optarg;
651 ✗ unsigned nfiles = kDefaultNfiles;
652 ✗ if (options_mgr_->GetValue("CVMFS_NFILES", &optarg))
653 ✗ nfiles = String2Uint64(optarg);
654 ✗ vector<string> cmd_line;
655 ✗ if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_CMDLINE", instance),
656 &optarg)) {
657 ✗ cmd_line = SplitString(optarg, ',');
658 }
659
660 ✗ if (!options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_LOCATOR", instance),
661 &optarg)) {
662 ✗ boot_error_ = MkCacheParm("CVMFS_CACHE_LOCATOR", instance) + " missing";
663 ✗ boot_status_ = loader::kFailCacheDir;
664 ✗ return NULL;
665 }
666
667 const std::unique_ptr<ExternalCacheManager::PluginHandle> plugin_handle(
668 ✗ ExternalCacheManager::CreatePlugin(optarg, cmd_line));
669 ✗ if (!plugin_handle->IsValid()) {
670 ✗ boot_error_ = plugin_handle->error_msg();
671 ✗ boot_status_ = loader::kFailCacheDir;
672 ✗ return NULL;
673 }
674 ✗ ExternalCacheManager *cache_mgr = ExternalCacheManager::Create(
675 ✗ plugin_handle->fd_connection(), nfiles, name_ + ":" + instance);
676 ✗ if (cache_mgr == NULL) {
677 ✗ boot_error_ = "failed to create external cache manager for " + instance;
678 ✗ boot_status_ = loader::kFailCacheDir;
679 ✗ return NULL;
680 }
681 ✗ cache_mgr->AcquireQuotaManager(ExternalQuotaManager::Create(cache_mgr));
682 ✗ return cache_mgr;
683 }
684
685
686 2310 CacheManager *FileSystem::SetupPosixCacheMgr(const string &instance) {
687
1/2
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
2310 const PosixCacheSettings settings = DeterminePosixCacheSettings(instance);
688
3/4
✓ Branch 1 taken 2310 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 144 times.
✓ Branch 4 taken 2166 times.
2310 if (!CheckPosixCacheSettings(settings))
689 144 return NULL;
690 std::unique_ptr<PosixCacheManager> cache_mgr(PosixCacheManager::Create(
691 2166 settings.cache_path, settings.is_alien,
692 2166 settings.avoid_rename ? PosixCacheManager::kRenameLink
693 : PosixCacheManager::kRenameNormal,
694
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2166 times.
✓ Branch 3 taken 2166 times.
✗ Branch 4 not taken.
2166 settings.do_refcount, settings.cleanup_unused_first));
695
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2166 times.
2166 if (cache_mgr.get() == nullptr) {
696 ✗ boot_error_ = "Failed to setup posix cache '" + instance + "' in "
697 ✗ + settings.cache_path + ": " + strerror(errno);
698 ✗ boot_status_ = loader::kFailCacheDir;
699 ✗ return NULL;
700 }
701
702 // Sentinel file for future use
703 // Might be a read-only cache
704 2166 const bool ignore_failure = settings.is_alien;
705
2/4
✓ Branch 1 taken 2166 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2166 times.
✗ Branch 5 not taken.
2166 CreateFile(settings.cache_path + "/.cvmfscache", 0600, ignore_failure);
706
707
2/2
✓ Branch 0 taken 1615 times.
✓ Branch 1 taken 551 times.
2166 if (settings.is_managed) {
708
2/4
✓ Branch 2 taken 1615 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1615 times.
1615 if (!SetupPosixQuotaMgr(settings, cache_mgr.get()))
709 ✗ return NULL;
710 }
711 2166 return cache_mgr.release();
712 2310 }
713
714
715 480 CacheManager *FileSystem::SetupRamCacheMgr(const string &instance) {
716 480 string optarg;
717 480 unsigned nfiles = kDefaultNfiles;
718
3/6
✓ Branch 2 taken 480 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 480 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 480 times.
480 if (options_mgr_->GetValue("CVMFS_NFILES", &optarg)) {
719 ✗ nfiles = String2Uint64(optarg);
720 }
721 uint64_t sz_cache_bytes;
722
4/8
✓ Branch 2 taken 480 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 480 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 480 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 480 times.
✗ Branch 14 not taken.
480 if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_SIZE", instance),
723 &optarg)) {
724
3/6
✓ Branch 2 taken 480 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 480 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 480 times.
480 if (HasSuffix(optarg, "%", false)) {
725 ✗ sz_cache_bytes = platform_memsize() * String2Uint64(optarg) / 100;
726 } else {
727
1/2
✓ Branch 1 taken 480 times.
✗ Branch 2 not taken.
480 sz_cache_bytes = String2Uint64(optarg) * 1024 * 1024;
728 }
729 } else {
730 ✗ sz_cache_bytes = platform_memsize() >> 5; // ~3%
731 }
732 480 MemoryKvStore::MemoryAllocator alloc = MemoryKvStore::kMallocHeap;
733
5/8
✓ Branch 2 taken 480 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 480 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 480 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 96 times.
✓ Branch 14 taken 384 times.
480 if (options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_MALLOC", instance),
734 &optarg)) {
735
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 48 times.
96 if (optarg == "libc") {
736 48 alloc = MemoryKvStore::kMallocLibc;
737
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 48 times.
48 } else if (optarg == "heap") {
738 ✗ alloc = MemoryKvStore::kMallocHeap;
739 } else {
740 boot_error_ = "Failure: unknown malloc "
741
4/8
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 48 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 48 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 48 times.
✗ Branch 12 not taken.
96 + MkCacheParm("CVMFS_CACHE_MALLOC", instance) + "="
742
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 + optarg;
743 48 boot_status_ = loader::kFailOptions;
744 48 return NULL;
745 }
746 }
747 432 sz_cache_bytes = RoundUp8(
748 432 std::max(static_cast<uint64_t>(40 * 1024 * 1024), sz_cache_bytes));
749 RamCacheManager *cache_mgr = new RamCacheManager(
750 sz_cache_bytes,
751 nfiles,
752 alloc,
753
4/8
✓ Branch 1 taken 432 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 432 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 432 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 432 times.
✗ Branch 11 not taken.
432 perf::StatisticsTemplate("cache." + instance, statistics_));
754
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 432 times.
432 if (cache_mgr == NULL) {
755 ✗ boot_error_ = "failed to create ram cache manager for " + instance;
756 ✗ boot_status_ = loader::kFailCacheDir;
757 ✗ return NULL;
758 }
759
3/6
✓ Branch 1 taken 432 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 432 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 432 times.
✗ Branch 8 not taken.
432 cache_mgr->AcquireQuotaManager(new NoopQuotaManager());
760 432 return cache_mgr;
761 480 }
762
763
764 384 CacheManager *FileSystem::SetupTieredCacheMgr(const string &instance) {
765 384 string optarg;
766
5/8
✓ Branch 2 taken 384 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 384 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 384 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 48 times.
✓ Branch 14 taken 336 times.
384 if (!options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_UPPER", instance),
767 &optarg)) {
768
3/6
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 48 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 48 times.
✗ Branch 9 not taken.
48 boot_error_ = MkCacheParm("CVMFS_CACHE_UPPER", instance) + " missing";
769 48 boot_status_ = loader::kFailOptions;
770 48 return NULL;
771 }
772
1/2
✓ Branch 1 taken 336 times.
✗ Branch 2 not taken.
336 std::unique_ptr<CacheManager> upper(SetupCacheMgr(optarg));
773
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 336 times.
336 if (upper.get() == nullptr)
774 ✗ return NULL;
775
776
5/8
✓ Branch 2 taken 336 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 336 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 336 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 48 times.
✓ Branch 14 taken 288 times.
336 if (!options_mgr_->GetValue(MkCacheParm("CVMFS_CACHE_LOWER", instance),
777 &optarg)) {
778
3/6
✓ Branch 2 taken 48 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 48 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 48 times.
✗ Branch 9 not taken.
48 boot_error_ = MkCacheParm("CVMFS_CACHE_LOWER", instance) + " missing";
779 48 boot_status_ = loader::kFailOptions;
780 48 return NULL;
781 }
782
1/2
✓ Branch 1 taken 288 times.
✗ Branch 2 not taken.
288 std::unique_ptr<CacheManager> lower(SetupCacheMgr(optarg));
783
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 240 times.
288 if (lower.get() == nullptr)
784 48 return NULL;
785
786
1/2
✓ Branch 3 taken 240 times.
✗ Branch 4 not taken.
240 CacheManager *tiered = TieredCacheManager::Create(upper.release(),
787 lower.release());
788
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 240 times.
240 if (tiered == NULL) {
789 ✗ boot_error_ = "Failed to setup tiered cache manager " + instance;
790 ✗ boot_status_ = loader::kFailCacheDir;
791 ✗ return NULL;
792 }
793 960 if (options_mgr_->GetValue(
794
5/16
✓ Branch 1 taken 240 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 240 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 240 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 240 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 240 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
480 MkCacheParm("CVMFS_CACHE_LOWER_READONLY", instance), &optarg)
795
3/10
✓ Branch 2 taken 240 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 240 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 240 times.
✗ Branch 12 not taken.
480 && options_mgr_->IsOn(optarg)) {
796 ✗ static_cast<TieredCacheManager *>(tiered)->SetLowerReadOnly();
797 }
798 240 return tiered;
799 384 }
800
801
802 2694 bool FileSystem::SetupCrashGuard() {
803
2/4
✓ Branch 1 taken 2694 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2694 times.
✗ Branch 5 not taken.
2694 path_crash_guard_ = workspace_ + "/running." + name_;
804 platform_stat64 info;
805 2694 int retval = platform_stat(path_crash_guard_.c_str(), &info);
806
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 2646 times.
2694 if (retval == 0) {
807 48 found_previous_crash_ = true;
808
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogWarn,
809 "looks like cvmfs has been crashed previously");
810 }
811
1/2
✓ Branch 2 taken 2694 times.
✗ Branch 3 not taken.
2694 retval = open(path_crash_guard_.c_str(), O_RDONLY | O_CREAT, 0600);
812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2694 times.
2694 if (retval < 0) {
813 ✗ boot_error_ = "could not open running sentinel (" + StringifyInt(errno)
814 ✗ + ")";
815 ✗ boot_status_ = loader::kFailCacheDir;
816 ✗ return false;
817 }
818
1/2
✓ Branch 1 taken 2694 times.
✗ Branch 2 not taken.
2694 close(retval);
819 2694 return true;
820 }
821
822
823 2694 bool FileSystem::SetupCwd() {
824
2/2
✓ Branch 0 taken 2431 times.
✓ Branch 1 taken 263 times.
2694 if (type_ == kFsFuse) {
825 // Try to jump to workspace / cache directory. This tests, if it is
826 // accessible and it brings speed later on.
827 2431 const int retval = chdir(workspace_.c_str());
828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2431 times.
2431 if (retval != 0) {
829 ✗ boot_error_ = "workspace " + workspace_ + " is unavailable";
830 ✗ boot_status_ = loader::kFailCacheDir;
831 ✗ return false;
832 }
833 2431 workspace_ = ".";
834 2431 return true;
835 }
836
837 // Note: as of version 2.4 support for CVMFS_CWD_CACHE is dropped due to
838 // disproportionate large complexity to configure correctly. This affects
839 // only libcvmfs, mostly the legacy part.
840 // string optarg;
841 // if (options_mgr_->GetValue("CVMFS_CWD_CACHE", &optarg) &&
842 // options_mgr_->IsOn(optarg))
843 // {
844 // ...
845 // }
846 263 return true;
847 }
848
849
850 2752 void FileSystem::SetupLoggingStandalone(const OptionsManager &options_mgr,
851 const std::string &prefix) {
852 2752 string optarg;
853
4/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 84 times.
✓ Branch 10 taken 2668 times.
2752 if (options_mgr.GetValue("CVMFS_SYSLOG_LEVEL", &optarg))
854
2/4
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 84 times.
✗ Branch 5 not taken.
84 SetLogSyslogLevel(String2Uint64(optarg));
855
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 2752 times.
2752 if (options_mgr.GetValue("CVMFS_SYSLOG_FACILITY", &optarg))
856 ✗ SetLogSyslogFacility(String2Int64(optarg));
857
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 2752 times.
2752 if (options_mgr.GetValue("CVMFS_USYSLOG", &optarg))
858 ✗ SetLogMicroSyslog(optarg);
859
3/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 2752 times.
2752 if (options_mgr.GetValue("CVMFS_DEBUGLOG", &optarg))
860 ✗ SetLogDebugFile(optarg);
861
4/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 20 times.
✓ Branch 10 taken 2732 times.
2752 if (options_mgr.GetValue("CVMFS_SYSLOG_PREFIX", &optarg)) {
862
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 SetLogSyslogPrefix(optarg);
863 } else {
864
1/2
✓ Branch 1 taken 2732 times.
✗ Branch 2 not taken.
2732 SetLogSyslogPrefix(prefix);
865 }
866 2752 }
867
868
869 2752 void FileSystem::SetupLogging() {
870 2752 SetupLoggingStandalone(*options_mgr_, name_);
871 2752 }
872
873
874 2262 bool FileSystem::SetupNfsMaps() {
875 #ifdef CVMFS_NFS_SUPPORT
876 ✗ if (!IsHaNfsSource())
877 ✗ nfs_maps_dir_ = workspace_;
878
879 ✗ string no_nfs_sentinel;
880 ✗ if (cache_mgr_->id() == kPosixCacheManager) {
881 ✗ PosixCacheManager *posix_cache_mgr = reinterpret_cast<PosixCacheManager *>(
882 cache_mgr_);
883 ✗ no_nfs_sentinel = posix_cache_mgr->cache_path() + "/no_nfs_maps." + name_;
884 ✗ if (!IsNfsSource()) {
885 // Might be a read-only cache
886 ✗ const bool ignore_failure = posix_cache_mgr->alien_cache();
887 ✗ CreateFile(no_nfs_sentinel, 0600, ignore_failure);
888 ✗ return true;
889 }
890 } else {
891 ✗ if (IsNfsSource()) {
892 ✗ boot_error_ = "NFS source only works with POSIX cache manager.";
893 ✗ boot_status_ = loader::kFailNfsMaps;
894 ✗ return false;
895 }
896 ✗ return true;
897 }
898
899 ✗ assert(cache_mgr_->id() == kPosixCacheManager);
900 ✗ assert(IsNfsSource());
901 #ifdef CVMFS_NFS_FRONTEND
902 // The loopback NFS mount is private to this process and starts with fresh
903 // file handles, so a cache used by non-NFS mounts (e.g. FSKit sharing the
904 // same cache) needs no wipe.
905 if (!no_nfs_sentinel.empty() && FileExists(no_nfs_sentinel)) {
906 LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslog,
907 "removing %s left by a non-NFS mount", no_nfs_sentinel.c_str());
908 unlink(no_nfs_sentinel.c_str());
909 }
910 #endif
911 ✗ if (!no_nfs_sentinel.empty() && FileExists(no_nfs_sentinel)) {
912 boot_error_ = "Cache was used without NFS maps before. "
913 ✗ "It has to be wiped out.";
914 ✗ boot_status_ = loader::kFailNfsMaps;
915 ✗ return false;
916 }
917
918 // nfs maps need to be protected by workspace lock
919 ✗ PosixCacheManager *posix_cache_mgr = reinterpret_cast<PosixCacheManager *>(
920 cache_mgr_);
921 ✗ if (posix_cache_mgr->cache_path() != workspace_) {
922 boot_error_ = "Cache directory and workspace must be identical for "
923 ✗ "NFS export";
924 ✗ boot_status_ = loader::kFailNfsMaps;
925 ✗ return false;
926 }
927
928 ✗ const string inode_cache_dir = nfs_maps_dir_ + "/nfs_maps." + name_;
929 ✗ if (!MkdirDeep(inode_cache_dir, 0700)) {
930 ✗ boot_error_ = "Failed to initialize NFS maps";
931 ✗ boot_status_ = loader::kFailNfsMaps;
932 ✗ return false;
933 }
934
935 // TODO(jblomer): make this a manager class
936 ✗ if (IsHaNfsSource()) {
937 ✗ nfs_maps_ = NfsMapsSqlite::Create(
938 inode_cache_dir,
939 catalog::ClientCatalogManager::kInodeOffset + 1,
940 ✗ found_previous_crash_,
941 statistics_);
942 } else {
943 ✗ nfs_maps_ = NfsMapsLeveldb::Create(
944 inode_cache_dir,
945 catalog::ClientCatalogManager::kInodeOffset + 1,
946 ✗ found_previous_crash_,
947 statistics_);
948 }
949
950 ✗ if (nfs_maps_ == NULL) {
951 ✗ boot_error_ = "Failed to initialize NFS maps";
952 ✗ boot_status_ = loader::kFailNfsMaps;
953 ✗ return false;
954 }
955
956 ✗ string optarg;
957 ✗ if (options_mgr_->GetValue("CVMFS_NFS_INTERLEAVED_INODES", &optarg)) {
958 ✗ vector<string> tokens = SplitString(optarg, '%');
959 ✗ if (tokens.size() != 2) {
960 boot_error_ = "invalid format for CVMFS_NFS_INTERLEAVED_INODES: "
961 ✗ + optarg;
962 ✗ boot_status_ = loader::kFailNfsMaps;
963 ✗ return false;
964 }
965 ✗ nfs_maps_->SetInodeResidue(String2Uint64(tokens[1]),
966 ✗ String2Uint64(tokens[0]));
967 }
968
969 ✗ return true;
970
971 #else
972 2262 return true;
973 #endif
974 }
975
976
977 1615 bool FileSystem::SetupPosixQuotaMgr(
978 const FileSystem::PosixCacheSettings &settings, CacheManager *cache_mgr) {
979
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1615 times.
1615 assert(settings.quota_limit >= 0);
980 1615 const int64_t quota_threshold = settings.quota_limit / 2;
981
1/2
✓ Branch 1 taken 1615 times.
✗ Branch 2 not taken.
1615 string cache_workspace = settings.cache_path;
982
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1615 times.
1615 if (settings.cache_path != settings.workspace) {
983 ✗ LogCvmfs(kLogQuota, kLogDebug | kLogSyslog,
984 "using workspace %s to protect cache database in %s",
985 settings.workspace.c_str(), settings.cache_path.c_str());
986 ✗ cache_workspace += ":" + settings.workspace;
987 }
988 PosixQuotaManager *quota_mgr;
989
990
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1615 times.
1615 if (settings.is_shared) {
991 ✗ quota_mgr = PosixQuotaManager::CreateShared(exe_path_,
992 cache_workspace,
993 ✗ settings.quota_limit,
994 quota_threshold,
995 ✗ foreground_);
996 ✗ if (quota_mgr == NULL) {
997 ✗ boot_error_ = "Failed to initialize shared lru cache";
998 ✗ boot_status_ = loader::kFailQuota;
999 ✗ return false;
1000 }
1001 } else {
1002 3230 quota_mgr = PosixQuotaManager::Create(cache_workspace,
1003 1615 settings.quota_limit,
1004 quota_threshold,
1005
1/2
✓ Branch 1 taken 1615 times.
✗ Branch 2 not taken.
1615 found_previous_crash_);
1006
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1615 times.
1615 if (quota_mgr == NULL) {
1007 ✗ boot_error_ = "Failed to initialize lru cache";
1008 ✗ boot_status_ = loader::kFailQuota;
1009 ✗ return false;
1010 }
1011 }
1012
1013
3/6
✓ Branch 1 taken 1615 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1615 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1615 times.
1615 if (quota_mgr->GetSize() > quota_mgr->GetCapacity()) {
1014 ✗ LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslog,
1015 "cache is already beyond quota size "
1016 "(size: %" PRId64 ", capacity: %" PRId64 "), cleaning up",
1017 ✗ quota_mgr->GetSize(), quota_mgr->GetCapacity());
1018 ✗ if (!quota_mgr->Cleanup(quota_threshold)) {
1019 ✗ delete quota_mgr;
1020 ✗ boot_error_ = "Failed to clean up cache";
1021 ✗ boot_status_ = loader::kFailQuota;
1022 ✗ return false;
1023 }
1024 }
1025
1/2
✓ Branch 1 taken 1615 times.
✗ Branch 2 not taken.
1615 quota_mgr->SetCleanupPolicy(settings.cleanup_unused_first);
1026
1027
1/2
✓ Branch 1 taken 1615 times.
✗ Branch 2 not taken.
1615 const int retval = cache_mgr->AcquireQuotaManager(quota_mgr);
1028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1615 times.
1615 assert(retval);
1029 1615 LogCvmfs(kLogCvmfs, kLogDebug,
1030 "CernVM-FS: quota initialized, current size %luMB",
1031
2/4
✓ Branch 1 taken 1615 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1615 times.
✗ Branch 5 not taken.
1615 quota_mgr->GetSize() / (1024 * 1024));
1032 1615 return true;
1033 1615 }
1034
1035
1036 2752 void FileSystem::SetupSqlite() {
1037 // Make sure SQlite starts clean after initialization
1038 2752 sqlite3_shutdown();
1039
1040 int retval;
1041 2752 retval = sqlite3_config(SQLITE_CONFIG_LOG, FileSystem::LogSqliteError, NULL);
1042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2752 times.
2752 assert(retval == SQLITE_OK);
1043 2752 retval = sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
1044
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2752 times.
2752 assert(retval == SQLITE_OK);
1045 2752 SqliteMemoryManager::GetInstance()->AssignGlobalArenas();
1046
1047 // Disable SQlite3 file locking
1048 2752 retval = sqlite3_vfs_register(sqlite3_vfs_find("unix-none"), 1);
1049
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2752 times.
2752 assert(retval == SQLITE_OK);
1050 2752 }
1051
1052
1053 /**
1054 * Describes why MkdirDeep() failed for path. Must be called immediately after
1055 * the failure, before errno is clobbered. MkdirDeep() reports EEXIST both for
1056 * a path that is already a directory (not a failure) and for a path that is
1057 * taken by a non-directory, so spell out the latter instead of printing the
1058 * confusing "File exists".
1059 */
1060 9 static string DescribeMkdirFailure(const string &path) {
1061 9 const int saved_errno = errno;
1062 platform_stat64 info;
1063
2/6
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 9 times.
9 if ((platform_stat(path.c_str(), &info) == 0) && !S_ISDIR(info.st_mode))
1064 ✗ return path + " exists but is not a directory";
1065
3/6
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 9 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 9 times.
✗ Branch 9 not taken.
18 return path + " (" + strerror(saved_errno) + ")";
1066 }
1067
1068
1069 2752 bool FileSystem::SetupWorkspace() {
1070 2752 string optarg;
1071 // This is very similar to "determine cache dir". It's for backward
1072 // compatibility with classic cache configuration where there was no
1073 // distinction between workspace and cache.
1074 // Complicated cache configurations should explicitly set CVMFS_WORKSPACE.
1075
1/2
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
2752 workspace_ = kDefaultCacheBase;
1076
4/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 2528 times.
✓ Branch 10 taken 224 times.
2752 if (options_mgr_->GetValue("CVMFS_CACHE_BASE", &optarg))
1077
1/2
✓ Branch 1 taken 2528 times.
✗ Branch 2 not taken.
2528 workspace_ = MakeCanonicalPath(optarg);
1078
4/10
✓ Branch 1 taken 2752 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2752 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 96 times.
✓ Branch 8 taken 2656 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5504 if (options_mgr_->GetValue("CVMFS_SHARED_CACHE", &optarg)
1079
7/10
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2240 times.
✓ Branch 5 taken 512 times.
✓ Branch 7 taken 2240 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 96 times.
✓ Branch 10 taken 2144 times.
✓ Branch 11 taken 2752 times.
✗ Branch 12 not taken.
5504 && options_mgr_->IsOn(optarg)) {
1080
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 workspace_ += "/shared";
1081 } else {
1082
2/4
✓ Branch 1 taken 2656 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2656 times.
✗ Branch 5 not taken.
2656 workspace_ += "/" + name_;
1083 }
1084
4/6
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2752 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 272 times.
✓ Branch 10 taken 2480 times.
2752 if (options_mgr_->GetValue("CVMFS_CACHE_DIR", &optarg)) {
1085
4/6
✓ Branch 2 taken 272 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 272 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 48 times.
✓ Branch 10 taken 224 times.
272 if (options_mgr_->IsDefined("CVMFS_CACHE_BASE")) {
1086 boot_error_ = "'CVMFS_CACHE_BASE' and 'CVMFS_CACHE_DIR' are mutually "
1087
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 "exclusive";
1088 48 boot_status_ = loader::kFailOptions;
1089 48 return false;
1090 }
1091
1/2
✓ Branch 1 taken 224 times.
✗ Branch 2 not taken.
224 workspace_ = optarg;
1092 }
1093
4/6
✓ Branch 2 taken 2704 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2704 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 58 times.
✓ Branch 10 taken 2646 times.
2704 if (options_mgr_->GetValue("CVMFS_WORKSPACE", &optarg))
1094
1/2
✓ Branch 1 taken 58 times.
✗ Branch 2 not taken.
58 workspace_ = optarg;
1095
1/2
✓ Branch 1 taken 2704 times.
✗ Branch 2 not taken.
2704 workspace_fullpath_ = workspace_;
1096
1097 // If workspace and alien cache are the same directory, we need to open
1098 // permission now to 0770 to avoid a race when fixing it later
1099 2704 const int mode = 0770;
1100
3/4
✓ Branch 1 taken 2704 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 2695 times.
2704 if (!MkdirDeep(workspace_, mode, false)) {
1101 boot_error_ = "cannot create workspace directory "
1102
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 + DescribeMkdirFailure(workspace_);
1103 9 boot_status_ = loader::kFailCacheDir;
1104 9 return false;
1105 }
1106
1107
3/4
✓ Branch 1 taken 2695 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 2694 times.
2695 if (!LockWorkspace())
1108 1 return false;
1109
2/4
✓ Branch 1 taken 2694 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2694 times.
2694 if (!SetupCwd())
1110 ✗ return false;
1111
2/4
✓ Branch 1 taken 2694 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2694 times.
2694 if (!SetupCrashGuard())
1112 ✗ return false;
1113
1114 2694 return true;
1115 2752 }
1116
1117
1118 2262 void FileSystem::SetupUuid() {
1119
1/2
✓ Branch 2 taken 2262 times.
✗ Branch 3 not taken.
2262 uuid_cache_ = cvmfs::Uuid::Create(workspace_ + "/uuid");
1120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2262 times.
2262 if (uuid_cache_ == NULL) {
1121 ✗ LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogWarn,
1122 "failed to load/store %s/uuid", workspace_.c_str());
1123 ✗ uuid_cache_ = cvmfs::Uuid::Create("");
1124 ✗ assert(uuid_cache_ != NULL);
1125 }
1126 2262 }
1127
1128
1129 /**
1130 * Required by CernVM: the fuse module needs to free r/w file descriptor to the
1131 * cache in order to properly unravel the file system stack on shutdown.
1132 */
1133 ✗ void FileSystem::TearDown2ReadOnly() {
1134 ✗ if ((cache_mgr_ != NULL) && (cache_mgr_->id() == kPosixCacheManager)) {
1135 ✗ PosixCacheManager *posix_cache_mgr = reinterpret_cast<PosixCacheManager *>(
1136 cache_mgr_);
1137 ✗ posix_cache_mgr->TearDown2ReadOnly();
1138 }
1139
1140 ✗ unlink(path_crash_guard_.c_str());
1141 ✗ LogCvmfs(kLogCache, kLogSyslog, "switch to read-only cache mode");
1142 ✗ SetLogMicroSyslog("");
1143 }
1144
1145
1146 ✗ void FileSystem::RemapCatalogFd(int from, int to) {
1147 ✗ sqlite::RegisterFdMapping(from, to);
1148 }
1149
1150 ✗ void FileSystem::ReplaceCacheManager(CacheManager *new_cache_mgr) {
1151 ✗ cache_mgr_ = new_cache_mgr;
1152 ✗ sqlite::ReplaceCacheManager(new_cache_mgr);
1153 }
1154
1155
1156 2694 bool FileSystem::TriageCacheMgr() {
1157
1/2
✓ Branch 1 taken 2694 times.
✗ Branch 2 not taken.
2694 cache_mgr_instance_ = kDefaultCacheMgrInstance;
1158 2694 string instance;
1159
4/10
✓ Branch 1 taken 2694 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2694 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 576 times.
✓ Branch 8 taken 2118 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5388 if (options_mgr_->GetValue("CVMFS_CACHE_PRIMARY", &instance)
1160
5/8
✓ Branch 2 taken 2694 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 576 times.
✓ Branch 5 taken 2118 times.
✓ Branch 7 taken 576 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2694 times.
✗ Branch 10 not taken.
5388 && !instance.empty()) {
1161
3/4
✓ Branch 1 taken 576 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 528 times.
576 if (!CheckInstanceName(instance))
1162 48 return false;
1163
1/2
✓ Branch 1 taken 528 times.
✗ Branch 2 not taken.
528 cache_mgr_instance_ = instance;
1164 }
1165
1166
1/2
✓ Branch 1 taken 2646 times.
✗ Branch 2 not taken.
2646 cache_mgr_ = SetupCacheMgr(cache_mgr_instance_);
1167
2/2
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 2262 times.
2646 if (cache_mgr_ == NULL)
1168 384 return false;
1169
1170 2262 std::string optarg;
1171
3/10
✓ Branch 1 taken 2262 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2262 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2262 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
4524 if (options_mgr_->GetValue("CVMFS_STREAMING_CACHE", &optarg)
1172
3/10
✓ Branch 2 taken 2262 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2262 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2262 times.
✗ Branch 12 not taken.
4524 && options_mgr_->IsOn(optarg)) {
1173 ✗ unsigned nfiles = kDefaultNfiles;
1174 ✗ if (options_mgr_->GetValue("CVMFS_NFILES", &optarg))
1175 ✗ nfiles = String2Uint64(optarg);
1176 ✗ size_t buffer_size = StreamingCacheManager::kDefaultBufferSize;
1177 ✗ if (options_mgr_->GetValue("CVMFS_STREAMING_CACHE_BUFFER_SIZE", &optarg))
1178 ✗ buffer_size = String2Uint64(optarg);
1179 ✗ cache_mgr_ = new StreamingCacheManager(nfiles, cache_mgr_, NULL, NULL,
1180 ✗ buffer_size, statistics_);
1181 }
1182
1183 2262 return true;
1184 2694 }
1185
1186
1187 //------------------------------------------------------------------------------
1188
1189
1190 const char *MountPoint::kDefaultAuthzSearchPath = "/usr/libexec/cvmfs/authz";
1191 const char *MountPoint::kDefaultBlacklist = "/etc/cvmfs/blacklist";
1192
1193 1592 bool MountPoint::CheckBlacklists() {
1194 1592 blacklist_paths_.clear();
1195 1592 string blacklist;
1196
4/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1496 times.
✓ Branch 10 taken 96 times.
1592 if (!options_mgr_->GetValue("CVMFS_BLACKLIST", &blacklist))
1197
1/2
✓ Branch 1 taken 1496 times.
✗ Branch 2 not taken.
1496 blacklist = kDefaultBlacklist;
1198
1/2
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
1592 blacklist_paths_.push_back(blacklist);
1199
1200 1592 bool append = false;
1201
3/4
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 1544 times.
1592 if (FileExists(blacklist)) {
1202
2/4
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 48 times.
48 if (!signature_mgr_->LoadBlacklist(blacklist, append)) {
1203 ✗ boot_error_ = "failed to load blacklist " + blacklist;
1204 ✗ boot_status_ = loader::kFailSignature;
1205 ✗ return false;
1206 }
1207 48 append = true;
1208 }
1209
1210 1592 string config_repository_path;
1211
3/4
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 144 times.
✓ Branch 4 taken 1448 times.
1592 if (options_mgr_->HasConfigRepository(fqrn_, &config_repository_path)) {
1212
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
144 blacklist = config_repository_path + "blacklist";
1213
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
144 blacklist_paths_.push_back(blacklist);
1214
3/4
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
✓ Branch 4 taken 48 times.
144 if (FileExists(blacklist)) {
1215
2/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 96 times.
96 if (!signature_mgr_->LoadBlacklist(blacklist, append)) {
1216 ✗ boot_error_ = "failed to load blacklist from config repository";
1217 ✗ boot_status_ = loader::kFailSignature;
1218 ✗ return false;
1219 }
1220 }
1221 }
1222
1223 1592 return true;
1224 1592 }
1225
1226
1227 /**
1228 * Like CheckBlacklists but supposed to be used after bootstrap, possibly in
1229 * multi-threaded context.
1230 */
1231 96 bool MountPoint::ReloadBlacklists() {
1232 96 const bool result = true;
1233 96 bool append = false;
1234
2/2
✓ Branch 1 taken 144 times.
✓ Branch 2 taken 96 times.
240 for (unsigned i = 0; i < blacklist_paths_.size(); ++i) {
1235
1/2
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
144 const string blacklist = blacklist_paths_[i];
1236
2/4
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 144 times.
144 if (FileExists(blacklist)) {
1237 ✗ const bool retval = signature_mgr_->LoadBlacklist(blacklist, append);
1238 // TODO(jblomer): this can leave us with a half-loaded blacklist
1239 ✗ if (!retval)
1240 ✗ return false;
1241 ✗ append = true;
1242 }
1243
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
144 }
1244 96 return result;
1245 }
1246
1247 /**
1248 * Disables kernel caching of symlinks.
1249 * Symlink caching requires fuse >= 3.10 (FUSE_CAP_CACHE_SYMLINKS) and
1250 * linux kernel >= 4.2. Some OS might backport it.
1251 *
1252 * NOTE: This function should only be called before or within cvmfs_init().
1253 *
1254 */
1255 ✗ void MountPoint::DisableCacheSymlinks() { cache_symlinks_ = false; }
1256
1257 /**
1258 * Instead of invalidate dentries, they should be expired.
1259 * Fixes issues with mount-on-top mounts and symlink caching.
1260 */
1261 ✗ void MountPoint::EnableFuseExpireEntry() { fuse_expire_entry_ = true; }
1262
1263
1264 /**
1265 * The option_mgr parameter can be NULL, in which case the global option manager
1266 * from the file system is used.
1267 */
1268 1640 MountPoint *MountPoint::Create(const string &fqrn,
1269 FileSystem *file_system,
1270 OptionsManager *options_mgr) {
1271
2/2
✓ Branch 0 taken 1422 times.
✓ Branch 1 taken 218 times.
1640 if (options_mgr == NULL)
1272 1422 options_mgr = file_system->options_mgr();
1273 std::unique_ptr<MountPoint> mountpoint(
1274
2/4
✓ Branch 1 taken 1640 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1640 times.
✗ Branch 5 not taken.
1640 new MountPoint(fqrn, file_system, options_mgr));
1275
1276 // At this point, we have a repository name, the type (fuse or library) and
1277 // an options manager (which can be the same than the FileSystem's one).
1278
1279
1/2
✓ Branch 2 taken 1640 times.
✗ Branch 3 not taken.
1640 mountpoint->CreateStatistics();
1280
1/2
✓ Branch 2 taken 1640 times.
✗ Branch 3 not taken.
1640 mountpoint->CreateAuthz();
1281
2/4
✓ Branch 1 taken 1640 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1640 times.
✗ Branch 5 not taken.
1640 mountpoint->backoff_throttle_ = new BackoffThrottle();
1282
1283
7/10
✓ Branch 2 taken 1640 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1592 times.
✓ Branch 5 taken 48 times.
✓ Branch 8 taken 1592 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1592 times.
✓ Branch 12 taken 48 times.
✓ Branch 13 taken 1592 times.
1640 if (!mountpoint->CreateSignatureManager() || !mountpoint->CheckBlacklists())
1284 48 return mountpoint.release();
1285
3/4
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 414 times.
✓ Branch 5 taken 1178 times.
1592 if (!mountpoint->CreateDownloadManagers())
1286 414 return mountpoint.release();
1287
2/4
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1178 times.
1178 if (file_system->cache_mgr()->id() == kStreamingCacheManager) {
1288 StreamingCacheManager
1289 ✗ *streaming_cachemgr = dynamic_cast<StreamingCacheManager *>(
1290 ✗ file_system->cache_mgr());
1291 ✗ streaming_cachemgr->SetRegularDownloadManager(mountpoint->download_mgr());
1292 ✗ streaming_cachemgr->SetExternalDownloadManager(
1293 mountpoint->external_download_mgr());
1294 }
1295
2/4
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1178 times.
1178 if (!mountpoint->CreateResolvConfWatcher()) {
1296 ✗ return mountpoint.release();
1297 }
1298
1/2
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
1178 mountpoint->CreateFetchers();
1299
1/2
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
1178 mountpoint->SetupPartialReplica();
1300
3/4
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 354 times.
✓ Branch 5 taken 824 times.
1178 if (!mountpoint->CreateCatalogManager())
1301 354 return mountpoint.release();
1302
2/4
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 824 times.
824 if (!mountpoint->CreateTracer())
1303 ✗ return mountpoint.release();
1304
1305
1/2
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
824 mountpoint->ReEvaluateAuthz();
1306
1/2
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
824 mountpoint->CreateTables();
1307
2/4
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 824 times.
824 if (!mountpoint->SetupBehavior())
1308 ✗ return mountpoint.release();
1309
1/2
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
824 mountpoint->CreateBundleMgr();
1310
1311 824 mountpoint->boot_status_ = loader::kFailOk;
1312 824 return mountpoint.release();
1313 1640 }
1314
1315
1316 1640 void MountPoint::CreateAuthz() {
1317 1640 string optarg;
1318 1640 string authz_helper;
1319
3/6
✓ Branch 2 taken 1640 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1640 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1640 times.
1640 if (options_mgr_->GetValue("CVMFS_AUTHZ_HELPER", &optarg))
1320 ✗ authz_helper = optarg;
1321
1/2
✓ Branch 2 taken 1640 times.
✗ Branch 3 not taken.
1640 string authz_search_path(kDefaultAuthzSearchPath);
1322
3/6
✓ Branch 2 taken 1640 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1640 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1640 times.
1640 if (options_mgr_->GetValue("CVMFS_AUTHZ_SEARCH_PATH", &optarg))
1323 ✗ authz_search_path = optarg;
1324
1325 3280 authz_fetcher_ = new AuthzExternalFetcher(fqrn_, authz_helper,
1326
2/4
✓ Branch 1 taken 1640 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1640 times.
✗ Branch 5 not taken.
1640 authz_search_path, options_mgr_);
1327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1640 times.
1640 assert(authz_fetcher_ != NULL);
1328
1329
1/2
✓ Branch 1 taken 1640 times.
✗ Branch 2 not taken.
1640 authz_session_mgr_ = AuthzSessionManager::Create(authz_fetcher_, statistics_);
1330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1640 times.
1640 assert(authz_session_mgr_ != NULL);
1331
1332
2/4
✓ Branch 1 taken 1640 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1640 times.
✗ Branch 5 not taken.
1640 authz_attachment_ = new AuthzAttachment(authz_session_mgr_);
1333
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1640 times.
1640 assert(authz_attachment_ != NULL);
1334 1640 }
1335
1336
1337 824 void MountPoint::CreateBundleMgr() {
1338 824 std::string optarg;
1339
3/10
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 824 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 824 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1648 if (options_mgr_->GetValue("CVMFS_PREFETCH_FILEBUNDLES", &optarg)
1340
3/10
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 824 times.
✗ Branch 12 not taken.
1648 && options_mgr_->IsOn(optarg)) {
1341 ✗ bundle_mgr_ = new BundleMgr(this);
1342 }
1343 824 }
1344
1345
1346 1178 bool MountPoint::CreateCatalogManager() {
1347 1178 string optarg;
1348
1349
2/4
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1178 times.
✗ Branch 5 not taken.
1178 catalog_mgr_ = new catalog::ClientCatalogManager(this);
1350
1351
1/2
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
1178 SetupInodeAnnotation();
1352
3/4
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 1130 times.
1178 if (!SetupOwnerMaps())
1353 48 return false;
1354
1/2
✓ Branch 1 taken 1130 times.
✗ Branch 2 not taken.
1130 shash::Any root_hash;
1355
3/4
✓ Branch 1 taken 1130 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
✓ Branch 4 taken 1034 times.
1130 if (!DetermineRootHash(&root_hash))
1356 96 return false;
1357
1358 bool retval;
1359
2/2
✓ Branch 1 taken 547 times.
✓ Branch 2 taken 487 times.
1034 if (root_hash.IsNull()) {
1360
1/2
✓ Branch 1 taken 547 times.
✗ Branch 2 not taken.
547 retval = catalog_mgr_->Init();
1361 } else {
1362 487 fixed_catalog_ = true;
1363
2/8
✓ Branch 1 taken 487 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 487 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
974 const bool alt_root_path = options_mgr_->GetValue("CVMFS_ALT_ROOT_PATH",
1364 &optarg)
1365
3/10
✓ Branch 2 taken 487 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 487 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 487 times.
✗ Branch 12 not taken.
974 && options_mgr_->IsOn(optarg);
1366
1/2
✓ Branch 1 taken 487 times.
✗ Branch 2 not taken.
487 retval = catalog_mgr_->InitFixed(root_hash, alt_root_path);
1367 }
1368
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 872 times.
1034 if (!retval) {
1369
1/2
✓ Branch 1 taken 162 times.
✗ Branch 2 not taken.
162 boot_error_ = "Failed to initialize root file catalog";
1370 162 boot_status_ = loader::kFailCatalog;
1371 162 return false;
1372 }
1373
1374
3/4
✓ Branch 1 taken 872 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 824 times.
872 if (catalog_mgr_->IsRevisionBlacklisted()) {
1375
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 boot_error_ = "repository revision blacklisted";
1376 48 boot_status_ = loader::kFailRevisionBlacklisted;
1377 48 return false;
1378 }
1379
1380
3/10
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 824 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 824 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1648 if (options_mgr_->GetValue("CVMFS_AUTO_UPDATE", &optarg)
1381
3/10
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 824 times.
✗ Branch 12 not taken.
1648 && !options_mgr_->IsOn(optarg)) {
1382 ✗ fixed_catalog_ = true;
1383 }
1384
1385
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_CATALOG_WATERMARK", &optarg)) {
1386 ✗ catalog_mgr_->SetCatalogWatermark(String2Uint64(optarg));
1387 } else {
1388 unsigned soft_limit;
1389 unsigned hard_limit;
1390
1/2
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
824 GetLimitNoFile(&soft_limit, &hard_limit);
1391 824 catalog_mgr_->SetCatalogWatermark(soft_limit / 4);
1392 }
1393
1394
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 824 times.
824 if (catalog_mgr_->volatile_flag()) {
1395 ✗ LogCvmfs(kLogCvmfs, kLogDebug, "content of repository flagged as VOLATILE");
1396 }
1397
1398 824 return true;
1399 1178 }
1400
1401
1402 1592 bool MountPoint::CreateDownloadManagers() {
1403 1592 string optarg;
1404
1/2
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
3184 download_mgr_ = new download::DownloadManager(
1405 kDefaultNumConnections,
1406
4/8
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1592 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1592 times.
✗ Branch 13 not taken.
4776 perf::StatisticsTemplate("download", statistics_));
1407
1/2
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
1592 download_mgr_->SetCredentialsAttachment(authz_attachment_);
1408
1409 // must be set before proxy and host chains are being initialized
1410 // error output is handled in SetShardingPolicy
1411
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_PROXY_SHARDING_POLICY", &optarg)) {
1412 ✗ if (optarg.compare("EXTERNAL") == 0) {
1413 ✗ download_mgr_->SetShardingPolicy(download::kShardingPolicyExternal);
1414 ✗ download_mgr_->SetFqrn(fqrn());
1415 }
1416 }
1417
1418
3/10
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1592 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1592 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3184 if (options_mgr_->GetValue("CVMFS_FAILOVER_INDEFINITELY", &optarg)
1419
3/10
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1592 times.
✗ Branch 12 not taken.
3184 && options_mgr_->IsOn(optarg)) {
1420 ✗ download_mgr_->SetFailoverIndefinitely();
1421 }
1422
1423
6/18
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1592 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1592 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1592 times.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1592 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
1592 if (options_mgr_->GetValue("CVMFS_METALINK_URL", &optarg) && (optarg != "")) {
1424 ✗ download_mgr_->SetMetalinkChain(optarg);
1425 // host chain will be set later when the metalink server is contacted
1426 ✗ download_mgr_->SetHostChain("");
1427 // metalink requires redirects
1428 ✗ download_mgr_->EnableRedirects();
1429
4/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1226 times.
✓ Branch 10 taken 366 times.
1592 } else if (options_mgr_->GetValue("CVMFS_SERVER_URL", &optarg)) {
1430
1/2
✓ Branch 1 taken 1226 times.
✗ Branch 2 not taken.
1226 download_mgr_->SetHostChain(optarg);
1431 }
1432
1433
3/10
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1592 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1592 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3184 if (options_mgr_->GetValue("_CVMFS_DEVEL_IGNORE_SIGNATURE_FAILURES", &optarg)
1434
3/10
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1592 times.
✗ Branch 12 not taken.
3184 && options_mgr_->IsOn(optarg)) {
1435 ✗ download_mgr_->EnableIgnoreSignatureFailures();
1436 ✗ LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogWarn,
1437 "Development option: Activate ignore signature failures during "
1438 "download. "
1439 "DO NOT USE IN PRODUCTION");
1440 }
1441
1442
1/2
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
1592 SetupDnsTuning(download_mgr_);
1443
1/2
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
1592 SetupHttpTuning();
1444
1445 1592 string forced_proxy_template;
1446
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_PROXY_TEMPLATE", &optarg))
1447 ✗ forced_proxy_template = optarg;
1448
2/4
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
1592 download_mgr_->SetProxyTemplates(file_system_->uuid_cache()->uuid(),
1449 forced_proxy_template);
1450
1451 1592 string proxies;
1452
4/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1178 times.
✓ Branch 10 taken 414 times.
1592 if (options_mgr_->GetValue("CVMFS_HTTP_PROXY", &optarg))
1453
1/2
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
1178 proxies = optarg;
1454
1/2
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
3184 proxies = download::ResolveProxyDescription(
1455 proxies,
1456
4/8
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1592 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1592 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1592 times.
✗ Branch 11 not taken.
3184 file_system_->workspace() + "/proxies" + GetUniqFileSuffix(),
1457 1592 download_mgr_);
1458
2/2
✓ Branch 1 taken 414 times.
✓ Branch 2 taken 1178 times.
1592 if (proxies == "") {
1459
1/2
✓ Branch 1 taken 414 times.
✗ Branch 2 not taken.
414 boot_error_ = "failed to discover HTTP proxy servers";
1460 414 boot_status_ = loader::kFailWpad;
1461 414 return false;
1462 }
1463 1178 string fallback_proxies;
1464
3/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1178 times.
1178 if (options_mgr_->GetValue("CVMFS_FALLBACK_PROXY", &optarg))
1465 ✗ fallback_proxies = optarg;
1466
1/2
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
1178 download_mgr_->SetProxyChain(proxies, fallback_proxies,
1467 download::DownloadManager::kSetProxyBoth);
1468
1469
2/8
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1178 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2356 const bool do_geosort = options_mgr_->GetValue("CVMFS_USE_GEOAPI", &optarg)
1470
3/10
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1178 times.
✗ Branch 12 not taken.
2356 && options_mgr_->IsOn(optarg);
1471
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1178 times.
1178 if (do_geosort) {
1472 ✗ download_mgr_->ProbeGeo();
1473 }
1474
4/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 192 times.
✓ Branch 10 taken 986 times.
1178 if (options_mgr_->GetValue("CVMFS_MAX_SERVERS", &optarg)) {
1475
1/2
✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
192 const unsigned max_servers = String2Uint64(optarg);
1476 192 std::vector<std::string> host_chain;
1477
1/2
✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
192 download_mgr_->GetHostInfo(&host_chain, NULL, NULL);
1478
6/6
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 48 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 96 times.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 144 times.
192 if (max_servers > 0 && max_servers < host_chain.size()) {
1479
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 host_chain.resize(max_servers);
1480
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 download_mgr_->SetHostChain(host_chain);
1481 }
1482 192 }
1483
1484
3/10
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1178 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1178 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2356 if (options_mgr_->GetValue("CVMFS_USE_SSL_SYSTEM_CA", &optarg)
1485
3/10
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1178 times.
✗ Branch 12 not taken.
2356 && options_mgr_->IsOn(optarg)) {
1486 ✗ download_mgr_->UseSystemCertificatePath();
1487 }
1488
1489
3/10
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1178 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1178 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2356 if (options_mgr_->GetValue("CVMFS_PROXY_SHARD", &optarg)
1490
3/10
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1178 times.
✗ Branch 12 not taken.
2356 && options_mgr_->IsOn(optarg)) {
1491 ✗ download_mgr_->ShardProxies();
1492 }
1493
1494 // configure http tracing header
1495
3/10
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1178 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1178 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2356 if (options_mgr_->GetValue("CVMFS_HTTP_TRACING", &optarg)
1496
3/10
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1178 times.
✗ Branch 12 not taken.
2356 && options_mgr_->IsOn(optarg)) {
1497 ✗ download_mgr_->EnableHTTPTracing();
1498 ✗ if (options_mgr_->GetValue("CVMFS_HTTP_TRACING_HEADERS", &optarg)) {
1499 ✗ if (optarg.size() > 1000) {
1500 ✗ LogCvmfs(kLogCvmfs, kLogSyslogErr | kLogDebug,
1501 "CVMFS_HTTP_TRACING_HEADERS too large ( max 1000 chars, given "
1502 "%ld )",
1503 optarg.size());
1504 } else {
1505 ✗ std::vector<std::string> tokens = SplitString(optarg, '|');
1506 ✗ const sanitizer::AlphaNumSanitizer sanitizer;
1507
1508 ✗ for (unsigned int i = 0; i < tokens.size(); i++) {
1509 ✗ const std::string token = Trim(tokens[i]);
1510
1511 ✗ std::vector<std::string> key_val = SplitString(token, ':');
1512
1513 ✗ if (key_val.size() != 2) {
1514 ✗ LogCvmfs(kLogCvmfs, kLogSyslogErr | kLogDebug,
1515 "Http tracing header: Skipping current token part of "
1516 "CVMFS_HTTP_TRACING_HEADERS! Invalid "
1517 "<key:value> pair. Token: %s",
1518 token.c_str());
1519 ✗ continue;
1520 }
1521
1522 ✗ const std::string prefix = "X-CVMFS-";
1523 ✗ const std::string key = Trim(key_val[0]);
1524
1525 ✗ if (!sanitizer.IsValid(key)) {
1526 ✗ LogCvmfs(kLogCvmfs, kLogSyslogErr | kLogDebug,
1527 "Http tracing header: Skipping current token part of "
1528 "CVMFS_HTTP_TRACING_HEADERS! Invalid key. Only "
1529 "alphanumeric keys "
1530 "are allowed (a-z, A-Z, 0-9). Token: %s",
1531 token.c_str());
1532 ✗ continue;
1533 }
1534
1535 ✗ const std::string final_token = prefix + key + ": "
1536 ✗ + Trim(key_val[1]);
1537
1538 ✗ download_mgr_->AddHTTPTracingHeader(final_token);
1539 }
1540 }
1541 }
1542 }
1543
1544
1/2
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
1178 return SetupExternalDownloadMgr(do_geosort);
1545 1592 }
1546
1547 1178 bool MountPoint::CreateResolvConfWatcher() {
1548 1178 std::string roaming_value;
1549
2/4
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
1178 options_mgr_->GetValue("CVMFS_DNS_ROAMING", &roaming_value);
1550
3/10
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1178 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1178 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2356 if (options_mgr_->IsDefined("CVMFS_DNS_ROAMING")
1551
3/10
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1178 times.
✗ Branch 12 not taken.
2356 && options_mgr_->IsOn(roaming_value)) {
1552 ✗ LogCvmfs(kLogCvmfs, kLogDebug,
1553 "DNS roaming is enabled for this repository.");
1554 // Create a file watcher to update the DNS settings of the download
1555 // managers when there are changes to /etc/resolv.conf
1556 ✗ resolv_conf_watcher_ = file_watcher::FileWatcher::Create();
1557
1558 ✗ if (resolv_conf_watcher_) {
1559 ResolvConfEventHandler *handler = new ResolvConfEventHandler(
1560 ✗ download_mgr_, external_download_mgr_);
1561 ✗ resolv_conf_watcher_->RegisterHandler("/etc/resolv.conf", handler);
1562 }
1563 } else {
1564
1/2
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
1178 LogCvmfs(kLogCvmfs, kLogDebug,
1565 "DNS roaming is disabled for this repository.");
1566 }
1567 1178 return true;
1568 1178 }
1569
1570 1178 void MountPoint::CreateFetchers() {
1571 1178 fetcher_ = new cvmfs::Fetcher(file_system_->cache_mgr(),
1572 download_mgr_,
1573 backoff_throttle_,
1574
4/8
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1178 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1178 times.
✗ Branch 12 not taken.
1178 perf::StatisticsTemplate("fetch", statistics_));
1575
1576 2356 external_fetcher_ = new cvmfs::Fetcher(
1577 1178 file_system_->cache_mgr(),
1578 external_download_mgr_,
1579 backoff_throttle_,
1580
4/8
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1178 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1178 times.
✗ Branch 12 not taken.
1178 perf::StatisticsTemplate("fetch-external", statistics_));
1581 1178 }
1582
1583
1584 /**
1585 * Sets up partial replica handling for the primary Stratum-1. This is opt-in:
1586 * unless CVMFS_PARTIAL_REPLICA_MODE is set, the function returns immediately so
1587 * that regular (full-replica) mounts incur no extra requests. When opted in:
1588 * - Probes for the .cvmfs_partial_replication file on the primary server.
1589 * - Parses the inclusion spec and stores it in partial_inclusion_spec_.
1590 * - Honours CVMFS_PARTIAL_REPLICA_MODE ("failover" [default] or "fail").
1591 * - In failover mode, creates a full_replica_download_mgr_ from
1592 * CVMFS_FULL_STRATUM1_URL and wires it as the fetcher's fallback.
1593 */
1594 1178 void MountPoint::SetupPartialReplica() {
1595 // Partial replica handling is opt-in on the client: only probe for and act
1596 // on a partial Stratum-1 when CVMFS_PARTIAL_REPLICA_MODE is explicitly set.
1597 // Auto-detection would buy nothing (failover still needs
1598 // CVMFS_FULL_STRATUM1_URL, fail mode is a client choice) while taxing every
1599 // regular mount with an extra request.
1600 1178 string mode;
1601
3/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1178 times.
✗ Branch 10 not taken.
1178 if (!options_mgr_->GetValue("CVMFS_PARTIAL_REPLICA_MODE", &mode)) {
1602 1178 return;
1603 }
1604
1605 // Validate the mode before doing any network I/O, so that an off/false/empty
1606 // (or otherwise invalid) value never adds a request to a normal mount. Only
1607 // "fail" and "failover" enable partial replica handling.
1608 ✗ const string mode_norm = ToUpper(Trim(mode));
1609 bool fail_mode;
1610 ✗ if (mode_norm == "FAIL") {
1611 ✗ fail_mode = true;
1612 ✗ } else if (mode_norm == "FAILOVER") {
1613 ✗ fail_mode = false;
1614 } else {
1615 // Disabled (empty/off/false) is silent; anything else is a config error.
1616 ✗ if (!mode_norm.empty() && !options_mgr_->IsOff(mode_norm)) {
1617 ✗ LogCvmfs(kLogCvmfs, kLogSyslogWarn | kLogDebug,
1618 "ignoring invalid CVMFS_PARTIAL_REPLICA_MODE='%s' "
1619 "(expected 'fail' or 'failover')",
1620 mode.c_str());
1621 }
1622 ✗ return;
1623 }
1624
1625 // Get primary server URL from the host chain
1626 ✗ vector<string> host_chain;
1627 ✗ download_mgr_->GetHostInfo(&host_chain, NULL, NULL);
1628 ✗ if (host_chain.empty()) {
1629 ✗ return;
1630 }
1631 ✗ const string primary_url = host_chain[0];
1632
1633 // Probe for the partial replication spec file
1634 ✗ const string spec_url = primary_url + "/.cvmfs_partial_replication";
1635 ✗ cvmfs::MemSink spec_memsink;
1636 ✗ download::JobInfo probe_job(&spec_url, false, false, NULL, &spec_memsink);
1637 ✗ const download::Failures probe_result = download_mgr_->Fetch(&probe_job);
1638
1639 ✗ if (probe_result != download::kFailOk) {
1640 // Not a partial replica (or not reachable — ignore silently)
1641 ✗ LogCvmfs(kLogCvmfs, kLogDebug,
1642 "no .cvmfs_partial_replication found at %s (result %d)",
1643 primary_url.c_str(), probe_result);
1644 ✗ return;
1645 }
1646
1647 // Parse the spec
1648 ✗ const string spec_content(reinterpret_cast<char *>(spec_memsink.data()),
1649 ✗ spec_memsink.pos());
1650 ✗ partial_inclusion_spec_ = new catalog::InclusionSpec();
1651 ✗ if (!partial_inclusion_spec_->Parse(spec_content)) {
1652 ✗ LogCvmfs(kLogCvmfs, kLogSyslogErr | kLogDebug,
1653 "failed to parse .cvmfs_partial_replication from %s",
1654 primary_url.c_str());
1655 ✗ delete partial_inclusion_spec_;
1656 ✗ partial_inclusion_spec_ = NULL;
1657 ✗ return;
1658 }
1659
1660 ✗ LogCvmfs(kLogCvmfs, kLogSyslog | kLogDebug,
1661 "connected to partial Stratum-1 at %s (spec version %d)",
1662 ✗ primary_url.c_str(), partial_inclusion_spec_->version());
1663
1664 // Apply the mode validated above
1665 ✗ string optarg;
1666 ✗ partial_replica_fail_mode_ = fail_mode;
1667 ✗ if (fail_mode) {
1668 ✗ LogCvmfs(kLogCvmfs, kLogDebug,
1669 "partial replica mode: fail (EIO for missing objects)");
1670 ✗ return; // No full replica manager needed in fail mode
1671 }
1672
1673 // Create the full replica download manager for failover
1674 ✗ if (!options_mgr_->GetValue("CVMFS_FULL_STRATUM1_URL", &optarg)
1675 ✗ || optarg.empty()) {
1676 ✗ LogCvmfs(kLogCvmfs, kLogSyslogWarn | kLogDebug,
1677 "partial replica mode is failover but CVMFS_FULL_STRATUM1_URL "
1678 "is not set; failover disabled");
1679 ✗ return;
1680 }
1681
1682 ✗ LogCvmfs(kLogCvmfs, kLogDebug, "partial replica mode: failover to %s",
1683 optarg.c_str());
1684
1685 // Clone the primary download manager so proxy, DNS, timeout, certificate and
1686 // sharding settings carry over unchanged; only the host chain is repointed at
1687 // the full Stratum-1. This avoids the configuration drift of re-reading a
1688 // hand-picked subset of options.
1689 ✗ full_replica_download_mgr_ = download_mgr_->Clone(
1690 ✗ perf::StatisticsTemplate("download-full-replica", statistics_),
1691 "download-full-replica");
1692 ✗ full_replica_download_mgr_->SetHostChain(optarg);
1693 // Not spawned here: like download_mgr_ and external_download_mgr_, the worker
1694 // thread is started later by the application's Init (cvmfs.cc, after the FUSE
1695 // fork; threads do not survive fork()). libcvmfs leaves it synchronous.
1696
1697 // Wire the full replica into the primary fetcher
1698 ✗ fetcher_->SetFullReplicaDownloadManager(full_replica_download_mgr_);
1699
1/18
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 1178 times.
1178 }
1700
1701
1702 1640 bool MountPoint::CreateSignatureManager() {
1703 1640 string optarg;
1704
2/4
✓ Branch 1 taken 1640 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1640 times.
✗ Branch 5 not taken.
1640 signature_mgr_ = new signature::SignatureManager();
1705
1/2
✓ Branch 1 taken 1640 times.
✗ Branch 2 not taken.
1640 signature_mgr_->Init();
1706
1707 1640 string public_keys;
1708
4/6
✓ Branch 2 taken 1640 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1640 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1256 times.
✓ Branch 10 taken 384 times.
1640 if (options_mgr_->GetValue("CVMFS_PUBLIC_KEY", &optarg)) {
1709
1/2
✓ Branch 1 taken 1256 times.
✗ Branch 2 not taken.
1256 public_keys = optarg;
1710
3/6
✓ Branch 2 taken 384 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 384 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 384 times.
384 } else if (options_mgr_->GetValue("CVMFS_KEYS_DIR", &optarg)) {
1711 // Collect .pub files from CVMFS_KEYS_DIR
1712 ✗ public_keys = JoinStrings(FindFilesBySuffix(optarg, ".pub"), ":");
1713 } else {
1714
5/10
✓ Branch 2 taken 384 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 384 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 384 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 384 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 384 times.
✗ Branch 17 not taken.
768 public_keys = JoinStrings(FindFilesBySuffix("/etc/cvmfs/keys", ".pub"),
1715 384 ":");
1716 }
1717
1718
3/4
✓ Branch 1 taken 1640 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 1592 times.
1640 if (!signature_mgr_->LoadPublicRsaKeys(public_keys)) {
1719
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 boot_error_ = "failed to load public key(s)";
1720 48 boot_status_ = loader::kFailSignature;
1721 48 return false;
1722 }
1723
1724
2/2
✓ Branch 1 taken 1208 times.
✓ Branch 2 taken 384 times.
1592 if (public_keys.size() > 0) {
1725
1/2
✓ Branch 2 taken 1208 times.
✗ Branch 3 not taken.
1208 LogCvmfs(kLogCvmfs, kLogDebug, "CernVM-FS: using public key(s) %s",
1726 public_keys.c_str());
1727 } else {
1728
1/2
✓ Branch 1 taken 384 times.
✗ Branch 2 not taken.
384 LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogWarn, "no public key loaded");
1729 }
1730
1731 1592 return true;
1732 1640 }
1733
1734
1735 1640 void MountPoint::CreateStatistics() {
1736 1640 statistics_ = file_system_->statistics()->Fork();
1737
2/2
✓ Branch 1 taken 74 times.
✓ Branch 2 taken 1566 times.
1640 if (file_system_->type() != FileSystem::kFsFuse)
1738 74 return;
1739
1740 // TODO(jblomer): this should be registered by the tracker
1741
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("inode_tracker.n_insert",
1742 "overall number of accessed inodes");
1743
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("inode_tracker.n_remove",
1744 "overall number of evicted inodes");
1745
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("inode_tracker.no_reference",
1746 "currently active inodes");
1747
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("inode_tracker.n_hit_inode",
1748 "overall number of inode lookups");
1749
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("inode_tracker.n_hit_path",
1750 "overall number of successful path lookups");
1751
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("inode_tracker.n_miss_path",
1752 "overall number of unsuccessful path lookups");
1753
1754
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("dentry_tracker.n_insert",
1755 "overall number of added negative cache entries");
1756
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("dentry_tracker.n_remove",
1757 "overall number of evicted negative cache entries");
1758
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("dentry_tracker.n_prune",
1759 "overall number of prune calls");
1760
1761
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("page_cache_tracker.n_insert",
1762 "overall number of added page cache entries");
1763
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("page_cache_tracker.n_remove",
1764 "overall number of evicted page cache entries");
1765
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register("page_cache_tracker.n_open_direct",
1766 "overall number of direct I/O open calls");
1767
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register(
1768 "page_cache_tracker.n_open_flush",
1769 "overall number of open calls where the file's page cache gets flushed");
1770
3/6
✓ Branch 2 taken 1566 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1566 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1566 times.
✗ Branch 10 not taken.
1566 statistics_->Register(
1771 "page_cache_tracker.n_open_cached",
1772 "overall number of open calls where the file's page cache is reused");
1773 }
1774
1775
1776 824 void MountPoint::CreateTables() {
1777
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 768 times.
824 if (file_system_->type() != FileSystem::kFsFuse) {
1778 // Libcvmfs simplified tables
1779
2/4
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 56 times.
✗ Branch 5 not taken.
56 md5path_cache_ = new lru::Md5PathCache(kLibPathCacheSize, statistics_);
1780
2/4
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 56 times.
✗ Branch 5 not taken.
56 simple_chunk_tables_ = new SimpleChunkTables();
1781 56 return;
1782 }
1783
1784
2/4
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 768 times.
✗ Branch 5 not taken.
768 chunk_tables_ = new ChunkTables();
1785
1786 768 string optarg;
1787 768 uint64_t mem_cache_size = kDefaultMemcacheSize;
1788
3/6
✓ Branch 2 taken 768 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 768 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 768 times.
768 if (options_mgr_->GetValue("CVMFS_MEMCACHE_SIZE", &optarg))
1789 ✗ mem_cache_size = String2Uint64(optarg) * 1024 * 1024;
1790
1791 const double memcache_unit_size = (static_cast<double>(kInodeCacheFactor)
1792
1/2
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
768 * lru::Md5PathCache::GetEntrySize())
1793
1/2
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
768 + lru::InodeCache::GetEntrySize()
1794
1/2
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
768 + lru::PathCache::GetEntrySize();
1795 768 const unsigned memcache_num_units = mem_cache_size
1796 768 / static_cast<unsigned>(
1797 memcache_unit_size);
1798 // Number of cache entries must be a multiple of 64
1799 768 const unsigned mask_64 = ~((1 << 6) - 1);
1800
2/4
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 768 times.
✗ Branch 5 not taken.
768 inode_cache_ = new lru::InodeCache(memcache_num_units & mask_64, statistics_);
1801
2/4
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 768 times.
✗ Branch 5 not taken.
768 path_cache_ = new lru::PathCache(memcache_num_units & mask_64, statistics_);
1802 1536 md5path_cache_ = new lru::Md5PathCache((memcache_num_units * 7) & mask_64,
1803
2/4
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 768 times.
✗ Branch 5 not taken.
768 statistics_);
1804
1805
2/4
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 768 times.
✗ Branch 5 not taken.
768 inode_tracker_ = new glue::InodeTracker();
1806
2/4
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 768 times.
✗ Branch 5 not taken.
768 dentry_tracker_ = new glue::DentryTracker();
1807
2/4
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 768 times.
✗ Branch 5 not taken.
768 page_cache_tracker_ = new glue::PageCacheTracker();
1808
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 768 times.
768 if (file_system_->IsNfsSource())
1809 ✗ page_cache_tracker_->Disable();
1810 768 }
1811
1812 /**
1813 * Will create a tracer for the current mount point
1814 * Tracefile path, Trace buffer size and trace buffer flush threshold
1815 * can be configured by the options: CVMFS_TRACEFILE,
1816 * CVMFS_TRACEBUFFER, CVMFS_TRACEBUFFER_THRESHOLD(respectively)
1817 * VMFS_TRACEBUFFER and CVMFS_TRACEBUFFER_THRESHOLD will silently fallback
1818 * to default values if configuration values don't exist or are invalid
1819 */
1820 824 bool MountPoint::CreateTracer() {
1821 824 string optarg;
1822
2/4
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 824 times.
✗ Branch 5 not taken.
824 tracer_ = new Tracer();
1823
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_TRACEFILE", &optarg)) {
1824 ✗ if (file_system_->type() != FileSystem::kFsFuse) {
1825 ✗ boot_error_ = "tracer is only supported in the fuse module";
1826 ✗ boot_status_ = loader::kFailOptions;
1827 ✗ return false;
1828 }
1829 ✗ const string tracebuffer_file = optarg;
1830 ✗ uint64_t tracebuffer_size = kTracerBufferSize;
1831 ✗ uint64_t tracebuffer_threshold = kTracerFlushThreshold;
1832
1833 ✗ if (options_mgr_->GetValue("CVMFS_TRACEBUFFER", &optarg)) {
1834 ✗ tracebuffer_size = String2Uint64(optarg);
1835 }
1836 ✗ if (options_mgr_->GetValue("CVMFS_TRACEBUFFER_THRESHOLD", &optarg)) {
1837 ✗ tracebuffer_threshold = String2Uint64(optarg);
1838 }
1839 ✗ assert(tracebuffer_size <= INT_MAX && tracebuffer_threshold <= INT_MAX);
1840 ✗ LogCvmfs(kLogCvmfs, kLogDebug,
1841 "Initialising tracer with buffer size %" PRIu64
1842 " and threshold %" PRIu64,
1843 tracebuffer_size, tracebuffer_threshold);
1844 ✗ tracer_->Activate(tracebuffer_size, tracebuffer_threshold,
1845 tracebuffer_file);
1846 }
1847 824 return true;
1848 824 }
1849
1850
1851 1130 bool MountPoint::DetermineRootHash(shash::Any *root_hash) {
1852 1130 string optarg;
1853
4/6
✓ Branch 2 taken 1130 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1130 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 391 times.
✓ Branch 10 taken 739 times.
1130 if (options_mgr_->GetValue("CVMFS_ROOT_HASH", &optarg)) {
1854
1/2
✓ Branch 2 taken 391 times.
✗ Branch 3 not taken.
391 *root_hash = MkFromHexPtr(shash::HexPtr(optarg), shash::kSuffixCatalog);
1855 391 return true;
1856 }
1857
1858
4/10
✓ Branch 1 taken 739 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 739 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 547 times.
✓ Branch 8 taken 192 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1478 if (!options_mgr_->IsDefined("CVMFS_REPOSITORY_TAG")
1859
12/20
✓ Branch 2 taken 739 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 643 times.
✓ Branch 5 taken 96 times.
✓ Branch 8 taken 643 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 643 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 547 times.
✓ Branch 14 taken 96 times.
✓ Branch 15 taken 643 times.
✓ Branch 16 taken 96 times.
✓ Branch 18 taken 643 times.
✓ Branch 19 taken 96 times.
✓ Branch 21 taken 739 times.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
1478 && !options_mgr_->IsDefined("CVMFS_REPOSITORY_DATE")) {
1860 547 root_hash->SetNull();
1861 547 return true;
1862 }
1863
1864 192 string history_path;
1865
2/4
✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 192 times.
192 if (!FetchHistory(&history_path))
1866 ✗ return false;
1867
1/2
✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
192 const UnlinkGuard history_file(history_path);
1868 const std::unique_ptr<history::History> tag_db(
1869
1/2
✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
192 history::SqliteHistory::Open(history_path));
1870
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 192 times.
192 if (tag_db.get() == nullptr) {
1871 ✗ LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslog,
1872 "failed to open history database (%s)", history_path.c_str());
1873 ✗ boot_error_ = "failed to open history database";
1874 ✗ boot_status_ = loader::kFailHistory;
1875 ✗ return false;
1876 }
1877
1878
1/2
✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
192 history::History::Tag tag;
1879 bool retval;
1880
4/6
✓ Branch 2 taken 192 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 192 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 96 times.
✓ Branch 10 taken 96 times.
192 if (!options_mgr_->GetValue("CVMFS_REPOSITORY_TAG", &repository_tag_)) {
1881 96 string repository_date;
1882 // options_mgr_->IsDefined("CVMFS_REPOSITORY_DATE") must be true
1883
2/4
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 96 times.
✗ Branch 6 not taken.
96 options_mgr_->GetValue("CVMFS_REPOSITORY_DATE", &repository_date);
1884
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 const time_t repository_utctime = IsoTimestamp2UtcTime(repository_date);
1885
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (repository_utctime == 0) {
1886 boot_error_ = "invalid timestamp in CVMFS_REPOSITORY_DATE: "
1887 ✗ + repository_date + ". Use YYYY-MM-DDTHH:MM:SSZ";
1888 ✗ boot_status_ = loader::kFailHistory;
1889 ✗ return false;
1890 }
1891
1/2
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
96 retval = tag_db->GetByDate(repository_utctime, &tag);
1892
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
96 if (!retval) {
1893 boot_error_ = "no repository state as early as utc timestamp "
1894
2/4
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 48 times.
✗ Branch 5 not taken.
48 + StringifyTime(repository_utctime, true);
1895 48 boot_status_ = loader::kFailHistory;
1896 48 return false;
1897 }
1898
1/5
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
96 LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslog,
1899 "time stamp %s UTC resolved to tag '%s'",
1900
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
96 StringifyTime(repository_utctime, true).c_str(), tag.name.c_str());
1901
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 repository_tag_ = tag.name;
1902
2/2
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 48 times.
96 } else {
1903
1/2
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
96 retval = tag_db->GetByName(repository_tag_, &tag);
1904
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
96 if (!retval) {
1905
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 boot_error_ = "no such tag: " + repository_tag_;
1906 48 boot_status_ = loader::kFailHistory;
1907 48 return false;
1908 }
1909 }
1910
1/2
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
96 LogCvmfs(kLogCvmfs, kLogDebug, "mounting tag %s", tag.name.c_str());
1911
1912 96 *root_hash = tag.root_hash;
1913 96 return true;
1914 1130 }
1915
1916
1917 192 bool MountPoint::FetchHistory(std::string *history_path) {
1918 manifest::Failures retval_mf;
1919 192 manifest::ManifestEnsemble ensemble;
1920
2/4
✓ Branch 2 taken 192 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 192 times.
✗ Branch 6 not taken.
192 retval_mf = manifest::Fetch("", fqrn_, 0, NULL, signature_mgr_, download_mgr_,
1921 &ensemble);
1922
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 192 times.
192 if (retval_mf != manifest::kFailOk) {
1923 ✗ boot_error_ = "Failed to fetch manifest";
1924 ✗ boot_status_ = loader::kFailHistory;
1925 ✗ return false;
1926 }
1927 192 const shash::Any history_hash = ensemble.manifest->history();
1928
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 192 times.
192 if (history_hash.IsNull()) {
1929 ✗ boot_error_ = "No history";
1930 ✗ boot_status_ = loader::kFailHistory;
1931 ✗ return false;
1932 }
1933
1934 192 CacheManager::Label label;
1935 192 label.flags = CacheManager::kLabelHistory;
1936
1/2
✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
192 label.path = fqrn_;
1937
2/4
✓ Branch 2 taken 192 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 192 times.
✗ Branch 6 not taken.
576 const int fd = fetcher_->Fetch(
1938
1/2
✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
384 CacheManager::LabeledObject(history_hash, label));
1939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 192 times.
192 if (fd < 0) {
1940 ✗ boot_error_ = "failed to download history: " + StringifyInt(-fd);
1941 ✗ boot_status_ = loader::kFailHistory;
1942 ✗ return false;
1943 }
1944 // We have the custom sqlite vfs driver installed
1945
2/4
✓ Branch 1 taken 192 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 192 times.
✗ Branch 5 not taken.
192 *history_path = "@" + StringifyInt(fd);
1946 192 return true;
1947 192 }
1948
1949
1950 ✗ unsigned MountPoint::GetEffectiveTtlSec() {
1951 unsigned max_ttl;
1952 {
1953 ✗ const MutexLockGuard lock_guard(lock_max_ttl_);
1954 ✗ max_ttl = max_ttl_sec_;
1955 }
1956 ✗ const unsigned catalog_ttl_sec = catalog_mgr_->GetTTL();
1957
1958 ✗ return max_ttl ? std::min(max_ttl, catalog_ttl_sec) : catalog_ttl_sec;
1959 }
1960
1961
1962 ✗ unsigned MountPoint::GetMaxTtlMn() {
1963 ✗ const MutexLockGuard lock_guard(lock_max_ttl_);
1964 ✗ return max_ttl_sec_ / 60;
1965 }
1966
1967
1968 /**
1969 * Files in the workspace from different file systems / mountpoints need to
1970 * have different names. Used, for example, for caching proxy settings.
1971 */
1972 1592 string MountPoint::GetUniqFileSuffix() {
1973
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1592 times.
✗ Branch 9 not taken.
3184 return "." + file_system_->name() + "-" + fqrn_;
1974 }
1975
1976
1977 1640 MountPoint::MountPoint(const string &fqrn,
1978 FileSystem *file_system,
1979 1640 OptionsManager *options_mgr)
1980
1/2
✓ Branch 1 taken 1640 times.
✗ Branch 2 not taken.
1640 : fqrn_(fqrn)
1981
2/4
✓ Branch 2 taken 1640 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1640 times.
✗ Branch 6 not taken.
1640 , uuid_(cvmfs::Uuid::Create(""))
1982 1640 , file_system_(file_system)
1983 1640 , options_mgr_(options_mgr)
1984 1640 , statistics_(NULL)
1985 1640 , telemetry_aggr_(NULL)
1986 1640 , authz_fetcher_(NULL)
1987 1640 , authz_session_mgr_(NULL)
1988 1640 , authz_attachment_(NULL)
1989 1640 , backoff_throttle_(NULL)
1990 1640 , signature_mgr_(NULL)
1991 1640 , download_mgr_(NULL)
1992 1640 , external_download_mgr_(NULL)
1993 1640 , full_replica_download_mgr_(NULL)
1994 1640 , fetcher_(NULL)
1995 1640 , external_fetcher_(NULL)
1996 1640 , partial_inclusion_spec_(NULL)
1997 1640 , partial_replica_fail_mode_(false)
1998 1640 , inode_annotation_(NULL)
1999 1640 , catalog_mgr_(NULL)
2000 1640 , bundle_mgr_(NULL)
2001 1640 , chunk_tables_(NULL)
2002 1640 , simple_chunk_tables_(NULL)
2003 1640 , inode_cache_(NULL)
2004 1640 , path_cache_(NULL)
2005 1640 , md5path_cache_(NULL)
2006 1640 , tracer_(NULL)
2007 1640 , inode_tracker_(NULL)
2008 1640 , dentry_tracker_(NULL)
2009 1640 , page_cache_tracker_(NULL)
2010 1640 , statfs_cache_(NULL)
2011 1640 , resolv_conf_watcher_(NULL)
2012 1640 , max_ttl_sec_(kDefaultMaxTtlSec)
2013 1640 , kcache_timeout_sec_(static_cast<double>(kDefaultKCacheTtlSec))
2014 1640 , fixed_catalog_(false)
2015 1640 , enforce_acls_(false)
2016 1640 , cache_symlinks_(false)
2017 1640 , fuse_expire_entry_(false)
2018 1640 , has_membership_req_(false)
2019
2/4
✓ Branch 2 taken 1640 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1640 times.
✗ Branch 6 not taken.
1640 , talk_socket_path_(std::string("./cvmfs_io.") + fqrn)
2020 1640 , talk_socket_uid_(0)
2021 3280 , talk_socket_gid_(0) {
2022 1640 const int retval = pthread_mutex_init(&lock_max_ttl_, NULL);
2023
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1640 times.
1640 assert(retval == 0);
2024 1640 }
2025
2026
2027 1640 MountPoint::~MountPoint() {
2028 1640 pthread_mutex_destroy(&lock_max_ttl_);
2029
2030 // The bundle prefetcher owns background threads that use the catalog
2031 // manager, the fetchers and the cache manager; join them before any of
2032 // those are destroyed.
2033
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1640 times.
1640 delete bundle_mgr_;
2034
2035
2/2
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 872 times.
1640 delete page_cache_tracker_;
2036
2/2
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 872 times.
1640 delete dentry_tracker_;
2037
2/2
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 872 times.
1640 delete inode_tracker_;
2038
2/2
✓ Branch 0 taken 824 times.
✓ Branch 1 taken 816 times.
1640 delete tracer_;
2039
2/2
✓ Branch 0 taken 824 times.
✓ Branch 1 taken 816 times.
1640 delete md5path_cache_;
2040
2/2
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 872 times.
1640 delete path_cache_;
2041
2/2
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 872 times.
1640 delete inode_cache_;
2042
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1584 times.
1640 delete simple_chunk_tables_;
2043
2/2
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 872 times.
1640 delete chunk_tables_;
2044
2045
2/2
✓ Branch 0 taken 1250 times.
✓ Branch 1 taken 390 times.
1640 delete catalog_mgr_;
2046
2/2
✓ Branch 0 taken 1178 times.
✓ Branch 1 taken 462 times.
1640 delete inode_annotation_;
2047
2/2
✓ Branch 0 taken 1250 times.
✓ Branch 1 taken 390 times.
1640 delete external_fetcher_;
2048
2/2
✓ Branch 0 taken 1250 times.
✓ Branch 1 taken 390 times.
1640 delete fetcher_;
2049
2050
2/2
✓ Branch 0 taken 1178 times.
✓ Branch 1 taken 462 times.
1640 delete external_download_mgr_;
2051
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1640 times.
1640 delete full_replica_download_mgr_;
2052
2/2
✓ Branch 0 taken 1592 times.
✓ Branch 1 taken 48 times.
1640 delete download_mgr_;
2053
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1640 times.
1640 delete partial_inclusion_spec_;
2054
2055
1/2
✓ Branch 0 taken 1640 times.
✗ Branch 1 not taken.
1640 if (signature_mgr_ != NULL) {
2056 1640 signature_mgr_->Fini();
2057
1/2
✓ Branch 0 taken 1640 times.
✗ Branch 1 not taken.
1640 delete signature_mgr_;
2058 }
2059
2060
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1640 times.
1640 if (resolv_conf_watcher_ != NULL) {
2061 ✗ resolv_conf_watcher_->Stop();
2062 ✗ delete resolv_conf_watcher_;
2063 }
2064
2065
1/2
✓ Branch 0 taken 1640 times.
✗ Branch 1 not taken.
1640 delete backoff_throttle_;
2066
1/2
✓ Branch 0 taken 1640 times.
✗ Branch 1 not taken.
1640 delete authz_attachment_;
2067
1/2
✓ Branch 0 taken 1640 times.
✗ Branch 1 not taken.
1640 delete authz_session_mgr_;
2068
1/2
✓ Branch 0 taken 1640 times.
✗ Branch 1 not taken.
1640 delete authz_fetcher_;
2069
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1640 times.
1640 delete telemetry_aggr_;
2070
1/2
✓ Branch 0 taken 1640 times.
✗ Branch 1 not taken.
1640 delete statistics_;
2071
1/2
✓ Branch 0 taken 1640 times.
✗ Branch 1 not taken.
1640 delete uuid_;
2072
2073
2/2
✓ Branch 0 taken 824 times.
✓ Branch 1 taken 816 times.
1640 delete statfs_cache_;
2074 1640 }
2075
2076
2077 826 void MountPoint::ReEvaluateAuthz() {
2078
1/2
✓ Branch 1 taken 826 times.
✗ Branch 2 not taken.
826 const string old_membership_req = membership_req_;
2079
1/2
✓ Branch 1 taken 826 times.
✗ Branch 2 not taken.
826 has_membership_req_ = catalog_mgr_->GetVOMSAuthz(&membership_req_);
2080
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 826 times.
826 if (old_membership_req != membership_req_) {
2081 ✗ authz_session_mgr_->ClearSessionCache();
2082 ✗ authz_attachment_->set_membership(membership_req_);
2083 }
2084 826 }
2085
2086
2087 ✗ void MountPoint::SetMaxTtlMn(unsigned value_minutes) {
2088 ✗ const MutexLockGuard lock_guard(lock_max_ttl_);
2089 ✗ max_ttl_sec_ = value_minutes * 60;
2090 }
2091
2092 ✗ void MountPoint::SetMaxTtlSec(unsigned value_secs) {
2093 ✗ const MutexLockGuard lock_guard(lock_max_ttl_);
2094 ✗ max_ttl_sec_ = value_secs;
2095 }
2096
2097 824 bool MountPoint::SetupBehavior() {
2098 824 string optarg;
2099
2100
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_MAX_TTL", &optarg))
2101 ✗ SetMaxTtlMn(String2Uint64(optarg));
2102
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_MAX_TTL_SECS", &optarg))
2103 ✗ SetMaxTtlSec(String2Uint64(optarg));
2104
2105
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_KCACHE_TIMEOUT", &optarg)) {
2106 // Can be negative and should then be interpreted as 0.0
2107 ✗ kcache_timeout_sec_ = std::max(0.0,
2108 ✗ static_cast<double>(String2Int64(optarg)));
2109 }
2110 824 LogCvmfs(kLogCvmfs, kLogDebug, "kernel caches expire after %d seconds",
2111
1/2
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
824 static_cast<int>(kcache_timeout_sec_));
2112
2113 824 uint64_t statfs_time_cache_valid = 0;
2114
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_STATFS_CACHE_TIMEOUT", &optarg)) {
2115 ✗ statfs_time_cache_valid = static_cast<uint64_t>(String2Uint64(optarg));
2116 }
2117
1/2
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
824 LogCvmfs(kLogCvmfs, kLogDebug, "statfs cache expires after %d seconds",
2118 static_cast<int>(statfs_time_cache_valid));
2119
1/2
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
824 statfs_cache_ = new StatfsCache(statfs_time_cache_valid);
2120
2121 MagicXattrManager::EVisibility
2122 824 xattr_visibility = MagicXattrManager::kVisibilityRootOnly;
2123
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_HIDE_MAGIC_XATTRS", &optarg)) {
2124 ✗ if (options_mgr_->IsOn(optarg))
2125 ✗ xattr_visibility = MagicXattrManager::kVisibilityNever;
2126 ✗ else if (options_mgr_->IsOff(optarg))
2127 ✗ xattr_visibility = MagicXattrManager::kVisibilityAlways;
2128 }
2129
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_MAGIC_XATTRS_VISIBILITY", &optarg)) {
2130 ✗ if (ToUpper(optarg) == "ROOTONLY") {
2131 ✗ xattr_visibility = MagicXattrManager::kVisibilityRootOnly;
2132 ✗ } else if (ToUpper(optarg) == "NEVER") {
2133 ✗ xattr_visibility = MagicXattrManager::kVisibilityNever;
2134 ✗ } else if (ToUpper(optarg) == "ALWAYS") {
2135 ✗ xattr_visibility = MagicXattrManager::kVisibilityAlways;
2136 } else {
2137 ✗ LogCvmfs(kLogCvmfs, kLogSyslogWarn | kLogDebug,
2138 "unsupported setting: CVMFS_MAGIC_XATTRS_VISIBILITY=%s",
2139 optarg.c_str());
2140 }
2141 }
2142
2143 824 std::set<gid_t> protected_xattr_gids;
2144
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_XATTR_PRIVILEGED_GIDS", &optarg)) {
2145 ✗ std::vector<string> tmp = SplitString(optarg, ',');
2146
2147 ✗ for (size_t i = 0; i < tmp.size(); i++) {
2148 ✗ const std::string trimmed = Trim(tmp[i]);
2149 ✗ LogCvmfs(kLogCvmfs, kLogDebug, "Privileged gid for xattr added: %s",
2150 trimmed.c_str());
2151 ✗ protected_xattr_gids.insert(static_cast<gid_t>(String2Uint64(trimmed)));
2152 }
2153 }
2154 824 std::set<std::string> protected_xattrs;
2155
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_XATTR_PROTECTED_XATTRS", &optarg)) {
2156 ✗ std::vector<string> tmp = SplitString(optarg, ',');
2157
2158 ✗ for (size_t i = 0; i < tmp.size(); i++) {
2159 ✗ const std::string trimmed = Trim(tmp[i]);
2160 ✗ LogCvmfs(kLogCvmfs, kLogDebug, "Protected xattr added: %s",
2161 trimmed.c_str());
2162 ✗ protected_xattrs.insert(trimmed);
2163 }
2164
2165 // root has always access to xattr
2166 ✗ if (protected_xattr_gids.count(0) < 1) {
2167 ✗ protected_xattr_gids.insert(0);
2168 ✗ LogCvmfs(kLogCvmfs, kLogDebug,
2169 "Automatically added root to have access to protected xattrs.");
2170 }
2171 }
2172 824 magic_xattr_mgr_ = new MagicXattrManager(
2173
2/4
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 824 times.
✗ Branch 5 not taken.
824 this, xattr_visibility, protected_xattrs, protected_xattr_gids);
2174
2175
2176
3/10
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 824 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 824 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1648 if (options_mgr_->GetValue("CVMFS_ENFORCE_ACLS", &optarg)
2177
3/10
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 824 times.
✗ Branch 12 not taken.
1648 && options_mgr_->IsOn(optarg)) {
2178 ✗ enforce_acls_ = true;
2179 }
2180
2181
3/10
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 824 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 824 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1648 if (options_mgr_->GetValue("CVMFS_CACHE_SYMLINKS", &optarg)
2182
3/10
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 824 times.
✗ Branch 12 not taken.
1648 && options_mgr_->IsOn(optarg)) {
2183 ✗ cache_symlinks_ = true;
2184 }
2185
2186
2187
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_TALK_SOCKET", &optarg)) {
2188 ✗ talk_socket_path_ = optarg;
2189 }
2190
3/6
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 824 times.
824 if (options_mgr_->GetValue("CVMFS_TALK_OWNER", &optarg)) {
2191 ✗ const bool retval = GetUidOf(optarg, &talk_socket_uid_, &talk_socket_gid_);
2192 ✗ if (!retval) {
2193 ✗ boot_error_ = "unknown owner of cvmfs_talk socket: " + optarg;
2194 ✗ boot_status_ = loader::kFailOptions;
2195 ✗ return false;
2196 }
2197 }
2198
2199 // this can be later be changed to switch through different
2200 // telemetryAggregators
2201
3/10
✓ Branch 1 taken 824 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 824 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 824 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
1648 if (options_mgr_->GetValue("CVMFS_TELEMETRY_SEND", &optarg)
2202
3/10
✓ Branch 2 taken 824 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 824 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 824 times.
✗ Branch 12 not taken.
1648 && options_mgr_->IsOn(optarg)) {
2203 ✗ int telemetry_send_rate_sec = kDefaultTelemetrySendRateSec;
2204 ✗ if (options_mgr_->GetValue("CVMFS_TELEMETRY_RATE", &optarg)) {
2205 ✗ telemetry_send_rate_sec = static_cast<int>(String2Uint64(optarg));
2206
2207 // minimum send rate: 5sec
2208 ✗ if (telemetry_send_rate_sec < kMinimumTelemetrySendRateSec) {
2209 ✗ telemetry_send_rate_sec = kMinimumTelemetrySendRateSec;
2210 }
2211
2212 ✗ telemetry_aggr_ = perf::TelemetryAggregator::Create(
2213 statistics_,
2214 telemetry_send_rate_sec,
2215 options_mgr_,
2216 this,
2217 ✗ fqrn_,
2218 perf::kTelemetryInflux);
2219 ✗ LogCvmfs(kLogTelemetry, kLogSyslog | kLogDebug,
2220 "Enable telemetry to report every %d seconds",
2221 telemetry_send_rate_sec);
2222 }
2223 }
2224
2225 824 return true;
2226 824 }
2227
2228
2229 /**
2230 * Called twice once for the regular download manager and once for the external
2231 * download manager.
2232 */
2233 1592 void MountPoint::SetupDnsTuning(download::DownloadManager *manager) {
2234 1592 string optarg;
2235 1592 unsigned dns_timeout_ms = download::DownloadManager::kDnsDefaultTimeoutMs;
2236 1592 unsigned dns_retries = download::DownloadManager::kDnsDefaultRetries;
2237
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_DNS_TIMEOUT", &optarg))
2238 ✗ dns_timeout_ms = String2Uint64(optarg) * 1000;
2239
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_DNS_RETRIES", &optarg))
2240 ✗ dns_retries = String2Uint64(optarg);
2241
1/2
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
1592 manager->SetDnsParameters(dns_retries, dns_timeout_ms);
2242
2243 // Rest has to be after SetDnsParameters because SetDnsParameters might
2244 // construct a new resolver object
2245
2246 1592 unsigned dns_min_ttl = dns::Resolver::kDefaultMinTtl;
2247 1592 unsigned dns_max_ttl = dns::Resolver::kDefaultMaxTtl;
2248
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_DNS_MIN_TTL", &optarg))
2249 ✗ dns_min_ttl = String2Uint64(optarg);
2250
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_DNS_MAX_TTL", &optarg))
2251 ✗ dns_max_ttl = String2Uint64(optarg);
2252
1/2
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
1592 manager->SetDnsTtlLimits(dns_min_ttl, dns_max_ttl);
2253
2254
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_DNS_SERVER", &optarg)) {
2255 ✗ download_mgr_->SetDnsServer(optarg);
2256 }
2257
2258
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_IPFAMILY_PREFER", &optarg)) {
2259 ✗ switch (String2Int64(optarg)) {
2260 ✗ case 4:
2261 ✗ manager->SetIpPreference(dns::kIpPreferV4);
2262 ✗ break;
2263 ✗ case 6:
2264 ✗ manager->SetIpPreference(dns::kIpPreferV6);
2265 ✗ break;
2266 }
2267 }
2268
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_MAX_IPADDR_PER_PROXY", &optarg))
2269 ✗ manager->SetMaxIpaddrPerProxy(String2Uint64(optarg));
2270 1592 }
2271
2272
2273 1178 bool MountPoint::SetupExternalDownloadMgr(bool dogeosort) {
2274 1178 string optarg;
2275
2/4
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
3534 external_download_mgr_ = download_mgr_->Clone(
2276
2/4
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
2356 perf::StatisticsTemplate("download-external", statistics_), "external");
2277
2278 unsigned timeout;
2279 unsigned timeout_direct;
2280
1/2
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
1178 download_mgr_->GetTimeout(&timeout, &timeout_direct);
2281
3/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1178 times.
1178 if (options_mgr_->GetValue("CVMFS_EXTERNAL_TIMEOUT", &optarg)) {
2282 ✗ timeout = String2Uint64(optarg);
2283 }
2284
3/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1178 times.
1178 if (options_mgr_->GetValue("CVMFS_EXTERNAL_TIMEOUT_DIRECT", &optarg)) {
2285 ✗ timeout_direct = String2Uint64(optarg);
2286 }
2287
1/2
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
1178 external_download_mgr_->SetTimeout(timeout, timeout_direct);
2288
2289
6/18
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1178 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1178 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1178 times.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 1178 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
1178 if (options_mgr_->GetValue("CVMFS_EXTERNAL_METALINK", &optarg) &&
2290 ✗ (optarg != "")) {
2291 ✗ external_download_mgr_->SetMetalinkChain(optarg);
2292 // host chain will be set later when the metalink server is contacted
2293 ✗ external_download_mgr_->SetHostChain("");
2294 // metalink requires redirects
2295 ✗ external_download_mgr_->EnableRedirects();
2296
4/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 96 times.
✓ Branch 10 taken 1082 times.
1178 } else if (options_mgr_->GetValue("CVMFS_EXTERNAL_URL", &optarg)) {
2297
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 external_download_mgr_->SetHostChain(optarg);
2298
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 if (dogeosort) {
2299 ✗ std::vector<std::string> host_chain;
2300 ✗ external_download_mgr_->GetHostInfo(&host_chain, NULL, NULL);
2301 ✗ download_mgr_->GeoSortServers(&host_chain);
2302 ✗ external_download_mgr_->SetHostChain(host_chain);
2303 }
2304 } else {
2305
2/4
✓ Branch 2 taken 1082 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1082 times.
✗ Branch 6 not taken.
1082 external_download_mgr_->SetHostChain("");
2306 }
2307
2308
4/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 144 times.
✓ Branch 10 taken 1034 times.
1178 if (options_mgr_->GetValue("CVMFS_EXTERNAL_MAX_SERVERS", &optarg)) {
2309
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
144 const unsigned max_servers = String2Uint64(optarg);
2310 144 std::vector<std::string> host_chain;
2311
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
144 external_download_mgr_->GetHostInfo(&host_chain, NULL, NULL);
2312
6/6
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 48 times.
✓ Branch 3 taken 48 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 96 times.
144 if (max_servers > 0 && max_servers < host_chain.size()) {
2313
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 host_chain.resize(max_servers);
2314
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 external_download_mgr_->SetHostChain(host_chain);
2315 }
2316 144 }
2317
2318
1/2
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
1178 string proxies = "DIRECT";
2319
3/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1178 times.
1178 if (options_mgr_->GetValue("CVMFS_EXTERNAL_HTTP_PROXY", &optarg)) {
2320 ✗ proxies = download::ResolveProxyDescription(
2321 optarg,
2322 ✗ file_system_->workspace() + "/proxies-external" + GetUniqFileSuffix(),
2323 ✗ external_download_mgr_);
2324 ✗ if (proxies == "") {
2325 ✗ boot_error_ = "failed to discover external HTTP proxy servers";
2326 ✗ boot_status_ = loader::kFailWpad;
2327 ✗ return false;
2328 }
2329 }
2330 1178 string fallback_proxies;
2331
3/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1178 times.
1178 if (options_mgr_->GetValue("CVMFS_EXTERNAL_FALLBACK_PROXY", &optarg))
2332 ✗ fallback_proxies = optarg;
2333
1/2
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
1178 external_download_mgr_->SetProxyChain(
2334 proxies, fallback_proxies, download::DownloadManager::kSetProxyBoth);
2335
2336 1178 return true;
2337 1178 }
2338
2339
2340 1592 void MountPoint::SetupHttpTuning() {
2341 1592 string optarg;
2342
2343 // TODO(jblomer): avoid double default settings
2344
2345 1592 unsigned timeout = kDefaultTimeoutSec;
2346 1592 unsigned timeout_direct = kDefaultTimeoutSec;
2347
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_TIMEOUT", &optarg))
2348 ✗ timeout = String2Uint64(optarg);
2349
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_TIMEOUT_DIRECT", &optarg))
2350 ✗ timeout_direct = String2Uint64(optarg);
2351
1/2
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
1592 download_mgr_->SetTimeout(timeout, timeout_direct);
2352
2353 1592 unsigned max_retries = kDefaultRetries;
2354 1592 unsigned backoff_init = kDefaultBackoffInitMs;
2355 1592 unsigned backoff_max = kDefaultBackoffMaxMs;
2356
4/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 1536 times.
✓ Branch 10 taken 56 times.
1592 if (options_mgr_->GetValue("CVMFS_MAX_RETRIES", &optarg))
2357
1/2
✓ Branch 1 taken 1536 times.
✗ Branch 2 not taken.
1536 max_retries = String2Uint64(optarg);
2358
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_BACKOFF_INIT", &optarg))
2359 ✗ backoff_init = String2Uint64(optarg) * 1000;
2360
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_BACKOFF_MAX", &optarg))
2361 ✗ backoff_max = String2Uint64(optarg) * 1000;
2362
1/2
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
1592 download_mgr_->SetRetryParameters(max_retries, backoff_init, backoff_max);
2363
2364
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_LOW_SPEED_LIMIT", &optarg))
2365 ✗ download_mgr_->SetLowSpeedLimit(String2Uint64(optarg));
2366
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_PROXY_RESET_AFTER", &optarg)) {
2367 ✗ download_mgr_->SetProxyGroupResetDelay(String2Uint64(optarg));
2368 // Use the proxy reset delay as the default for the metalink reset delay
2369 ✗ download_mgr_->SetMetalinkResetDelay(String2Uint64(optarg));
2370 }
2371
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_METALINK_RESET_AFTER", &optarg))
2372 ✗ download_mgr_->SetMetalinkResetDelay(String2Uint64(optarg));
2373
3/6
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1592 times.
1592 if (options_mgr_->GetValue("CVMFS_HOST_RESET_AFTER", &optarg))
2374 ✗ download_mgr_->SetHostResetDelay(String2Uint64(optarg));
2375
2376
3/10
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1592 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1592 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3184 if (options_mgr_->GetValue("CVMFS_FOLLOW_REDIRECTS", &optarg)
2377
3/10
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1592 times.
✗ Branch 12 not taken.
3184 && options_mgr_->IsOn(optarg)) {
2378 ✗ download_mgr_->EnableRedirects();
2379 }
2380
6/18
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1592 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1592 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1592 times.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 1592 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
1592 if (options_mgr_->GetValue("CVMFS_INFO_HEADER", &optarg) && (optarg != "")) {
2381 ✗ download_mgr_->EnableInfoHeader();
2382 ✗ download_mgr_->SetInfoHeaderTemplate(optarg);
2383
3/10
✓ Branch 1 taken 1592 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1592 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1592 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
3184 } else if (options_mgr_->GetValue("CVMFS_SEND_INFO_HEADER", &optarg)
2384
3/10
✓ Branch 2 taken 1592 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1592 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1592 times.
✗ Branch 12 not taken.
3184 && options_mgr_->IsOn(optarg)) {
2385 ✗ download_mgr_->EnableInfoHeader();
2386 ✗ download_mgr_->SetInfoHeaderTemplate("%{path}");
2387 }
2388 1592 }
2389
2390 /*
2391 * Check whether permission is needed to read from user process environment.
2392 */
2393 ✗ bool MountPoint::NeedsReadEnviron(OptionsManager *omgr) {
2394 // This is a class (static) method because it is used early, before
2395 // all the above initialization is done, so can't rely on mountpoint
2396 // object data.
2397 ✗ string info_header;
2398 ✗ omgr->GetValue("CVMFS_INFO_HEADER", &info_header);
2399 ✗ return (info_header.find("%{env:") != std::string::npos);
2400 }
2401
2402 1178 void MountPoint::SetupInodeAnnotation() {
2403 1178 string optarg;
2404
2405
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1178 times.
1178 if (file_system_->IsNfsSource()) {
2406 ✗ inode_annotation_ = new catalog::InodeNfsGenerationAnnotation();
2407 } else {
2408
1/2
✓ Branch 1 taken 1178 times.
✗ Branch 2 not taken.
1178 inode_annotation_ = new catalog::InodeGenerationAnnotation();
2409 }
2410
3/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1178 times.
1178 if (options_mgr_->GetValue("CVMFS_INITIAL_GENERATION", &optarg)) {
2411 ✗ inode_annotation_->IncGeneration(String2Uint64(optarg));
2412 }
2413
2414
2/2
✓ Branch 1 taken 1104 times.
✓ Branch 2 taken 74 times.
1178 if (file_system_->type() == FileSystem::kFsFuse) {
2415 1104 catalog_mgr_->SetInodeAnnotation(inode_annotation_);
2416 }
2417 1178 }
2418
2419
2420 1178 bool MountPoint::SetupOwnerMaps() {
2421 1178 string optarg;
2422 1178 catalog::OwnerMap uid_map;
2423 1178 catalog::OwnerMap gid_map;
2424
2425
4/6
✓ Branch 2 taken 1178 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1178 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 48 times.
✓ Branch 10 taken 1130 times.
1178 if (options_mgr_->GetValue("CVMFS_UID_MAP", &optarg)) {
2426
2/4
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 48 times.
✗ Branch 4 not taken.
48 if (!uid_map.Read(optarg)) {
2427
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 boot_error_ = "failed to parse uid map " + optarg;
2428 48 boot_status_ = loader::kFailOptions;
2429 48 return false;
2430 }
2431 }
2432
3/6
✓ Branch 2 taken 1130 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1130 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1130 times.
1130 if (options_mgr_->GetValue("CVMFS_GID_MAP", &optarg)) {
2433 ✗ if (!gid_map.Read(optarg)) {
2434 ✗ boot_error_ = "failed to parse gid map " + optarg;
2435 ✗ boot_status_ = loader::kFailOptions;
2436 ✗ return false;
2437 }
2438 }
2439
1/2
✓ Branch 1 taken 1130 times.
✗ Branch 2 not taken.
1130 catalog_mgr_->SetOwnerMaps(uid_map, gid_map);
2440
2441 // TODO(jblomer): make local to catalog manager
2442
3/10
✓ Branch 1 taken 1130 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1130 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1130 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2260 if (options_mgr_->GetValue("CVMFS_CLAIM_OWNERSHIP", &optarg)
2443
3/10
✓ Branch 2 taken 1130 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1130 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1130 times.
✗ Branch 12 not taken.
2260 && options_mgr_->IsOn(optarg)) {
2444 ✗ g_claim_ownership = true;
2445 }
2446
3/10
✓ Branch 1 taken 1130 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1130 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1130 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2260 if (options_mgr_->GetValue("CVMFS_WORLD_READABLE", &optarg)
2447
3/10
✓ Branch 2 taken 1130 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1130 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1130 times.
✗ Branch 12 not taken.
2260 && options_mgr_->IsOn(optarg)) {
2448 ✗ g_world_readable = true;
2449 }
2450
2451
2452 1130 return true;
2453 1178 }
2454