GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/loader.h
Date: 2026-04-19 02:41:37
Exec Total Coverage
Lines: 0 66 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_LOADER_H_
6 #define CVMFS_LOADER_H_
7
8 #define _FILE_OFFSET_BITS 64
9
10 #include <stdint.h>
11 #include <time.h>
12
13 #include <cstring>
14 #include <string>
15 #include <vector>
16
17 #include "duplex_fuse.h"
18
19 namespace loader {
20
21 extern std::string *usyslog_path_;
22
23 /**
24 * Possible failures when booting/mounting cvmfs. Remember to add a constant
25 * to libcvmfs.h and libcvmfs_legacy.cc when a constant to this enum is added.
26 */
27 enum Failures {
28 kFailOk = 0,
29 kFailUnknown,
30 kFailOptions,
31 kFailPermission,
32 kFailMount,
33 kFailLoaderTalk,
34 kFailFuseLoop,
35 kFailLoadLibrary,
36 kFailIncompatibleVersions, // TODO(jblomer)
37 kFailCacheDir,
38 kFailPeers,
39 kFailNfsMaps,
40 kFailQuota,
41 kFailMonitor,
42 kFailTalk,
43 kFailSignature,
44 kFailCatalog,
45 kFailMaintenanceMode,
46 kFailSaveState,
47 kFailRestoreState,
48 kFailOtherMount,
49 kFailDoubleMount,
50 kFailHistory,
51 kFailWpad,
52 kFailLockWorkspace,
53 kFailRevisionBlacklisted,
54 kFailIgnoredMount,
55
56 kFailNumEntries
57 };
58
59 inline const char *Code2Ascii(const Failures error) {
60 const char *texts[kFailNumEntries + 1];
61 texts[0] = "OK";
62 texts[1] = "unknown error";
63 texts[2] = "illegal options";
64 texts[3] = "permission denied";
65 texts[4] = "failed to mount";
66 texts[5] = "unable to init loader talk socket";
67 texts[6] = "cannot run FUSE event loop";
68 texts[7] = "failed to load shared library";
69 texts[8] = "incompatible library version";
70 texts[9] = "cache directory/plugin problem";
71 texts[10] = "peering problem";
72 texts[11] = "NFS maps init failure";
73 texts[12] = "quota init failure";
74 texts[13] = "watchdog failure";
75 texts[14] = "talk socket failure";
76 texts[15] = "signature verification failure";
77 texts[16] = "file catalog failure";
78 texts[17] = "maintenance mode";
79 texts[18] = "state saving failure";
80 texts[19] = "state restore failure";
81 texts[20] = "already mounted";
82 texts[21] = "double mount";
83 texts[22] = "history init failure";
84 texts[23] = "proxy auto-discovery failed";
85 texts[24] = "workspace already locked";
86 texts[25] = "revision blacklisted";
87 texts[26] = "mount attempt ignored";
88 texts[27] = "no text";
89 return texts[error];
90 }
91
92
93 enum StateId {
94 kStateUnknown = 0,
95 kStateOpenDirs, // >= 2.1.4
96 kStateOpenChunks, // >= 2.1.4, used as of 2.1.15
97 kStateGlueBuffer, // >= 2.1.9
98 kStateInodeGeneration, // >= 2.1.9
99 kStateOpenFilesCounter, // >= 2.1.9
100 kStateGlueBufferV2, // >= 2.1.10
101 kStateGlueBufferV3, // >= 2.1.15
102 kStateGlueBufferV4, // >= 2.1.20
103 kStateOpenChunksV2, // >= 2.1.20
104 kStateOpenChunksV3, // >= 2.2.0
105 kStateOpenChunksV4, // >= 2.2.3
106 kStateOpenFiles, // >= 2.4
107 kStateDentryTracker, // >= 2.7 (renamed from kStateNentryTracker in 2.10)
108 kStatePageCacheTracker, // >= 2.10
109 kStateFuse, // >= 2.11
110 kStateWatchdog, // >= 2.14
111
112 // Note: kStateOpenFilesXXX was renamed to kStateOpenChunksXXX as of 2.4
113 };
114
115
116 struct SavedState {
117 SavedState() {
118 version = 1;
119 size = sizeof(SavedState);
120 state_id = kStateUnknown;
121 state = NULL;
122 }
123
124 uint32_t version;
125 uint32_t size;
126 StateId state_id;
127 void *state;
128 };
129 typedef std::vector<SavedState *> StateList;
130
131
132 struct LoadEvent {
133 LoadEvent() {
134 version = 1;
135 size = sizeof(LoadEvent);
136 timestamp = 0;
137 }
138
139 uint32_t version;
140 uint32_t size;
141 time_t timestamp;
142 std::string so_version;
143 };
144 typedef std::vector<LoadEvent *> EventList;
145
146
147 /**
148 * This contains the public interface of the cvmfs loader.
149 * Whenever something changes, change the version number.
150 *
151 * Note: Do not forget to check the version of LoaderExports in cvmfs.cc when
152 * using fields that were not present in version 1
153 *
154 * CernVM-FS 2.1.8 --> Version 2
155 * CernVM-FS 2.2.0 --> Version 3
156 * CernVM-FS 2.4.0 --> Version 4
157 * CernVM-FS 2.7.0 --> Version 4, fuse_channel --> fuse_channel_or_session
158 * CernVM-FS 2.8.2 --> Version 5, add device_id
159 * CernVM-FS 2.14.0 --> Version 6, no change to fields, but signifies that the
160 * main watchdog process does not restart during reload
161 */
162 struct LoaderExports {
163 LoaderExports()
164 : version(6)
165 , size(sizeof(LoaderExports))
166 , boot_time(0)
167 , foreground(false)
168 , disable_watchdog(false)
169 , simple_options_parsing(false)
170 , fuse_channel_or_session(NULL)
171 , fuse_passthrough(false)
172 { }
173
174 ~LoaderExports() {
175 for (unsigned i = 0; i < history.size(); ++i)
176 delete history[i];
177 }
178
179 uint32_t version;
180 uint32_t size;
181 time_t boot_time;
182 std::string loader_version;
183 bool foreground;
184 std::string repository_name;
185 std::string mount_point;
186 std::string config_files;
187 std::string program_name;
188 EventList history;
189 StateList saved_states;
190
191 // added with CernVM-FS 2.1.8 (LoaderExports Version: 2)
192 bool disable_watchdog;
193
194 // added with CernVM-FS 2.2.0 (LoaderExports Version: 3)
195 bool simple_options_parsing;
196
197 // added with CernVM-FS 2.4.0 (LoaderExports Version: 4)
198 // As of CernVM-FS 2.7, this has been rebranded from
199 // struct fuse_chan **fuse_channel to
200 // void **fuse_channel_or_session
201 // in order to work with both libfuse2 and libfuse3
202 void **fuse_channel_or_session;
203
204 bool fuse_passthrough;
205
206 // Linux only, stores the major:minor internal mountpoint identifier
207 // The identifier is read just after mount from /proc/self/mountinfo
208 // If it cannot be determined (e.g. on macOS), device_id is "0:0".
209 std::string device_id;
210 };
211
212
213 /**
214 * This contains the public interface of the cvmfs fuse module.
215 * Whenever something changes, change the version number and add only
216 * to the end of the struct.
217 * A global CvmfsExports struct is looked up by the loader via dlsym.
218 * Since the cvmfs fuse module gets replaced each time there's an
219 * upgrade or downgrade, the only way to get a cvmfs module older than
220 * the loader is via a downgrade, which is an unusual situation.
221 * It is still possible, however, so code that uses newer fields should
222 * check the version before doing so.
223 *
224 * Note: as of cvmfs version 2.8, we set cvmfs_operations.forget_multi on new
225 * enough fuse
226 *
227 * CernVM-FS 2.14.0 --> Version 2, add fnClearExit
228 */
229 struct CvmfsExports {
230 CvmfsExports() {
231 version = 2;
232 size = sizeof(CvmfsExports);
233 fnAltProcessFlavor = NULL;
234 fnInit = NULL;
235 fnSpawn = NULL;
236 fnFini = NULL;
237 fnGetErrorMsg = NULL;
238 fnMaintenanceMode = NULL;
239 fnSaveState = NULL;
240 fnRestoreState = NULL;
241 fnFreeSavedState = NULL;
242 memset(&cvmfs_operations, 0, sizeof(cvmfs_operations));
243 fnClearExit = NULL;
244 }
245
246 uint32_t version;
247 uint32_t size;
248 std::string so_version;
249
250 int (*fnAltProcessFlavor)(int argc, char **argv);
251 int (*fnInit)(const LoaderExports *loader_exports);
252 void (*fnSpawn)();
253 void (*fnFini)();
254 std::string (*fnGetErrorMsg)();
255 bool (*fnMaintenanceMode)(const int fd_progress);
256 bool (*fnSaveState)(const int fd_progress, StateList *saved_states);
257 bool (*fnRestoreState)(const int fd_progress, const StateList &saved_states);
258 void (*fnFreeSavedState)(const int fd_progress,
259 const StateList &saved_states);
260 struct fuse_lowlevel_ops cvmfs_operations;
261
262 // added with CernVM-FS 2.14.0 (CvmfsExports Version: 2)
263 void (*fnClearExit)();
264 };
265
266 enum ReloadMode {
267 kReloadNoDebug = 0,
268 kReloadDebug,
269 kReloadLegacy
270 };
271
272 Failures Reload(const int fd_progress, const bool stop_and_go,
273 const ReloadMode reload_mode = kReloadLegacy);
274
275 } // namespace loader
276
277 #endif // CVMFS_LOADER_H_
278