]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - include/mount-api-utils.h
8dbe534672438b9e74069f1505cde739c74111f1
2 * No copyright is claimed. This code is in the public domain; do with
5 #ifndef UTIL_LINUX_MOUNT_API_UTILS
6 #define UTIL_LINUX_MOUNT_API_UTILS
8 #ifdef HAVE_LINUX_MOUNT_H
10 #include <linux/mount.h>
11 #include <linux/unistd.h>
12 #include <sys/syscall.h>
16 * File descritors based mount API
18 #ifdef HAVE_MOUNTFD_API
20 /* Accepted by both open_tree() and mount_setattr(). */
22 # define AT_RECURSIVE 0x8000
25 #ifndef OPEN_TREE_CLONE
26 # define OPEN_TREE_CLONE 1
29 #ifndef OPEN_TREE_CLOEXEC
30 # define OPEN_TREE_CLOEXEC O_CLOEXEC
33 #if !defined(HAVE_OPEN_TREE) && defined(SYS_open_tree)
34 static inline int open_tree(int dfd
, const char *filename
, unsigned int flags
)
36 return syscall(SYS_open_tree
, dfd
, filename
, flags
);
40 #ifndef MOVE_MOUNT_F_SYMLINKS
41 # define MOVE_MOUNT_F_SYMLINKS 0x00000001 /* Follow symlinks on from path */
44 #ifndef MOVE_MOUNT_F_AUTOMOUNTS
45 # define MOVE_MOUNT_F_AUTOMOUNTS 0x00000002 /* Follow automounts on from path */
48 #ifndef MOVE_MOUNT_F_EMPTY_PATH
49 # define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 /* Empty from path permitted */
52 #ifndef MOVE_MOUNT_T_SYMLINKS
53 # define MOVE_MOUNT_T_SYMLINKS 0x00000010 /* Follow symlinks on to path */
56 #ifndef MOVE_MOUNT_T_AUTOMOUNTS
57 # define MOVE_MOUNT_T_AUTOMOUNTS 0x00000020 /* Follow automounts on to path */
60 #ifndef MOVE_MOUNT_T_EMPTY_PATH
61 # define MOVE_MOUNT_T_EMPTY_PATH 0x00000040 /* Empty to path permitted */
64 #ifndef MOVE_MOUNT_SET_GROUP
65 # define MOVE_MOUNT_SET_GROUP 0x00000100 /* Set sharing group instead */
68 #ifndef MOVE_MOUNT__MASK
69 # define MOVE_MOUNT__MASK 0x00000077
72 #if !defined(HAVE_MOVE_MOUNT) && defined(SYS_move_mount)
73 static inline int move_mount(int from_dfd
, const char *from_pathname
, int to_dfd
,
74 const char *to_pathname
, unsigned int flags
)
76 return syscall(SYS_move_mount
, from_dfd
, from_pathname
, to_dfd
,
81 #ifndef MOUNT_ATTR_RDONLY
82 # define MOUNT_ATTR_RDONLY 0x00000001
85 #ifndef MOUNT_ATTR_NOSUID
86 # define MOUNT_ATTR_NOSUID 0x00000002
89 #ifndef MOUNT_ATTR_NODEV
90 # define MOUNT_ATTR_NODEV 0x00000004
93 #ifndef MOUNT_ATTR_NOEXEC
94 # define MOUNT_ATTR_NOEXEC 0x00000008
97 #ifndef MOUNT_ATTR__ATIME
98 # define MOUNT_ATTR__ATIME 0x00000070
101 #ifndef MOUNT_ATTR_RELATIME
102 # define MOUNT_ATTR_RELATIME 0x00000000
105 #ifndef MOUNT_ATTR_NOATIME
106 # define MOUNT_ATTR_NOATIME 0x00000010
109 #ifndef MOUNT_ATTR_STRICTATIME
110 # define MOUNT_ATTR_STRICTATIME 0x00000020
113 #ifndef MOUNT_ATTR_NODIRATIME
114 # define MOUNT_ATTR_NODIRATIME 0x00000080
117 #ifndef MOUNT_ATTR_IDMAP
118 # define MOUNT_ATTR_IDMAP 0x00100000
121 #ifndef MOUNT_ATTR_NOSYMFOLLOW
122 # define MOUNT_ATTR_NOSYMFOLLOW 0x00200000
125 #ifndef HAVE_STRUCT_MOUNT_ATTR
126 # ifndef MOUNT_ATTR_SIZE_VER0 /* For case mount.h comes from a place invisible for autotools/meson */
127 # include <inttypes.h>
131 uint64_t propagation
;
137 #if !defined(HAVE_MOUNT_SETATTR) && defined(SYS_mount_setattr)
138 static inline int mount_setattr(int dfd
, const char *path
, unsigned int flags
,
139 struct mount_attr
*attr
, size_t size
)
141 return syscall(SYS_mount_setattr
, dfd
, path
, flags
, attr
, size
);
145 #ifndef HAVE_ENUM_FSCONFIG_COMMAND
146 # ifndef FSOPEN_CLOEXEC /* For case mount.h comes from a place invisible for autotools/meson */
147 enum fsconfig_command
{
148 FSCONFIG_SET_FLAG
= 0, /* Set parameter, supplying no value */
149 FSCONFIG_SET_STRING
= 1, /* Set parameter, supplying a string value */
150 FSCONFIG_SET_BINARY
= 2, /* Set parameter, supplying a binary blob value */
151 FSCONFIG_SET_PATH
= 3, /* Set parameter, supplying an object by path */
152 FSCONFIG_SET_PATH_EMPTY
= 4, /* Set parameter, supplying an object by (empty) path */
153 FSCONFIG_SET_FD
= 5, /* Set parameter, supplying an object by fd */
154 FSCONFIG_CMD_CREATE
= 6, /* Invoke superblock creation */
155 FSCONFIG_CMD_RECONFIGURE
= 7, /* Invoke superblock reconfiguration */
160 #if !defined(HAVE_FSCONFIG) && defined(SYS_fsconfig)
161 static inline int fsconfig(int fd
, unsigned int cmd
, const char *key
,
162 const void *value
, int aux
)
164 return syscall(SYS_fsconfig
, fd
, cmd
, key
, value
, aux
);
168 #ifndef FSOPEN_CLOEXEC
169 # define FSOPEN_CLOEXEC 0x00000001
172 #if !defined(HAVE_FSOPEN) && defined(SYS_fsopen)
173 static inline int fsopen(const char *fsname
, unsigned int flags
)
175 return syscall(SYS_fsopen
, fsname
, flags
);
179 #ifndef FSMOUNT_CLOEXEC
180 # define FSMOUNT_CLOEXEC 0x00000001
183 #if !defined(HAVE_FSMOUNT) && defined(SYS_fsmount)
184 static inline int fsmount(int fd
, unsigned int flags
, unsigned int mount_attrs
)
186 return syscall(SYS_fsmount
, fd
, flags
, mount_attrs
);
190 #ifndef FSPICK_CLOEXEC
191 # define FSPICK_CLOEXEC 0x00000001
194 #ifndef FSPICK_SYMLINK_NOFOLLOW
195 # define FSPICK_SYMLINK_NOFOLLOW 0x00000002
198 #ifndef FSPICK_NO_AUTOMOUNT
199 # define FSPICK_NO_AUTOMOUNT 0x00000004
202 #ifdef FSPICK_EMPTY_PATH
203 # define FSPICK_EMPTY_PATH 0x00000008
206 #if !defined(HAVE_FSPICK) && defined(SYS_fspick)
207 static inline int fspick(int dfd
, const char *pathname
, unsigned int flags
)
209 return syscall(SYS_fspick
, dfd
, pathname
, flags
);
213 #endif /* HAVE_MOUNTFD_API */
216 * statmount() and listmount()
218 #ifdef HAVE_STATMOUNT_API
220 #ifndef MNT_ID_REQ_SIZE_VER0
221 # define MNT_ID_REQ_SIZE_VER0 24 /* sizeof first published struct */
223 #ifndef MNT_ID_REQ_SIZE_VER1
224 # define MNT_ID_REQ_SIZE_VER1 32 /* sizeof second published struct */
228 * The structs mnt_id_req and statmount may differ between kernel versions, so
229 * we must ensure that the structs contain everything we need. For now (during
230 * development), it seems best to define local copies of the structs to avoid
231 * relying on installed kernel headers and to avoid a storm of #ifdefs.
235 * listmount() and statmount() request
237 struct ul_mnt_id_req
{
246 * Please note that due to the variable length of the statmount buffer, the
247 * struct cannot be versioned by size (like struct mnt_id_req).
249 struct ul_statmount
{
250 uint32_t size
; /* Total size, including strings */
251 uint32_t mnt_opts
; /* [str] Mount options of the mount */
252 uint64_t mask
; /* What results were written */
253 uint32_t sb_dev_major
; /* Device ID */
254 uint32_t sb_dev_minor
;
255 uint64_t sb_magic
; /* ..._SUPER_MAGIC */
256 uint32_t sb_flags
; /* SB_{RDONLY,SYNCHRONOUS,DIRSYNC,LAZYTIME} */
257 uint32_t fs_type
; /* [str] Filesystem type */
258 uint64_t mnt_id
; /* Unique ID of mount */
259 uint64_t mnt_parent_id
; /* Unique ID of parent (for root == mnt_id) */
260 uint32_t mnt_id_old
; /* Reused IDs used in proc/.../mountinfo */
261 uint32_t mnt_parent_id_old
;
262 uint64_t mnt_attr
; /* MOUNT_ATTR_... */
263 uint64_t mnt_propagation
; /* MS_{SHARED,SLAVE,PRIVATE,UNBINDABLE} */
264 uint64_t mnt_peer_group
; /* ID of shared peer group */
265 uint64_t mnt_master
; /* Mount receives propagation from this ID */
266 uint64_t propagate_from
; /* Propagation from in current namespace */
267 uint32_t mnt_root
; /* [str] Root of mount relative to root of fs */
268 uint32_t mnt_point
; /* [str] Mountpoint relative to current root */
269 uint64_t mnt_ns_id
; /* ID of the mount namespace */
270 uint32_t fs_subtype
; /* [str] Subtype of fs_type (if any) */
271 uint32_t sb_source
; /* [str] Source string of the mount */
272 uint32_t opt_num
; /* Number of fs options */
273 uint32_t opt_array
; /* [str] Array of nul terminated fs options */
274 uint32_t opt_sec_num
; /* Number of security options */
275 uint32_t opt_sec_array
; /* [str] Array of nul terminated security options */
276 uint64_t __spare2
[46];
277 char str
[]; /* Variable size part containing strings */
280 /* sb_flags (defined in kernel include/linux/fs.h) */
282 # define SB_RDONLY BIT(0) /* Mount read-only */
283 # define SB_NOSUID BIT(1) /* Ignore suid and sgid bits */
284 # define SB_NODEV BIT(2) /* Disallow access to device special files */
285 # define SB_NOEXEC BIT(3) /* Disallow program execution */
286 # define SB_SYNCHRONOUS BIT(4) /* Writes are synced at once */
287 # define SB_MANDLOCK BIT(6) /* Allow mandatory locks on an FS */
288 # define SB_DIRSYNC BIT(7) /* Directory modifications are synchronous */
289 # define SB_NOATIME BIT(10) /* Do not update access times. */
290 # define SB_NODIRATIME BIT(11) /* Do not update directory access times */
291 # define SB_SILENT BIT(15)
292 # define SB_POSIXACL BIT(16) /* Supports POSIX ACLs */
293 # define SB_INLINECRYPT BIT(17) /* Use blk-crypto for encrypted files */
294 # define SB_KERNMOUNT BIT(22) /* this is a kern_mount call */
295 # define SB_I_VERSION BIT(23) /* Update inode I_version field */
296 # define SB_LAZYTIME BIT(25) /* Update the on-disk [acm]times lazily */
300 * @mask bits for statmount(2)
302 #ifndef STATMOUNT_SB_BASIC
303 # define STATMOUNT_SB_BASIC 0x00000001U /* Want/got sb_... */
305 #ifndef STATMOUNT_MNT_BASIC
306 # define STATMOUNT_MNT_BASIC 0x00000002U /* Want/got mnt_... */
308 #ifndef STATMOUNT_PROPAGATE_FROM
309 # define STATMOUNT_PROPAGATE_FROM 0x00000004U /* Want/got propagate_from */
311 #ifndef STATMOUNT_MNT_ROOT
312 # define STATMOUNT_MNT_ROOT 0x00000008U /* Want/got mnt_root */
314 #ifndef STATMOUNT_MNT_POINT
315 # define STATMOUNT_MNT_POINT 0x00000010U /* Want/got mnt_point */
317 #ifndef STATMOUNT_FS_TYPE
318 # define STATMOUNT_FS_TYPE 0x00000020U /* Want/got fs_type */
320 #ifndef STATMOUNT_MNT_NS_ID
321 # define STATMOUNT_MNT_NS_ID 0x00000040U /* Want/got mnt_ns_id */
323 #ifndef STATMOUNT_MNT_OPTS
324 # define STATMOUNT_MNT_OPTS 0x00000080U /* Want/got mnt_opts */
326 #ifndef STATMOUNT_FS_SUBTYPE
327 # define STATMOUNT_FS_SUBTYPE 0x00000100U /* Want/got fs_subtype */
329 #ifndef STATMOUNT_SB_SOURCE
330 # define STATMOUNT_SB_SOURCE 0x00000200U /* Want/got sb_source */
332 #ifndef STATMOUNT_OPT_ARRAY
333 # define STATMOUNT_OPT_ARRAY 0x00000400U /* Want/got opt_... */
335 #ifndef STATMOUNT_OPT_SEC_ARRAY
336 # define STATMOUNT_OPT_SEC_ARRAY 0x00000800U /* Want/got opt_sec... */
341 * Special @mnt_id values that can be passed to listmount
344 # define LSMT_ROOT 0xffffffffffffffff /* root mount */
347 #ifndef LISTMOUNT_REVERSE
348 # define LISTMOUNT_REVERSE BIT(0) /* List later mounts first */
351 /* Don't use this "raw" version. See ul_statmount() below. */
352 #if defined(SYS_statmount)
353 static inline int ul_statmount_syscall(uint64_t mnt_id
,
356 struct ul_statmount
*buf
,
357 size_t bufsize
, unsigned int flags
)
359 struct ul_mnt_id_req req
= {
360 .size
= MNT_ID_REQ_SIZE_VER1
,
366 return syscall(SYS_statmount
, &req
, buf
, bufsize
, flags
);
369 static inline int has_statmount(void)
373 if (ul_statmount_syscall(0, 0, 0, NULL
, 0, 0) < 0 && errno
== ENOSYS
)
378 /* This is a version of statmount() that reallocates @buf to be large enough to
379 * store data for the requested @id. This function never deallocates; it is the
380 * caller's responsibility.
382 static inline int ul_statmount(uint64_t id
,
385 struct ul_statmount
**buf
,
401 struct ul_statmount
*tmp
= realloc(*buf
, sz
);
409 rc
= ul_statmount_syscall(id
, ns_id
, mask
, *buf
, *bufsiz
, flags
);
412 if (errno
!= EOVERFLOW
)
414 if (sz
>= SIZE_MAX
/ 2)
421 #endif /* SYS_statmount */
424 #if defined(SYS_listmount)
425 static inline ssize_t
ul_listmount(uint64_t mnt_id
,
427 uint64_t last_mnt_id
,
428 uint64_t list
[], size_t num
,
431 struct ul_mnt_id_req req
= {
432 .size
= MNT_ID_REQ_SIZE_VER1
,
434 .param
= last_mnt_id
,
438 return syscall(SYS_listmount
, &req
, list
, num
, flags
);
441 static inline int has_listmount(void)
447 if (ul_listmount(LSMT_ROOT
, 0, 0, &dummy
, 1, LISTMOUNT_REVERSE
) != 1)
453 #endif /* HAVE_STATMOUNT_API */
455 #endif /* HAVE_LINUX_MOUNT_H */
457 #endif /* UTIL_LINUX_MOUNT_API_UTILS */