GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/fuse_remount.h Lines: 0 10 0.0 %
Date: 2019-02-03 02:48:13 Branches: 0 4 0.0 %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 */
4
5
#ifndef CVMFS_FUSE_REMOUNT_H_
6
#define CVMFS_FUSE_REMOUNT_H_
7
8
#include <pthread.h>
9
10
#include <ctime>
11
12
#include "atomic.h"
13
#include "duplex_fuse.h"
14
#include "fence.h"
15
#include "fuse_evict.h"
16
#include "util/single_copy.h"
17
18
namespace cvmfs {
19
struct InodeGenerationInfo;
20
}
21
class MountPoint;
22
23
/**
24
 * Orchestrates an orderly remount of a new snapshot revision in the Fuse
25
 * module.  Remounting always happens as a result of calling Check() followed
26
 * by a call to TryFinish().  The Check() method is either called from the
27
 * remount trigger or from the TalkManager.  The TryFinish() method is either
28
 * called from a fuse callback function or from CheckSynchronously().  If a new
29
 * root file catalog is available online and the kernel caches got flushed, the
30
 * actual heavy-lifting of applying the new catalog takes place in TryFinish();
31
 *
32
 * Remounting is inherently asynchronous because the kernel caches need to be
33
 * flushed.  We do this through the FuseInvalidator.  Once the FuseInvalidor
34
 * is ready (either by waiting or by active eviction), we flush all user-level
35
 * caches and reload a new root catalog.
36
 */
37
class FuseRemounter : SingleCopy {
38
 public:
39
  enum Status {
40
    kStatusUp2Date = 0,
41
    kStatusDraining,
42
    kStatusMaintenance,
43
    kStatusFailGeneral,
44
    kStatusFailNoSpace,
45
  };
46
47
  FuseRemounter(MountPoint *mountpoint,
48
                cvmfs::InodeGenerationInfo *inode_generation_info,
49
                struct fuse_chan **fuse_channel,
50
                bool fuse_notify_invalidation);
51
  ~FuseRemounter();
52
  void Spawn();
53
54
  Status Check();
55
  Status CheckSynchronously();
56
  void TryFinish();
57
  void EnterMaintenanceMode();
58
  bool IsCaching() {
59
    return (atomic_read32(&maintenance_mode_) == 0) &&
60
           (atomic_read32(&drainout_mode_) == 0);
61
  }
62
  bool IsInDrainoutMode() { return atomic_read32(&drainout_mode_) == 2; }
63
  bool IsInMaintenanceMode() { return atomic_read32(&maintenance_mode_) == 1; }
64
65
  Fence *fence() { return fence_; }
66
  time_t catalogs_valid_until() { return catalogs_valid_until_; }
67
68
 private:
69
  static void *MainRemountTrigger(void *data);
70
71
  bool HasRemountTrigger() { return pipe_remount_trigger_[0] >= 0; }
72
  void SetAlarm(int timeout);
73
74
  bool EnterCriticalSection() {
75
    return atomic_cas32(&critical_section_, 0, 1);
76
  }
77
  void LeaveCriticalSection() { atomic_dec32(&critical_section_); /* 1 -> 0 */ }
78
79
  void SetOfflineMode(bool value);
80
81
  MountPoint *mountpoint_;  ///< Not owned
82
  cvmfs::InodeGenerationInfo *inode_generation_info_;  ///< Not owned
83
  FuseInvalidator *invalidator_;
84
  /**
85
   * Used to query whether the kernel cache invalidation is done.
86
   */
87
  FuseInvalidator::Handle invalidator_handle_;
88
  /**
89
   * Ensures that within a fuse callback all operations take place on the same
90
   * catalog revision.
91
   */
92
  Fence *fence_;
93
  /**
94
   * This fence makes sure that Check() and TryFinish() have been left after
95
   * the maintenance mode flag was set.
96
   */
97
  Fence fence_maintenance_;
98
  pthread_t thread_remount_trigger_;
99
  /**
100
   * The thread that triggers the reload of the root catalog is controlled
101
   * through this pipe.
102
   */
103
  int pipe_remount_trigger_[2];
104
  /**
105
   * Indicates whether the last reload attempt failed. If so, the short term
106
   * TTL is active.
107
   */
108
  bool offline_mode_;
109
  /**
110
   * Stores the deadline after which the remount trigger will look again for
111
   * an updated version.  Can be MountPoint::kIndefiniteDeadline if a fixed root
112
   * catalog is used.  Only for information purposes ('expires' xattr).
113
   * TODO(jblomer): access to this field should be locked
114
   */
115
  time_t catalogs_valid_until_;
116
  /**
117
   * In drainout mode, the fuse module sets the timeout of meta data replys to
118
   * zero.  If supported by Fuse, the FuseInvalidator will evict all active
119
   * entries from the kernel cache.  Drainout mode is left only once the new
120
   * root catalog is active (after TryFinish()).
121
   *
122
   * Moving into drainout mode is a two-steps procedure.  Going from zero to one
123
   * the handle of the FuseInvalidator is prepared, from one to two is the
124
   * actual move into drainout mode.
125
   */
126
  atomic_int32 drainout_mode_;
127
  /**
128
   * in maintenance mode, cache timeout is 0 and catalogs are not reloaded.
129
   * Maintenance mode is entered when the fuse module gets reloaded.
130
   */
131
  atomic_int32 maintenance_mode_;
132
  /**
133
   * Only one thread must perform the actual remount (stopping user-level
134
   * caches, loading new catalog, etc.).  This is used to protect TyrFinish()
135
   * from concurrent execution.
136
   */
137
  atomic_int32 critical_section_;
138
};  // class FuseRemounter
139
140
#endif  // CVMFS_FUSE_REMOUNT_H_