/src/util-linux/libmount/src/mountP.h
Line | Count | Source |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | /* |
3 | | * mountP.h - private library header file |
4 | | * |
5 | | * This file is part of libmount from util-linux project. |
6 | | * |
7 | | * Copyright (C) 2008-2018 Karel Zak <kzak@redhat.com> |
8 | | * |
9 | | * libmount is free software; you can redistribute it and/or modify it |
10 | | * under the terms of the GNU Lesser General Public License as published by |
11 | | * the Free Software Foundation; either version 2.1 of the License, or |
12 | | * (at your option) any later version. |
13 | | */ |
14 | | #ifndef _LIBMOUNT_PRIVATE_H |
15 | | #define _LIBMOUNT_PRIVATE_H |
16 | | |
17 | | #include <errno.h> |
18 | | #include <stdlib.h> |
19 | | #include <string.h> |
20 | | #include <sys/stat.h> |
21 | | #include <sys/types.h> |
22 | | #include <sys/vfs.h> |
23 | | #include <unistd.h> |
24 | | #include <stdio.h> |
25 | | #include <stdarg.h> |
26 | | #include <stdint.h> |
27 | | #include <inttypes.h> |
28 | | |
29 | | #include "c.h" |
30 | | |
31 | | #include "list.h" |
32 | | #include "debug.h" |
33 | | #include "buffer.h" |
34 | | #include "libmount.h" |
35 | | |
36 | | #include "mount-api-utils.h" |
37 | | |
38 | | /* |
39 | | * Debug |
40 | | */ |
41 | 0 | #define MNT_DEBUG_HELP (1 << 0) |
42 | 0 | #define MNT_DEBUG_INIT (1 << 1) |
43 | 459 | #define MNT_DEBUG_CACHE (1 << 2) |
44 | | #define MNT_DEBUG_OPTIONS (1 << 3) |
45 | | #define MNT_DEBUG_LOCKS (1 << 4) |
46 | 306k | #define MNT_DEBUG_TAB (1 << 5) |
47 | 203k | #define MNT_DEBUG_FS (1 << 6) |
48 | | #define MNT_DEBUG_UPDATE (1 << 7) |
49 | 96 | #define MNT_DEBUG_UTILS (1 << 8) |
50 | 0 | #define MNT_DEBUG_CXT (1 << 9) |
51 | | #define MNT_DEBUG_DIFF (1 << 10) |
52 | | #define MNT_DEBUG_MONITOR (1 << 11) |
53 | 0 | #define MNT_DEBUG_BTRFS (1 << 12) |
54 | | #define MNT_DEBUG_LOOP (1 << 13) |
55 | | #define MNT_DEBUG_VERITY (1 << 14) |
56 | | #define MNT_DEBUG_HOOK (1 << 15) |
57 | 0 | #define MNT_DEBUG_OPTLIST (1 << 16) |
58 | 0 | #define MNT_DEBUG_STATMNT (1 << 17) |
59 | | |
60 | | #define MNT_DEBUG_ALL 0xFFFFFF |
61 | | |
62 | | UL_DEBUG_DECLARE_MASK(libmount); |
63 | 510k | #define DBG(m, x) __UL_DBG(libmount, MNT_DEBUG_, m, x) |
64 | 0 | #define ON_DBG(m, x) __UL_DBG_CALL(libmount, MNT_DEBUG_, m, x) |
65 | | #define DBG_FLUSH __UL_DBG_FLUSH(libmount, MNT_DEBUG_) |
66 | | |
67 | 0 | #define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(libmount) |
68 | | #include "debugobj.h" |
69 | | |
70 | | /* |
71 | | * NLS -- the library has to be independent on main program, so define |
72 | | * UL_TEXTDOMAIN_EXPLICIT before you include nls.h. |
73 | | * |
74 | | * Now we use util-linux.po (=PACKAGE), rather than maintain the texts |
75 | | * in the separate libmount.po file. |
76 | | */ |
77 | | #define LIBMOUNT_TEXTDOMAIN PACKAGE |
78 | | #define UL_TEXTDOMAIN_EXPLICIT LIBMOUNT_TEXTDOMAIN |
79 | | #include "nls.h" |
80 | | |
81 | | |
82 | | /* extension for files in the directory */ |
83 | 0 | #define MNT_MNTTABDIR_EXT ".fstab" |
84 | | |
85 | | /* library private paths */ |
86 | 0 | #define MNT_RUNTIME_TOPDIR "/run" |
87 | | /* private userspace mount table */ |
88 | 0 | #define MNT_PATH_UTAB MNT_RUNTIME_TOPDIR "/mount/utab" |
89 | | /* temporary mount target */ |
90 | | #define MNT_PATH_TMPTGT MNT_RUNTIME_TOPDIR "/mount/tmptgt" |
91 | | |
92 | | #define MNT_UTAB_HEADER "# libmount utab file\n" |
93 | | |
94 | | #ifdef TEST_PROGRAM |
95 | | struct libmnt_test { |
96 | | const char *name; |
97 | | int (*body)(struct libmnt_test *ts, int argc, char *argv[]); |
98 | | const char *usage; |
99 | | }; |
100 | | |
101 | | /* test.c */ |
102 | | extern int mnt_run_test(struct libmnt_test *tests, int argc, char *argv[]); |
103 | | #endif |
104 | | |
105 | | /* private tab_listmount.c */ |
106 | | struct libmnt_listmnt; |
107 | | |
108 | | /* utils.c */ |
109 | | extern int mnt_valid_tagname(const char *tagname); |
110 | | |
111 | | extern const char *mnt_statfs_get_fstype(struct statfs *vfs); |
112 | | extern const char *mnt_fstype_to_mounttype(const char *fstype); |
113 | | extern int is_file_empty(const char *name); |
114 | | |
115 | | extern int mnt_is_readonly(const char *path) |
116 | | __attribute__((nonnull)); |
117 | | |
118 | | extern int mnt_parse_offset(const char *str, size_t len, uintmax_t *res); |
119 | | |
120 | | extern int mnt_chdir_to_parent(const char *target, char **filename); |
121 | | |
122 | | extern char *mnt_get_username(const uid_t uid); |
123 | | extern int mnt_get_uid(const char *username, uid_t *uid); |
124 | | extern int mnt_get_gid(const char *groupname, gid_t *gid); |
125 | | extern int mnt_parse_uid(const char *user, size_t user_len, uid_t *gid); |
126 | | extern int mnt_parse_gid(const char *group, size_t group_len, gid_t *gid); |
127 | | extern int mnt_parse_mode(const char *mode, size_t mode_len, mode_t *gid); |
128 | | extern int mnt_in_group(gid_t gid); |
129 | | |
130 | | extern int mnt_open_uniq_filename(const char *filename, char **name); |
131 | | |
132 | | extern int mnt_has_regular_utab(const char **utab, int *writable); |
133 | | extern const char *mnt_get_utab_path(void); |
134 | | |
135 | | extern int mnt_get_filesystems(char ***filesystems, const char *pattern); |
136 | | extern void mnt_free_filesystems(char **filesystems); |
137 | | |
138 | | extern char *mnt_get_kernel_cmdline_option(const char *name); |
139 | | |
140 | | extern int mnt_safe_stat(const char *target, struct stat *st); |
141 | | extern int mnt_safe_lstat(const char *target, struct stat *st); |
142 | | extern int mnt_is_path(const char *target); |
143 | | |
144 | | extern int mnt_tmptgt_unshare(int *old_ns_fd); |
145 | | extern int mnt_tmptgt_cleanup(int old_ns_fd); |
146 | | |
147 | | extern int mnt_id_from_fd(int fd, uint64_t *uniq_id, int *id); |
148 | | |
149 | | /* tab.c */ |
150 | | extern int is_mountinfo(struct libmnt_table *tb); |
151 | | extern int mnt_table_set_parser_fltrcb( struct libmnt_table *tb, |
152 | | int (*cb)(struct libmnt_fs *, void *), |
153 | | void *data); |
154 | | |
155 | | extern int __mnt_table_parse_mountinfo(struct libmnt_table *tb, |
156 | | const char *filename, |
157 | | struct libmnt_table *u_tb); |
158 | | |
159 | | extern struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb, |
160 | | struct libmnt_fs *fs, |
161 | | unsigned long mountflags, |
162 | | char **fsroot); |
163 | | |
164 | | extern int __mnt_table_is_fs_mounted( struct libmnt_table *tb, |
165 | | struct libmnt_fs *fstab_fs, |
166 | | const char *tgt_prefix); |
167 | | |
168 | | extern int mnt_table_enable_noautofs(struct libmnt_table *tb, int ignore); |
169 | | extern int mnt_table_is_noautofs(struct libmnt_table *tb); |
170 | | |
171 | | /* tab_listmount.c */ |
172 | | extern int mnt_table_next_lsmnt(struct libmnt_table *tb, int direction); |
173 | | extern int mnt_table_reset_listmount(struct libmnt_table *tb); |
174 | | extern int mnt_table_want_listmount(struct libmnt_table *tb); |
175 | | |
176 | | /* |
177 | | * Generic iterator |
178 | | */ |
179 | | struct libmnt_iter { |
180 | | struct list_head *p; /* current position */ |
181 | | struct list_head *head; /* start position */ |
182 | | int direction; /* MNT_ITER_{FOR,BACK}WARD */ |
183 | | }; |
184 | | |
185 | 0 | #define IS_ITER_FORWARD(_i) ((_i)->direction == MNT_ITER_FORWARD) |
186 | | #define IS_ITER_BACKWARD(_i) ((_i)->direction == MNT_ITER_BACKWARD) |
187 | | |
188 | | #define MNT_ITER_INIT(itr, list) \ |
189 | 0 | do { \ |
190 | 0 | (itr)->p = IS_ITER_FORWARD(itr) ? \ |
191 | 0 | (list)->next : (list)->prev; \ |
192 | 0 | (itr)->head = (list); \ |
193 | 0 | } while(0) |
194 | | |
195 | | #define MNT_ITER_GET_ENTRY(itr, restype, member) \ |
196 | 0 | list_entry((itr)->p, restype, member) |
197 | | |
198 | | #define MNT_ITER_ITERATE(itr) \ |
199 | 0 | do { \ |
200 | 0 | (itr)->p = IS_ITER_FORWARD(itr) ? \ |
201 | 0 | (itr)->p->next : (itr)->p->prev; \ |
202 | 0 | } while(0) |
203 | | |
204 | | |
205 | | /* |
206 | | * statmount setting; shared between tables and filesystems |
207 | | */ |
208 | | struct libmnt_statmnt { |
209 | | int refcount; |
210 | | uint64_t mask; /* default statmount() mask */ |
211 | | |
212 | | struct ul_statmount *buf; |
213 | | size_t bufsiz; |
214 | | |
215 | | unsigned int disabled: 1; /* enable or disable statmount() */ |
216 | | }; |
217 | | |
218 | | |
219 | | /* |
220 | | * This struct represents one entry in a fstab/mountinfo file. |
221 | | * (note that fstab[1] means the first column from fstab, and so on...) |
222 | | */ |
223 | | struct libmnt_fs { |
224 | | struct list_head ents; |
225 | | struct libmnt_table *tab; |
226 | | |
227 | | int refcount; /* reference counter */ |
228 | | |
229 | | unsigned int opts_age; /* to sync with optlist */ |
230 | | struct libmnt_optlist *optlist; |
231 | | |
232 | | int id; /* mountinfo[1]: ID */ |
233 | | uint64_t uniq_id; /* unique node ID; statx(STATX_MNT_ID_UNIQUE); statmount->mnt_id */ |
234 | | uint64_t ns_id; /* namespace ID; statmount->mnt_ns_id */ |
235 | | |
236 | | int parent; /* mountinfo[2]: parent */ |
237 | | uint64_t uniq_parent; /* unique parent ID; statmount->mnt_parent_id */ |
238 | | dev_t devno; /* mountinfo[3]: st_dev */ |
239 | | |
240 | | char *bindsrc; /* utab, full path from fstab[1] for bind mounts */ |
241 | | |
242 | | char *source; /* fstab[1], mountinfo[10], swaps[1]: |
243 | | * source dev, file, dir or TAG */ |
244 | | char *tagname; /* fstab[1]: tag name - "LABEL", "UUID", ..*/ |
245 | | char *tagval; /* tag value */ |
246 | | |
247 | | char *root; /* mountinfo[4]: root of the mount within the FS */ |
248 | | char *target; /* mountinfo[5], fstab[2]: mountpoint */ |
249 | | char *fstype; /* mountinfo[9], fstab[3]: filesystem type */ |
250 | | |
251 | | char *optstr; /* fstab[4], merged options */ |
252 | | char *vfs_optstr; /* mountinfo[6]: fs-independent (VFS) options */ |
253 | | |
254 | | char *opt_fields; /* mountinfo[7]: optional fields */ |
255 | | uint64_t propagation; /* statmmount() or parsed opt_fields */ |
256 | | |
257 | | char *fs_optstr; /* mountinfo[11]: fs-dependent options */ |
258 | | char *user_optstr; /* userspace mount options */ |
259 | | char *attrs; /* mount attributes */ |
260 | | |
261 | | int freq; /* fstab[5]: dump frequency in days */ |
262 | | int passno; /* fstab[6]: pass number on parallel fsck */ |
263 | | |
264 | | /* /proc/swaps */ |
265 | | char *swaptype; /* swaps[2]: device type (partition, file, ...) */ |
266 | | off_t size; /* swaps[3]: swaparea size */ |
267 | | off_t usedsize; /* swaps[4]: used size */ |
268 | | int priority; /* swaps[5]: swap priority */ |
269 | | |
270 | | int flags; /* MNT_FS_* flags */ |
271 | | pid_t tid; /* /proc/<tid>/mountinfo otherwise zero */ |
272 | | |
273 | | uint64_t stmnt_done; /* mask of already called masks */ |
274 | | struct libmnt_statmnt *stmnt; /* statmount() stuff */ |
275 | | |
276 | | char *comment; /* fstab comment */ |
277 | | |
278 | | void *userdata; /* library independent data */ |
279 | | }; |
280 | | |
281 | | /* |
282 | | * fs flags |
283 | | */ |
284 | 51.1k | #define MNT_FS_PSEUDO (1 << 1) /* pseudo filesystem */ |
285 | 53.8k | #define MNT_FS_NET (1 << 2) /* network filesystem */ |
286 | 51.4k | #define MNT_FS_SWAP (1 << 3) /* swap device */ |
287 | 8.26k | #define MNT_FS_KERNEL (1 << 4) /* data from /proc/{mounts,self/mountinfo} */ |
288 | 0 | #define MNT_FS_MERGED (1 << 5) /* already merged data from /run/mount/utab */ |
289 | | |
290 | 8.26k | #define MNT_FS_STATUS_ATTACH (1 << 6) |
291 | 8.26k | #define MNT_FS_STATUS_DETACH (1 << 7) |
292 | | |
293 | | static inline void mnt_fs_mark_attached(struct libmnt_fs *fs) |
294 | 8.26k | { |
295 | 8.26k | fs->flags &= ~MNT_FS_STATUS_DETACH; |
296 | 8.26k | fs->flags |= MNT_FS_STATUS_ATTACH; |
297 | 8.26k | } Unexecuted instantiation: fuzz.c:mnt_fs_mark_attached Unexecuted instantiation: tab.c:mnt_fs_mark_attached Unexecuted instantiation: tab_listmount.c:mnt_fs_mark_attached tab_parse.c:mnt_fs_mark_attached Line | Count | Source | 294 | 8.26k | { | 295 | 8.26k | fs->flags &= ~MNT_FS_STATUS_DETACH; | 296 | 8.26k | fs->flags |= MNT_FS_STATUS_ATTACH; | 297 | 8.26k | } |
Unexecuted instantiation: utils.c:mnt_fs_mark_attached Unexecuted instantiation: btrfs.c:mnt_fs_mark_attached Unexecuted instantiation: cache.c:mnt_fs_mark_attached Unexecuted instantiation: fs.c:mnt_fs_mark_attached Unexecuted instantiation: fs_statmount.c:mnt_fs_mark_attached Unexecuted instantiation: init.c:mnt_fs_mark_attached Unexecuted instantiation: iter.c:mnt_fs_mark_attached Unexecuted instantiation: optmap.c:mnt_fs_mark_attached Unexecuted instantiation: optlist.c:mnt_fs_mark_attached Unexecuted instantiation: optstr.c:mnt_fs_mark_attached Unexecuted instantiation: version.c:mnt_fs_mark_attached |
298 | | |
299 | | static inline void mnt_fs_mark_detached(struct libmnt_fs *fs) |
300 | 0 | { |
301 | 0 | fs->flags &= ~MNT_FS_STATUS_ATTACH; |
302 | 0 | fs->flags |= MNT_FS_STATUS_DETACH; |
303 | 0 | } Unexecuted instantiation: fuzz.c:mnt_fs_mark_detached Unexecuted instantiation: tab.c:mnt_fs_mark_detached Unexecuted instantiation: tab_listmount.c:mnt_fs_mark_detached Unexecuted instantiation: tab_parse.c:mnt_fs_mark_detached Unexecuted instantiation: utils.c:mnt_fs_mark_detached Unexecuted instantiation: btrfs.c:mnt_fs_mark_detached Unexecuted instantiation: cache.c:mnt_fs_mark_detached Unexecuted instantiation: fs.c:mnt_fs_mark_detached Unexecuted instantiation: fs_statmount.c:mnt_fs_mark_detached Unexecuted instantiation: init.c:mnt_fs_mark_detached Unexecuted instantiation: iter.c:mnt_fs_mark_detached Unexecuted instantiation: optmap.c:mnt_fs_mark_detached Unexecuted instantiation: optlist.c:mnt_fs_mark_detached Unexecuted instantiation: optstr.c:mnt_fs_mark_detached Unexecuted instantiation: version.c:mnt_fs_mark_detached |
304 | | |
305 | | static inline void mnt_fs_mark_moved(struct libmnt_fs *fs) |
306 | 0 | { |
307 | 0 | fs->flags |= MNT_FS_STATUS_ATTACH | MNT_FS_STATUS_DETACH; |
308 | 0 | } Unexecuted instantiation: fuzz.c:mnt_fs_mark_moved Unexecuted instantiation: tab.c:mnt_fs_mark_moved Unexecuted instantiation: tab_listmount.c:mnt_fs_mark_moved Unexecuted instantiation: tab_parse.c:mnt_fs_mark_moved Unexecuted instantiation: utils.c:mnt_fs_mark_moved Unexecuted instantiation: btrfs.c:mnt_fs_mark_moved Unexecuted instantiation: cache.c:mnt_fs_mark_moved Unexecuted instantiation: fs.c:mnt_fs_mark_moved Unexecuted instantiation: fs_statmount.c:mnt_fs_mark_moved Unexecuted instantiation: init.c:mnt_fs_mark_moved Unexecuted instantiation: iter.c:mnt_fs_mark_moved Unexecuted instantiation: optmap.c:mnt_fs_mark_moved Unexecuted instantiation: optlist.c:mnt_fs_mark_moved Unexecuted instantiation: optstr.c:mnt_fs_mark_moved Unexecuted instantiation: version.c:mnt_fs_mark_moved |
309 | | |
310 | | #ifdef HAVE_STATMOUNT_API |
311 | | # define mnt_fs_try_statmount(FS, MEMBER, FLAGS) __extension__ ({ \ |
312 | | if (!(FS)->MEMBER \ |
313 | | && (FS)->stmnt \ |
314 | | && !(FS)->stmnt->disabled \ |
315 | | && ((FLAGS) & ~((FS)->stmnt_done))) \ |
316 | | mnt_fs_fetch_statmount((FS), (FLAGS)); }) |
317 | | #endif |
318 | | |
319 | | |
320 | | /* |
321 | | * fstab/mountinfo file |
322 | | */ |
323 | | struct libmnt_table { |
324 | | int fmt; /* MNT_FMT_* file format */ |
325 | | int nents; /* number of entries */ |
326 | | int refcount; /* reference counter */ |
327 | | int comms; /* enable/disable comment parsing */ |
328 | | char *comm_intro; /* First comment in file */ |
329 | | char *comm_tail; /* Last comment in file */ |
330 | | |
331 | | struct libmnt_cache *cache; /* canonicalized paths/tags cache */ |
332 | | |
333 | | int (*errcb)(struct libmnt_table *tb, |
334 | | const char *filename, int line); |
335 | | |
336 | | int (*fltrcb)(struct libmnt_fs *fs, void *data); |
337 | | void *fltrcb_data; |
338 | | |
339 | | struct libmnt_listmnt *lsmnt; /* listmount() stuff */ |
340 | | struct libmnt_statmnt *stmnt; /* statmount() stuff */ |
341 | | |
342 | | int noautofs; /* ignore autofs mounts */ |
343 | | |
344 | | struct list_head ents; /* list of entries (libmnt_fs) */ |
345 | | void *userdata; |
346 | | }; |
347 | | |
348 | | extern struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt, int empty_for_enoent); |
349 | | |
350 | | /* |
351 | | * Tab file format |
352 | | */ |
353 | | enum { |
354 | | MNT_FMT_GUESS, |
355 | | MNT_FMT_FSTAB, /* /etc/{fs,m}tab */ |
356 | | MNT_FMT_MTAB = MNT_FMT_FSTAB, /* alias */ |
357 | | MNT_FMT_MOUNTINFO, /* /proc/#/mountinfo */ |
358 | | MNT_FMT_UTAB, /* /run/mount/utab */ |
359 | | MNT_FMT_SWAPS /* /proc/swaps */ |
360 | | }; |
361 | | |
362 | | /* |
363 | | * Context hooks |
364 | | * |
365 | | * TODO: this will be public one day when libmount will support modules for |
366 | | * stuff like veritydev.c. |
367 | | */ |
368 | | enum { |
369 | | MNT_STAGE_PREP_SOURCE = 1, /* mount source preparation */ |
370 | | MNT_STAGE_PREP_TARGET, /* mount target preparation */ |
371 | | MNT_STAGE_PREP_OPTIONS, /* mount options preparation */ |
372 | | MNT_STAGE_PREP, /* all prepared */ |
373 | | |
374 | | MNT_STAGE_MOUNT_PRE = 100, /* before mount */ |
375 | | MNT_STAGE_MOUNT, /* mount(2) or fsmount(2) or tree-clone */ |
376 | | MNT_STAGE_MOUNT_POST, /* after mount */ |
377 | | |
378 | | MNT_STAGE_POST = 200 /* all is done */ |
379 | | }; |
380 | | |
381 | | struct libmnt_hookset { |
382 | | const char *name; /* hook set name */ |
383 | | |
384 | | int firststage; |
385 | | int (*firstcall)(struct libmnt_context *, const struct libmnt_hookset *, void *); |
386 | | |
387 | | int (*deinit)(struct libmnt_context *, const struct libmnt_hookset *); /* cleanup function */ |
388 | | }; |
389 | | |
390 | | /* built-in hooks */ |
391 | | extern const struct libmnt_hookset hookset_mount_legacy; |
392 | | extern const struct libmnt_hookset hookset_mount; |
393 | | extern const struct libmnt_hookset hookset_mkdir; |
394 | | extern const struct libmnt_hookset hookset_subdir; |
395 | | extern const struct libmnt_hookset hookset_owner; |
396 | | extern const struct libmnt_hookset hookset_idmap; |
397 | | extern const struct libmnt_hookset hookset_loopdev; |
398 | | #ifdef HAVE_CRYPTSETUP |
399 | | extern const struct libmnt_hookset hookset_veritydev; |
400 | | #endif |
401 | | #ifdef HAVE_LIBSELINUX |
402 | | extern const struct libmnt_hookset hookset_selinux; |
403 | | #endif |
404 | | |
405 | | extern int mnt_context_deinit_hooksets(struct libmnt_context *cxt); |
406 | | extern const struct libmnt_hookset *mnt_context_get_hookset(struct libmnt_context *cxt, const char *name); |
407 | | |
408 | | extern int mnt_context_set_hookset_data(struct libmnt_context *cxt, |
409 | | const struct libmnt_hookset *hs, |
410 | | void *data); |
411 | | |
412 | | extern void *mnt_context_get_hookset_data(struct libmnt_context *cxt, |
413 | | const struct libmnt_hookset *hs); |
414 | | |
415 | | extern int mnt_context_has_hook(struct libmnt_context *cxt, |
416 | | const struct libmnt_hookset *hs, |
417 | | int stage, |
418 | | void *data); |
419 | | |
420 | | extern int mnt_context_append_hook(struct libmnt_context *cxt, |
421 | | const struct libmnt_hookset *hs, |
422 | | int stage, |
423 | | void *data, |
424 | | int (*func)(struct libmnt_context *, |
425 | | const struct libmnt_hookset *, |
426 | | void *)); |
427 | | extern int mnt_context_insert_hook(struct libmnt_context *cxt, |
428 | | const char *after, |
429 | | const struct libmnt_hookset *hs, |
430 | | int stage, |
431 | | void *data, |
432 | | int (*func)(struct libmnt_context *, |
433 | | const struct libmnt_hookset *, |
434 | | void *)); |
435 | | |
436 | | extern int mnt_context_remove_hook(struct libmnt_context *cxt, |
437 | | const struct libmnt_hookset *hs, |
438 | | int stage, |
439 | | void **data); |
440 | | extern int mnt_context_call_hooks(struct libmnt_context *cxt, int stage); |
441 | | |
442 | | /* |
443 | | * Namespace |
444 | | */ |
445 | | struct libmnt_ns { |
446 | | int fd; /* file descriptor of namespace, -1 when inactive */ |
447 | | struct libmnt_cache *cache; /* paths cache associated with NS */ |
448 | | }; |
449 | | |
450 | | /* |
451 | | * Mount context -- high-level API |
452 | | */ |
453 | | struct libmnt_context |
454 | | { |
455 | | int action; /* MNT_ACT_{MOUNT,UMOUNT} */ |
456 | | int restricted; /* root or not? */ |
457 | | |
458 | | char *fstype_pattern; /* for mnt_match_fstype() */ |
459 | | char *optstr_pattern; /* for mnt_match_options() */ |
460 | | |
461 | | struct libmnt_fs *fs; /* filesystem description (type, mountpoint, device, ...) */ |
462 | | |
463 | | struct libmnt_table *fstab; /* fstab entries */ |
464 | | struct libmnt_table *mountinfo; /* already mounted filesystems */ |
465 | | struct libmnt_table *utab; /* rarely used by umount only */ |
466 | | |
467 | | int (*table_errcb)(struct libmnt_table *tb, /* callback for libmnt_table structs */ |
468 | | const char *filename, int line); |
469 | | |
470 | | int (*table_fltrcb)(struct libmnt_fs *fs, void *data); /* callback for libmnt_table structs */ |
471 | | void *table_fltrcb_data; |
472 | | |
473 | | char *(*pwd_get_cb)(struct libmnt_context *); /* get encryption password */ |
474 | | void (*pwd_release_cb)(struct libmnt_context *, char *); /* release password */ |
475 | | |
476 | | int optsmode; /* fstab optstr mode MNT_OPTSMODE_{AUTO,FORCE,IGNORE} */ |
477 | | |
478 | | const void *mountdata; /* final mount(2) data, string or binary data */ |
479 | | |
480 | | struct libmnt_cache *cache; /* paths cache */ |
481 | | struct libmnt_lock *lock; /* utab lock */ |
482 | | struct libmnt_update *update; /* utab update */ |
483 | | |
484 | | struct libmnt_optlist *optlist; /* parsed mount options */ |
485 | | struct libmnt_optlist *optlist_saved; /* save/apply context template */ |
486 | | |
487 | | const struct libmnt_optmap *map_linux; /* system options map */ |
488 | | const struct libmnt_optmap *map_userspace; /* userspace options map */ |
489 | | |
490 | | const char *mountinfo_path; /* usually /proc/self/moutinfo */ |
491 | | |
492 | | const char *utab_path; /* path to utab */ |
493 | | int utab_writable; /* is utab writable */ |
494 | | |
495 | | char *tgt_prefix; /* path used for all targets */ |
496 | | |
497 | | int flags; /* private context flags */ |
498 | | |
499 | | char *helper; /* name of the used /sbin/[u]mount.<type> helper */ |
500 | | int helper_status; /* helper wait(2) status */ |
501 | | int helper_exec_status; /* 1: not called yet, 0: success, <0: -errno */ |
502 | | |
503 | | pid_t *children; /* "mount -a --fork" PIDs */ |
504 | | int nchildren; /* number of children */ |
505 | | pid_t pid; /* 0=parent; PID=child */ |
506 | | |
507 | | int syscall_status; /* 1: not called yet, 0: success, <0: -errno */ |
508 | | const char *syscall_name; /* failed syscall name */ |
509 | | |
510 | | char **mesgs; /* library or kernel messages (NULL terminated array) */ |
511 | | |
512 | | struct libmnt_ns ns_orig; /* original namespace */ |
513 | | struct libmnt_ns ns_tgt; /* target namespace */ |
514 | | struct libmnt_ns *ns_cur; /* pointer to current namespace */ |
515 | | |
516 | | unsigned int enabled_textdomain : 1; /* bindtextdomain() called */ |
517 | | unsigned int noautofs : 1; /* ignore autofs mounts */ |
518 | | unsigned int has_selinux_opt : 1; /* temporary for broken fsconfig() syscall */ |
519 | | unsigned int force_clone : 1; /* OPEN_TREE_CLONE */ |
520 | | |
521 | | struct list_head hooksets_datas; /* global hooksets data */ |
522 | | struct list_head hooksets_hooks; /* global hooksets data */ |
523 | | }; |
524 | | |
525 | | /* flags */ |
526 | | #define MNT_FL_NOMTAB (1 << 1) |
527 | | #define MNT_FL_FAKE (1 << 2) |
528 | | #define MNT_FL_SLOPPY (1 << 3) |
529 | | #define MNT_FL_VERBOSE (1 << 4) |
530 | | #define MNT_FL_NOHELPERS (1 << 5) |
531 | | #define MNT_FL_LOOPDEL (1 << 6) |
532 | | #define MNT_FL_LAZY (1 << 7) |
533 | | #define MNT_FL_FORCE (1 << 8) |
534 | | #define MNT_FL_NOCANONICALIZE (1 << 9) |
535 | | #define MNT_FL_RDONLY_UMOUNT (1 << 11) /* remount,ro after EBUSY umount(2) */ |
536 | | #define MNT_FL_FORK (1 << 12) |
537 | | #define MNT_FL_NOSWAPMATCH (1 << 13) |
538 | | #define MNT_FL_RWONLY_MOUNT (1 << 14) /* explicit mount -w; never try read-only */ |
539 | | #define MNT_FL_ONLYONCE (1 << 15) |
540 | | #define MNT_FL_EXCL (1 << 16) |
541 | | #define MNT_FL_BENEATH (1 << 17) |
542 | | |
543 | | #define MNT_FL_MOUNTDATA (1 << 20) |
544 | | #define MNT_FL_TAB_APPLIED (1 << 21) /* fstab merged to cxt->fs */ |
545 | | #define MNT_FL_MOUNTFLAGS_MERGED (1 << 22) /* MS_* flags was read from optstr */ |
546 | | #define MNT_FL_SAVED_USER (1 << 23) |
547 | | #define MNT_FL_PREPARED (1 << 24) |
548 | | #define MNT_FL_HELPER (1 << 25) /* [u]mount.<type> */ |
549 | | #define MNT_FL_MOUNTOPTS_FIXED (1 << 27) |
550 | | #define MNT_FL_TABPATHS_CHECKED (1 << 28) |
551 | | #define MNT_FL_FORCED_RDONLY (1 << 29) /* mounted read-only on write-protected device */ |
552 | | #define MNT_FL_VERITYDEV_READY (1 << 30) /* /dev/mapper/<FOO> initialized by the library */ |
553 | | |
554 | | /* default flags */ |
555 | | #define MNT_FL_DEFAULT 0 |
556 | | |
557 | | /* Flags usable with MS_BIND|MS_REMOUNT */ |
558 | | #define MNT_BIND_SETTABLE (MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_NOATIME|MS_NODIRATIME|MS_RELATIME|MS_RDONLY|MS_NOSYMFOLLOW) |
559 | | |
560 | | |
561 | | /* optmap.c */ |
562 | | extern const struct libmnt_optmap *mnt_optmap_get_entry( |
563 | | struct libmnt_optmap const **maps, |
564 | | int nmaps, |
565 | | const char *name, |
566 | | size_t namelen, |
567 | | const struct libmnt_optmap **mapent); |
568 | | |
569 | | /* optstr.c */ |
570 | | extern int mnt_optstr_remove_option_at(char **optstr, char *begin, char *end); |
571 | | extern int mnt_optstr_get_missing(const char *optstr, const char *wanted, char **missing); |
572 | | |
573 | | extern int mnt_buffer_append_option(struct ul_buffer *buf, |
574 | | const char *name, size_t namesz, |
575 | | const char *val, size_t valsz, int quoted); |
576 | | |
577 | | /* optlist.h */ |
578 | | struct libmnt_opt; |
579 | | struct libmnt_optlist; |
580 | | |
581 | | extern struct libmnt_optlist *mnt_new_optlist(void); |
582 | | extern void mnt_ref_optlist(struct libmnt_optlist *ls); |
583 | | extern void mnt_unref_optlist(struct libmnt_optlist *ls); |
584 | | extern struct libmnt_optlist *mnt_copy_optlist(struct libmnt_optlist *ls); |
585 | | extern int mnt_optlist_is_empty(struct libmnt_optlist *ls); |
586 | | extern unsigned int mnt_optlist_get_age(struct libmnt_optlist *ls); |
587 | | extern int mnt_optlist_register_map(struct libmnt_optlist *ls, const struct libmnt_optmap *map); |
588 | | extern int mnt_optlist_remove_opt(struct libmnt_optlist *ls, struct libmnt_opt *opt); |
589 | | extern int mnt_optlist_remove_named(struct libmnt_optlist *ls, const char *name, |
590 | | const struct libmnt_optmap *map); |
591 | | extern int mnt_optlist_remove_flags(struct libmnt_optlist *ls, unsigned long flags, |
592 | | const struct libmnt_optmap *map); |
593 | | extern int mnt_optlist_next_opt(struct libmnt_optlist *ls, |
594 | | struct libmnt_iter *itr, struct libmnt_opt **opt); |
595 | | extern struct libmnt_opt *mnt_optlist_get_opt(struct libmnt_optlist *ls, |
596 | | unsigned long id, const struct libmnt_optmap *map); |
597 | | extern struct libmnt_opt *mnt_optlist_get_named(struct libmnt_optlist *ls, |
598 | | const char *name, const struct libmnt_optmap *map); |
599 | | extern int mnt_optlist_set_optstr(struct libmnt_optlist *ls, const char *optstr, |
600 | | const struct libmnt_optmap *map); |
601 | | extern int mnt_optlist_append_optstr(struct libmnt_optlist *ls, const char *optstr, |
602 | | const struct libmnt_optmap *map); |
603 | | extern int mnt_optlist_prepend_optstr(struct libmnt_optlist *ls, const char *optstr, |
604 | | const struct libmnt_optmap *map); |
605 | | extern int mnt_optlist_append_flags(struct libmnt_optlist *ls, unsigned long flags, |
606 | | const struct libmnt_optmap *map); |
607 | | extern int mnt_optlist_set_flags(struct libmnt_optlist *ls, unsigned long flags, |
608 | | const struct libmnt_optmap *map); |
609 | | extern int mnt_optlist_insert_flags(struct libmnt_optlist *ls, unsigned long flags, |
610 | | const struct libmnt_optmap *map, |
611 | | unsigned long after, |
612 | | const struct libmnt_optmap *after_map); |
613 | | /* "what" argument */ |
614 | | enum { |
615 | | /* Default -- if @map specified then returns all options for the map, otherwise |
616 | | * returns all options including uknonwn options, exclude external options */ |
617 | | MNT_OL_FLTR_DFLT = 0, |
618 | | /* Options as expected by mount.<type> helpers */ |
619 | | MNT_OL_FLTR_HELPERS, |
620 | | /* Options as expected in mtab */ |
621 | | MNT_OL_FLTR_MTAB, |
622 | | /* All options -- include mapped, unknown and external options */ |
623 | | MNT_OL_FLTR_ALL, |
624 | | /* All unknown options -- exclude external (usually FS specific options) */ |
625 | | MNT_OL_FLTR_UNKNOWN, |
626 | | |
627 | | __MNT_OL_FLTR_COUNT /* keep it last */ |
628 | | }; |
629 | | |
630 | | |
631 | | extern int mnt_optlist_get_flags(struct libmnt_optlist *ls, unsigned long *flags, |
632 | | const struct libmnt_optmap *map, unsigned int what); |
633 | | |
634 | | /* recursive status for mnt_optlist_get_attrs() */ |
635 | | #define MNT_OL_REC 1 |
636 | | #define MNT_OL_NOREC 2 |
637 | | |
638 | | extern int mnt_optlist_get_attrs(struct libmnt_optlist *ls, uint64_t *set, uint64_t *clr, int rec); |
639 | | |
640 | | extern int mnt_optlist_get_optstr(struct libmnt_optlist *ol, const char **optstr, |
641 | | const struct libmnt_optmap *map, unsigned int what); |
642 | | extern int mnt_optlist_strdup_optstr(struct libmnt_optlist *ls, char **optstr, |
643 | | const struct libmnt_optmap *map, unsigned int what); |
644 | | |
645 | | extern int mnt_optlist_get_propagation(struct libmnt_optlist *ls); |
646 | | extern int mnt_optlist_is_propagation_only(struct libmnt_optlist *ls); |
647 | | extern int mnt_optlist_is_remount(struct libmnt_optlist *ls); |
648 | | extern int mnt_optlist_is_rpropagation(struct libmnt_optlist *ls); |
649 | | extern int mnt_optlist_is_bind(struct libmnt_optlist *ls); |
650 | | extern int mnt_optlist_is_rbind(struct libmnt_optlist *ls); |
651 | | extern int mnt_optlist_is_move(struct libmnt_optlist *ls); |
652 | | extern int mnt_optlist_is_rdonly(struct libmnt_optlist *ls); |
653 | | extern int mnt_optlist_is_silent(struct libmnt_optlist *ls); |
654 | | |
655 | | extern int mnt_optlist_merge_opts(struct libmnt_optlist *ls); |
656 | | |
657 | | extern int mnt_opt_has_value(struct libmnt_opt *opt); |
658 | | extern const char *mnt_opt_get_value(struct libmnt_opt *opt); |
659 | | extern const char *mnt_opt_get_name(struct libmnt_opt *opt); |
660 | | extern const struct libmnt_optmap *mnt_opt_get_map(struct libmnt_opt *opt); |
661 | | extern const struct libmnt_optmap *mnt_opt_get_mapent(struct libmnt_opt *opt); |
662 | | extern int mnt_opt_set_external(struct libmnt_opt *opt, int enable); |
663 | | extern int mnt_opt_set_value(struct libmnt_opt *opt, const char *str); |
664 | | extern int mnt_opt_set_u64value(struct libmnt_opt *opt, uint64_t num); |
665 | | extern int mnt_opt_set_quoted_value(struct libmnt_opt *opt, const char *str); |
666 | | extern int mnt_opt_is_external(struct libmnt_opt *opt); |
667 | | extern int mnt_opt_is_sepnodata(struct libmnt_opt *opt); |
668 | | extern int mnt_opt_value_with(struct libmnt_opt *opt, const char *str); |
669 | | |
670 | | /* fs.c */ |
671 | | extern int mnt_fs_follow_optlist(struct libmnt_fs *fs, struct libmnt_optlist *ol); |
672 | | extern struct libmnt_fs *mnt_copy_mtab_fs(struct libmnt_fs *fs); |
673 | | extern int __mnt_fs_set_source_ptr(struct libmnt_fs *fs, char *source) |
674 | | __attribute__((nonnull(1))); |
675 | | extern int __mnt_fs_set_fstype_ptr(struct libmnt_fs *fs, char *fstype) |
676 | | __attribute__((nonnull(1))); |
677 | | extern int __mnt_fs_set_target_ptr(struct libmnt_fs *fs, char *tgt) |
678 | | __attribute__((nonnull(1))); |
679 | | |
680 | | /* context.c */ |
681 | | extern void mnt_context_syscall_save_status(struct libmnt_context *cxt, |
682 | | const char *syscallname, int success); |
683 | | extern void mnt_context_syscall_reset_status(struct libmnt_context *cxt); |
684 | | |
685 | | extern struct libmnt_context *mnt_copy_context(struct libmnt_context *o); |
686 | | extern int mnt_context_utab_writable(struct libmnt_context *cxt); |
687 | | extern const char *mnt_context_get_writable_tabpath(struct libmnt_context *cxt); |
688 | | |
689 | | extern int mnt_context_within_helper(struct libmnt_context *cxt); |
690 | | |
691 | | extern int mnt_context_get_mountinfo(struct libmnt_context *cxt, struct libmnt_table **tb); |
692 | | extern int mnt_context_get_mountinfo_for_target(struct libmnt_context *cxt, |
693 | | struct libmnt_table **mountinfo, const char *tgt); |
694 | | |
695 | | extern int mnt_context_prepare_srcpath(struct libmnt_context *cxt); |
696 | | extern int mnt_context_guess_srcpath_fstype(struct libmnt_context *cxt, char **type); |
697 | | extern int mnt_context_guess_fstype(struct libmnt_context *cxt); |
698 | | extern int mnt_context_prepare_helper(struct libmnt_context *cxt, |
699 | | const char *name, const char *type); |
700 | | extern int mnt_context_prepare_update(struct libmnt_context *cxt); |
701 | | extern int mnt_context_merge_mflags(struct libmnt_context *cxt); |
702 | | extern int mnt_context_update_tabs(struct libmnt_context *cxt); |
703 | | |
704 | | extern int mnt_context_umount_setopt(struct libmnt_context *cxt, int c, char *arg); |
705 | | extern int mnt_context_mount_setopt(struct libmnt_context *cxt, int c, char *arg); |
706 | | |
707 | | extern void mnt_context_reset_mesgs(struct libmnt_context *cxt); |
708 | | extern int mnt_context_append_mesg(struct libmnt_context *cxt, const char *msg); |
709 | | extern int mnt_context_sprintf_mesg(struct libmnt_context *cxt, const char *msg, ...); |
710 | | extern int mnt_context_read_mesgs(struct libmnt_context *cxt, int fd); |
711 | | |
712 | | extern int mnt_context_propagation_only(struct libmnt_context *cxt) |
713 | | __attribute__((nonnull)); |
714 | | |
715 | | extern int mnt_context_delete_loopdev(struct libmnt_context *cxt); |
716 | | |
717 | | extern int mnt_fork_context(struct libmnt_context *cxt); |
718 | | |
719 | | extern int mnt_context_set_tabfilter(struct libmnt_context *cxt, |
720 | | int (*fltr)(struct libmnt_fs *, void *), |
721 | | void *data); |
722 | | |
723 | | extern int mnt_context_get_generic_excode(int rc, char *buf, size_t bufsz, const char *fmt, ...) |
724 | | __attribute__ ((__format__ (__printf__, 4, 5))); |
725 | | extern int mnt_context_get_mount_excode(struct libmnt_context *cxt, int mntrc, char *buf, size_t bufsz); |
726 | | extern int mnt_context_get_umount_excode(struct libmnt_context *cxt, int mntrc, char *buf, size_t bufsz); |
727 | | |
728 | | extern int mnt_context_has_template(struct libmnt_context *cxt); |
729 | | extern int mnt_context_apply_template(struct libmnt_context *cxt); |
730 | | extern int mnt_context_save_template(struct libmnt_context *cxt); |
731 | | |
732 | | extern int mnt_context_apply_fs(struct libmnt_context *cxt, struct libmnt_fs *fs); |
733 | | |
734 | | extern struct libmnt_optlist *mnt_context_get_optlist(struct libmnt_context *cxt); |
735 | | |
736 | | extern int mnt_context_is_xnocanonicalize(struct libmnt_context *cxt, const char *type); |
737 | | |
738 | | /* tab_update.c */ |
739 | | extern int mnt_update_emit_event(struct libmnt_update *upd); |
740 | | extern int mnt_update_set_filename(struct libmnt_update *upd, const char *filename); |
741 | | extern int mnt_update_already_done(struct libmnt_update *upd); |
742 | | extern int mnt_update_start(struct libmnt_update *upd); |
743 | | extern int mnt_update_end(struct libmnt_update *upd); |
744 | | |
745 | | #if __linux__ |
746 | | /* btrfs.c */ |
747 | | extern uint64_t btrfs_get_default_subvol_id(const char *path); |
748 | | #endif |
749 | | |
750 | | #ifdef USE_LIBMOUNT_MOUNTFD_SUPPORT |
751 | | /* fsconfig/fsopen based stuff */ |
752 | | struct libmnt_sysapi { |
753 | | int fd_fs; /* FD from fsopen() or fspick() */ |
754 | | int fd_tree; /* FD from fsmount() or open_tree() */ |
755 | | |
756 | | char *subdir; /* Linux >= 6.15 can directly open subdir; |
757 | | * hook_subdir sets this variable */ |
758 | | |
759 | | unsigned int is_new_fs : 1 ; /* fd_fs comes from fsopen() */ |
760 | | }; |
761 | | |
762 | | static inline struct libmnt_sysapi *mnt_context_get_sysapi(struct libmnt_context *cxt) |
763 | | { |
764 | | return mnt_context_get_hookset_data(cxt, &hookset_mount); |
765 | | } |
766 | | |
767 | | int mnt_context_open_tree(struct libmnt_context *cxt, const char *path, unsigned long mflg); |
768 | | |
769 | | #endif |
770 | | |
771 | | #endif /* _LIBMOUNT_PRIVATE_H */ |