GCC Code Coverage Report


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