Line |
Branch |
Exec |
Source |
1 |
|
|
/** |
2 |
|
|
* This file is part of the CernVM File System. |
3 |
|
|
* |
4 |
|
|
* Steers the booting of CernVM-FS repositories. |
5 |
|
|
*/ |
6 |
|
|
|
7 |
|
|
#ifndef CVMFS_MOUNTPOINT_H_ |
8 |
|
|
#define CVMFS_MOUNTPOINT_H_ |
9 |
|
|
|
10 |
|
|
#include <pthread.h> |
11 |
|
|
#include <sys/statvfs.h> |
12 |
|
|
#include <unistd.h> |
13 |
|
|
|
14 |
|
|
#include <ctime> |
15 |
|
|
#include <set> |
16 |
|
|
#include <string> |
17 |
|
|
#include <vector> |
18 |
|
|
|
19 |
|
|
#include "cache.h" |
20 |
|
|
#include "crypto/hash.h" |
21 |
|
|
#include "file_watcher.h" |
22 |
|
|
#include "gtest/gtest_prod.h" |
23 |
|
|
#include "loader.h" |
24 |
|
|
#include "magic_xattr.h" |
25 |
|
|
#include "util/algorithm.h" |
26 |
|
|
#include "util/pointer.h" |
27 |
|
|
|
28 |
|
|
class AuthzAttachment; |
29 |
|
|
class AuthzFetcher; |
30 |
|
|
class AuthzSessionManager; |
31 |
|
|
class BackoffThrottle; |
32 |
|
|
class CacheManager; |
33 |
|
|
namespace catalog { |
34 |
|
|
class ClientCatalogManager; |
35 |
|
|
class InodeAnnotation; |
36 |
|
|
} // namespace catalog |
37 |
|
|
struct ChunkTables; |
38 |
|
|
namespace cvmfs { |
39 |
|
|
class Fetcher; |
40 |
|
|
class Uuid; |
41 |
|
|
} // namespace cvmfs |
42 |
|
|
namespace download { |
43 |
|
|
class DownloadManager; |
44 |
|
|
} |
45 |
|
|
namespace glue { |
46 |
|
|
class InodeTracker; |
47 |
|
|
class DentryTracker; |
48 |
|
|
class PageCacheTracker; |
49 |
|
|
} // namespace glue |
50 |
|
|
namespace lru { |
51 |
|
|
class InodeCache; |
52 |
|
|
class Md5PathCache; |
53 |
|
|
class PathCache; |
54 |
|
|
} // namespace lru |
55 |
|
|
class NfsMaps; |
56 |
|
|
class OptionsManager; |
57 |
|
|
namespace perf { |
58 |
|
|
class Counter; |
59 |
|
|
class Statistics; |
60 |
|
|
class TelemetryAggregator; |
61 |
|
|
} // namespace perf |
62 |
|
|
namespace signature { |
63 |
|
|
class SignatureManager; |
64 |
|
|
} |
65 |
|
|
class SimpleChunkTables; |
66 |
|
|
class Tracer; |
67 |
|
|
|
68 |
|
|
|
69 |
|
|
/** |
70 |
|
|
* Construction of FileSystem and MountPoint can go wrong. In this case, we'd |
71 |
|
|
* like to know why. This is a base class for both FileSystem and MountPoint. |
72 |
|
|
*/ |
73 |
|
|
class BootFactory { |
74 |
|
|
public: |
75 |
|
1425 |
BootFactory() : boot_status_(loader::kFailUnknown) { } |
76 |
|
43 |
bool IsValid() { return boot_status_ == loader::kFailOk; } |
77 |
|
1104 |
loader::Failures boot_status() { return boot_status_; } |
78 |
|
13 |
std::string boot_error() { return boot_error_; } |
79 |
|
|
|
80 |
|
|
/** |
81 |
|
|
* Used in the fuse module to artificially set boot errors that are specific |
82 |
|
|
* to the fuse boot procedure. |
83 |
|
|
*/ |
84 |
|
✗ |
void set_boot_status(loader::Failures code) { boot_status_ = code; } |
85 |
|
|
|
86 |
|
|
protected: |
87 |
|
|
loader::Failures boot_status_; |
88 |
|
|
std::string boot_error_; |
89 |
|
|
}; |
90 |
|
|
|
91 |
|
|
|
92 |
|
|
/** |
93 |
|
|
* The FileSystem object initializes cvmfs' global state. It sets up sqlite and |
94 |
|
|
* the cache directory and it can contain multiple mount points. It currently |
95 |
|
|
* does so only for libcvmfs; the cvmfs fuse module has exactly one FileSystem |
96 |
|
|
* object and one MountPoint object. |
97 |
|
|
*/ |
98 |
|
|
class FileSystem : SingleCopy, public BootFactory { |
99 |
|
|
FRIEND_TEST(T_MountPoint, MkCacheParm); |
100 |
|
|
FRIEND_TEST(T_MountPoint, CacheSettings); |
101 |
|
|
FRIEND_TEST(T_MountPoint, CheckInstanceName); |
102 |
|
|
FRIEND_TEST(T_MountPoint, CheckPosixCacheSettings); |
103 |
|
|
FRIEND_TEST(T_Cvmfs, Basics); |
104 |
|
|
|
105 |
|
|
public: |
106 |
|
|
enum Type { |
107 |
|
|
kFsFuse = 0, |
108 |
|
|
kFsLibrary |
109 |
|
|
}; |
110 |
|
|
|
111 |
|
|
struct FileSystemInfo { |
112 |
|
547 |
FileSystemInfo() |
113 |
|
1094 |
: type(kFsFuse) |
114 |
|
547 |
, options_mgr(NULL) |
115 |
|
547 |
, wait_workspace(false) |
116 |
|
547 |
, foreground(false) { } |
117 |
|
|
/** |
118 |
|
|
* Name can is used to identify this particular instance of cvmfs in the |
119 |
|
|
* cache (directory). Normally it is the fully qualified repository name. |
120 |
|
|
* For libcvmfs and in other special mount conditions, it can be something |
121 |
|
|
* else. Only file systems with different names can share a cache because |
122 |
|
|
* the name is part of a lock file. |
123 |
|
|
*/ |
124 |
|
|
std::string name; |
125 |
|
|
|
126 |
|
|
/** |
127 |
|
|
* Used to fork & execve into different flavors of the binary, e.g. the |
128 |
|
|
* quota manager. |
129 |
|
|
*/ |
130 |
|
|
std::string exe_path; |
131 |
|
|
|
132 |
|
|
/** |
133 |
|
|
* Fuse mount point or libcvmfs. |
134 |
|
|
*/ |
135 |
|
|
Type type; |
136 |
|
|
|
137 |
|
|
/** |
138 |
|
|
* All further configuration has to be present in the options manager. |
139 |
|
|
*/ |
140 |
|
|
OptionsManager *options_mgr; |
141 |
|
|
|
142 |
|
|
/** |
143 |
|
|
* Decides if FileSystem construction should block if the workspace is |
144 |
|
|
* currently taken. This is used to coordinate fuse mounts where the next |
145 |
|
|
* mount happens while the previous fuse module is not yet fully cleaned |
146 |
|
|
* up. |
147 |
|
|
*/ |
148 |
|
|
bool wait_workspace; |
149 |
|
|
/** |
150 |
|
|
* The fuse module should not daemonize. That means the quota manager |
151 |
|
|
* should not daemonize, too, but print debug messages to stdout. |
152 |
|
|
*/ |
153 |
|
|
bool foreground; |
154 |
|
|
}; |
155 |
|
|
|
156 |
|
|
/** |
157 |
|
|
* Keeps information about I/O errors, e.g. writing local files, permanent |
158 |
|
|
* network errors, etc. It counts the number of errors and the timestamp |
159 |
|
|
* of the latest errors for consumption by monitoring tools such as Nagios |
160 |
|
|
*/ |
161 |
|
|
class IoErrorInfo { |
162 |
|
|
public: |
163 |
|
|
IoErrorInfo(); |
164 |
|
|
|
165 |
|
|
void Reset(); |
166 |
|
|
void AddIoError(); |
167 |
|
|
void SetCounter(perf::Counter *c); |
168 |
|
|
int64_t count(); |
169 |
|
|
time_t timestamp_last(); |
170 |
|
|
|
171 |
|
|
private: |
172 |
|
|
perf::Counter *counter_; |
173 |
|
|
time_t timestamp_last_; |
174 |
|
|
}; |
175 |
|
|
|
176 |
|
|
/** |
177 |
|
|
* No NFS maps. |
178 |
|
|
*/ |
179 |
|
|
static const unsigned kNfsNone = 0x00; |
180 |
|
|
/** |
181 |
|
|
* Normal NFS maps by leveldb |
182 |
|
|
*/ |
183 |
|
|
static const unsigned kNfsMaps = 0x01; |
184 |
|
|
/** |
185 |
|
|
* NFS maps maintained by sqlite so that they can reside on an NFS mount |
186 |
|
|
*/ |
187 |
|
|
static const unsigned kNfsMapsHa = 0x02; |
188 |
|
|
|
189 |
|
|
static FileSystem *Create(const FileSystemInfo &fs_info); |
190 |
|
|
~FileSystem(); |
191 |
|
|
|
192 |
|
|
// Used to setup logging before the file system object is created |
193 |
|
|
static void SetupLoggingStandalone(const OptionsManager &options_mgr, |
194 |
|
|
const std::string &prefix); |
195 |
|
|
|
196 |
|
666 |
bool IsNfsSource() { return nfs_mode_ & kNfsMaps; } |
197 |
|
14 |
bool IsHaNfsSource() { return nfs_mode_ & kNfsMapsHa; } |
198 |
|
|
void ResetErrorCounters(); |
199 |
|
|
void TearDown2ReadOnly(); |
200 |
|
|
void RemapCatalogFd(int from, int to); |
201 |
|
|
|
202 |
|
|
// Used in cvmfs' RestoreState to prevent change of cache manager type |
203 |
|
|
// during reload |
204 |
|
|
void ReplaceCacheManager(CacheManager *new_cache_mgr); |
205 |
|
|
|
206 |
|
1372 |
CacheManager *cache_mgr() { return cache_mgr_; } |
207 |
|
84 |
std::string cache_mgr_instance() { return cache_mgr_instance_; } |
208 |
|
|
std::string exe_path() { return exe_path_; } |
209 |
|
28 |
bool found_previous_crash() { return found_previous_crash_; } |
210 |
|
✗ |
Log2Histogram *hist_fs_lookup() { return hist_fs_lookup_; } |
211 |
|
✗ |
Log2Histogram *hist_fs_forget() { return hist_fs_forget_; } |
212 |
|
✗ |
Log2Histogram *hist_fs_forget_multi() { return hist_fs_forget_multi_; } |
213 |
|
✗ |
Log2Histogram *hist_fs_getattr() { return hist_fs_getattr_; } |
214 |
|
✗ |
Log2Histogram *hist_fs_readlink() { return hist_fs_readlink_; } |
215 |
|
✗ |
Log2Histogram *hist_fs_opendir() { return hist_fs_opendir_; } |
216 |
|
✗ |
Log2Histogram *hist_fs_releasedir() { return hist_fs_releasedir_; } |
217 |
|
✗ |
Log2Histogram *hist_fs_readdir() { return hist_fs_readdir_; } |
218 |
|
✗ |
Log2Histogram *hist_fs_open() { return hist_fs_open_; } |
219 |
|
✗ |
Log2Histogram *hist_fs_read() { return hist_fs_read_; } |
220 |
|
✗ |
Log2Histogram *hist_fs_release() { return hist_fs_release_; } |
221 |
|
|
|
222 |
|
✗ |
perf::Counter *n_fs_dir_open() { return n_fs_dir_open_; } |
223 |
|
✗ |
perf::Counter *n_fs_forget() { return n_fs_forget_; } |
224 |
|
✗ |
perf::Counter *n_fs_inode_replace() { return n_fs_inode_replace_; } |
225 |
|
✗ |
perf::Counter *n_fs_lookup() { return n_fs_lookup_; } |
226 |
|
✗ |
perf::Counter *n_fs_lookup_negative() { return n_fs_lookup_negative_; } |
227 |
|
✗ |
perf::Counter *n_fs_open() { return n_fs_open_; } |
228 |
|
✗ |
perf::Counter *n_fs_read() { return n_fs_read_; } |
229 |
|
✗ |
perf::Counter *n_fs_readlink() { return n_fs_readlink_; } |
230 |
|
99 |
perf::Counter *n_fs_stat() { return n_fs_stat_; } |
231 |
|
✗ |
perf::Counter *n_fs_stat_stale() { return n_fs_stat_stale_; } |
232 |
|
✗ |
perf::Counter *n_fs_statfs() { return n_fs_statfs_; } |
233 |
|
✗ |
perf::Counter *n_fs_statfs_cached() { return n_fs_statfs_cached_; } |
234 |
|
✗ |
IoErrorInfo *io_error_info() { return &io_error_info_; } |
235 |
|
526 |
std::string name() { return name_; } |
236 |
|
✗ |
NfsMaps *nfs_maps() { return nfs_maps_; } |
237 |
|
✗ |
perf::Counter *no_open_dirs() { return no_open_dirs_; } |
238 |
|
✗ |
perf::Counter *no_open_files() { return no_open_files_; } |
239 |
|
✗ |
perf::Counter *n_eio_total() { return n_eio_total_; } |
240 |
|
✗ |
perf::Counter *n_eio_01() { return n_eio_01_; } |
241 |
|
✗ |
perf::Counter *n_eio_02() { return n_eio_02_; } |
242 |
|
✗ |
perf::Counter *n_eio_03() { return n_eio_03_; } |
243 |
|
✗ |
perf::Counter *n_eio_04() { return n_eio_04_; } |
244 |
|
✗ |
perf::Counter *n_eio_05() { return n_eio_05_; } |
245 |
|
✗ |
perf::Counter *n_eio_06() { return n_eio_06_; } |
246 |
|
✗ |
perf::Counter *n_eio_07() { return n_eio_07_; } |
247 |
|
✗ |
perf::Counter *n_eio_08() { return n_eio_08_; } |
248 |
|
✗ |
perf::Counter *n_emfile() { return n_emfile_; } |
249 |
|
1313 |
OptionsManager *options_mgr() { return options_mgr_; } |
250 |
|
540 |
perf::Statistics *statistics() { return statistics_; } |
251 |
|
1218 |
Type type() { return type_; } |
252 |
|
554 |
cvmfs::Uuid *uuid_cache() { return uuid_cache_; } |
253 |
|
960 |
std::string workspace() { return workspace_; } |
254 |
|
|
|
255 |
|
|
protected: |
256 |
|
✗ |
void SetHasCustomVfs(bool setting) { has_custom_sqlitevfs_ = setting; } |
257 |
|
|
|
258 |
|
|
private: |
259 |
|
|
/** |
260 |
|
|
* Only one instance may be alive at any given time |
261 |
|
|
*/ |
262 |
|
|
static bool g_alive; |
263 |
|
|
static const char *kDefaultCacheBase; // /var/lib/cvmfs |
264 |
|
|
static const unsigned kDefaultQuotaLimit = 1024 * 1024 * 1024; // 1GB |
265 |
|
|
static const unsigned kDefaultNfiles = 8192; // if CVMFS_NFILES is unset |
266 |
|
|
static const char *kDefaultCacheMgrInstance; // "default" |
267 |
|
|
|
268 |
|
|
struct PosixCacheSettings { |
269 |
|
768 |
PosixCacheSettings() |
270 |
|
768 |
: is_shared(false) |
271 |
|
768 |
, is_alien(false) |
272 |
|
768 |
, is_managed(false) |
273 |
|
768 |
, avoid_rename(false) |
274 |
|
768 |
, cache_base_defined(false) |
275 |
|
768 |
, cache_dir_defined(false) |
276 |
|
768 |
, quota_limit(0) |
277 |
|
768 |
, do_refcount(true) { } |
278 |
|
|
bool is_shared; |
279 |
|
|
bool is_alien; |
280 |
|
|
bool is_managed; |
281 |
|
|
bool avoid_rename; |
282 |
|
|
bool cache_base_defined; |
283 |
|
|
bool cache_dir_defined; |
284 |
|
|
/** |
285 |
|
|
* Soft limit in bytes for the cache. The quota manager removes half the |
286 |
|
|
* cache when the limit is exceeded. |
287 |
|
|
*/ |
288 |
|
|
int64_t quota_limit; |
289 |
|
|
bool do_refcount; |
290 |
|
|
std::string cache_path; |
291 |
|
|
/** |
292 |
|
|
* Different from cache_path only if CVMFS_WORKSPACE or |
293 |
|
|
* CVMFS_CACHE_WORKSPACE is set. |
294 |
|
|
*/ |
295 |
|
|
std::string workspace; |
296 |
|
|
}; |
297 |
|
|
|
298 |
|
|
static void LogSqliteError(void *user_data __attribute__((unused)), |
299 |
|
|
int sqlite_extended_error, |
300 |
|
|
const char *message); |
301 |
|
|
|
302 |
|
|
explicit FileSystem(const FileSystemInfo &fs_info); |
303 |
|
|
|
304 |
|
|
static void SetupGlobalEnvironmentParams(); |
305 |
|
|
void SetupLogging(); |
306 |
|
|
void CreateStatistics(); |
307 |
|
|
void SetupSqlite(); |
308 |
|
|
bool DetermineNfsMode(); |
309 |
|
|
bool SetupWorkspace(); |
310 |
|
|
bool SetupCwd(); |
311 |
|
|
bool LockWorkspace(); |
312 |
|
|
bool SetupCrashGuard(); |
313 |
|
|
bool SetupNfsMaps(); |
314 |
|
|
void SetupUuid(); |
315 |
|
|
|
316 |
|
|
std::string MkCacheParm(const std::string &generic_parameter, |
317 |
|
|
const std::string &instance); |
318 |
|
|
bool CheckInstanceName(const std::string &instance); |
319 |
|
|
bool TriageCacheMgr(); |
320 |
|
|
CacheManager *SetupCacheMgr(const std::string &instance); |
321 |
|
|
CacheManager *SetupPosixCacheMgr(const std::string &instance); |
322 |
|
|
CacheManager *SetupRamCacheMgr(const std::string &instance); |
323 |
|
|
CacheManager *SetupTieredCacheMgr(const std::string &instance); |
324 |
|
|
CacheManager *SetupExternalCacheMgr(const std::string &instance); |
325 |
|
|
PosixCacheSettings DeterminePosixCacheSettings(const std::string &instance); |
326 |
|
|
bool CheckPosixCacheSettings(const PosixCacheSettings &settings); |
327 |
|
|
bool SetupPosixQuotaMgr(const PosixCacheSettings &settings, |
328 |
|
|
CacheManager *cache_mgr); |
329 |
|
|
|
330 |
|
|
// See FileSystemInfo for the following fields |
331 |
|
|
std::string name_; |
332 |
|
|
std::string exe_path_; |
333 |
|
|
Type type_; |
334 |
|
|
/** |
335 |
|
|
* Not owned by the FileSystem object |
336 |
|
|
*/ |
337 |
|
|
OptionsManager *options_mgr_; |
338 |
|
|
bool wait_workspace_; |
339 |
|
|
bool foreground_; |
340 |
|
|
|
341 |
|
|
perf::Counter *n_fs_open_; |
342 |
|
|
perf::Counter *n_fs_dir_open_; |
343 |
|
|
perf::Counter *n_fs_lookup_; |
344 |
|
|
perf::Counter *n_fs_lookup_negative_; |
345 |
|
|
perf::Counter *n_fs_stat_; |
346 |
|
|
perf::Counter *n_fs_stat_stale_; |
347 |
|
|
perf::Counter *n_fs_statfs_; |
348 |
|
|
perf::Counter *n_fs_statfs_cached_; |
349 |
|
|
perf::Counter *n_fs_read_; |
350 |
|
|
perf::Counter *n_fs_readlink_; |
351 |
|
|
perf::Counter *n_fs_forget_; |
352 |
|
|
perf::Counter *n_fs_inode_replace_; |
353 |
|
|
perf::Counter *no_open_files_; |
354 |
|
|
perf::Counter *no_open_dirs_; |
355 |
|
|
perf::Counter *n_eio_total_; |
356 |
|
|
perf::Counter *n_eio_01_; |
357 |
|
|
perf::Counter *n_eio_02_; |
358 |
|
|
perf::Counter *n_eio_03_; |
359 |
|
|
perf::Counter *n_eio_04_; |
360 |
|
|
perf::Counter *n_eio_05_; |
361 |
|
|
perf::Counter *n_eio_06_; |
362 |
|
|
perf::Counter *n_eio_07_; |
363 |
|
|
perf::Counter *n_eio_08_; |
364 |
|
|
perf::Counter *n_emfile_; |
365 |
|
|
IoErrorInfo io_error_info_; |
366 |
|
|
perf::Statistics *statistics_; |
367 |
|
|
|
368 |
|
|
Log2Histogram *hist_fs_lookup_; |
369 |
|
|
Log2Histogram *hist_fs_forget_; |
370 |
|
|
Log2Histogram *hist_fs_forget_multi_; |
371 |
|
|
Log2Histogram *hist_fs_getattr_; |
372 |
|
|
Log2Histogram *hist_fs_readlink_; |
373 |
|
|
Log2Histogram *hist_fs_opendir_; |
374 |
|
|
Log2Histogram *hist_fs_releasedir_; |
375 |
|
|
Log2Histogram *hist_fs_readdir_; |
376 |
|
|
Log2Histogram *hist_fs_open_; |
377 |
|
|
Log2Histogram *hist_fs_read_; |
378 |
|
|
Log2Histogram *hist_fs_release_; |
379 |
|
|
|
380 |
|
|
/** |
381 |
|
|
* A writeable local directory. Only small amounts of data (few bytes) will |
382 |
|
|
* be stored here. Needed because the cache can be read-only. The workspace |
383 |
|
|
* and the cache directory can be identical. A workspace can be shared among |
384 |
|
|
* FileSystem instances if their name is different. |
385 |
|
|
*/ |
386 |
|
|
std::string workspace_; |
387 |
|
|
/** |
388 |
|
|
* During setup, the fuse module changes its working directory to workspace. |
389 |
|
|
* Afterwards, workspace_ is ".". Store the original one in |
390 |
|
|
* workspace_fullpath_ |
391 |
|
|
*/ |
392 |
|
|
std::string workspace_fullpath_; |
393 |
|
|
int fd_workspace_lock_; |
394 |
|
|
std::string path_workspace_lock_; |
395 |
|
|
|
396 |
|
|
/** |
397 |
|
|
* An empty file that is removed on proper shutdown. |
398 |
|
|
*/ |
399 |
|
|
std::string path_crash_guard_; |
400 |
|
|
|
401 |
|
|
/** |
402 |
|
|
* A crash guard was found, thus we assume the file system was not shutdown |
403 |
|
|
* properly last time. |
404 |
|
|
*/ |
405 |
|
|
bool found_previous_crash_; |
406 |
|
|
|
407 |
|
|
/** |
408 |
|
|
* Only needed for fuse to detect and prevent double mounting at the same |
409 |
|
|
* location. |
410 |
|
|
*/ |
411 |
|
|
std::string mountpoint_; |
412 |
|
|
/** |
413 |
|
|
* The user-provided name of the parimay cache manager or 'default' if none |
414 |
|
|
* is specified. |
415 |
|
|
*/ |
416 |
|
|
std::string cache_mgr_instance_; |
417 |
|
|
/** |
418 |
|
|
* Keep track of all the cache instances to detect circular definitions with |
419 |
|
|
* the tiered cache. |
420 |
|
|
*/ |
421 |
|
|
std::set<std::string> constructed_instances_; |
422 |
|
|
std::string nfs_maps_dir_; |
423 |
|
|
/** |
424 |
|
|
* Combination of kNfs... flags |
425 |
|
|
*/ |
426 |
|
|
unsigned nfs_mode_; |
427 |
|
|
CacheManager *cache_mgr_; |
428 |
|
|
/** |
429 |
|
|
* Persistent for the cache directory + name combination. It is used in the |
430 |
|
|
* Geo-API to allow for per-client responses when no proxy is used. |
431 |
|
|
*/ |
432 |
|
|
cvmfs::Uuid *uuid_cache_; |
433 |
|
|
|
434 |
|
|
/** |
435 |
|
|
* TODO(jblomer): Move to MountPoint. Tricky because of the sqlite maps |
436 |
|
|
* and the sqlite configuration done for the file catalogs. |
437 |
|
|
*/ |
438 |
|
|
NfsMaps *nfs_maps_; |
439 |
|
|
/** |
440 |
|
|
* Used internally to remember if the Sqlite memory manager need to be shut |
441 |
|
|
* down. |
442 |
|
|
*/ |
443 |
|
|
bool has_custom_sqlitevfs_; |
444 |
|
|
}; |
445 |
|
|
|
446 |
|
|
/** |
447 |
|
|
* The StatfsCache class is a class purely designed as "struct" (= holding |
448 |
|
|
* object for all its parameters). |
449 |
|
|
* All its logic, including the locking mechanism, is implemented in the |
450 |
|
|
* function cvmfs_statfs in cvmfs.cc |
451 |
|
|
*/ |
452 |
|
|
class StatfsCache : SingleCopy { |
453 |
|
|
public: |
454 |
|
286 |
explicit StatfsCache(uint64_t cacheValid) |
455 |
|
286 |
: expiry_deadline_(0), cache_timeout_(cacheValid) { |
456 |
|
286 |
memset(&info_, 0, sizeof(info_)); |
457 |
|
286 |
lock_ = reinterpret_cast<pthread_mutex_t *>( |
458 |
|
286 |
smalloc(sizeof(pthread_mutex_t))); |
459 |
|
286 |
const int retval = pthread_mutex_init(lock_, NULL); |
460 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 286 times.
|
286 |
assert(retval == 0); |
461 |
|
286 |
} |
462 |
|
286 |
~StatfsCache() { |
463 |
|
286 |
pthread_mutex_destroy(lock_); |
464 |
|
286 |
free(lock_); |
465 |
|
286 |
} |
466 |
|
✗ |
uint64_t *expiry_deadline() { return &expiry_deadline_; } |
467 |
|
✗ |
const uint64_t cache_timeout() { return cache_timeout_; } |
468 |
|
✗ |
struct statvfs *info() { return &info_; } |
469 |
|
✗ |
pthread_mutex_t *lock() { return lock_; } |
470 |
|
|
|
471 |
|
|
private: |
472 |
|
|
pthread_mutex_t *lock_; |
473 |
|
|
// Timestamp/deadline when the currently cached statvfs info_ becomes invalid |
474 |
|
|
uint64_t expiry_deadline_; |
475 |
|
|
// Time in seconds how long statvfs info_ should be cached |
476 |
|
|
uint64_t cache_timeout_; |
477 |
|
|
struct statvfs info_; |
478 |
|
|
}; |
479 |
|
|
|
480 |
|
|
/** |
481 |
|
|
* A MountPoint provides a clip around all the different *Manager objects that |
482 |
|
|
* in combination represent a mounted cvmfs repository. Its main purpose is |
483 |
|
|
* the controlled construction and deconstruction of the involved ensemble of |
484 |
|
|
* classes based on the information passed from an options manager. |
485 |
|
|
* |
486 |
|
|
* A MountPoint is constructed on top of a successfully constructed FileSystem. |
487 |
|
|
* |
488 |
|
|
* We use pointers to manager classes to make the order of construction and |
489 |
|
|
* destruction explicit and also to keep the include list for this header small. |
490 |
|
|
*/ |
491 |
|
|
class MountPoint : SingleCopy, public BootFactory { |
492 |
|
|
public: |
493 |
|
|
/** |
494 |
|
|
* If catalog reload fails, try again in 3 minutes |
495 |
|
|
*/ |
496 |
|
|
static const unsigned kShortTermTTL = 180; |
497 |
|
|
static const time_t kIndefiniteDeadline = time_t(-1); |
498 |
|
|
|
499 |
|
|
static MountPoint *Create(const std::string &fqrn, |
500 |
|
|
FileSystem *file_system, |
501 |
|
|
OptionsManager *options_mgr = NULL); |
502 |
|
|
~MountPoint(); |
503 |
|
|
|
504 |
|
|
unsigned GetMaxTtlMn(); |
505 |
|
|
unsigned GetEffectiveTtlSec(); |
506 |
|
|
void SetMaxTtlMn(unsigned value_minutes); |
507 |
|
|
void ReEvaluateAuthz(); |
508 |
|
|
|
509 |
|
✗ |
AuthzSessionManager *authz_session_mgr() { return authz_session_mgr_; } |
510 |
|
✗ |
BackoffThrottle *backoff_throttle() { return backoff_throttle_; } |
511 |
|
595 |
catalog::ClientCatalogManager *catalog_mgr() { return catalog_mgr_; } |
512 |
|
✗ |
ChunkTables *chunk_tables() { return chunk_tables_; } |
513 |
|
94 |
download::DownloadManager *download_mgr() { return download_mgr_; } |
514 |
|
56 |
download::DownloadManager *external_download_mgr() { |
515 |
|
56 |
return external_download_mgr_; |
516 |
|
|
} |
517 |
|
✗ |
file_watcher::FileWatcher *resolv_conf_watcher() { |
518 |
|
✗ |
return resolv_conf_watcher_; |
519 |
|
|
} |
520 |
|
392 |
cvmfs::Fetcher *fetcher() { return fetcher_; } |
521 |
|
✗ |
bool fixed_catalog() { return fixed_catalog_; } |
522 |
|
432 |
std::string fqrn() const { return fqrn_; } |
523 |
|
|
// TODO(jblomer): use only a singler fetcher object |
524 |
|
✗ |
cvmfs::Fetcher *external_fetcher() { return external_fetcher_; } |
525 |
|
392 |
FileSystem *file_system() { return file_system_; } |
526 |
|
✗ |
MagicXattrManager *magic_xattr_mgr() { return magic_xattr_mgr_; } |
527 |
|
20 |
bool has_membership_req() { return has_membership_req_; } |
528 |
|
✗ |
bool enforce_acls() { return enforce_acls_; } |
529 |
|
✗ |
bool cache_symlinks() { return cache_symlinks_; } |
530 |
|
✗ |
bool fuse_expire_entry() { return fuse_expire_entry_; } |
531 |
|
✗ |
catalog::InodeAnnotation *inode_annotation() { return inode_annotation_; } |
532 |
|
✗ |
glue::InodeTracker *inode_tracker() { return inode_tracker_; } |
533 |
|
✗ |
lru::InodeCache *inode_cache() { return inode_cache_; } |
534 |
|
✗ |
double kcache_timeout_sec() { return kcache_timeout_sec_; } |
535 |
|
194 |
lru::Md5PathCache *md5path_cache() { return md5path_cache_; } |
536 |
|
✗ |
std::string membership_req() { return membership_req_; } |
537 |
|
✗ |
glue::DentryTracker *dentry_tracker() { return dentry_tracker_; } |
538 |
|
✗ |
glue::PageCacheTracker *page_cache_tracker() { return page_cache_tracker_; } |
539 |
|
✗ |
lru::PathCache *path_cache() { return path_cache_; } |
540 |
|
✗ |
std::string repository_tag() { return repository_tag_; } |
541 |
|
✗ |
SimpleChunkTables *simple_chunk_tables() { return simple_chunk_tables_; } |
542 |
|
1176 |
perf::Statistics *statistics() { return statistics_; } |
543 |
|
✗ |
perf::TelemetryAggregator *telemetry_aggr() { return telemetry_aggr_; } |
544 |
|
392 |
signature::SignatureManager *signature_mgr() { return signature_mgr_; } |
545 |
|
✗ |
uid_t talk_socket_uid() { return talk_socket_uid_; } |
546 |
|
✗ |
gid_t talk_socket_gid() { return talk_socket_gid_; } |
547 |
|
✗ |
std::string talk_socket_path() { return talk_socket_path_; } |
548 |
|
✗ |
Tracer *tracer() { return tracer_; } |
549 |
|
✗ |
cvmfs::Uuid *uuid() { return uuid_; } |
550 |
|
✗ |
StatfsCache *statfs_cache() { return statfs_cache_; } |
551 |
|
|
|
552 |
|
|
bool ReloadBlacklists(); |
553 |
|
|
void DisableCacheSymlinks(); |
554 |
|
|
void EnableFuseExpireEntry(); |
555 |
|
|
|
556 |
|
|
MountPoint(const std::string &fqrn, |
557 |
|
|
FileSystem *file_system, |
558 |
|
|
OptionsManager *options_mgr); |
559 |
|
|
|
560 |
|
|
private: |
561 |
|
|
/** |
562 |
|
|
* The maximum TTL can be used to cap a root catalogs registered ttl. By |
563 |
|
|
* default this is disabled (= 0). |
564 |
|
|
*/ |
565 |
|
|
static const unsigned kDefaultMaxTtlSec = 0; |
566 |
|
|
/** |
567 |
|
|
* Let fuse cache dentries for 1 minute. |
568 |
|
|
*/ |
569 |
|
|
static const unsigned kDefaultKCacheTtlSec = 60; |
570 |
|
|
/** |
571 |
|
|
* Number of Md5Path entries in the libcvmfs cache. |
572 |
|
|
*/ |
573 |
|
|
static const unsigned kLibPathCacheSize = 32000; |
574 |
|
|
/** |
575 |
|
|
* Cache seven times more md5 paths than inodes in the fuse module. |
576 |
|
|
*/ |
577 |
|
|
static const unsigned kInodeCacheFactor = 7; |
578 |
|
|
/** |
579 |
|
|
* Default to 16M RAM for meta-data caches; does not include the inode tracker |
580 |
|
|
*/ |
581 |
|
|
static const unsigned kDefaultMemcacheSize = 16 * 1024 * 1024; |
582 |
|
|
/** |
583 |
|
|
* Where to look for external authz helpers. |
584 |
|
|
*/ |
585 |
|
|
static const char *kDefaultAuthzSearchPath; // "/usr/libexec/cvmfs/authz" |
586 |
|
|
/** |
587 |
|
|
* Maximum number of concurrent HTTP connections. |
588 |
|
|
*/ |
589 |
|
|
static const unsigned kDefaultNumConnections = 16; |
590 |
|
|
/** |
591 |
|
|
* Default network timeout |
592 |
|
|
*/ |
593 |
|
|
static const unsigned kDefaultTimeoutSec = 5; |
594 |
|
|
static const unsigned kDefaultRetries = 1; |
595 |
|
|
static const unsigned kDefaultBackoffInitMs = 2000; |
596 |
|
|
static const unsigned kDefaultBackoffMaxMs = 10000; |
597 |
|
|
/** |
598 |
|
|
* Memory buffer sizes for an activated tracer |
599 |
|
|
*/ |
600 |
|
|
static const unsigned kTracerBufferSize = 8192; |
601 |
|
|
static const unsigned kTracerFlushThreshold = 7000; |
602 |
|
|
static const char *kDefaultBlacklist; // "/etc/cvmfs/blacklist" |
603 |
|
|
/** |
604 |
|
|
* Default values for telemetry aggregator |
605 |
|
|
*/ |
606 |
|
|
static const int kDefaultTelemetrySendRateSec = 5 * 60; // 5min |
607 |
|
|
static const int kMinimumTelemetrySendRateSec = 5; // 5sec |
608 |
|
|
|
609 |
|
|
|
610 |
|
|
void CreateStatistics(); |
611 |
|
|
void CreateAuthz(); |
612 |
|
|
bool CreateSignatureManager(); |
613 |
|
|
bool CheckBlacklists(); |
614 |
|
|
bool CreateDownloadManagers(); |
615 |
|
|
bool CreateResolvConfWatcher(); |
616 |
|
|
void CreateFetchers(); |
617 |
|
|
bool CreateCatalogManager(); |
618 |
|
|
void CreateTables(); |
619 |
|
|
bool CreateTracer(); |
620 |
|
|
bool SetupBehavior(); |
621 |
|
|
void SetupDnsTuning(download::DownloadManager *manager); |
622 |
|
|
void SetupHttpTuning(); |
623 |
|
|
bool SetupExternalDownloadMgr(bool dogeosort); |
624 |
|
|
void SetupInodeAnnotation(); |
625 |
|
|
bool SetupOwnerMaps(); |
626 |
|
|
bool DetermineRootHash(shash::Any *root_hash); |
627 |
|
|
bool FetchHistory(std::string *history_path); |
628 |
|
|
std::string ReplaceHosts(std::string hosts); |
629 |
|
|
std::string GetUniqFileSuffix(); |
630 |
|
|
|
631 |
|
|
std::string fqrn_; |
632 |
|
|
cvmfs::Uuid *uuid_; |
633 |
|
|
/** |
634 |
|
|
* In contrast to the manager objects, the FileSystem is not owned. |
635 |
|
|
*/ |
636 |
|
|
FileSystem *file_system_; |
637 |
|
|
/** |
638 |
|
|
* The options manager is not owned. |
639 |
|
|
*/ |
640 |
|
|
OptionsManager *options_mgr_; |
641 |
|
|
|
642 |
|
|
perf::Statistics *statistics_; |
643 |
|
|
perf::TelemetryAggregator *telemetry_aggr_; |
644 |
|
|
AuthzFetcher *authz_fetcher_; |
645 |
|
|
AuthzSessionManager *authz_session_mgr_; |
646 |
|
|
AuthzAttachment *authz_attachment_; |
647 |
|
|
BackoffThrottle *backoff_throttle_; |
648 |
|
|
signature::SignatureManager *signature_mgr_; |
649 |
|
|
download::DownloadManager *download_mgr_; |
650 |
|
|
download::DownloadManager *external_download_mgr_; |
651 |
|
|
cvmfs::Fetcher *fetcher_; |
652 |
|
|
cvmfs::Fetcher *external_fetcher_; |
653 |
|
|
catalog::InodeAnnotation *inode_annotation_; |
654 |
|
|
catalog::ClientCatalogManager *catalog_mgr_; |
655 |
|
|
ChunkTables *chunk_tables_; |
656 |
|
|
SimpleChunkTables *simple_chunk_tables_; |
657 |
|
|
lru::InodeCache *inode_cache_; |
658 |
|
|
lru::PathCache *path_cache_; |
659 |
|
|
lru::Md5PathCache *md5path_cache_; |
660 |
|
|
Tracer *tracer_; |
661 |
|
|
glue::InodeTracker *inode_tracker_; |
662 |
|
|
glue::DentryTracker *dentry_tracker_; |
663 |
|
|
glue::PageCacheTracker *page_cache_tracker_; |
664 |
|
|
MagicXattrManager *magic_xattr_mgr_; |
665 |
|
|
StatfsCache *statfs_cache_; |
666 |
|
|
|
667 |
|
|
file_watcher::FileWatcher *resolv_conf_watcher_; |
668 |
|
|
|
669 |
|
|
unsigned max_ttl_sec_; |
670 |
|
|
pthread_mutex_t lock_max_ttl_; |
671 |
|
|
double kcache_timeout_sec_; |
672 |
|
|
bool fixed_catalog_; |
673 |
|
|
bool enforce_acls_; |
674 |
|
|
bool cache_symlinks_; |
675 |
|
|
bool fuse_expire_entry_; |
676 |
|
|
std::string repository_tag_; |
677 |
|
|
std::vector<std::string> blacklist_paths_; |
678 |
|
|
|
679 |
|
|
// TODO(jblomer): this should go in the catalog manager |
680 |
|
|
std::string membership_req_; |
681 |
|
|
bool has_membership_req_; |
682 |
|
|
|
683 |
|
|
std::string talk_socket_path_; |
684 |
|
|
uid_t talk_socket_uid_; |
685 |
|
|
gid_t talk_socket_gid_; |
686 |
|
|
}; // class MointPoint |
687 |
|
|
|
688 |
|
|
#endif // CVMFS_MOUNTPOINT_H_ |
689 |
|
|
|