Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 1 | ===================== |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 2 | autofs - how it works |
| 3 | ===================== |
| 4 | |
| 5 | Purpose |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 6 | ======= |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 7 | |
| 8 | The goal of autofs is to provide on-demand mounting and race free |
| 9 | automatic unmounting of various other filesystems. This provides two |
| 10 | key advantages: |
| 11 | |
| 12 | 1. There is no need to delay boot until all filesystems that |
| 13 | might be needed are mounted. Processes that try to access those |
| 14 | slow filesystems might be delayed but other processes can |
| 15 | continue freely. This is particularly important for |
| 16 | network filesystems (e.g. NFS) or filesystems stored on |
| 17 | media with a media-changing robot. |
| 18 | |
| 19 | 2. The names and locations of filesystems can be stored in |
| 20 | a remote database and can change at any time. The content |
| 21 | in that data base at the time of access will be used to provide |
| 22 | a target for the access. The interpretation of names in the |
| 23 | filesystem can even be programmatic rather than database-backed, |
| 24 | allowing wildcards for example, and can vary based on the user who |
| 25 | first accessed a name. |
| 26 | |
| 27 | Context |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 28 | ======= |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 29 | |
Ian Kent | b6bb226 | 2018-06-07 17:11:38 -0700 | [diff] [blame] | 30 | The "autofs" filesystem module is only one part of an autofs system. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 31 | There also needs to be a user-space program which looks up names |
| 32 | and mounts filesystems. This will often be the "automount" program, |
Ian Kent | b6bb226 | 2018-06-07 17:11:38 -0700 | [diff] [blame] | 33 | though other tools including "systemd" can make use of "autofs". |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 34 | This document describes only the kernel module and the interactions |
| 35 | required with any user-space program. Subsequent text refers to this |
| 36 | as the "automount daemon" or simply "the daemon". |
| 37 | |
Wasin Thonkaew | 53b606f | 2021-11-03 19:35:04 +0000 | [diff] [blame] | 38 | "autofs" is a Linux kernel module which provides the "autofs" |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 39 | filesystem type. Several "autofs" filesystems can be mounted and they |
| 40 | can each be managed separately, or all managed by the same daemon. |
| 41 | |
| 42 | Content |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 43 | ======= |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 44 | |
| 45 | An autofs filesystem can contain 3 sorts of objects: directories, |
| 46 | symbolic links and mount traps. Mount traps are directories with |
| 47 | extra properties as described in the next section. |
| 48 | |
| 49 | Objects can only be created by the automount daemon: symlinks are |
| 50 | created with a regular `symlink` system call, while directories and |
| 51 | mount traps are created with `mkdir`. The determination of whether a |
Jaskaran Singh | e8a9e30 | 2019-11-17 22:54:36 +0530 | [diff] [blame] | 52 | directory should be a mount trap is based on a master map. This master |
| 53 | map is consulted by autofs to determine which directories are mount |
| 54 | points. Mount points can be *direct*/*indirect*/*offset*. |
| 55 | On most systems, the default master map is located at */etc/auto.master*. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 56 | |
| 57 | If neither the *direct* or *offset* mount options are given (so the |
| 58 | mount is considered to be *indirect*), then the root directory is |
| 59 | always a regular directory, otherwise it is a mount trap when it is |
| 60 | empty and a regular directory when not empty. Note that *direct* and |
| 61 | *offset* are treated identically so a concise summary is that the root |
| 62 | directory is a mount trap only if the filesystem is mounted *direct* |
| 63 | and the root is empty. |
| 64 | |
| 65 | Directories created in the root directory are mount traps only if the |
Tomohiro Kusumi | d0846dd | 2017-02-27 14:27:02 -0800 | [diff] [blame] | 66 | filesystem is mounted *indirect* and they are empty. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 67 | |
| 68 | Directories further down the tree depend on the *maxproto* mount |
| 69 | option and particularly whether it is less than five or not. |
| 70 | When *maxproto* is five, no directories further down the |
| 71 | tree are ever mount traps, they are always regular directories. When |
| 72 | the *maxproto* is four (or three), these directories are mount traps |
| 73 | precisely when they are empty. |
| 74 | |
| 75 | So: non-empty (i.e. non-leaf) directories are never mount traps. Empty |
| 76 | directories are sometimes mount traps, and sometimes not depending on |
| 77 | where in the tree they are (root, top level, or lower), the *maxproto*, |
| 78 | and whether the mount was *indirect* or not. |
| 79 | |
| 80 | Mount Traps |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 81 | =========== |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 82 | |
| 83 | A core element of the implementation of autofs is the Mount Traps |
| 84 | which are provided by the Linux VFS. Any directory provided by a |
| 85 | filesystem can be designated as a trap. This involves two separate |
| 86 | features that work together to allow autofs to do its job. |
| 87 | |
| 88 | **DCACHE_NEED_AUTOMOUNT** |
| 89 | |
| 90 | If a dentry has the DCACHE_NEED_AUTOMOUNT flag set (which gets set if |
| 91 | the inode has S_AUTOMOUNT set, or can be set directly) then it is |
| 92 | (potentially) a mount trap. Any access to this directory beyond a |
| 93 | "`stat`" will (normally) cause the `d_op->d_automount()` dentry operation |
| 94 | to be called. The task of this method is to find the filesystem that |
| 95 | should be mounted on the directory and to return it. The VFS is |
| 96 | responsible for actually mounting the root of this filesystem on the |
| 97 | directory. |
| 98 | |
| 99 | autofs doesn't find the filesystem itself but sends a message to the |
| 100 | automount daemon asking it to find and mount the filesystem. The |
| 101 | autofs `d_automount` method then waits for the daemon to report that |
| 102 | everything is ready. It will then return "`NULL`" indicating that the |
| 103 | mount has already happened. The VFS doesn't try to mount anything but |
| 104 | follows down the mount that is already there. |
| 105 | |
| 106 | This functionality is sufficient for some users of mount traps such |
| 107 | as NFS which creates traps so that mountpoints on the server can be |
| 108 | reflected on the client. However it is not sufficient for autofs. As |
| 109 | mounting onto a directory is considered to be "beyond a `stat`", the |
| 110 | automount daemon would not be able to mount a filesystem on the 'trap' |
| 111 | directory without some way to avoid getting caught in the trap. For |
| 112 | that purpose there is another flag. |
| 113 | |
| 114 | **DCACHE_MANAGE_TRANSIT** |
| 115 | |
| 116 | If a dentry has DCACHE_MANAGE_TRANSIT set then two very different but |
Ian Kent | 2ad56ad | 2019-05-14 15:44:14 -0700 | [diff] [blame] | 117 | related behaviours are invoked, both using the `d_op->d_manage()` |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 118 | dentry operation. |
| 119 | |
| 120 | Firstly, before checking to see if any filesystem is mounted on the |
| 121 | directory, d_manage() will be called with the `rcu_walk` parameter set |
| 122 | to `false`. It may return one of three things: |
| 123 | |
| 124 | - A return value of zero indicates that there is nothing special |
| 125 | about this dentry and normal checks for mounts and automounts |
| 126 | should proceed. |
| 127 | |
| 128 | autofs normally returns zero, but first waits for any |
| 129 | expiry (automatic unmounting of the mounted filesystem) to |
| 130 | complete. This avoids races. |
| 131 | |
| 132 | - A return value of `-EISDIR` tells the VFS to ignore any mounts |
| 133 | on the directory and to not consider calling `->d_automount()`. |
| 134 | This effectively disables the **DCACHE_NEED_AUTOMOUNT** flag |
| 135 | causing the directory not be a mount trap after all. |
| 136 | |
| 137 | autofs returns this if it detects that the process performing the |
| 138 | lookup is the automount daemon and that the mount has been |
| 139 | requested but has not yet completed. How it determines this is |
| 140 | discussed later. This allows the automount daemon not to get |
| 141 | caught in the mount trap. |
| 142 | |
| 143 | There is a subtlety here. It is possible that a second autofs |
| 144 | filesystem can be mounted below the first and for both of them to |
| 145 | be managed by the same daemon. For the daemon to be able to mount |
| 146 | something on the second it must be able to "walk" down past the |
| 147 | first. This means that d_manage cannot *always* return -EISDIR for |
| 148 | the automount daemon. It must only return it when a mount has |
| 149 | been requested, but has not yet completed. |
| 150 | |
| 151 | `d_manage` also returns `-EISDIR` if the dentry shouldn't be a |
| 152 | mount trap, either because it is a symbolic link or because it is |
| 153 | not empty. |
| 154 | |
| 155 | - Any other negative value is treated as an error and returned |
| 156 | to the caller. |
| 157 | |
| 158 | autofs can return |
| 159 | |
| 160 | - -ENOENT if the automount daemon failed to mount anything, |
| 161 | - -ENOMEM if it ran out of memory, |
| 162 | - -EINTR if a signal arrived while waiting for expiry to |
| 163 | complete |
| 164 | - or any other error sent down by the automount daemon. |
| 165 | |
| 166 | |
| 167 | The second use case only occurs during an "RCU-walk" and so `rcu_walk` |
| 168 | will be set. |
| 169 | |
| 170 | An RCU-walk is a fast and lightweight process for walking down a |
| 171 | filename path (i.e. it is like running on tip-toes). RCU-walk cannot |
| 172 | cope with all situations so when it finds a difficulty it falls back |
| 173 | to "REF-walk", which is slower but more robust. |
| 174 | |
| 175 | RCU-walk will never call `->d_automount`; the filesystems must already |
| 176 | be mounted or RCU-walk cannot handle the path. |
| 177 | To determine if a mount-trap is safe for RCU-walk mode it calls |
| 178 | `->d_manage()` with `rcu_walk` set to `true`. |
| 179 | |
| 180 | In this case `d_manage()` must avoid blocking and should avoid taking |
| 181 | spinlocks if at all possible. Its sole purpose is to determine if it |
| 182 | would be safe to follow down into any mounted directory and the only |
| 183 | reason that it might not be is if an expiry of the mount is |
| 184 | underway. |
| 185 | |
| 186 | In the `rcu_walk` case, `d_manage()` cannot return -EISDIR to tell the |
| 187 | VFS that this is a directory that doesn't require d_automount. If |
| 188 | `rcu_walk` sees a dentry with DCACHE_NEED_AUTOMOUNT set but nothing |
| 189 | mounted, it *will* fall back to REF-walk. `d_manage()` cannot make the |
| 190 | VFS remain in RCU-walk mode, but can only tell it to get out of |
| 191 | RCU-walk mode by returning `-ECHILD`. |
| 192 | |
| 193 | So `d_manage()`, when called with `rcu_walk` set, should either return |
Ian Kent | 2ad56ad | 2019-05-14 15:44:14 -0700 | [diff] [blame] | 194 | -ECHILD if there is any reason to believe it is unsafe to enter the |
| 195 | mounted filesystem, otherwise it should return 0. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 196 | |
| 197 | autofs will return `-ECHILD` if an expiry of the filesystem has been |
| 198 | initiated or is being considered, otherwise it returns 0. |
| 199 | |
| 200 | |
| 201 | Mountpoint expiry |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 202 | ================= |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 203 | |
Tomohiro Kusumi | e662145 | 2016-10-11 13:52:25 -0700 | [diff] [blame] | 204 | The VFS has a mechanism for automatically expiring unused mounts, |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 205 | much as it can expire any unused dentry information from the dcache. |
Tomohiro Kusumi | e662145 | 2016-10-11 13:52:25 -0700 | [diff] [blame] | 206 | This is guided by the MNT_SHRINKABLE flag. This only applies to |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 207 | mounts that were created by `d_automount()` returning a filesystem to be |
| 208 | mounted. As autofs doesn't return such a filesystem but leaves the |
| 209 | mounting to the automount daemon, it must involve the automount daemon |
| 210 | in unmounting as well. This also means that autofs has more control |
Ian Kent | 2ad56ad | 2019-05-14 15:44:14 -0700 | [diff] [blame] | 211 | over expiry. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 212 | |
| 213 | The VFS also supports "expiry" of mounts using the MNT_EXPIRE flag to |
| 214 | the `umount` system call. Unmounting with MNT_EXPIRE will fail unless |
| 215 | a previous attempt had been made, and the filesystem has been inactive |
Ian Kent | b6bb226 | 2018-06-07 17:11:38 -0700 | [diff] [blame] | 216 | and untouched since that previous attempt. autofs does not depend on |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 217 | this but has its own internal tracking of whether filesystems were |
| 218 | recently used. This allows individual names in the autofs directory |
| 219 | to expire separately. |
| 220 | |
| 221 | With version 4 of the protocol, the automount daemon can try to |
| 222 | unmount any filesystems mounted on the autofs filesystem or remove any |
| 223 | symbolic links or empty directories any time it likes. If the unmount |
| 224 | or removal is successful the filesystem will be returned to the state |
| 225 | it was before the mount or creation, so that any access of the name |
Ian Kent | 2ad56ad | 2019-05-14 15:44:14 -0700 | [diff] [blame] | 226 | will trigger normal auto-mount processing. In particular, `rmdir` and |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 227 | `unlink` do not leave negative entries in the dcache as a normal |
| 228 | filesystem would, so an attempt to access a recently-removed object is |
| 229 | passed to autofs for handling. |
| 230 | |
| 231 | With version 5, this is not safe except for unmounting from top-level |
| 232 | directories. As lower-level directories are never mount traps, other |
| 233 | processes will see an empty directory as soon as the filesystem is |
| 234 | unmounted. So it is generally safest to use the autofs expiry |
| 235 | protocol described below. |
| 236 | |
| 237 | Normally the daemon only wants to remove entries which haven't been |
| 238 | used for a while. For this purpose autofs maintains a "`last_used`" |
| 239 | time stamp on each directory or symlink. For symlinks it genuinely |
| 240 | does record the last time the symlink was "used" or followed to find |
Ian Kent | 9200026 | 2019-05-14 15:44:17 -0700 | [diff] [blame] | 241 | out where it points to. For directories the field is used slightly |
| 242 | differently. The field is updated at mount time and during expire |
| 243 | checks if it is found to be in use (ie. open file descriptor or |
| 244 | process working directory) and during path walks. The update done |
| 245 | during path walks prevents frequent expire and immediate mount of |
| 246 | frequently accessed automounts. But in the case where a GUI continually |
| 247 | access or an application frequently scans an autofs directory tree |
| 248 | there can be an accumulation of mounts that aren't actually being |
| 249 | used. To cater for this case the "`strictexpire`" autofs mount option |
| 250 | can be used to avoid the "`last_used`" update on path walk thereby |
| 251 | preventing this apparent inability to expire mounts that aren't |
| 252 | really in use. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 253 | |
| 254 | The daemon is able to ask autofs if anything is due to be expired, |
| 255 | using an `ioctl` as discussed later. For a *direct* mount, autofs |
| 256 | considers if the entire mount-tree can be unmounted or not. For an |
| 257 | *indirect* mount, autofs considers each of the names in the top level |
| 258 | directory to determine if any of those can be unmounted and cleaned |
| 259 | up. |
| 260 | |
| 261 | There is an option with indirect mounts to consider each of the leaves |
| 262 | that has been mounted on instead of considering the top-level names. |
Ian Kent | f23ceaa | 2019-05-14 15:44:20 -0700 | [diff] [blame] | 263 | This was originally intended for compatibility with version 4 of autofs |
| 264 | and should be considered as deprecated for Sun Format automount maps. |
| 265 | However, it may be used again for amd format mount maps (which are |
| 266 | generally indirect maps) because the amd automounter allows for the |
| 267 | setting of an expire timeout for individual mounts. But there are |
| 268 | some difficulties in making the needed changes for this. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 269 | |
| 270 | When autofs considers a directory it checks the `last_used` time and |
| 271 | compares it with the "timeout" value set when the filesystem was |
| 272 | mounted, though this check is ignored in some cases. It also checks if |
| 273 | the directory or anything below it is in use. For symbolic links, |
| 274 | only the `last_used` time is ever considered. |
| 275 | |
| 276 | If both appear to support expiring the directory or symlink, an action |
| 277 | is taken. |
| 278 | |
| 279 | There are two ways to ask autofs to consider expiry. The first is to |
| 280 | use the **AUTOFS_IOC_EXPIRE** ioctl. This only works for indirect |
| 281 | mounts. If it finds something in the root directory to expire it will |
| 282 | return the name of that thing. Once a name has been returned the |
| 283 | automount daemon needs to unmount any filesystems mounted below the |
| 284 | name normally. As described above, this is unsafe for non-toplevel |
Ian Kent | 2ad56ad | 2019-05-14 15:44:14 -0700 | [diff] [blame] | 285 | mounts in a version-5 autofs. For this reason the current `automount(8)` |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 286 | does not use this ioctl. |
| 287 | |
| 288 | The second mechanism uses either the **AUTOFS_DEV_IOCTL_EXPIRE_CMD** or |
| 289 | the **AUTOFS_IOC_EXPIRE_MULTI** ioctl. This will work for both direct and |
| 290 | indirect mounts. If it selects an object to expire, it will notify |
| 291 | the daemon using the notification mechanism described below. This |
| 292 | will block until the daemon acknowledges the expiry notification. |
| 293 | This implies that the "`EXPIRE`" ioctl must be sent from a different |
| 294 | thread than the one which handles notification. |
| 295 | |
| 296 | While the ioctl is blocking, the entry is marked as "expiring" and |
| 297 | `d_manage` will block until the daemon affirms that the unmount has |
| 298 | completed (together with removing any directories that might have been |
| 299 | necessary), or has been aborted. |
| 300 | |
| 301 | Communicating with autofs: detecting the daemon |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 302 | =============================================== |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 303 | |
| 304 | There are several forms of communication between the automount daemon |
| 305 | and the filesystem. As we have already seen, the daemon can create and |
| 306 | remove directories and symlinks using normal filesystem operations. |
| 307 | autofs knows whether a process requesting some operation is the daemon |
| 308 | or not based on its process-group id number (see getpgid(1)). |
| 309 | |
Tomohiro Kusumi | e662145 | 2016-10-11 13:52:25 -0700 | [diff] [blame] | 310 | When an autofs filesystem is mounted the pgid of the mounting |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 311 | processes is recorded unless the "pgrp=" option is given, in which |
| 312 | case that number is recorded instead. Any request arriving from a |
| 313 | process in that process group is considered to come from the daemon. |
| 314 | If the daemon ever has to be stopped and restarted a new pgid can be |
| 315 | provided through an ioctl as will be described below. |
| 316 | |
| 317 | Communicating with autofs: the event pipe |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 318 | ========================================= |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 319 | |
| 320 | When an autofs filesystem is mounted, the 'write' end of a pipe must |
| 321 | be passed using the 'fd=' mount option. autofs will write |
| 322 | notification messages to this pipe for the daemon to respond to. |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 323 | For version 5, the format of the message is:: |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 324 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 325 | struct autofs_v5_packet { |
Jaskaran Singh | c11565e | 2019-11-17 22:54:35 +0530 | [diff] [blame] | 326 | struct autofs_packet_hdr hdr; |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 327 | autofs_wqt_t wait_queue_token; |
| 328 | __u32 dev; |
| 329 | __u64 ino; |
| 330 | __u32 uid; |
| 331 | __u32 gid; |
| 332 | __u32 pid; |
| 333 | __u32 tgid; |
| 334 | __u32 len; |
| 335 | char name[NAME_MAX+1]; |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 336 | }; |
| 337 | |
Jaskaran Singh | c11565e | 2019-11-17 22:54:35 +0530 | [diff] [blame] | 338 | And the format of the header is:: |
| 339 | |
| 340 | struct autofs_packet_hdr { |
| 341 | int proto_version; /* Protocol version */ |
| 342 | int type; /* Type of packet */ |
| 343 | }; |
| 344 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 345 | where the type is one of :: |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 346 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 347 | autofs_ptype_missing_indirect |
| 348 | autofs_ptype_expire_indirect |
| 349 | autofs_ptype_missing_direct |
| 350 | autofs_ptype_expire_direct |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 351 | |
| 352 | so messages can indicate that a name is missing (something tried to |
| 353 | access it but it isn't there) or that it has been selected for expiry. |
| 354 | |
| 355 | The pipe will be set to "packet mode" (equivalent to passing |
| 356 | `O_DIRECT`) to _pipe2(2)_ so that a read from the pipe will return at |
| 357 | most one packet, and any unread portion of a packet will be discarded. |
| 358 | |
Linus Torvalds | 7cee938 | 2017-07-10 11:40:19 -0700 | [diff] [blame] | 359 | The `wait_queue_token` is a unique number which can identify a |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 360 | particular request to be acknowledged. When a message is sent over |
| 361 | the pipe the affected dentry is marked as either "active" or |
| 362 | "expiring" and other accesses to it block until the message is |
Ian Kent | 2ad56ad | 2019-05-14 15:44:14 -0700 | [diff] [blame] | 363 | acknowledged using one of the ioctls below with the relevant |
Linus Torvalds | 7cee938 | 2017-07-10 11:40:19 -0700 | [diff] [blame] | 364 | `wait_queue_token`. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 365 | |
| 366 | Communicating with autofs: root directory ioctls |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 367 | ================================================ |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 368 | |
| 369 | The root directory of an autofs filesystem will respond to a number of |
Tomohiro Kusumi | d0846dd | 2017-02-27 14:27:02 -0800 | [diff] [blame] | 370 | ioctls. The process issuing the ioctl must have the CAP_SYS_ADMIN |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 371 | capability, or must be the automount daemon. |
| 372 | |
| 373 | The available ioctl commands are: |
| 374 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 375 | - **AUTOFS_IOC_READY**: |
| 376 | a notification has been handled. The argument |
| 377 | to the ioctl command is the "wait_queue_token" number |
| 378 | corresponding to the notification being acknowledged. |
| 379 | - **AUTOFS_IOC_FAIL**: |
| 380 | similar to above, but indicates failure with |
| 381 | the error code `ENOENT`. |
| 382 | - **AUTOFS_IOC_CATATONIC**: |
| 383 | Causes the autofs to enter "catatonic" |
| 384 | mode meaning that it stops sending notifications to the daemon. |
| 385 | This mode is also entered if a write to the pipe fails. |
| 386 | - **AUTOFS_IOC_PROTOVER**: |
| 387 | This returns the protocol version in use. |
| 388 | - **AUTOFS_IOC_PROTOSUBVER**: |
| 389 | Returns the protocol sub-version which |
| 390 | is really a version number for the implementation. |
| 391 | - **AUTOFS_IOC_SETTIMEOUT**: |
| 392 | This passes a pointer to an unsigned |
| 393 | long. The value is used to set the timeout for expiry, and |
| 394 | the current timeout value is stored back through the pointer. |
| 395 | - **AUTOFS_IOC_ASKUMOUNT**: |
| 396 | Returns, in the pointed-to `int`, 1 if |
| 397 | the filesystem could be unmounted. This is only a hint as |
| 398 | the situation could change at any instant. This call can be |
| 399 | used to avoid a more expensive full unmount attempt. |
| 400 | - **AUTOFS_IOC_EXPIRE**: |
| 401 | as described above, this asks if there is |
| 402 | anything suitable to expire. A pointer to a packet:: |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 403 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 404 | struct autofs_packet_expire_multi { |
Jaskaran Singh | c11565e | 2019-11-17 22:54:35 +0530 | [diff] [blame] | 405 | struct autofs_packet_hdr hdr; |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 406 | autofs_wqt_t wait_queue_token; |
| 407 | int len; |
| 408 | char name[NAME_MAX+1]; |
| 409 | }; |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 410 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 411 | is required. This is filled in with the name of something |
| 412 | that can be unmounted or removed. If nothing can be expired, |
| 413 | `errno` is set to `EAGAIN`. Even though a `wait_queue_token` |
| 414 | is present in the structure, no "wait queue" is established |
| 415 | and no acknowledgment is needed. |
| 416 | - **AUTOFS_IOC_EXPIRE_MULTI**: |
| 417 | This is similar to |
| 418 | **AUTOFS_IOC_EXPIRE** except that it causes notification to be |
| 419 | sent to the daemon, and it blocks until the daemon acknowledges. |
| 420 | The argument is an integer which can contain two different flags. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 421 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 422 | **AUTOFS_EXP_IMMEDIATE** causes `last_used` time to be ignored |
| 423 | and objects are expired if the are not in use. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 424 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 425 | **AUTOFS_EXP_FORCED** causes the in use status to be ignored |
| 426 | and objects are expired ieven if they are in use. This assumes |
| 427 | that the daemon has requested this because it is capable of |
| 428 | performing the umount. |
Ian Kent | 841964e | 2019-05-14 15:44:23 -0700 | [diff] [blame] | 429 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 430 | **AUTOFS_EXP_LEAVES** will select a leaf rather than a top-level |
| 431 | name to expire. This is only safe when *maxproto* is 4. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 432 | |
| 433 | Communicating with autofs: char-device ioctls |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 434 | ============================================= |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 435 | |
| 436 | It is not always possible to open the root of an autofs filesystem, |
| 437 | particularly a *direct* mounted filesystem. If the automount daemon |
| 438 | is restarted there is no way for it to regain control of existing |
| 439 | mounts using any of the above communication channels. To address this |
| 440 | need there is a "miscellaneous" character device (major 10, minor 235) |
| 441 | which can be used to communicate directly with the autofs filesystem. |
| 442 | It requires CAP_SYS_ADMIN for access. |
| 443 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 444 | The 'ioctl's that can be used on this device are described in a separate |
Ian Kent | 2ad56ad | 2019-05-14 15:44:14 -0700 | [diff] [blame] | 445 | document `autofs-mount-control.txt`, and are summarised briefly here. |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 446 | Each ioctl is passed a pointer to an `autofs_dev_ioctl` structure:: |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 447 | |
| 448 | struct autofs_dev_ioctl { |
| 449 | __u32 ver_major; |
| 450 | __u32 ver_minor; |
| 451 | __u32 size; /* total size of data passed in |
| 452 | * including this struct */ |
| 453 | __s32 ioctlfd; /* automount command fd */ |
| 454 | |
Tomohiro Kusumi | 8848808 | 2017-02-27 14:27:08 -0800 | [diff] [blame] | 455 | /* Command parameters */ |
| 456 | union { |
| 457 | struct args_protover protover; |
| 458 | struct args_protosubver protosubver; |
| 459 | struct args_openmount openmount; |
| 460 | struct args_ready ready; |
| 461 | struct args_fail fail; |
| 462 | struct args_setpipefd setpipefd; |
| 463 | struct args_timeout timeout; |
| 464 | struct args_requester requester; |
| 465 | struct args_expire expire; |
| 466 | struct args_askumount askumount; |
| 467 | struct args_ismountpoint ismountpoint; |
| 468 | }; |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 469 | |
| 470 | char path[0]; |
| 471 | }; |
| 472 | |
| 473 | For the **OPEN_MOUNT** and **IS_MOUNTPOINT** commands, the target |
| 474 | filesystem is identified by the `path`. All other commands identify |
| 475 | the filesystem by the `ioctlfd` which is a file descriptor open on the |
| 476 | root, and which can be returned by **OPEN_MOUNT**. |
| 477 | |
| 478 | The `ver_major` and `ver_minor` are in/out parameters which check that |
| 479 | the requested version is supported, and report the maximum version |
| 480 | that the kernel module can support. |
| 481 | |
| 482 | Commands are: |
| 483 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 484 | - **AUTOFS_DEV_IOCTL_VERSION_CMD**: |
| 485 | does nothing, except validate and |
| 486 | set version numbers. |
| 487 | - **AUTOFS_DEV_IOCTL_OPENMOUNT_CMD**: |
| 488 | return an open file descriptor |
| 489 | on the root of an autofs filesystem. The filesystem is identified |
| 490 | by name and device number, which is stored in `openmount.devid`. |
| 491 | Device numbers for existing filesystems can be found in |
| 492 | `/proc/self/mountinfo`. |
| 493 | - **AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD**: |
| 494 | same as `close(ioctlfd)`. |
| 495 | - **AUTOFS_DEV_IOCTL_SETPIPEFD_CMD**: |
| 496 | if the filesystem is in |
| 497 | catatonic mode, this can provide the write end of a new pipe |
| 498 | in `setpipefd.pipefd` to re-establish communication with a daemon. |
| 499 | The process group of the calling process is used to identify the |
| 500 | daemon. |
| 501 | - **AUTOFS_DEV_IOCTL_REQUESTER_CMD**: |
| 502 | `path` should be a |
| 503 | name within the filesystem that has been auto-mounted on. |
| 504 | On successful return, `requester.uid` and `requester.gid` will be |
| 505 | the UID and GID of the process which triggered that mount. |
| 506 | - **AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD**: |
| 507 | Check if path is a |
| 508 | mountpoint of a particular type - see separate documentation for |
| 509 | details. |
| 510 | |
| 511 | - **AUTOFS_DEV_IOCTL_PROTOVER_CMD** |
| 512 | - **AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD** |
| 513 | - **AUTOFS_DEV_IOCTL_READY_CMD** |
| 514 | - **AUTOFS_DEV_IOCTL_FAIL_CMD** |
| 515 | - **AUTOFS_DEV_IOCTL_CATATONIC_CMD** |
| 516 | - **AUTOFS_DEV_IOCTL_TIMEOUT_CMD** |
| 517 | - **AUTOFS_DEV_IOCTL_EXPIRE_CMD** |
| 518 | - **AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD** |
| 519 | |
| 520 | These all have the same |
| 521 | function as the similarly named **AUTOFS_IOC** ioctls, except |
| 522 | that **FAIL** can be given an explicit error number in `fail.status` |
| 523 | instead of assuming `ENOENT`, and this **EXPIRE** command |
| 524 | corresponds to **AUTOFS_IOC_EXPIRE_MULTI**. |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 525 | |
| 526 | Catatonic mode |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 527 | ============== |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 528 | |
| 529 | As mentioned, an autofs mount can enter "catatonic" mode. This |
| 530 | happens if a write to the notification pipe fails, or if it is |
| 531 | explicitly requested by an `ioctl`. |
| 532 | |
| 533 | When entering catatonic mode, the pipe is closed and any pending |
| 534 | notifications are acknowledged with the error `ENOENT`. |
| 535 | |
| 536 | Once in catatonic mode attempts to access non-existing names will |
| 537 | result in `ENOENT` while attempts to access existing directories will |
| 538 | be treated in the same way as if they came from the daemon, so mount |
| 539 | traps will not fire. |
| 540 | |
| 541 | When the filesystem is mounted a _uid_ and _gid_ can be given which |
| 542 | set the ownership of directories and symbolic links. When the |
| 543 | filesystem is in catatonic mode, any process with a matching UID can |
| 544 | create directories or symlinks in the root directory, but not in other |
| 545 | directories. |
| 546 | |
| 547 | Catatonic mode can only be left via the |
| 548 | **AUTOFS_DEV_IOCTL_OPENMOUNT_CMD** ioctl on the `/dev/autofs`. |
| 549 | |
Ian Kent | 1dcaa13 | 2019-05-14 15:44:26 -0700 | [diff] [blame] | 550 | The "ignore" mount option |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 551 | ========================= |
Ian Kent | 1dcaa13 | 2019-05-14 15:44:26 -0700 | [diff] [blame] | 552 | |
| 553 | The "ignore" mount option can be used to provide a generic indicator |
| 554 | to applications that the mount entry should be ignored when displaying |
| 555 | mount information. |
| 556 | |
| 557 | In other OSes that provide autofs and that provide a mount list to user |
| 558 | space based on the kernel mount list a no-op mount option ("ignore" is |
| 559 | the one use on the most common OSes) is allowed so that autofs file |
| 560 | system users can optionally use it. |
| 561 | |
| 562 | This is intended to be used by user space programs to exclude autofs |
| 563 | mounts from consideration when reading the mounts list. |
| 564 | |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 565 | autofs, name spaces, and shared mounts |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 566 | ====================================== |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 567 | |
| 568 | With bind mounts and name spaces it is possible for an autofs |
| 569 | filesystem to appear at multiple places in one or more filesystem |
| 570 | name spaces. For this to work sensibly, the autofs filesystem should |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 571 | always be mounted "shared". e.g. :: |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 572 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 573 | mount --make-shared /autofs/mount/point |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 574 | |
Tomohiro Kusumi | d0846dd | 2017-02-27 14:27:02 -0800 | [diff] [blame] | 575 | The automount daemon is only able to manage a single mount location for |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 576 | an autofs filesystem and if mounts on that are not 'shared', other |
| 577 | locations will not behave as expected. In particular access to those |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 578 | other locations will likely result in the `ELOOP` error :: |
NeilBrown | 87d672c | 2014-10-13 15:52:24 -0700 | [diff] [blame] | 579 | |
Jaskaran Singh | f11f2a3 | 2019-11-17 22:54:34 +0530 | [diff] [blame] | 580 | Too many levels of symbolic links |