]> git.ipfire.org Git - thirdparty/util-linux.git/blob - libmount/src/optmap.c
6136e27be180e41acf48ffb9349c17785a72f497
[thirdparty/util-linux.git] / libmount / src / optmap.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /*
3 * This file is part of libmount from util-linux project.
4 *
5 * Copyright (C) 2010-2018 Karel Zak <kzak@redhat.com>
6 *
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.
11 */
12
13 /**
14 * SECTION: optmap
15 * @title: Option maps
16 * @short_description: description for mount options
17 *
18 * The mount(2) linux syscall uses two arguments for mount options:
19 *
20 * @mountflags: (see MS_* macros in linux/fs.h)
21 *
22 * @mountdata: (usually a comma separated string of options)
23 *
24 * The libmount uses options-map(s) to describe mount options.
25 *
26 * The option description (map entry) includes:
27 *
28 * @name: and argument name
29 *
30 * @id: (in the map unique identifier or a mountflags, e.g MS_RDONLY)
31 *
32 * @mask: (MNT_INVERT, MNT_NOMTAB)
33 *
34 * The option argument value is defined by:
35 *
36 * "=" -- required argument, e.g "comment="
37 *
38 * "[=]" -- optional argument, e.g. "loop[=]"
39 *
40 * Example:
41 *
42 * <informalexample>
43 * <programlisting>
44 * #define MY_MS_FOO (1 << 1)
45 * #define MY_MS_BAR (1 << 2)
46 *
47 * libmnt_optmap myoptions[] = {
48 * { "foo", MY_MS_FOO },
49 * { "nofoo", MY_MS_FOO | MNT_INVERT },
50 * { "bar=", MY_MS_BAR },
51 * { NULL }
52 * };
53 * </programlisting>
54 * </informalexample>
55 *
56 * The libmount defines two basic built-in options maps:
57 *
58 * @MNT_LINUX_MAP: fs-independent kernel mount options (usually MS_* flags)
59 *
60 * @MNT_USERSPACE_MAP: userspace specific mount options (e.g. "user", "loop")
61 *
62 * For more details about option map struct see "struct mnt_optmap" in
63 * mount/mount.h.
64 */
65 #include "mountP.h"
66 #include "strutils.h"
67
68 /*
69 * fs-independent mount flags (built-in MNT_LINUX_MAP)
70 */
71 static const struct libmnt_optmap linux_flags_map[] =
72 {
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 */
81
82 { "sync", MS_SYNCHRONOUS }, /* synchronous I/O */
83 { "async", MS_SYNCHRONOUS, MNT_INVERT },/* asynchronous I/O */
84
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 */
89 #ifdef MS_NOSUB
90 { "sub", MS_NOSUB, MNT_INVERT }, /* allow submounts */
91 { "nosub", MS_NOSUB }, /* don't allow submounts */
92 #endif
93 #ifdef MS_SILENT
94 { "silent", MS_SILENT }, /* be quiet */
95 { "loud", MS_SILENT, MNT_INVERT }, /* print out messages. */
96 #endif
97 #ifdef MS_MANDLOCK
98 { "mand", MS_MANDLOCK }, /* Allow mandatory locks on this FS */
99 { "nomand", MS_MANDLOCK, MNT_INVERT }, /* Forbid mandatory locks on this FS */
100 #endif
101 #ifdef MS_NOATIME
102 { "atime", MS_NOATIME, MNT_INVERT }, /* Update access time */
103 { "noatime", MS_NOATIME }, /* Do not update access time */
104 #endif
105 #ifdef MS_I_VERSION
106 { "iversion", MS_I_VERSION }, /* Update inode I_version time */
107 { "noiversion", MS_I_VERSION, MNT_INVERT},/* Don't update inode I_version time */
108 #endif
109 #ifdef MS_NODIRATIME
110 { "diratime", MS_NODIRATIME, MNT_INVERT }, /* Update dir access times */
111 { "nodiratime", MS_NODIRATIME }, /* Do not update dir access times */
112 #endif
113 #ifdef MS_RELATIME
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 */
116 #endif
117 #ifdef MS_STRICTATIME
118 { "strictatime", MS_STRICTATIME }, /* Strict atime semantics */
119 { "nostrictatime", MS_STRICTATIME, MNT_INVERT }, /* kernel default atime */
120 #endif
121 #ifdef MS_LAZYTIME
122 { "lazytime", MS_LAZYTIME }, /* Update {a,m,c}time on the in-memory inode only */
123 { "nolazytime", MS_LAZYTIME, MNT_INVERT },
124 #endif
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 },
134 #endif
135 { NULL, 0, 0 }
136 };
137
138 /*
139 * userspace mount option (built-in MNT_USERSPACE_MAP)
140 */
141 static const struct libmnt_optmap userspace_opts_map[] =
142 {
143 { "defaults", 0, 0 }, /* default options */
144
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 */
147
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 */
150
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 */
153
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 */
156
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 */
159
160 /*
161 * Note that traditional init scripts assume the _netdev option in /etc/mtab to
162 * umount network block devices on shutdown.
163 */
164 { "_netdev", MNT_MS_NETDEV }, /* Device requires network */
165
166 { "comment=", MNT_MS_COMMENT, MNT_NOHLPS | MNT_NOMTAB },/* fstab comment only */
167
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 */
170
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 */
175
176 { "nofail", MNT_MS_NOFAIL, MNT_NOMTAB }, /* Do not fail if ENOENT on dev */
177
178 { "uhelper=", MNT_MS_UHELPER }, /* /sbin/umount.<helper> */
179
180 { "helper=", MNT_MS_HELPER }, /* /sbin/mount.<helper> */
181
182 { NULL, 0, 0 }
183 };
184
185 /**
186 * mnt_get_builtin_map:
187 * @id: map id -- MNT_LINUX_MAP or MNT_USERSPACE_MAP
188 *
189 * MNT_LINUX_MAP - Linux kernel fs-independent mount options
190 * (usually MS_* flags, see linux/fs.h)
191 *
192 * MNT_USERSPACE_MAP - userspace mount(8) specific mount options
193 * (e.g user=, _netdev, ...)
194 *
195 * Returns: static built-in libmount map.
196 */
197 const struct libmnt_optmap *mnt_get_builtin_optmap(int id)
198 {
199 assert(id);
200
201 if (id == MNT_LINUX_MAP)
202 return linux_flags_map;
203 else if (id == MNT_USERSPACE_MAP)
204 return userspace_opts_map;
205 return NULL;
206 }
207
208 /*
209 * Looks up the @name in @maps and returns a map and in @mapent
210 * returns the map entry
211 */
212 const struct libmnt_optmap *mnt_optmap_get_entry(
213 struct libmnt_optmap const **maps,
214 int nmaps,
215 const char *name,
216 size_t namelen,
217 const struct libmnt_optmap **mapent)
218 {
219 int i;
220
221 assert(maps);
222 assert(nmaps);
223 assert(name);
224 assert(namelen);
225
226 if (mapent)
227 *mapent = NULL;
228
229 for (i = 0; i < nmaps; i++) {
230 const struct libmnt_optmap *map = maps[i];
231 const struct libmnt_optmap *ent;
232 const char *p;
233
234 for (ent = map; ent && ent->name; ent++) {
235 if (ent->mask & MNT_PREFIX) {
236 if (startswith(name, ent->name)) {
237 if (mapent)
238 *mapent = ent;
239 return map;
240 }
241 continue;
242 }
243 if (strncmp(ent->name, name, namelen))
244 continue;
245 p = ent->name + namelen;
246 if (*p == '\0' || *p == '=' || *p == '[') {
247 if (mapent)
248 *mapent = ent;
249 return map;
250 }
251 }
252 }
253 return NULL;
254 }
255