autofs-mount-control.rst 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. .. SPDX-License-Identifier: GPL-2.0
  2. ====================================================================
  3. Miscellaneous Device control operations for the autofs kernel module
  4. ====================================================================
  5. The problem
  6. ===========
  7. There is a problem with active restarts in autofs (that is to say
  8. restarting autofs when there are busy mounts).
  9. During normal operation autofs uses a file descriptor opened on the
  10. directory that is being managed in order to be able to issue control
  11. operations. Using a file descriptor gives ioctl operations access to
  12. autofs specific information stored in the super block. The operations
  13. are things such as setting an autofs mount catatonic, setting the
  14. expire timeout and requesting expire checks. As is explained below,
  15. certain types of autofs triggered mounts can end up covering an autofs
  16. mount itself which prevents us being able to use open(2) to obtain a
  17. file descriptor for these operations if we don't already have one open.
  18. Currently autofs uses "umount -l" (lazy umount) to clear active mounts
  19. at restart. While using lazy umount works for most cases, anything that
  20. needs to walk back up the mount tree to construct a path, such as
  21. getcwd(2) and the proc file system /proc/<pid>/cwd, no longer works
  22. because the point from which the path is constructed has been detached
  23. from the mount tree.
  24. The actual problem with autofs is that it can't reconnect to existing
  25. mounts. Immediately one thinks of just adding the ability to remount
  26. autofs file systems would solve it, but alas, that can't work. This is
  27. because autofs direct mounts and the implementation of "on demand mount
  28. and expire" of nested mount trees have the file system mounted directly
  29. on top of the mount trigger directory dentry.
  30. For example, there are two types of automount maps, direct (in the kernel
  31. module source you will see a third type called an offset, which is just
  32. a direct mount in disguise) and indirect.
  33. Here is a master map with direct and indirect map entries::
  34. /- /etc/auto.direct
  35. /test /etc/auto.indirect
  36. and the corresponding map files::
  37. /etc/auto.direct:
  38. /automount/dparse/g6 budgie:/autofs/export1
  39. /automount/dparse/g1 shark:/autofs/export1
  40. and so on.
  41. /etc/auto.indirect::
  42. g1 shark:/autofs/export1
  43. g6 budgie:/autofs/export1
  44. and so on.
  45. For the above indirect map an autofs file system is mounted on /test and
  46. mounts are triggered for each sub-directory key by the inode lookup
  47. operation. So we see a mount of shark:/autofs/export1 on /test/g1, for
  48. example.
  49. The way that direct mounts are handled is by making an autofs mount on
  50. each full path, such as /automount/dparse/g1, and using it as a mount
  51. trigger. So when we walk on the path we mount shark:/autofs/export1 "on
  52. top of this mount point". Since these are always directories we can
  53. use the follow_link inode operation to trigger the mount.
  54. But, each entry in direct and indirect maps can have offsets (making
  55. them multi-mount map entries).
  56. For example, an indirect mount map entry could also be::
  57. g1 \
  58. / shark:/autofs/export5/testing/test \
  59. /s1 shark:/autofs/export/testing/test/s1 \
  60. /s2 shark:/autofs/export5/testing/test/s2 \
  61. /s1/ss1 shark:/autofs/export1 \
  62. /s2/ss2 shark:/autofs/export2
  63. and a similarly a direct mount map entry could also be::
  64. /automount/dparse/g1 \
  65. / shark:/autofs/export5/testing/test \
  66. /s1 shark:/autofs/export/testing/test/s1 \
  67. /s2 shark:/autofs/export5/testing/test/s2 \
  68. /s1/ss1 shark:/autofs/export2 \
  69. /s2/ss2 shark:/autofs/export2
  70. One of the issues with version 4 of autofs was that, when mounting an
  71. entry with a large number of offsets, possibly with nesting, we needed
  72. to mount and umount all of the offsets as a single unit. Not really a
  73. problem, except for people with a large number of offsets in map entries.
  74. This mechanism is used for the well known "hosts" map and we have seen
  75. cases (in 2.4) where the available number of mounts are exhausted or
  76. where the number of privileged ports available is exhausted.
  77. In version 5 we mount only as we go down the tree of offsets and
  78. similarly for expiring them which resolves the above problem. There is
  79. somewhat more detail to the implementation but it isn't needed for the
  80. sake of the problem explanation. The one important detail is that these
  81. offsets are implemented using the same mechanism as the direct mounts
  82. above and so the mount points can be covered by a mount.
  83. The current autofs implementation uses an ioctl file descriptor opened
  84. on the mount point for control operations. The references held by the
  85. descriptor are accounted for in checks made to determine if a mount is
  86. in use and is also used to access autofs file system information held
  87. in the mount super block. So the use of a file handle needs to be
  88. retained.
  89. The Solution
  90. ============
  91. To be able to restart autofs leaving existing direct, indirect and
  92. offset mounts in place we need to be able to obtain a file handle
  93. for these potentially covered autofs mount points. Rather than just
  94. implement an isolated operation it was decided to re-implement the
  95. existing ioctl interface and add new operations to provide this
  96. functionality.
  97. In addition, to be able to reconstruct a mount tree that has busy mounts,
  98. the uid and gid of the last user that triggered the mount needs to be
  99. available because these can be used as macro substitution variables in
  100. autofs maps. They are recorded at mount request time and an operation
  101. has been added to retrieve them.
  102. Since we're re-implementing the control interface, a couple of other
  103. problems with the existing interface have been addressed. First, when
  104. a mount or expire operation completes a status is returned to the
  105. kernel by either a "send ready" or a "send fail" operation. The
  106. "send fail" operation of the ioctl interface could only ever send
  107. ENOENT so the re-implementation allows user space to send an actual
  108. status. Another expensive operation in user space, for those using
  109. very large maps, is discovering if a mount is present. Usually this
  110. involves scanning /proc/mounts and since it needs to be done quite
  111. often it can introduce significant overhead when there are many entries
  112. in the mount table. An operation to lookup the mount status of a mount
  113. point dentry (covered or not) has also been added.
  114. Current kernel development policy recommends avoiding the use of the
  115. ioctl mechanism in favor of systems such as Netlink. An implementation
  116. using this system was attempted to evaluate its suitability and it was
  117. found to be inadequate, in this case. The Generic Netlink system was
  118. used for this as raw Netlink would lead to a significant increase in
  119. complexity. There's no question that the Generic Netlink system is an
  120. elegant solution for common case ioctl functions but it's not a complete
  121. replacement probably because its primary purpose in life is to be a
  122. message bus implementation rather than specifically an ioctl replacement.
  123. While it would be possible to work around this there is one concern
  124. that lead to the decision to not use it. This is that the autofs
  125. expire in the daemon has become far to complex because umount
  126. candidates are enumerated, almost for no other reason than to "count"
  127. the number of times to call the expire ioctl. This involves scanning
  128. the mount table which has proved to be a big overhead for users with
  129. large maps. The best way to improve this is try and get back to the
  130. way the expire was done long ago. That is, when an expire request is
  131. issued for a mount (file handle) we should continually call back to
  132. the daemon until we can't umount any more mounts, then return the
  133. appropriate status to the daemon. At the moment we just expire one
  134. mount at a time. A Generic Netlink implementation would exclude this
  135. possibility for future development due to the requirements of the
  136. message bus architecture.
  137. autofs Miscellaneous Device mount control interface
  138. ====================================================
  139. The control interface is opening a device node, typically /dev/autofs.
  140. All the ioctls use a common structure to pass the needed parameter
  141. information and return operation results::
  142. struct autofs_dev_ioctl {
  143. __u32 ver_major;
  144. __u32 ver_minor;
  145. __u32 size; /* total size of data passed in
  146. * including this struct */
  147. __s32 ioctlfd; /* automount command fd */
  148. /* Command parameters */
  149. union {
  150. struct args_protover protover;
  151. struct args_protosubver protosubver;
  152. struct args_openmount openmount;
  153. struct args_ready ready;
  154. struct args_fail fail;
  155. struct args_setpipefd setpipefd;
  156. struct args_timeout timeout;
  157. struct args_requester requester;
  158. struct args_expire expire;
  159. struct args_askumount askumount;
  160. struct args_ismountpoint ismountpoint;
  161. };
  162. char path[];
  163. };
  164. The ioctlfd field is a mount point file descriptor of an autofs mount
  165. point. It is returned by the open call and is used by all calls except
  166. the check for whether a given path is a mount point, where it may
  167. optionally be used to check a specific mount corresponding to a given
  168. mount point file descriptor, and when requesting the uid and gid of the
  169. last successful mount on a directory within the autofs file system.
  170. The union is used to communicate parameters and results of calls made
  171. as described below.
  172. The path field is used to pass a path where it is needed and the size field
  173. is used account for the increased structure length when translating the
  174. structure sent from user space.
  175. This structure can be initialized before setting specific fields by using
  176. the void function call init_autofs_dev_ioctl(``struct autofs_dev_ioctl *``).
  177. All of the ioctls perform a copy of this structure from user space to
  178. kernel space and return -EINVAL if the size parameter is smaller than
  179. the structure size itself, -ENOMEM if the kernel memory allocation fails
  180. or -EFAULT if the copy itself fails. Other checks include a version check
  181. of the compiled in user space version against the module version and a
  182. mismatch results in a -EINVAL return. If the size field is greater than
  183. the structure size then a path is assumed to be present and is checked to
  184. ensure it begins with a "/" and is NULL terminated, otherwise -EINVAL is
  185. returned. Following these checks, for all ioctl commands except
  186. AUTOFS_DEV_IOCTL_VERSION_CMD, AUTOFS_DEV_IOCTL_OPENMOUNT_CMD and
  187. AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD the ioctlfd is validated and if it is
  188. not a valid descriptor or doesn't correspond to an autofs mount point
  189. an error of -EBADF, -ENOTTY or -EINVAL (not an autofs descriptor) is
  190. returned.
  191. The ioctls
  192. ==========
  193. An example of an implementation which uses this interface can be seen
  194. in autofs version 5.0.4 and later in file lib/dev-ioctl-lib.c of the
  195. distribution tar available for download from kernel.org in directory
  196. /pub/linux/daemons/autofs/v5.
  197. The device node ioctl operations implemented by this interface are:
  198. AUTOFS_DEV_IOCTL_VERSION
  199. ------------------------
  200. Get the major and minor version of the autofs device ioctl kernel module
  201. implementation. It requires an initialized struct autofs_dev_ioctl as an
  202. input parameter and sets the version information in the passed in structure.
  203. It returns 0 on success or the error -EINVAL if a version mismatch is
  204. detected.
  205. AUTOFS_DEV_IOCTL_PROTOVER_CMD and AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD
  206. ------------------------------------------------------------------
  207. Get the major and minor version of the autofs protocol version understood
  208. by loaded module. This call requires an initialized struct autofs_dev_ioctl
  209. with the ioctlfd field set to a valid autofs mount point descriptor
  210. and sets the requested version number in version field of struct args_protover
  211. or sub_version field of struct args_protosubver. These commands return
  212. 0 on success or one of the negative error codes if validation fails.
  213. AUTOFS_DEV_IOCTL_OPENMOUNT and AUTOFS_DEV_IOCTL_CLOSEMOUNT
  214. ----------------------------------------------------------
  215. Obtain and release a file descriptor for an autofs managed mount point
  216. path. The open call requires an initialized struct autofs_dev_ioctl with
  217. the path field set and the size field adjusted appropriately as well
  218. as the devid field of struct args_openmount set to the device number of
  219. the autofs mount. The device number can be obtained from the mount options
  220. shown in /proc/mounts. The close call requires an initialized struct
  221. autofs_dev_ioct with the ioctlfd field set to the descriptor obtained
  222. from the open call. The release of the file descriptor can also be done
  223. with close(2) so any open descriptors will also be closed at process exit.
  224. The close call is included in the implemented operations largely for
  225. completeness and to provide for a consistent user space implementation.
  226. AUTOFS_DEV_IOCTL_READY_CMD and AUTOFS_DEV_IOCTL_FAIL_CMD
  227. --------------------------------------------------------
  228. Return mount and expire result status from user space to the kernel.
  229. Both of these calls require an initialized struct autofs_dev_ioctl
  230. with the ioctlfd field set to the descriptor obtained from the open
  231. call and the token field of struct args_ready or struct args_fail set
  232. to the wait queue token number, received by user space in the foregoing
  233. mount or expire request. The status field of struct args_fail is set to
  234. the errno of the operation. It is set to 0 on success.
  235. AUTOFS_DEV_IOCTL_SETPIPEFD_CMD
  236. ------------------------------
  237. Set the pipe file descriptor used for kernel communication to the daemon.
  238. Normally this is set at mount time using an option but when reconnecting
  239. to a existing mount we need to use this to tell the autofs mount about
  240. the new kernel pipe descriptor. In order to protect mounts against
  241. incorrectly setting the pipe descriptor we also require that the autofs
  242. mount be catatonic (see next call).
  243. The call requires an initialized struct autofs_dev_ioctl with the
  244. ioctlfd field set to the descriptor obtained from the open call and
  245. the pipefd field of struct args_setpipefd set to descriptor of the pipe.
  246. On success the call also sets the process group id used to identify the
  247. controlling process (eg. the owning automount(8) daemon) to the process
  248. group of the caller.
  249. AUTOFS_DEV_IOCTL_CATATONIC_CMD
  250. ------------------------------
  251. Make the autofs mount point catatonic. The autofs mount will no longer
  252. issue mount requests, the kernel communication pipe descriptor is released
  253. and any remaining waits in the queue released.
  254. The call requires an initialized struct autofs_dev_ioctl with the
  255. ioctlfd field set to the descriptor obtained from the open call.
  256. AUTOFS_DEV_IOCTL_TIMEOUT_CMD
  257. ----------------------------
  258. Set the expire timeout for mounts within an autofs mount point.
  259. The call requires an initialized struct autofs_dev_ioctl with the
  260. ioctlfd field set to the descriptor obtained from the open call.
  261. AUTOFS_DEV_IOCTL_REQUESTER_CMD
  262. ------------------------------
  263. Return the uid and gid of the last process to successfully trigger a the
  264. mount on the given path dentry.
  265. The call requires an initialized struct autofs_dev_ioctl with the path
  266. field set to the mount point in question and the size field adjusted
  267. appropriately. Upon return the uid field of struct args_requester contains
  268. the uid and gid field the gid.
  269. When reconstructing an autofs mount tree with active mounts we need to
  270. re-connect to mounts that may have used the original process uid and
  271. gid (or string variations of them) for mount lookups within the map entry.
  272. This call provides the ability to obtain this uid and gid so they may be
  273. used by user space for the mount map lookups.
  274. AUTOFS_DEV_IOCTL_EXPIRE_CMD
  275. ---------------------------
  276. Issue an expire request to the kernel for an autofs mount. Typically
  277. this ioctl is called until no further expire candidates are found.
  278. The call requires an initialized struct autofs_dev_ioctl with the
  279. ioctlfd field set to the descriptor obtained from the open call. In
  280. addition an immediate expire that's independent of the mount timeout,
  281. and a forced expire that's independent of whether the mount is busy,
  282. can be requested by setting the how field of struct args_expire to
  283. AUTOFS_EXP_IMMEDIATE or AUTOFS_EXP_FORCED, respectively . If no
  284. expire candidates can be found the ioctl returns -1 with errno set to
  285. EAGAIN.
  286. This call causes the kernel module to check the mount corresponding
  287. to the given ioctlfd for mounts that can be expired, issues an expire
  288. request back to the daemon and waits for completion.
  289. AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD
  290. ------------------------------
  291. Checks if an autofs mount point is in use.
  292. The call requires an initialized struct autofs_dev_ioctl with the
  293. ioctlfd field set to the descriptor obtained from the open call and
  294. it returns the result in the may_umount field of struct args_askumount,
  295. 1 for busy and 0 otherwise.
  296. AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD
  297. ---------------------------------
  298. Check if the given path is a mountpoint.
  299. The call requires an initialized struct autofs_dev_ioctl. There are two
  300. possible variations. Both use the path field set to the path of the mount
  301. point to check and the size field adjusted appropriately. One uses the
  302. ioctlfd field to identify a specific mount point to check while the other
  303. variation uses the path and optionally in.type field of struct args_ismountpoint
  304. set to an autofs mount type. The call returns 1 if this is a mount point
  305. and sets out.devid field to the device number of the mount and out.magic
  306. field to the relevant super block magic number (described below) or 0 if
  307. it isn't a mountpoint. In both cases the device number (as returned
  308. by new_encode_dev()) is returned in out.devid field.
  309. If supplied with a file descriptor we're looking for a specific mount,
  310. not necessarily at the top of the mounted stack. In this case the path
  311. the descriptor corresponds to is considered a mountpoint if it is itself
  312. a mountpoint or contains a mount, such as a multi-mount without a root
  313. mount. In this case we return 1 if the descriptor corresponds to a mount
  314. point and also returns the super magic of the covering mount if there
  315. is one or 0 if it isn't a mountpoint.
  316. If a path is supplied (and the ioctlfd field is set to -1) then the path
  317. is looked up and is checked to see if it is the root of a mount. If a
  318. type is also given we are looking for a particular autofs mount and if
  319. a match isn't found a fail is returned. If the located path is the
  320. root of a mount 1 is returned along with the super magic of the mount
  321. or 0 otherwise.