]>
Commit | Line | Data |
---|---|---|
2c37ca7c | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
078edb2d | 2 | /* |
2c37ca7c | 3 | * This file is part of libmount from util-linux project. |
078edb2d | 4 | * |
2c37ca7c KZ |
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. | |
192c6aad KZ |
11 | */ |
12 | ||
13 | /** | |
14 | * SECTION: optmap | |
15 | * @title: Option maps | |
16 | * @short_description: description for mount options | |
078edb2d | 17 | * |
078edb2d KZ |
18 | * The mount(2) linux syscall uses two arguments for mount options: |
19 | * | |
3d735589 KZ |
20 | * @mountflags: (see MS_* macros in linux/fs.h) |
21 | * | |
9e930041 | 22 | * @mountdata: (usually a comma separated string of options) |
078edb2d | 23 | * |
0f32f1e2 | 24 | * The libmount uses options-map(s) to describe mount options. |
078edb2d KZ |
25 | * |
26 | * The option description (map entry) includes: | |
27 | * | |
0f32f1e2 | 28 | * @name: and argument name |
3d735589 KZ |
29 | * |
30 | * @id: (in the map unique identifier or a mountflags, e.g MS_RDONLY) | |
31 | * | |
66b8b8cd | 32 | * @mask: (MNT_INVERT, MNT_NOMTAB) |
078edb2d | 33 | * |
0f32f1e2 | 34 | * The option argument value is defined by: |
078edb2d | 35 | * |
0f32f1e2 | 36 | * "=" -- required argument, e.g "comment=" |
3d735589 | 37 | * |
0f32f1e2 | 38 | * "[=]" -- optional argument, e.g. "loop[=]" |
078edb2d | 39 | * |
3d735589 KZ |
40 | * Example: |
41 | * | |
42 | * <informalexample> | |
43 | * <programlisting> | |
44 | * #define MY_MS_FOO (1 << 1) | |
45 | * #define MY_MS_BAR (1 << 2) | |
46 | * | |
68164f6c | 47 | * libmnt_optmap myoptions[] = { |
66b8b8cd KZ |
48 | * { "foo", MY_MS_FOO }, |
49 | * { "nofoo", MY_MS_FOO | MNT_INVERT }, | |
0f32f1e2 | 50 | * { "bar=", MY_MS_BAR }, |
3d735589 KZ |
51 | * { NULL } |
52 | * }; | |
53 | * </programlisting> | |
54 | * </informalexample> | |
55 | * | |
078edb2d KZ |
56 | * The libmount defines two basic built-in options maps: |
57 | * | |
3d735589 KZ |
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") | |
078edb2d | 61 | * |
192c6aad KZ |
62 | * For more details about option map struct see "struct mnt_optmap" in |
63 | * mount/mount.h. | |
078edb2d | 64 | */ |
078edb2d | 65 | #include "mountP.h" |
199e939d | 66 | #include "strutils.h" |
078edb2d KZ |
67 | |
68 | /* | |
69 | * fs-independent mount flags (built-in MNT_LINUX_MAP) | |
70 | */ | |
68164f6c | 71 | static const struct libmnt_optmap linux_flags_map[] = |
078edb2d | 72 | { |
66b8b8cd KZ |
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 */ | |
078edb2d | 81 | |
66b8b8cd KZ |
82 | { "sync", MS_SYNCHRONOUS }, /* synchronous I/O */ |
83 | { "async", MS_SYNCHRONOUS, MNT_INVERT },/* asynchronous I/O */ | |
078edb2d | 84 | |
66b8b8cd | 85 | { "dirsync", MS_DIRSYNC }, /* synchronous directory modifications */ |
f84fa6f7 | 86 | { "remount", MS_REMOUNT, MNT_NOMTAB }, /* alter flags of mounted FS */ |
d58b3157 | 87 | { "bind", MS_BIND }, /* Remount part of the tree elsewhere */ |
66b8b8cd | 88 | { "rbind", MS_BIND | MS_REC }, /* Idem, plus mounted subtrees */ |
078edb2d | 89 | #ifdef MS_NOSUB |
66b8b8cd KZ |
90 | { "sub", MS_NOSUB, MNT_INVERT }, /* allow submounts */ |
91 | { "nosub", MS_NOSUB }, /* don't allow submounts */ | |
078edb2d KZ |
92 | #endif |
93 | #ifdef MS_SILENT | |
5af1532e | 94 | { "silent", MS_SILENT }, /* be quiet */ |
66b8b8cd | 95 | { "loud", MS_SILENT, MNT_INVERT }, /* print out messages. */ |
078edb2d KZ |
96 | #endif |
97 | #ifdef MS_MANDLOCK | |
66b8b8cd KZ |
98 | { "mand", MS_MANDLOCK }, /* Allow mandatory locks on this FS */ |
99 | { "nomand", MS_MANDLOCK, MNT_INVERT }, /* Forbid mandatory locks on this FS */ | |
078edb2d KZ |
100 | #endif |
101 | #ifdef MS_NOATIME | |
66b8b8cd KZ |
102 | { "atime", MS_NOATIME, MNT_INVERT }, /* Update access time */ |
103 | { "noatime", MS_NOATIME }, /* Do not update access time */ | |
078edb2d KZ |
104 | #endif |
105 | #ifdef MS_I_VERSION | |
66b8b8cd KZ |
106 | { "iversion", MS_I_VERSION }, /* Update inode I_version time */ |
107 | { "noiversion", MS_I_VERSION, MNT_INVERT},/* Don't update inode I_version time */ | |
078edb2d KZ |
108 | #endif |
109 | #ifdef MS_NODIRATIME | |
66b8b8cd KZ |
110 | { "diratime", MS_NODIRATIME, MNT_INVERT }, /* Update dir access times */ |
111 | { "nodiratime", MS_NODIRATIME }, /* Do not update dir access times */ | |
078edb2d KZ |
112 | #endif |
113 | #ifdef MS_RELATIME | |
66b8b8cd KZ |
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 */ | |
078edb2d KZ |
116 | #endif |
117 | #ifdef MS_STRICTATIME | |
66b8b8cd KZ |
118 | { "strictatime", MS_STRICTATIME }, /* Strict atime semantics */ |
119 | { "nostrictatime", MS_STRICTATIME, MNT_INVERT }, /* kernel default atime */ | |
6498ece0 | 120 | #endif |
8c7f073a KZ |
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 | |
6498ece0 KZ |
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 }, | |
078edb2d KZ |
134 | #endif |
135 | { NULL, 0, 0 } | |
136 | }; | |
137 | ||
138 | /* | |
139 | * userspace mount option (built-in MNT_USERSPACE_MAP) | |
140 | */ | |
68164f6c | 141 | static const struct libmnt_optmap userspace_opts_map[] = |
078edb2d | 142 | { |
76a06ca4 | 143 | { "defaults", 0, 0 }, /* default options */ |
078edb2d | 144 | |
5810d870 | 145 | { "auto", MNT_MS_NOAUTO, MNT_NOHLPS | MNT_INVERT | MNT_NOMTAB }, /* Can be mounted using -a */ |
d58b3157 | 146 | { "noauto", MNT_MS_NOAUTO, MNT_NOHLPS | MNT_NOMTAB }, /* Can only be mounted explicitly */ |
078edb2d | 147 | |
699abc83 | 148 | { "user[=]", MNT_MS_USER }, /* Allow ordinary user to mount (mtab) */ |
078edb2d KZ |
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 | ||
94b0c44f | 160 | /* |
d58b3157 | 161 | * Note that traditional init scripts assume the _netdev option in /etc/mtab to |
94b0c44f KZ |
162 | * umount network block devices on shutdown. |
163 | */ | |
078edb2d KZ |
164 | { "_netdev", MNT_MS_NETDEV }, /* Device requires network */ |
165 | ||
5810d870 | 166 | { "comment=", MNT_MS_COMMENT, MNT_NOHLPS | MNT_NOMTAB },/* fstab comment only */ |
83601b1a | 167 | |
0a14cc8b KZ |
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 */ | |
078edb2d | 170 | |
5810d870 KZ |
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 */ | |
078edb2d KZ |
175 | |
176 | { "nofail", MNT_MS_NOFAIL, MNT_NOMTAB }, /* Do not fail if ENOENT on dev */ | |
177 | ||
0f32f1e2 | 178 | { "uhelper=", MNT_MS_UHELPER }, /* /sbin/umount.<helper> */ |
f309b8a7 | 179 | |
5810d870 | 180 | { "helper=", MNT_MS_HELPER }, /* /sbin/mount.<helper> */ |
4b658e09 | 181 | |
e6a49887 LB |
182 | { "verity.hashdevice=", MNT_MS_HASH_DEVICE, MNT_NOHLPS | MNT_NOMTAB }, /* mount a verity device */ |
183 | { "verity.roothash=", MNT_MS_ROOT_HASH, MNT_NOHLPS | MNT_NOMTAB }, /* verity device root hash */ | |
184 | { "verity.hashoffset=", MNT_MS_HASH_OFFSET, MNT_NOHLPS | MNT_NOMTAB }, /* verity device hash offset */ | |
141bb954 | 185 | { "verity.roothashfile=", MNT_MS_ROOT_HASH_FILE, MNT_NOHLPS | MNT_NOMTAB },/* verity device root hash (read from file) */ |
9835a4b6 LB |
186 | { "verity.fecdevice=", MNT_MS_FEC_DEVICE, MNT_NOHLPS | MNT_NOMTAB }, /* verity FEC device */ |
187 | { "verity.fecoffset=", MNT_MS_FEC_OFFSET, MNT_NOHLPS | MNT_NOMTAB }, /* verity FEC area offset */ | |
188 | { "verity.fecroots=", MNT_MS_FEC_ROOTS, MNT_NOHLPS | MNT_NOMTAB }, /* verity FEC roots */ | |
123b1a67 | 189 | { "verity.roothashsig=", MNT_MS_ROOT_HASH_SIG, MNT_NOHLPS | MNT_NOMTAB }, /* verity device root hash signature file */ |
e6a49887 | 190 | |
078edb2d KZ |
191 | { NULL, 0, 0 } |
192 | }; | |
193 | ||
194 | /** | |
195 | * mnt_get_builtin_map: | |
196 | * @id: map id -- MNT_LINUX_MAP or MNT_USERSPACE_MAP | |
197 | * | |
198 | * MNT_LINUX_MAP - Linux kernel fs-independent mount options | |
199 | * (usually MS_* flags, see linux/fs.h) | |
200 | * | |
9e930041 | 201 | * MNT_USERSPACE_MAP - userspace mount(8) specific mount options |
078edb2d KZ |
202 | * (e.g user=, _netdev, ...) |
203 | * | |
192c6aad | 204 | * Returns: static built-in libmount map. |
078edb2d | 205 | */ |
68164f6c | 206 | const struct libmnt_optmap *mnt_get_builtin_optmap(int id) |
078edb2d KZ |
207 | { |
208 | assert(id); | |
209 | ||
210 | if (id == MNT_LINUX_MAP) | |
211 | return linux_flags_map; | |
042f62df | 212 | if (id == MNT_USERSPACE_MAP) |
078edb2d KZ |
213 | return userspace_opts_map; |
214 | return NULL; | |
215 | } | |
216 | ||
217 | /* | |
d58b3157 | 218 | * Looks up the @name in @maps and returns a map and in @mapent |
078edb2d KZ |
219 | * returns the map entry |
220 | */ | |
68164f6c KZ |
221 | const struct libmnt_optmap *mnt_optmap_get_entry( |
222 | struct libmnt_optmap const **maps, | |
078edb2d KZ |
223 | int nmaps, |
224 | const char *name, | |
225 | size_t namelen, | |
68164f6c | 226 | const struct libmnt_optmap **mapent) |
078edb2d KZ |
227 | { |
228 | int i; | |
229 | ||
230 | assert(maps); | |
231 | assert(nmaps); | |
232 | assert(name); | |
233 | assert(namelen); | |
078edb2d | 234 | |
3661b841 KZ |
235 | if (mapent) |
236 | *mapent = NULL; | |
078edb2d KZ |
237 | |
238 | for (i = 0; i < nmaps; i++) { | |
68164f6c KZ |
239 | const struct libmnt_optmap *map = maps[i]; |
240 | const struct libmnt_optmap *ent; | |
078edb2d KZ |
241 | const char *p; |
242 | ||
243 | for (ent = map; ent && ent->name; ent++) { | |
699abc83 KZ |
244 | if (ent->mask & MNT_PREFIX) { |
245 | if (startswith(name, ent->name)) { | |
246 | if (mapent) | |
247 | *mapent = ent; | |
248 | return map; | |
249 | } | |
250 | continue; | |
251 | } | |
078edb2d KZ |
252 | if (strncmp(ent->name, name, namelen)) |
253 | continue; | |
254 | p = ent->name + namelen; | |
255 | if (*p == '\0' || *p == '=' || *p == '[') { | |
3661b841 KZ |
256 | if (mapent) |
257 | *mapent = ent; | |
078edb2d KZ |
258 | return map; |
259 | } | |
260 | } | |
261 | } | |
262 | return NULL; | |
263 | } | |
264 |