GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/mountpoint.h Lines: 33 66 50.0 %
Date: 2019-02-03 02:48:13 Branches: 0 0 - %

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 <unistd.h>
12
13
#include <ctime>
14
#include <set>
15
#include <string>
16
#include <vector>
17
18
#include "cache.h"
19
#include "file_watcher.h"
20
#include "gtest/gtest_prod.h"
21
#include "hash.h"
22
#include "loader.h"
23
#include "util/pointer.h"
24
25
class AuthzAttachment;
26
class AuthzFetcher;
27
class AuthzSessionManager;
28
class BackoffThrottle;
29
class CacheManager;
30
namespace catalog {
31
class ClientCatalogManager;
32
class InodeGenerationAnnotation;
33
}
34
struct ChunkTables;
35
namespace cvmfs {
36
class Fetcher;
37
class Uuid;
38
}
39
namespace download {
40
class DownloadManager;
41
}
42
namespace glue {
43
class InodeTracker;
44
}
45
namespace lru {
46
class InodeCache;
47
class Md5PathCache;
48
class PathCache;
49
}
50
class NfsMaps;
51
class OptionsManager;
52
namespace perf {
53
class Counter;
54
class Statistics;
55
}
56
namespace signature {
57
class SignatureManager;
58
}
59
class SimpleChunkTables;
60
class Tracer;
61
62
63
/**
64
 * Construction of FileSystem and MountPoint can go wrong.  In this case, we'd
65
 * like to know why.  This is a base class for both FileSystem and MountPoint.
66
 */
67
195
class BootFactory {
68
 public:
69
198
  BootFactory() : boot_status_(loader::kFailUnknown) { }
70
8
  bool IsValid() { return boot_status_ == loader::kFailOk; }
71
185
  loader::Failures boot_status() { return boot_status_; }
72
4
  std::string boot_error() { return boot_error_; }
73
74
  /**
75
   * Used in the fuse module to artificially set boot errors that are specific
76
   * to the fuse boot procedure.
77
   */
78
  void set_boot_status(loader::Failures code) { boot_status_ = code; }
79
80
 protected:
81
  loader::Failures boot_status_;
82
  std::string boot_error_;
83
};
84
85
86
/**
87
 * The FileSystem object initializes cvmfs' global state.  It sets up sqlite and
88
 * the cache directory and it can contain multiple mount points.  It currently
89
 * does so only for libcvmfs; the cvmfs fuse module has exactly one FileSystem
90
 * object and one MountPoint object.
91
 */
