1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 * This file is part of libmount from util-linux project.
5 * Copyright (C) 2010-2018 Karel Zak <kzak@redhat.com>
7 * libmount is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
16 * @short_description: description for mount options
18 * The mount(2) linux syscall uses two arguments for mount options:
20 * @mountflags: (see MS_* macros in linux/fs.h)
22 * @mountdata: (usually a comma separated string of options)
24 * The libmount uses options-map(s) to describe mount options.
26 * The option description (map entry) includes:
28 * @name: and argument name
30 * @id: (in the map unique identifier or a mountflags, e.g MS_RDONLY)
32 * @mask: (MNT_INVERT, MNT_NOMTAB)
34 * The option argument value is defined by:
36 * "=" -- required argument, e.g "comment="
38 * "[=]" -- optional argument, e.g. "loop[=]"
44 * #define MY_MS_FOO (1 << 1)
45 * #define MY_MS_BAR (1 << 2)
47 * libmnt_optmap myoptions[] = {
48 * { "foo", MY_MS_FOO },
49 * { "nofoo", MY_MS_FOO | MNT_INVERT },
50 * { "bar=", MY_MS_BAR },
56 * The libmount defines two basic built-in options maps:
58 * @MNT_LINUX_MAP: fs-independent kernel mount options (usually MS_* flags)
60 * @MNT_USERSPACE_MAP: userspace specific mount options (e.g. "user", "loop")
62 * For more details about option map struct see "struct mnt_optmap" in
69 * fs-independent mount flags (built-in MNT_LINUX_MAP)
71 static const struct libmnt_optmap linux_flags_map
[] =
73 { "ro", MS_RDONLY
}, /* read-only */
74 { "rw", MS_RDONLY
, MNT_INVERT
}, /* read-write */
75 { "exec", MS_NOEXEC
, MNT_INVERT
}, /* permit execution of binaries */
76 { "noexec", MS_NOEXEC
}, /* don't execute binaries */
77 { "suid", MS_NOSUID
, MNT_INVERT
}, /* honor suid executables */
78 { "nosuid", MS_NOSUID
}, /* don't honor suid executables */
79 { "dev", MS_NODEV
, MNT_INVERT
}, /* interpret device files */
80 { "nodev", MS_NODEV
}, /* don't interpret devices */
82 { "sync", MS_SYNCHRONOUS
}, /* synchronous I/O */
83 { "async", MS_SYNCHRONOUS
, MNT_INVERT
},/* asynchronous I/O */
85 { "dirsync", MS_DIRSYNC
}, /* synchronous directory modifications */
86 { "remount", MS_REMOUNT
, MNT_NOMTAB
}, /* alter flags of mounted FS */
87 { "bind", MS_BIND
}, /* Remount part of the tree elsewhere */
88 { "rbind", MS_BIND
| MS_REC
}, /* Idem, plus mounted subtrees */
90 { "sub", MS_NOSUB
, MNT_INVERT
}, /* allow submounts */
91 { "nosub", MS_NOSUB
}, /* don't allow submounts */
94 { "silent", MS_SILENT
}, /* be quiet */
95 { "loud", MS_SILENT
, MNT_INVERT
}, /* print out messages. */
98 { "mand", MS_MANDLOCK
}, /* Allow mandatory locks on this FS */
99 { "nomand", MS_MANDLOCK
, MNT_INVERT
}, /* Forbid mandatory locks on this FS */
102 { "atime", MS_NOATIME
, MNT_INVERT
}, /* Update access time */
103 { "noatime", MS_NOATIME
}, /* Do not update access time */
106 { "iversion", MS_I_VERSION
}, /* Update inode I_version time */
107 { "noiversion", MS_I_VERSION
, MNT_INVERT
},/* Don't update inode I_version time */
110 { "diratime", MS_NODIRATIME
, MNT_INVERT
}, /* Update dir access times */
111 { "nodiratime", MS_NODIRATIME
}, /* Do not update dir access times */
114 { "relatime", MS_RELATIME
}, /* Update access times relative to mtime/ctime */
115 { "norelatime", MS_RELATIME
, MNT_INVERT
}, /* Update access time without regard to mtime/ctime */
117 #ifdef MS_STRICTATIME
118 { "strictatime", MS_STRICTATIME
}, /* Strict atime semantics */
119 { "nostrictatime", MS_STRICTATIME
, MNT_INVERT
}, /* kernel default atime */
122 { "lazytime", MS_LAZYTIME
}, /* Update {a,m,c}time on the in-memory inode only */
123 { "nolazytime", MS_LAZYTIME
, MNT_INVERT
},
125 #ifdef MS_PROPAGATION
126 { "unbindable", MS_UNBINDABLE
, MNT_NOHLPS
| MNT_NOMTAB
}, /* Unbindable */
127 { "runbindable", MS_UNBINDABLE
| MS_REC
, MNT_NOHLPS
| MNT_NOMTAB
},
128 { "private", MS_PRIVATE
, MNT_NOHLPS
| MNT_NOMTAB
}, /* Private */
129 { "rprivate", MS_PRIVATE
| MS_REC
, MNT_NOHLPS
| MNT_NOMTAB
},
130 { "slave", MS_SLAVE
, MNT_NOHLPS
| MNT_NOMTAB
}, /* Slave */
131 { "rslave", MS_SLAVE
| MS_REC
, MNT_NOHLPS
| MNT_NOMTAB
},
132 { "shared", MS_SHARED
, MNT_NOHLPS
| MNT_NOMTAB
}, /* Shared */
133 { "rshared", MS_SHARED
| MS_REC
, MNT_NOHLPS
| MNT_NOMTAB
},
139 * userspace mount option (built-in MNT_USERSPACE_MAP)
141 static const struct libmnt_optmap userspace_opts_map
[] =
143 { "defaults", 0, 0 }, /* default options */
145 { "auto", MNT_MS_NOAUTO
, MNT_NOHLPS
| MNT_INVERT
| MNT_NOMTAB
}, /* Can be mounted using -a */
146 { "noauto", MNT_MS_NOAUTO
, MNT_NOHLPS
| MNT_NOMTAB
}, /* Can only be mounted explicitly */
148 { "user[=]", MNT_MS_USER
}, /* Allow ordinary user to mount (mtab) */
149 { "nouser", MNT_MS_USER
, MNT_INVERT
| MNT_NOMTAB
}, /* Forbid ordinary user to mount */
151 { "users", MNT_MS_USERS
, MNT_NOMTAB
}, /* Allow ordinary users to mount */
152 { "nousers", MNT_MS_USERS
, MNT_INVERT
| MNT_NOMTAB
}, /* Forbid ordinary users to mount */
154 { "owner", MNT_MS_OWNER
, MNT_NOMTAB
}, /* Let the owner of the device mount */
155 { "noowner", MNT_MS_OWNER
, MNT_INVERT
| MNT_NOMTAB
}, /* Device owner has no special privs */
157 { "group", MNT_MS_GROUP
, MNT_NOMTAB
}, /* Let the group of the device mount */
158 { "nogroup", MNT_MS_GROUP
, MNT_INVERT
| MNT_NOMTAB
}, /* Device group has no special privs */
161 * Note that traditional init scripts assume the _netdev option in /etc/mtab to
162 * umount network block devices on shutdown.
164 { "_netdev", MNT_MS_NETDEV
}, /* Device requires network */
166 { "comment=", MNT_MS_COMMENT
, MNT_NOHLPS
| MNT_NOMTAB
},/* fstab comment only */
168 { "x-", MNT_MS_XCOMMENT
, MNT_NOHLPS
| MNT_PREFIX
}, /* persistent comments (utab) */
169 { "X-", MNT_MS_XFSTABCOMM
, MNT_NOHLPS
| MNT_NOMTAB
| MNT_PREFIX
}, /* fstab only comments */
171 { "loop[=]", MNT_MS_LOOP
, MNT_NOHLPS
}, /* use the loop device */
172 { "offset=", MNT_MS_OFFSET
, MNT_NOHLPS
| MNT_NOMTAB
}, /* loop device offset */
173 { "sizelimit=", MNT_MS_SIZELIMIT
, MNT_NOHLPS
| MNT_NOMTAB
}, /* loop device size limit */
174 { "encryption=", MNT_MS_ENCRYPTION
, MNT_NOHLPS
| MNT_NOMTAB
}, /* loop device encryption */
176 { "nofail", MNT_MS_NOFAIL
, MNT_NOMTAB
}, /* Do not fail if ENOENT on dev */
178 { "uhelper=", MNT_MS_UHELPER
}, /* /sbin/umount.<helper> */
180 { "helper=", MNT_MS_HELPER
}, /* /sbin/mount.<helper> */
186 * mnt_get_builtin_map:
187 * @id: map id -- MNT_LINUX_MAP or MNT_USERSPACE_MAP
189 * MNT_LINUX_MAP - Linux kernel fs-independent mount options
190 * (usually MS_* flags, see linux/fs.h)
192 * MNT_USERSPACE_MAP - userspace mount(8) specific mount options
193 * (e.g user=, _netdev, ...)
195 * Returns: static built-in libmount map.
197 const struct libmnt_optmap
*mnt_get_builtin_optmap(int id
)
201 if (id
== MNT_LINUX_MAP
)
202 return linux_flags_map
;
203 else if (id
== MNT_USERSPACE_MAP
)
204 return userspace_opts_map
;
209 * Looks up the @name in @maps and returns a map and in @mapent
210 * returns the map entry
212 const struct libmnt_optmap
*mnt_optmap_get_entry(
213 struct libmnt_optmap
const **maps
,
217 const struct libmnt_optmap
**mapent
)
229 for (i
= 0; i
< nmaps
; i
++) {
230 const struct libmnt_optmap
*map
= maps
[i
];
231 const struct libmnt_optmap
*ent
;
234 for (ent
= map
; ent
&& ent
->name
; ent
++) {
235 if (ent
->mask
& MNT_PREFIX
) {
236 if (startswith(name
, ent
->name
)) {
243 if (strncmp(ent
->name
, name
, namelen
))
245 p
= ent
->name
+ namelen
;
246 if (*p
== '\0' || *p
== '=' || *p
== '[') {