GCC Code Coverage Report


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