92
class FileSystem : SingleCopy, public BootFactory {
93
  FRIEND_TEST(T_MountPoint, MkCacheParm);
94
  FRIEND_TEST(T_MountPoint, CacheSettings);
95
  FRIEND_TEST(T_MountPoint, CheckInstanceName);
96
  FRIEND_TEST(T_MountPoint, CheckPosixCacheSettings);
97
98
 public:
99
  enum Type {
100
    kFsFuse = 0,
101
    kFsLibrary
102
  };
103
104
70
  struct FileSystemInfo {
105
72
    FileSystemInfo()
106
      : type(kFsFuse)
107
      , options_mgr(NULL)
108
      , wait_workspace(false)
109
72
      , foreground(false) { }
110
    /**
111
     * Name can is used to identify this particular instance of cvmfs in the
112
     * cache (directory).  Normally it is the fully qualified repository name.
113
     * For libcvmfs and in other special mount conditions, it can be something
114
     * else.  Only file systems with different names can share a cache because
115
     * the name is part of a lock file.
116
     */
117
    std::string name;
118
119
    /**
120
     * Used to fork & execve into different flavors of the binary, e.g. the
121
     * quota manager.
122
     */
123
    std::string exe_path;
124
125
    /**
126
     * Fuse mount point or libcvmfs.
127
     */
128
    Type type;
129
130
    /**
131
     * All further configuration has to be present in the options manager.
132
     */
133
    OptionsManager *options_mgr;
134
135
    /**
136
     * Decides if FileSystem construction should block if the workspace is
137
     * currently taken.  This is used to coordinate fuse mounts where the next
138
     * mount happens while the previous fuse module is not yet fully cleaned
139
     * up.
140
     */
141
    bool wait_workspace;
142
    /**
143
     * The fuse module should not daemonize.  That means the quota manager
144
     * should not daemonize, too, but print debug messages to stdout.
145
     */
146
    bool foreground;
147
  };
148
149
  /**
150
   * No NFS maps.
151
   */
152
  static const unsigned kNfsNone = 0x00;
153
  /**
154
   * Normal NFS maps by leveldb
155
   */
156
  static const unsigned kNfsMaps = 0x01;
157
  /**
158
   * NFS maps maintained by sqlite so that they can reside on an NFS mount
159
   */
160
  static const unsigned kNfsMapsHa = 0x02;
161
162
  static FileSystem *Create(const FileSystemInfo &fs_info);
163
  ~FileSystem();
164
165
52
  bool IsNfsSource() { return nfs_mode_ & kNfsMaps; }
166
3
  bool IsHaNfsSource() { return nfs_mode_ & kNfsMapsHa; }
167
  void ResetErrorCounters();
168
  void TearDown2ReadOnly();
169
170
163
  CacheManager *cache_mgr() { return cache_mgr_; }
171
14
  std::string cache_mgr_instance() { return cache_mgr_instance_; }
172
  std::string exe_path() { return exe_path_; }
173
4
  bool found_previous_crash() { return found_previous_crash_; }
174
  perf::Counter *n_fs_dir_open() { return n_fs_dir_open_; }
175
  perf::Counter *n_fs_forget() { return n_fs_forget_; }
176
  perf::Counter *n_fs_lookup() { return n_fs_lookup_; }
177
  perf::Counter *n_fs_lookup_negative() { return n_fs_lookup_negative_; }
178
  perf::Counter *n_fs_open() { return n_fs_open_; }
179
  perf::Counter *n_fs_read() { return n_fs_read_; }
180
  perf::Counter *n_fs_readlink() { return n_fs_readlink_; }
181
23
  perf::Counter *n_fs_stat() { return n_fs_stat_; }
182
  perf::Counter *n_io_error() { return n_io_error_; }
183
59
  std::string name() { return name_; }
184
  NfsMaps *nfs_maps() { return nfs_maps_; }
185
  perf::Counter *no_open_dirs() { return no_open_dirs_; }
186
  perf::Counter *no_open_files() { return no_open_files_; }
187
190
  OptionsManager *options_mgr() { return options_mgr_; }
188
61
  perf::Statistics *statistics() { return statistics_; }
189
155
  Type type() { return type_; }
190
63
  cvmfs::Uuid *uuid_cache() { return uuid_cache_; }
191
125
  std::string workspace() { return workspace_; }
192
193
 private:
194
  /**
195
   * Only one instance may be alive at any given time
196
   */
197
  static bool g_alive;
198
  static const char *kDefaultCacheBase;  // /var/lib/cvmfs
199
  static const unsigned kDefaultQuotaLimit = 1024 * 1024 * 1024;  // 1GB
200
  static const unsigned kDefaultNfiles = 8192;  // if CVMFS_NFILES is unset
201
  static const char *kDefaultCacheMgrInstance;  // "default"
202
203
120
  struct PosixCacheSettings {
204
120
    PosixCacheSettings() :
205
      is_shared(false), is_alien(false), is_managed(false),
206
      avoid_rename(false), cache_base_defined(false), cache_dir_defined(false),
207
120
      quota_limit(0)
208
      { }
209
    bool is_shared;
210
    bool is_alien;
211
    bool is_managed;
212
    bool avoid_rename;
213
    bool cache_base_defined;
214
    bool cache_dir_defined;
215
    /**
216
     * Soft limit in bytes for the cache.  The quota manager removes half the
217
     * cache when the limit is exceeded.
218
     */
219
    int64_t quota_limit;
220
    std::string cache_path;
221
    /**
222
     * Different from cache_path only if CVMFS_WORKSPACE or
223
     * CVMFS_CACHE_WORKSPACE is set.
224
     */
225
    std::string workspace;
226
  };
227
228
  static void LogSqliteError(void *user_data __attribute__((unused)),
229
                             int sqlite_extended_error,
230
                             const char *message);
231
232
  explicit FileSystem(const FileSystemInfo &fs_info);
233
234
  void SetupLogging();
235
  void CreateStatistics();
236
  void SetupSqlite();
237
  bool DetermineNfsMode();
238
  bool SetupWorkspace();
239
  bool SetupCwd();
240
  bool LockWorkspace();
241
  bool SetupCrashGuard();
242
  bool SetupNfsMaps();
243
  void SetupUuid();
244
245
  std::string MkCacheParm(const std::string &generic_parameter,
246
                          const std::string &instance);
247
  bool CheckInstanceName(const std::string &instance);
248
  bool TriageCacheMgr();
249
  CacheManager *SetupCacheMgr(const std::string &instance);
250
  CacheManager *SetupPosixCacheMgr(const std::string &instance);
251
  CacheManager *SetupRamCacheMgr(const std::string &instance);
252
  CacheManager *SetupTieredCacheMgr(const std::string &instance);
253
  CacheManager *SetupExternalCacheMgr(const std::string &instance);
254
  PosixCacheSettings DeterminePosixCacheSettings(const std::string &instance);
255
  bool CheckPosixCacheSettings(const PosixCacheSettings &settings);
256
  bool SetupPosixQuotaMgr(const PosixCacheSettings &settings,
257
                          CacheManager *cache_mgr);
258
259
  // See FileSystemInfo for the following fields
260
  std::string name_;
261
  std::string exe_path_;
262
  Type type_;
263
  /**
264
   * Not owned by the FileSystem object
265
   */
266
  OptionsManager *options_mgr_;
267
  bool wait_workspace_;
268
  bool foreground_;
269
270
  perf::Counter *n_fs_open_;
271
  perf::Counter *n_fs_dir_open_;
272
  perf::Counter *n_fs_lookup_;
273
  perf::Counter *n_fs_lookup_negative_;
274
  perf::Counter *n_fs_stat_;
275
  perf::Counter *n_fs_read_;
276
  perf::Counter *n_fs_readlink_;
277
  perf::Counter *n_fs_forget_;
278
  perf::Counter *n_io_error_;
279
  perf::Counter *no_open_files_;
280
  perf::Counter *no_open_dirs_;
281
  perf::Statistics *statistics_;
282
283
  /**
284
   * A writeable local directory.  Only small amounts of data (few bytes) will
285
   * be stored here.  Needed because the cache can be read-only.  The workspace
286
   * and the cache directory can be identical.  A workspace can be shared among
287
   * FileSystem instances if their name is different.
288
   */
289
  std::string workspace_;
290
  /**
291
   * During setup, the fuse module changes its working directory to workspace.
292
   * Afterwards, workspace_ is ".".  Store the original one in
293
   * workspace_fullpath_
294
   */
295
  std::string workspace_fullpath_;
296
  int fd_workspace_lock_;
297
  std::string path_workspace_lock_;
298
299
  /**
300
   * An empty file that is removed on proper shutdown.
301
   */
302
  std::string path_crash_guard_;
303
304
  /**
305
   * A crash guard was found, thus we assume the file system was not shutdown
306
   * properly last time.
307
   */
308
  bool found_previous_crash_;
309
310
  /**
311
   * Only needed for fuse to detect and prevent double mounting at the same
312
   * location.
313
   */
314
  std::string mountpoint_;
315
  /**
316
   * The user-provided name of the parimay cache manager or 'default' if none
317
   * is specified.
318
   */
319
  std::string cache_mgr_instance_;
320
  /**
321
   * Keep track of all the cache instances to detect circular definitions with
322
   * the tiered cache.
323
   */
324
  std::set<std::string> constructed_instances_;
325
  std::string nfs_maps_dir_;
326
  /**
327
   * Combination of kNfs... flags
328
   */
329
  unsigned nfs_mode_;
330
  CacheManager *cache_mgr_;
331
  /**
332
   * Persistent for the cache directory + name combination.  It is used in the
333
   * Geo-API to allow for per-client responses when no proxy is used.
334
   */
335
  cvmfs::Uuid *uuid_cache_;
336
337
  /**
338
   * TODO(jblomer): Move to MountPoint. Tricky because of the sqlite maps
339
   * and the sqlite configuration done for the file catalogs.
340
   */
341
  NfsMaps *nfs_maps_;
342
  /**
343
   * Used internally to remember if the Sqlite memory manager need to be shut
344
   * down.
345
   */
346
  bool has_custom_sqlitevfs_;
347
};
348
349
350
/**
351
 * A MountPoint provides a clip around all the different *Manager objects that
352
 * in combination represent a mounted cvmfs repository.  Its main purpose is
353
 * the controlled construction and deconstruction of the involved ensemble of
354
 * classes based on the information passed from an options manager.
355
 *
356
 * A MountPoint is constructed on top of a successfully constructed FileSystem.
357
 *
358
 * We use pointers to manager classes to make the order of construction and
359
 * destruction explicit and also to keep the include list for this header small.
360
 */
