1 .. SPDX-License-Identifier: GPL-2.0 2 3 ============================================== 4 Miscellaneous Device control operations for th 5 ============================================== 6 7 The problem 8 =========== 9 10 There is a problem with active restarts in aut 11 restarting autofs when there are busy mounts). 12 13 During normal operation autofs uses a file des 14 directory that is being managed in order to be 15 operations. Using a file descriptor gives ioct 16 autofs specific information stored in the supe 17 are things such as setting an autofs mount cat 18 expire timeout and requesting expire checks. A 19 certain types of autofs triggered mounts can e 20 mount itself which prevents us being able to u 21 file descriptor for these operations if we don 22 23 Currently autofs uses "umount -l" (lazy umount 24 at restart. While using lazy umount works for 25 needs to walk back up the mount tree to constr 26 getcwd(2) and the proc file system /proc/<pid> 27 because the point from which the path is const 28 from the mount tree. 29 30 The actual problem with autofs is that it can' 31 mounts. Immediately one thinks of just adding 32 autofs file systems would solve it, but alas, 33 because autofs direct mounts and the implement 34 and expire" of nested mount trees have the fil 35 on top of the mount trigger directory dentry. 36 37 For example, there are two types of automount 38 module source you will see a third type called 39 a direct mount in disguise) and indirect. 40 41 Here is a master map with direct and indirect 42 43 /- /etc/auto.direct 44 /test /etc/auto.indirect 45 46 and the corresponding map files:: 47 48 /etc/auto.direct: 49 50 /automount/dparse/g6 budgie:/autofs/expor 51 /automount/dparse/g1 shark:/autofs/export 52 and so on. 53 54 /etc/auto.indirect:: 55 56 g1 shark:/autofs/export1 57 g6 budgie:/autofs/export1 58 and so on. 59 60 For the above indirect map an autofs file syst 61 mounts are triggered for each sub-directory ke 62 operation. So we see a mount of shark:/autofs/ 63 example. 64 65 The way that direct mounts are handled is by m 66 each full path, such as /automount/dparse/g1, 67 trigger. So when we walk on the path we mount 68 top of this mount point". Since these are alwa 69 use the follow_link inode operation to trigger 70 71 But, each entry in direct and indirect maps ca 72 them multi-mount map entries). 73 74 For example, an indirect mount map entry could 75 76 g1 \ 77 / shark:/autofs/export5/testing/tes 78 /s1 shark:/autofs/export/testing/test 79 /s2 shark:/autofs/export5/testing/tes 80 /s1/ss1 shark:/autofs/export1 \ 81 /s2/ss2 shark:/autofs/export2 82 83 and a similarly a direct mount map entry could 84 85 /automount/dparse/g1 \ 86 / shark:/autofs/export5/testing/ 87 /s1 shark:/autofs/export/testing/t 88 /s2 shark:/autofs/export5/testing/ 89 /s1/ss1 shark:/autofs/export2 \ 90 /s2/ss2 shark:/autofs/export2 91 92 One of the issues with version 4 of autofs was 93 entry with a large number of offsets, possibly 94 to mount and umount all of the offsets as a si 95 problem, except for people with a large number 96 This mechanism is used for the well known "hos 97 cases (in 2.4) where the available number of m 98 where the number of privileged ports available 99 100 In version 5 we mount only as we go down the t 101 similarly for expiring them which resolves the 102 somewhat more detail to the implementation but 103 sake of the problem explanation. The one impor 104 offsets are implemented using the same mechani 105 above and so the mount points can be covered b 106 107 The current autofs implementation uses an ioct 108 on the mount point for control operations. The 109 descriptor are accounted for in checks made to 110 in use and is also used to access autofs file 111 in the mount super block. So the use of a file 112 retained. 113 114 115 The Solution 116 ============ 117 118 To be able to restart autofs leaving existing 119 offset mounts in place we need to be able to o 120 for these potentially covered autofs mount poi 121 implement an isolated operation it was decided 122 existing ioctl interface and add new operation 123 functionality. 124 125 In addition, to be able to reconstruct a mount 126 the uid and gid of the last user that triggere 127 available because these can be used as macro s 128 autofs maps. They are recorded at mount reques 129 has been added to retrieve them. 130 131 Since we're re-implementing the control interf 132 problems with the existing interface have been 133 a mount or expire operation completes a status 134 kernel by either a "send ready" or a "send fai 135 "send fail" operation of the ioctl interface c 136 ENOENT so the re-implementation allows user sp 137 status. Another expensive operation in user sp 138 very large maps, is discovering if a mount is 139 involves scanning /proc/mounts and since it ne 140 often it can introduce significant overhead wh 141 in the mount table. An operation to lookup the 142 point dentry (covered or not) has also been ad 143 144 Current kernel development policy recommends a 145 ioctl mechanism in favor of systems such as Ne 146 using this system was attempted to evaluate it 147 found to be inadequate, in this case. The Gene 148 used for this as raw Netlink would lead to a s 149 complexity. There's no question that the Gener 150 elegant solution for common case ioctl functio 151 replacement probably because its primary purpo 152 message bus implementation rather than specifi 153 While it would be possible to work around this 154 that lead to the decision to not use it. This 155 expire in the daemon has become far to complex 156 candidates are enumerated, almost for no other 157 the number of times to call the expire ioctl. 158 the mount table which has proved to be a big o 159 large maps. The best way to improve this is tr 160 way the expire was done long ago. That is, whe 161 issued for a mount (file handle) we should con 162 the daemon until we can't umount any more moun 163 appropriate status to the daemon. At the momen 164 mount at a time. A Generic Netlink implementat 165 possibility for future development due to the 166 message bus architecture. 167 168 169 autofs Miscellaneous Device mount control inte 170 ============================================== 171 172 The control interface is opening a device node 173 174 All the ioctls use a common structure to pass 175 information and return operation results:: 176 177 struct autofs_dev_ioctl { 178 __u32 ver_major; 179 __u32 ver_minor; 180 __u32 size; /* total s 181 * includin 182 __s32 ioctlfd; /* automou 183 184 /* Command parameters */ 185 union { 186 struct args_protover 187 struct args_protosubver 188 struct args_openmount 189 struct args_ready 190 struct args_fail 191 struct args_setpipefd 192 struct args_timeout 193 struct args_requester 194 struct args_expire 195 struct args_askumount 196 struct args_ismountpoint 197 }; 198 199 char path[]; 200 }; 201 202 The ioctlfd field is a mount point file descri 203 point. It is returned by the open call and is 204 the check for whether a given path is a mount 205 optionally be used to check a specific mount c 206 mount point file descriptor, and when requesti 207 last successful mount on a directory within th 208 209 The union is used to communicate parameters an 210 as described below. 211 212 The path field is used to pass a path where it 213 is used account for the increased structure le 214 structure sent from user space. 215 216 This structure can be initialized before setti 217 the void function call init_autofs_dev_ioctl(` 218 219 All of the ioctls perform a copy of this struc 220 kernel space and return -EINVAL if the size pa 221 the structure size itself, -ENOMEM if the kern 222 or -EFAULT if the copy itself fails. Other che 223 of the compiled in user space version against 224 mismatch results in a -EINVAL return. If the s 225 the structure size then a path is assumed to b 226 ensure it begins with a "/" and is NULL termin 227 returned. Following these checks, for all ioct 228 AUTOFS_DEV_IOCTL_VERSION_CMD, AUTOFS_DEV_IOCTL 229 AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD the ioctlfd is 230 not a valid descriptor or doesn't correspond t 231 an error of -EBADF, -ENOTTY or -EINVAL (not an 232 returned. 233 234 235 The ioctls 236 ========== 237 238 An example of an implementation which uses thi 239 in autofs version 5.0.4 and later in file lib/ 240 distribution tar available for download from k 241 /pub/linux/daemons/autofs/v5. 242 243 The device node ioctl operations implemented b 244 245 246 AUTOFS_DEV_IOCTL_VERSION 247 ------------------------ 248 249 Get the major and minor version of the autofs 250 implementation. It requires an initialized str 251 input parameter and sets the version informati 252 It returns 0 on success or the error -EINVAL i 253 detected. 254 255 256 AUTOFS_DEV_IOCTL_PROTOVER_CMD and AUTOFS_DEV_I 257 ---------------------------------------------- 258 259 Get the major and minor version of the autofs 260 by loaded module. This call requires an initia 261 with the ioctlfd field set to a valid autofs m 262 and sets the requested version number in versi 263 or sub_version field of struct args_protosubve 264 0 on success or one of the negative error code 265 266 267 AUTOFS_DEV_IOCTL_OPENMOUNT and AUTOFS_DEV_IOCT 268 ---------------------------------------------- 269 270 Obtain and release a file descriptor for an au 271 path. The open call requires an initialized st 272 the path field set and the size field adjusted 273 as the devid field of struct args_openmount se 274 the autofs mount. The device number can be obt 275 shown in /proc/mounts. The close call requires 276 autofs_dev_ioct with the ioctlfd field set to 277 from the open call. The release of the file de 278 with close(2) so any open descriptors will als 279 The close call is included in the implemented 280 completeness and to provide for a consistent u 281 282 283 AUTOFS_DEV_IOCTL_READY_CMD and AUTOFS_DEV_IOCT 284 ---------------------------------------------- 285 286 Return mount and expire result status from use 287 Both of these calls require an initialized str 288 with the ioctlfd field set to the descriptor o 289 call and the token field of struct args_ready 290 to the wait queue token number, received by us 291 mount or expire request. The status field of s 292 the errno of the operation. It is set to 0 on 293 294 295 AUTOFS_DEV_IOCTL_SETPIPEFD_CMD 296 ------------------------------ 297 298 Set the pipe file descriptor used for kernel c 299 Normally this is set at mount time using an op 300 to a existing mount we need to use this to tel 301 the new kernel pipe descriptor. In order to pr 302 incorrectly setting the pipe descriptor we als 303 mount be catatonic (see next call). 304 305 The call requires an initialized struct autofs 306 ioctlfd field set to the descriptor obtained f 307 the pipefd field of struct args_setpipefd set 308 On success the call also sets the process grou 309 controlling process (eg. the owning automount( 310 group of the caller. 311 312 313 AUTOFS_DEV_IOCTL_CATATONIC_CMD 314 ------------------------------ 315 316 Make the autofs mount point catatonic. The aut 317 issue mount requests, the kernel communication 318 and any remaining waits in the queue released. 319 320 The call requires an initialized struct autofs 321 ioctlfd field set to the descriptor obtained f 322 323 324 AUTOFS_DEV_IOCTL_TIMEOUT_CMD 325 ---------------------------- 326 327 Set the expire timeout for mounts within an au 328 329 The call requires an initialized struct autofs 330 ioctlfd field set to the descriptor obtained f 331 332 333 AUTOFS_DEV_IOCTL_REQUESTER_CMD 334 ------------------------------ 335 336 Return the uid and gid of the last process to 337 mount on the given path dentry. 338 339 The call requires an initialized struct autofs 340 field set to the mount point in question and t 341 appropriately. Upon return the uid field of st 342 the uid and gid field the gid. 343 344 When reconstructing an autofs mount tree with 345 re-connect to mounts that may have used the or 346 gid (or string variations of them) for mount l 347 This call provides the ability to obtain this 348 used by user space for the mount map lookups. 349 350 351 AUTOFS_DEV_IOCTL_EXPIRE_CMD 352 --------------------------- 353 354 Issue an expire request to the kernel for an a 355 this ioctl is called until no further expire c 356 357 The call requires an initialized struct autofs 358 ioctlfd field set to the descriptor obtained f 359 addition an immediate expire that's independen 360 and a forced expire that's independent of whet 361 can be requested by setting the how field of s 362 AUTOFS_EXP_IMMEDIATE or AUTOFS_EXP_FORCED, res 363 expire candidates can be found the ioctl retur 364 EAGAIN. 365 366 This call causes the kernel module to check th 367 to the given ioctlfd for mounts that can be ex 368 request back to the daemon and waits for compl 369 370 AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD 371 ------------------------------ 372 373 Checks if an autofs mount point is in use. 374 375 The call requires an initialized struct autofs 376 ioctlfd field set to the descriptor obtained f 377 it returns the result in the may_umount field 378 1 for busy and 0 otherwise. 379 380 381 AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD 382 --------------------------------- 383 384 Check if the given path is a mountpoint. 385 386 The call requires an initialized struct autofs 387 possible variations. Both use the path field s 388 point to check and the size field adjusted app 389 ioctlfd field to identify a specific mount poi 390 variation uses the path and optionally in.type 391 set to an autofs mount type. The call returns 392 and sets out.devid field to the device number 393 field to the relevant super block magic number 394 it isn't a mountpoint. In both cases the devic 395 by new_encode_dev()) is returned in out.devid 396 397 If supplied with a file descriptor we're looki 398 not necessarily at the top of the mounted stac 399 the descriptor corresponds to is considered a 400 a mountpoint or contains a mount, such as a mu 401 mount. In this case we return 1 if the descrip 402 point and also returns the super magic of the 403 is one or 0 if it isn't a mountpoint. 404 405 If a path is supplied (and the ioctlfd field i 406 is looked up and is checked to see if it is th 407 type is also given we are looking for a partic 408 a match isn't found a fail is returned. If the 409 root of a mount 1 is returned along with the s 410 or 0 otherwise.
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.