| |
| The problem |
| ----------- |
| |
| The initial release of autofs version 5 used the "umount -l" (lazy |
| umount) to clear stale mounts at startup so that new mounts could |
| be made with a clean slate. This proved to be a bad choice because |
| the lazy umount removes the mount from the kernel mount tree. While |
| the mount itself persists (invisibe to further VFS lookups) until |
| the mount isn't busy anymore the kernel function d_path(), used to |
| calculate the path from the mount point to the root, isn't able to |
| perform its function any more. This leads to things that use d_path(), |
| such as /bin/pwd, the contents of the link /proc/<pid>/cwd, and so on. |
| |
| The actual problem with autofs is that it can't re-connect to existing |
| mounts. Immediately one thinks of just adding the ability to remount |
| the autofs file system would solve it, but that can't work. This is |
| because autofs direct mounts and the implementation of "on demand mount |
| and expire" of nested mount trees i(multi-mounts) have the file system |
| mounted directly on top of the mount trigger directory. |
| |
| For example, there are two types of automount maps, direct (in the kernel |
| module source you will see a third type called an offset, which is just |
| a direct mount in disguise) and indirect. |
| |
| Here is a master map with direct and indirect map entries: |
| |
| /- /etc/auto.direct |
| /test /etc/auto.indirect |
| |
| and the corresponding map files: |
| |
| /etc/auto.direct: |
| |
| /automount/dparse/g6 budgie:/autofs/export1 |
| /automount/dparse/g1 shark:/autofs/export1 |
| and so on. |
| |
| /etc/auto.indirect: |
| |
| g1 shark:/autofs/export1 |
| g6 budgie:/autofs/export1 |
| and so on. |
| |
| For the above indirect map an autofs file system is mounted on /test and |
| mounts are triggered for each sub-directory key. So we see a mount of |
| shark:/autofs/export1 on /test/g1, for example. |
| |
| The way that direct mounts are handled is by making an autofs mount on |
| each full path, such as /automount/dparse/g1, and using it as a mount |
| trigger. So when we walk on the path we mount shark:/autofs/export1 "on |
| top of this mount point". |
| |
| But, each entry in direct and indirect maps can have offsets (making |
| them multi-mount map entries). |
| |
| For example, an indirect mount map entry could also be: |
| |
| g1 \ |
| / shark:/autofs/export5/testing/test \ |
| /s1 shark:/autofs/export/testing/test/s1 \ |
| /s2 shark:/autofs/export5/testing/test/s2 \ |
| /s1/ss1 shark:/autofs/export1 \ |
| /s2/ss2 shark:/autofs/export2 |
| |
| and a similarly a direct mount map entry could also be: |
| |
| /automount/dparse/g1 \ |
| / shark:/autofs/export5/testing/test \ |
| /s1 shark:/autofs/export/testing/test/s1 \ |
| /s2 shark:/autofs/export5/testing/test/s2 \ |
| /s1/ss1 shark:/autofs/export2 \ |
| /s2/ss2 shark:/autofs/export2 |
| |
| One of the issues with version 4 of autofs was that, when mounting an |
| entry with a large number of offsets, possibly with nesting, we needed |
| to mount and umount all of the offsets as a single unit. Not really a |
| problem, except for people with a large number of offsets in map entries. |
| This mechanism is used for the well known "hosts" map and we have seen |
| cases (in 2.4) where the available number of mounts are exhausted or |
| where the number of privileged ports available is exhausted. |
| |
| In version 5 we mount only as we go down the tree of offsets and |
| similarly for expiring them which resolves the above problem. There is |
| somewhat more detail to the implementation but it isn't needed for the |
| sake of the problem explanation. The one important detail is that these |
| offsets are implemented using the same mechanism as the direct mounts |
| above and so the autofs mount points can be covered by another mount. |
| |
| To be able to restart autofs leaving existing direct, indirect and |
| offset mounts in place we need to be able to obtain a file handle |
| for these potentially covered autofs mount points. To do this the |
| autofs ioctl control implementation has been re-implemented, |
| providing the same functions as the existing ioctl interface and |
| new operations to the ability to open a file handle on a covered |
| autofs mount point. |
| |
| In order to utilize the new interface both kernel and user space |
| changes (included in this release) are needed. The default install |
| of autofs won't use the new interface unless it is enabled in the |
| configuration. This can be done by setting "USE_MISC_DEVICE" to "yes" |
| in the autofs configuration. In addition, if selinux is being used, |
| it will likely need to allow operations on the autofs device file |
| or be set to permissive mode. |
| |
| Patches for several recent kernel that don't have the implementation |
| can be found in the patches directory. They have "dev-ioctl" in their |
| name. Note that, to use these patches, you should be using a kernel |
| patched with all the current autofs bug fixes since, apart from porobably |
| not working, the patch probably won't apply either. The bug fix patches |
| can also be found in the patches directory and they have "v5-update" in |
| their names. |
| |
| Ian |