361
class MountPoint : SingleCopy, public BootFactory {
362
 public:
363
  /**
364
   * If catalog reload fails, try again in 3 minutes
365
   */
366
  static const unsigned kShortTermTTL = 180;
367
  static const time_t kIndefiniteDeadline = time_t(-1);
368
369
  static MountPoint *Create(const std::string &fqrn,
370
                            FileSystem *file_system,
371
                            OptionsManager *options_mgr = NULL);
372
  ~MountPoint();
373
374
  unsigned GetMaxTtlMn();
375
  unsigned GetEffectiveTtlSec();
376
  void SetMaxTtlMn(unsigned value_minutes);
377
  void ReEvaluateAuthz();
378
379
  AuthzSessionManager *authz_session_mgr() { return authz_session_mgr_; }
380
  BackoffThrottle *backoff_throttle() { return backoff_throttle_; }
381
27
  catalog::ClientCatalogManager *catalog_mgr() { return catalog_mgr_; }
382
  ChunkTables *chunk_tables() { return chunk_tables_; }
383
9
  download::DownloadManager *download_mgr() { return download_mgr_; }
384
12
  download::DownloadManager *external_download_mgr() {
385
12
    return external_download_mgr_;
386
  }
387
  file_watcher::FileWatcher* resolv_conf_watcher() {
388
    return resolv_conf_watcher_;
389
  }
390
57
  cvmfs::Fetcher *fetcher() { return fetcher_; }
391
  bool fixed_catalog() { return fixed_catalog_; }
392
57
  std::string fqrn() { return fqrn_; }
393
  cvmfs::Fetcher *external_fetcher() { return external_fetcher_; }
394
57
  FileSystem *file_system() { return file_system_; }
395
  bool has_membership_req() { return has_membership_req_; }
396
  bool hide_magic_xattrs() { return hide_magic_xattrs_; }
397
  catalog::InodeGenerationAnnotation *inode_annotation() {
398
    return inode_annotation_;
399
  }
400
  glue::InodeTracker *inode_tracker() { return inode_tracker_; }
401
  lru::InodeCache *inode_cache() { return inode_cache_; }
402
  double kcache_timeout_sec() { return kcache_timeout_sec_; }
403
43
  lru::Md5PathCache *md5path_cache() { return md5path_cache_; }
404
  std::string membership_req() { return membership_req_; }
405
  lru::PathCache *path_cache() { return path_cache_; }
406
  std::string repository_tag() { return repository_tag_; }
407
  SimpleChunkTables *simple_chunk_tables() { return simple_chunk_tables_; }
408
171
  perf::Statistics *statistics() { return statistics_; }
409
57
  signature::SignatureManager *signature_mgr() { return signature_mgr_; }
410
  Tracer *tracer() { return tracer_; }
411
  cvmfs::Uuid *uuid() { return uuid_; }
412
413
  bool ReloadBlacklists();
414
415
 private:
416
  /**
417
   * The maximum TTL can be used to cap a root catalogs registered ttl.  By
418
   * default this is disabled (= 0).
419
   */
420
  static const unsigned kDefaultMaxTtlSec = 0;
421
  /**
422
   * Let fuse cache dentries for 1 minute.
423
   */
424
  static const unsigned kDefaultKCacheTtlSec = 60;
425
  /**
426
   * Number of Md5Path entries in the libcvmfs cache.
427
   */
428
  static const unsigned kLibPathCacheSize = 32000;
429
  /**
430
   * Cache seven times more md5 paths than inodes in the fuse module.
431
   */
432
  static const unsigned kInodeCacheFactor = 7;
433
  /**
434
   * Default to 16M RAM for meta-data caches; does not include the inode tracker
435
   */
436
  static const unsigned kDefaultMemcacheSize = 16 * 1024 * 1024;
437
  /**
438
   * Where to look for external authz helpers.
439
   */
440
  static const char *kDefaultAuthzSearchPath;  // "/usr/libexec/cvmfs/authz"
441
  /**
442
   * Maximum number of concurrent HTTP connections.
443
   */
444
  static const unsigned kDefaultNumConnections = 16;
445
  /**
446
   * Default network timeout
447
   */
448
  static const unsigned kDefaultTimeoutSec = 5;
449
  static const unsigned kDefaultRetries = 1;
450
  static const unsigned kDefaultBackoffInitMs = 2000;
451
  static const unsigned kDefaultBackoffMaxMs = 10000;
452
  /**
453
   * Memory buffer sizes for an activated tracer
454
   */
455
  static const unsigned kTracerBufferSize = 8192;
456
  static const unsigned kTracerFlushThreshold = 7000;
457
  static const char *kDefaultBlacklist;  // "/etc/cvmfs/blacklist"
458
459
  MountPoint(const std::string &fqrn,
460
             FileSystem *file_system,
461
             OptionsManager *options_mgr);
462
463
  void CreateStatistics();
464
  void CreateAuthz();
465
  bool CreateSignatureManager();
466
  bool CheckBlacklists();
467
  bool CreateDownloadManagers();
468
  bool CreateResolvConfWatcher();
469
  void CreateFetchers();
470
  bool CreateCatalogManager();
471
  void CreateTables();
472
  bool CreateTracer();
473
  void SetupBehavior();
474
  void SetupDnsTuning(download::DownloadManager *manager);
475
  void SetupHttpTuning();
476
  bool SetupExternalDownloadMgr(bool dogeosort);
477
  void SetupInodeAnnotation();
478
  bool SetupOwnerMaps();
479
  bool DetermineRootHash(shash::Any *root_hash);
480
  bool FetchHistory(std::string *history_path);
481
  std::string ReplaceHosts(std::string hosts);
482
  std::string GetUniqFileSuffix();
483
484
  std::string fqrn_;
485
  cvmfs::Uuid *uuid_;
486
  /**
487
   * In contrast to the manager objects, the FileSystem is not owned.
488
   */
489
  FileSystem *file_system_;
490
  /**
491
   * The options manager is not owned.
492
   */
493
  OptionsManager *options_mgr_;
494
495
  perf::Statistics *statistics_;
496
  AuthzFetcher *authz_fetcher_;
497
  AuthzSessionManager *authz_session_mgr_;
498
  AuthzAttachment *authz_attachment_;
499
  BackoffThrottle *backoff_throttle_;
500
  signature::SignatureManager *signature_mgr_;
501
  download::DownloadManager *download_mgr_;
502
  download::DownloadManager *external_download_mgr_;
503
  cvmfs::Fetcher *fetcher_;
504
  cvmfs::Fetcher *external_fetcher_;
505
  catalog::InodeGenerationAnnotation *inode_annotation_;
506
  catalog::ClientCatalogManager *catalog_mgr_;
507
  ChunkTables *chunk_tables_;
508
  SimpleChunkTables *simple_chunk_tables_;
509
  lru::InodeCache *inode_cache_;
510
  lru::PathCache *path_cache_;
511
  lru::Md5PathCache *md5path_cache_;
512
  Tracer *tracer_;
513
  glue::InodeTracker *inode_tracker_;
514
515
  file_watcher::FileWatcher* resolv_conf_watcher_;
516
517
  unsigned max_ttl_sec_;
518
  pthread_mutex_t lock_max_ttl_;
519
  double kcache_timeout_sec_;
520
  bool fixed_catalog_;
521
  bool hide_magic_xattrs_;
522
  std::string repository_tag_;
523
  std::vector<std::string> blacklist_paths_;
524
525
  // TODO(jblomer): this should go in the catalog manager
526
  std::string membership_req_;
527
  bool has_membership_req_;
528
};  // class MointPoint
529
530
#endif  // CVMFS_MOUNTPOINT_H_