요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=====================
autofs - how it works
=====================
Purpose
=======
The goal of autofs is to provide on-demand mounting and race free
automatic unmounting of various other filesystems. This provides two
key advantages:
1. There is no need to delay boot until all filesystems that
might be needed are mounted. Processes that try to access those
slow filesystems might be delayed but other processes can
continue freely. This is particularly important for
network filesystems (e.g. NFS) or filesystems stored on
media with a media-changing robot.
2. The names and locations of filesystems can be stored in
a remote database and can change at any time. The content
in that database at the time of access will be used to provide
a target for the access. The interpretation of names in the
filesystem can even be programmatic rather than database-backed,
allowing wildcards for example, and can vary based on the user who
first accessed a name.
Context
=======
The "autofs" filesystem module is only one part of an autofs system.
There also needs to be a user-space program which looks up names
and mounts filesystems. This will often be the "automount" program,
though other tools including "systemd" can make use of "autofs".
This document describes only the kernel module and the interactions
required with any user-space program. Subsequent text refers to this
as the "automount daemon" or simply "the daemon".
"autofs" is a Linux kernel module which provides the "autofs"
filesystem type. Several "autofs" filesystems can be mounted and they
can each be managed separately, or all managed by the same daemon.
Content
=======
An autofs filesystem can contain 3 sorts of objects: directories,
symbolic links and mount traps. Mount traps are directories with
extra properties as described in the next section.
Objects can only be created by the automount daemon: symlinks are
created with a regular `symlink` system call, while directories and
mount traps are created with `mkdir`. The determination of whether a
directory should be a mount trap is based on a master map. This master
map is consulted by autofs to determine which directories are mount
points. Mount points can be *direct*/*indirect*/*offset*.
On most systems, the default master map is located at */etc/auto.master*.
If neither the *direct* or *offset* mount options are given (so the
mount is considered to be *indirect*), then the root directory is
always a regular directory, otherwise it is a mount trap when it is
empty and a regular directory when not empty. Note that *direct* and
*offset* are treated identically so a concise summary is that the root
directory is a mount trap only if the filesystem is mounted *direct*
and the root is empty.
Directories created in the root directory are mount traps only if the
filesystem is mounted *indirect* and they are empty.
Directories further down the tree depend on the *maxproto* mount
option and particularly whether it is less than five or not.
When *maxproto* is five, no directories further down the
tree are ever mount traps, they are always regular directories. When
the *maxproto* is four (or three), these directories are mount traps
precisely when they are empty.
So: non-empty (i.e. non-leaf) directories are never mount traps. Empty
directories are sometimes mount traps, and sometimes not depending on
where in the tree they are (root, top level, or lower), the *maxproto*,
and whether the mount was *indirect* or not.
Mount Traps
===========
A core element of the implementation of autofs is the Mount Traps
which are provided by the Linux VFS. Any directory provided by a
filesystem can be designated as a trap. This involves two separate
features that work together to allow autofs to do its job.
**DCACHE_NEED_AUTOMOUNT**
If a dentry has the DCACHE_NEED_AUTOMOUNT flag set (which gets set if
the inode has S_AUTOMOUNT set, or can be set directly) then it is
(potentially) a mount trap. Any access to this directory beyond a
"`stat`" will (normally) cause the `d_op->d_automount()` dentry operation
to be called. The task of this method is to find the filesystem that
should be mounted on the directory and to return it. The VFS is
responsible for actually mounting the root of this filesystem on the
directory.
autofs doesn't find the filesystem itself but sends a message to the
automount daemon asking it to find and mount the filesystem. The
autofs `d_automount` method then waits for the daemon to report that
everything is ready. It will then return "`NULL`" indicating that the
mount has already happened. The VFS doesn't try to mount anything but
follows down the mount that is already there.
This functionality is sufficient for some users of mount traps such
as NFS which creates traps so that mountpoints on the server can be
reflected on the client. However it is not sufficient for autofs. As
mounting onto a directory is considered to be "beyond a `stat`", the
automount daemon would not be able to mount a filesystem on the 'trap'
directory without some way to avoid getting caught in the trap. For
that purpose there is another flag.
**DCACHE_MANAGE_TRANSIT**
If a dentry has DCACHE_MANAGE_TRANSIT set then two very different but
related behaviours are invoked, both using the `d_op->d_manage()`
dentry operation.
Firstly, before checking to see if any filesystem is mounted on the
directory, d_manage() will be called with the `rcu_walk` parameter set
to `false`. It may return one of three things:
- A return value of zero indicates that there is nothing special
about this dentry and normal checks for mounts and automounts
should proceed.
autofs normally returns zero, but first waits for any
expiry (automatic unmounting of the mounted filesystem) to
complete. This avoids races.
- A return value of `-EISDIR` tells the VFS to ignore any mounts
on the directory and to not consider calling `->d_automount()`.
This effectively disables the **DCACHE_NEED_AUTOMOUNT** flag
causing the directory not be a mount trap after all.
autofs returns this if it detects that the process performing the
lookup is the automount daemon and that the mount has been
requested but has not yet completed. How it determines this is
discussed later. This allows the automount daemon not to get
caught in the mount trap.
There is a subtlety here. It is possible that a second autofs
filesystem can be mounted below the first and for both of them to
be managed by the same daemon. For the daemon to be able to mount
something on the second it must be able to "walk" down past the
first. This means that d_manage cannot *always* return -EISDIR for
the automount daemon. It must only return it when a mount has
been requested, but has not yet completed.
`d_manage` also returns `-EISDIR` if the dentry shouldn't be a
mount trap, either because it is a symbolic link or because it is
not empty.
- Any other negative value is treated as an error and returned
to the caller.
autofs can return
- -ENOENT if the automount daemon failed to mount anything,
- -ENOMEM if it ran out of memory,
- -EINTR if a signal arrived while waiting for expiry to
complete
- or any other error sent down by the automount daemon.
The second use case only occurs during an "RCU-walk" and so `rcu_walk`
will be set.
An RCU-walk is a fast and lightweight process for walking down a
filename path (i.e. it is like running on tip-toes). RCU-walk cannot
cope with all situations so when it finds a difficulty it falls back
to "REF-walk", which is slower but more robust.
RCU-walk will never call `->d_automount`; the filesystems must already
be mounted or RCU-walk cannot handle the path.
To determine if a mount-trap is safe for RCU-walk mode it calls
`->d_manage()` with `rcu_walk` set to `true`.
In this case `d_manage()` must avoid blocking and should avoid taking
spinlocks if at all possible. Its sole purpose is to determine if it
would be safe to follow down into any mounted directory and the only
reason that it might not be is if an expiry of the mount is
underway.
In the `rcu_walk` case, `d_manage()` cannot return -EISDIR to tell the
VFS that this is a directory that doesn't require d_automount. If
`rcu_walk` sees a dentry with DCACHE_NEED_AUTOMOUNT set but nothing
mounted, it *will* fall back to REF-walk. `d_manage()` cannot make the
VFS remain in RCU-walk mode, but can only tell it to get out of
RCU-walk mode by returning `-ECHILD`.
So `d_manage()`, when called with `rcu_walk` set, should either return
-ECHILD if there is any reason to believe it is unsafe to enter the
mounted filesystem, otherwise it should return 0.
autofs will return `-ECHILD` if an expiry of the filesystem has been
initiated or is being considered, otherwise it returns 0.
Mountpoint expiry
=================
The VFS has a mechanism for automatically expiring unused mounts,
much as it can expire any unused dentry information from the dcache.
This is guided by the MNT_SHRINKABLE flag. This only applies to
mounts that were created by `d_automount()` returning a filesystem to be
mounted. As autofs doesn't return such a filesystem but leaves the
mounting to the automount daemon, it must involve the automount daemon
in unmounting as well. This also means that autofs has more control
over expiry.
The VFS also supports "expiry" of mounts using the MNT_EXPIRE flag to
the `umount` system call. Unmounting with MNT_EXPIRE will fail unless
a previous attempt had been made, and the filesystem has been inactive
and untouched since that previous attempt. autofs does not depend on
this but has its own internal tracking of whether filesystems were
recently used. This allows individual names in the autofs directory
to expire separately.
With version 4 of the protocol, the automount daemon can try to
unmount any filesystems mounted on the autofs filesystem or remove any
symbolic links or empty directories any time it likes. If the unmount
or removal is successful the filesystem will be returned to the state
it was before the mount or creation, so that any access of the name
will trigger normal auto-mount processing. In particular, `rmdir` and
`unlink` do not leave negative entries in the dcache as a normal
filesystem would, so an attempt to access a recently-removed object is
passed to autofs for handling.
With version 5, this is not safe except for unmounting from top-level
directories. As lower-level directories are never mount traps, other
processes will see an empty directory as soon as the filesystem is
unmounted. So it is generally safest to use the autofs expiry
protocol described below.
Normally the daemon only wants to remove entries which haven't been
used for a while. For this purpose autofs maintains a "`last_used`"
time stamp on each directory or symlink. For symlinks it genuinely
does record the last time the symlink was "used" or followed to find
out where it points to. For directories the field is used slightly
differently. The field is updated at mount time and during expire
checks if it is found to be in use (ie. open file descriptor or
process working directory) and during path walks. The update done
during path walks prevents frequent expire and immediate mount of
frequently accessed automounts. But in the case where a GUI continually
access or an application frequently scans an autofs directory tree
there can be an accumulation of mounts that aren't actually being
used. To cater for this case the "`strictexpire`" autofs mount option
can be used to avoid the "`last_used`" update on path walk thereby
preventing this apparent inability to expire mounts that aren't
really in use.
The daemon is able to ask autofs if anything is due to be expired,
using an `ioctl` as discussed later. For a *direct* mount, autofs
considers if the entire mount-tree can be unmounted or not. For an
*indirect* mount, autofs considers each of the names in the top level
directory to determine if any of those can be unmounted and cleaned
up.
There is an option with indirect mounts to consider each of the leaves
that has been mounted on instead of considering the top-level names.
This was originally intended for compatibility with version 4 of autofs
and should be considered as deprecated for Sun Format automount maps.
However, it may be used again for amd format mount maps (which are
generally indirect maps) because the amd automounter allows for the
setting of an expire timeout for individual mounts. But there are
some difficulties in making the needed changes for this.
When autofs considers a directory it checks the `last_used` time and
compares it with the "timeout" value set when the filesystem was
mounted, though this check is ignored in some cases. It also checks if
the directory or anything below it is in use. For symbolic links,
only the `last_used` time is ever considered.
If both appear to support expiring the directory or symlink, an action
is taken.
There are two ways to ask autofs to consider expiry. The first is to
use the **AUTOFS_IOC_EXPIRE** ioctl. This only works for indirect
mounts. If it finds something in the root directory to expire it will
return the name of that thing. Once a name has been returned the
automount daemon needs to unmount any filesystems mounted below the
name normally. As described above, this is unsafe for non-toplevel
mounts in a version-5 autofs. For this reason the current `automount(8)`
does not use this ioctl.
The second mechanism uses either the **AUTOFS_DEV_IOCTL_EXPIRE_CMD** or
the **AUTOFS_IOC_EXPIRE_MULTI** ioctl. This will work for both direct and
indirect mounts. If it selects an object to expire, it will notify
the daemon using the notification mechanism described below. This
will block until the daemon acknowledges the expiry notification.
This implies that the "`EXPIRE`" ioctl must be sent from a different
thread than the one which handles notification.
While the ioctl is blocking, the entry is marked as "expiring" and
`d_manage` will block until the daemon affirms that the unmount has
completed (together with removing any directories that might have been
necessary), or has been aborted.
Communicating with autofs: detecting the daemon
===============================================
There are several forms of communication between the automount daemon
and the filesystem. As we have already seen, the daemon can create and
remove directories and symlinks using normal filesystem operations.
autofs knows whether a process requesting some operation is the daemon
or not based on its process-group id number (see getpgid(1)).
When an autofs filesystem is mounted the pgid of the mounting
processes is recorded unless the "pgrp=" option is given, in which
case that number is recorded instead. Any request arriving from a
process in that process group is considered to come from the daemon.
If the daemon ever has to be stopped and restarted a new pgid can be
provided through an ioctl as will be described below.
Communicating with autofs: the event pipe
=========================================
When an autofs filesystem is mounted, the 'write' end of a pipe must
be passed using the 'fd=' mount option. autofs will write
notification messages to this pipe for the daemon to respond to.
For version 5, the format of the message is::
struct autofs_v5_packet {
struct autofs_packet_hdr hdr;
autofs_wqt_t wait_queue_token;
__u32 dev;
__u64 ino;
__u32 uid;
__u32 gid;
__u32 pid;
__u32 tgid;
__u32 len;
char name[NAME_MAX+1];
};
And the format of the header is::
struct autofs_packet_hdr {
int proto_version; /* Protocol version */
int type; /* Type of packet */
};
where the type is one of ::
autofs_ptype_missing_indirect
autofs_ptype_expire_indirect
autofs_ptype_missing_direct
autofs_ptype_expire_direct
so messages can indicate that a name is missing (something tried to
access it but it isn't there) or that it has been selected for expiry.
The pipe will be set to "packet mode" (equivalent to passing
`O_DIRECT`) to _pipe2(2)_ so that a read from the pipe will return at
most one packet, and any unread portion of a packet will be discarded.
The `wait_queue_token` is a unique number which can identify a
particular request to be acknowledged. When a message is sent over
the pipe the affected dentry is marked as either "active" or
"expiring" and other accesses to it block until the message is
acknowledged using one of the ioctls below with the relevant
`wait_queue_token`.
Communicating with autofs: root directory ioctls
================================================
The root directory of an autofs filesystem will respond to a number of
ioctls. The process issuing the ioctl must have the CAP_SYS_ADMIN
capability, or must be the automount daemon.
The available ioctl commands are:
- **AUTOFS_IOC_READY**:
a notification has been handled. The argument
to the ioctl command is the "wait_queue_token" number
corresponding to the notification being acknowledged.
- **AUTOFS_IOC_FAIL**:
similar to above, but indicates failure with
the error code `ENOENT`.
- **AUTOFS_IOC_CATATONIC**:
Causes the autofs to enter "catatonic"
mode meaning that it stops sending notifications to the daemon.
This mode is also entered if a write to the pipe fails.
- **AUTOFS_IOC_PROTOVER**:
This returns the protocol version in use.
- **AUTOFS_IOC_PROTOSUBVER**:
Returns the protocol sub-version which
is really a version number for the implementation.
- **AUTOFS_IOC_SETTIMEOUT**:
This passes a pointer to an unsigned
long. The value is used to set the timeout for expiry, and
the current timeout value is stored back through the pointer.
- **AUTOFS_IOC_ASKUMOUNT**:
Returns, in the pointed-to `int`, 1 if
the filesystem could be unmounted. This is only a hint as
the situation could change at any instant. This call can be
used to avoid a more expensive full unmount attempt.
- **AUTOFS_IOC_EXPIRE**:
as described above, this asks if there is
anything suitable to expire. A pointer to a packet::
struct autofs_packet_expire_multi {
struct autofs_packet_hdr hdr;
autofs_wqt_t wait_queue_token;
int len;
char name[NAME_MAX+1];
};
is required. This is filled in with the name of something
that can be unmounted or removed. If nothing can be expired,
`errno` is set to `EAGAIN`. Even though a `wait_queue_token`
is present in the structure, no "wait queue" is established
and no acknowledgment is needed.
- **AUTOFS_IOC_EXPIRE_MULTI**:
This is similar to
**AUTOFS_IOC_EXPIRE** except that it causes notification to be
sent to the daemon, and it blocks until the daemon acknowledges.
The argument is an integer which can contain two different flags.
**AUTOFS_EXP_IMMEDIATE** causes `last_used` time to be ignored
and objects are expired if the are not in use.
**AUTOFS_EXP_FORCED** causes the in use status to be ignored
and objects are expired even if they are in use. This assumes
that the daemon has requested this because it is capable of
performing the umount.
**AUTOFS_EXP_LEAVES** will select a leaf rather than a top-level
name to expire. This is only safe when *maxproto* is 4.
Communicating with autofs: char-device ioctls
=============================================
It is not always possible to open the root of an autofs filesystem,
particularly a *direct* mounted filesystem. If the automount daemon
is restarted there is no way for it to regain control of existing
mounts using any of the above communication channels. To address this
need there is a "miscellaneous" character device (major 10, minor 235)
which can be used to communicate directly with the autofs filesystem.
It requires CAP_SYS_ADMIN for access.
The 'ioctl's that can be used on this device are described in a separate
document `autofs-mount-control.rst`, and are summarised briefly here.
Each ioctl is passed a pointer to an `autofs_dev_ioctl` structure::
struct autofs_dev_ioctl {
__u32 ver_major;
__u32 ver_minor;
__u32 size; /* total size of data passed in
* including this struct */
__s32 ioctlfd; /* automount command fd */
/* Command parameters */
union {
struct args_protover protover;
struct args_protosubver protosubver;
struct args_openmount openmount;
struct args_ready ready;
struct args_fail fail;
struct args_setpipefd setpipefd;
struct args_timeout timeout;
struct args_requester requester;
struct args_expire expire;
struct args_askumount askumount;
struct args_ismountpoint ismountpoint;
};
char path[];
};
For the **OPEN_MOUNT** and **IS_MOUNTPOINT** commands, the target
filesystem is identified by the `path`. All other commands identify
the filesystem by the `ioctlfd` which is a file descriptor open on the
root, and which can be returned by **OPEN_MOUNT**.
The `ver_major` and `ver_minor` are in/out parameters which check that
the requested version is supported, and report the maximum version
that the kernel module can support.
Commands are:
- **AUTOFS_DEV_IOCTL_VERSION_CMD**:
does nothing, except validate and
set version numbers.
- **AUTOFS_DEV_IOCTL_OPENMOUNT_CMD**:
return an open file descriptor
on the root of an autofs filesystem. The filesystem is identified
by name and device number, which is stored in `openmount.devid`.
Device numbers for existing filesystems can be found in
`/proc/self/mountinfo`.
- **AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD**:
same as `close(ioctlfd)`.
- **AUTOFS_DEV_IOCTL_SETPIPEFD_CMD**:
if the filesystem is in
catatonic mode, this can provide the write end of a new pipe
in `setpipefd.pipefd` to re-establish communication with a daemon.
The process group of the calling process is used to identify the
daemon.
- **AUTOFS_DEV_IOCTL_REQUESTER_CMD**:
`path` should be a
name within the filesystem that has been auto-mounted on.
On successful return, `requester.uid` and `requester.gid` will be
the UID and GID of the process which triggered that mount.
- **AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD**:
Check if path is a
mountpoint of a particular type - see separate documentation for
details.
- **AUTOFS_DEV_IOCTL_PROTOVER_CMD**
- **AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD**
- **AUTOFS_DEV_IOCTL_READY_CMD**
- **AUTOFS_DEV_IOCTL_FAIL_CMD**
- **AUTOFS_DEV_IOCTL_CATATONIC_CMD**
- **AUTOFS_DEV_IOCTL_TIMEOUT_CMD**
- **AUTOFS_DEV_IOCTL_EXPIRE_CMD**
- **AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD**
These all have the same
function as the similarly named **AUTOFS_IOC** ioctls, except
that **FAIL** can be given an explicit error number in `fail.status`
instead of assuming `ENOENT`, and this **EXPIRE** command
corresponds to **AUTOFS_IOC_EXPIRE_MULTI**.
Catatonic mode
==============
As mentioned, an autofs mount can enter "catatonic" mode. This
happens if a write to the notification pipe fails, or if it is
explicitly requested by an `ioctl`.
When entering catatonic mode, the pipe is closed and any pending
notifications are acknowledged with the error `ENOENT`.
Once in catatonic mode attempts to access non-existing names will
result in `ENOENT` while attempts to access existing directories will
be treated in the same way as if they came from the daemon, so mount
traps will not fire.
When the filesystem is mounted a _uid_ and _gid_ can be given which
set the ownership of directories and symbolic links. When the
filesystem is in catatonic mode, any process with a matching UID can
create directories or symlinks in the root directory, but not in other
directories.
Catatonic mode can only be left via the
**AUTOFS_DEV_IOCTL_OPENMOUNT_CMD** ioctl on the `/dev/autofs`.
The "ignore" mount option
=========================
The "ignore" mount option can be used to provide a generic indicator
to applications that the mount entry should be ignored when displaying
mount information.
In other OSes that provide autofs and that provide a mount list to user
space based on the kernel mount list a no-op mount option ("ignore" is
the one use on the most common OSes) is allowed so that autofs file
system users can optionally use it.
This is intended to be used by user space programs to exclude autofs
mounts from consideration when reading the mounts list.
autofs, name spaces, and shared mounts
======================================
With bind mounts and name spaces it is possible for an autofs
filesystem to appear at multiple places in one or more filesystem
name spaces. For this to work sensibly, the autofs filesystem should
always be mounted "shared". e.g. ::
mount --make-shared /autofs/mount/point
The automount daemon is only able to manage a single mount location for
an autofs filesystem and if mounts on that are not 'shared', other
locations will not behave as expected. In particular access to those
other locations will likely result in the `ELOOP` error ::
Too many levels of symbolic links
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
목적
1-26autofs의 목적은 여러 파일시스템을 필요할 때 마운트하고, 경쟁 조건 없이 자동으로 언마운트하는 것입니다. 이 방식에는 두 가지 핵심 장점이 있습니다.
첫째, 필요할 가능성이 있는 모든 파일시스템이 마운트될 때까지 부팅을 지연할 필요가 없습니다. 느린 파일시스템에 접근하는 프로세스는 기다릴 수 있지만 다른 프로세스는 계속 실행할 수 있습니다. 이는 NFS 같은 네트워크 파일시스템이나 매체 교환 로봇이 다루는 저장 매체의 파일시스템에서 특히 중요합니다.
둘째, 파일시스템의 이름과 위치를 원격 데이터베이스에 저장하고 언제든 변경할 수 있습니다. 접근 시점의 데이터베이스 내용이 접근 대상을 결정합니다. 이름 해석은 데이터베이스가 아니라 프로그램 로직으로 수행할 수도 있어 와일드카드를 지원할 수 있고, 어떤 이름을 처음 접근한 사용자에 따라 결과를 달리할 수도 있습니다.
필요 시 마운트와 자동 만료가 해결하는 두 문제입니다.
=====================
autofs - how it works
=====================
Purpose
=======
The goal of autofs is to provide on-demand mounting and race free
automatic unmounting of various other filesystems. This provides two
key advantages:
1. There is no need to delay boot until all filesystems that
might be needed are mounted. Processes that try to access those
slow filesystems might be delayed but other processes can
continue freely. This is particularly important for
network filesystems (e.g. NFS) or filesystems stored on
media with a media-changing robot.
2. The names and locations of filesystems can be stored in
a remote database and can change at any time. The content
in that database at the time of access will be used to provide
a target for the access. The interpretation of names in the
filesystem can even be programmatic rather than database-backed,
allowing wildcards for example, and can vary based on the user who
first accessed a name.
구성 요소와 문서 범위
27-41`autofs` 파일시스템 모듈은 autofs 시스템의 한 부분일 뿐입니다. 이름을 조회하고 실제 파일시스템을 마운트하는 사용자 공간 프로그램도 필요합니다. 일반적으로 `automount`가 이 역할을 하지만 `systemd`를 비롯한 다른 도구도 `autofs`를 사용할 수 있습니다. 이 문서는 커널 모듈과 사용자 공간 프로그램 사이에 필요한 상호작용만 설명하며, 이후 해당 프로그램을 "automount 데몬" 또는 간단히 "데몬"이라고 부릅니다.
`autofs`는 `autofs` 파일시스템 형식을 제공하는 Linux 커널 모듈입니다. 여러 autofs 파일시스템을 마운트해 각각 별도로 관리하거나 하나의 데몬으로 모두 관리할 수 있습니다.
경로 접근에서 실제 파일시스템 마운트까지의 책임 분담입니다.
Context
=======
The "autofs" filesystem module is only one part of an autofs system.
There also needs to be a user-space program which looks up names
and mounts filesystems. This will often be the "automount" program,
though other tools including "systemd" can make use of "autofs".
This document describes only the kernel module and the interactions
required with any user-space program. Subsequent text refers to this
as the "automount daemon" or simply "the daemon".
"autofs" is a Linux kernel module which provides the "autofs"
filesystem type. Several "autofs" filesystems can be mounted and they
can each be managed separately, or all managed by the same daemon.
객체와 마운트 트랩 판정
42-79autofs 파일시스템에는 디렉터리, 심볼릭 링크, 마운트 트랩의 세 종류 객체가 들어갈 수 있습니다. 마운트 트랩은 다음 절에서 설명하는 추가 속성을 가진 디렉터리입니다.
객체는 automount 데몬만 만들 수 있습니다. 심볼릭 링크는 일반 `symlink` 시스템 호출로 만들고, 디렉터리와 마운트 트랩은 `mkdir`로 만듭니다. 디렉터리가 마운트 트랩인지 여부는 master map을 기준으로 결정합니다. autofs는 이 master map에서 어떤 디렉터리가 마운트 지점인지 확인하며, 마운트 지점은 *direct*, *indirect*, *offset* 형식일 수 있습니다. 대부분의 시스템에서 기본 master map은 `/etc/auto.master`에 있습니다.
*direct*와 *offset* 마운트 옵션을 모두 주지 않으면 마운트는 *indirect*로 간주되고 루트 디렉터리는 항상 일반 디렉터리입니다. 둘 중 하나를 주면 루트는 비어 있을 때 마운트 트랩이고 내용이 있으면 일반 디렉터리입니다. *direct*와 *offset*은 동일하게 취급되므로, 간단히 말해 루트는 파일시스템이 *direct*로 마운트되었고 비어 있을 때만 마운트 트랩입니다.
루트 바로 아래에 생성된 디렉터리는 파일시스템이 *indirect*로 마운트되었고 해당 디렉터리가 비어 있을 때만 마운트 트랩입니다.
트리에서 더 아래에 있는 디렉터리의 판정은 *maxproto* 마운트 옵션, 특히 값이 5보다 작은지에 따라 달라집니다. *maxproto*가 5이면 하위 디렉터리는 절대로 마운트 트랩이 되지 않고 항상 일반 디렉터리입니다. *maxproto*가 4 또는 3이면 하위 디렉터리는 정확히 비어 있을 때 마운트 트랩입니다.
따라서 비어 있지 않은 디렉터리, 즉 리프가 아닌 디렉터리는 절대로 마운트 트랩이 아닙니다. 빈 디렉터리는 트리에서의 위치가 루트인지, 최상위인지, 더 아래인지와 *maxproto* 값, 그리고 *indirect* 마운트 여부에 따라 마운트 트랩일 수도 있고 아닐 수도 있습니다.
비어 있지 않은 디렉터리는 모든 경우 일반 디렉터리입니다.
Content
=======
An autofs filesystem can contain 3 sorts of objects: directories,
symbolic links and mount traps. Mount traps are directories with
extra properties as described in the next section.
Objects can only be created by the automount daemon: symlinks are
created with a regular `symlink` system call, while directories and
mount traps are created with `mkdir`. The determination of whether a
directory should be a mount trap is based on a master map. This master
map is consulted by autofs to determine which directories are mount
points. Mount points can be *direct*/*indirect*/*offset*.
On most systems, the default master map is located at */etc/auto.master*.
If neither the *direct* or *offset* mount options are given (so the
mount is considered to be *indirect*), then the root directory is
always a regular directory, otherwise it is a mount trap when it is
empty and a regular directory when not empty. Note that *direct* and
*offset* are treated identically so a concise summary is that the root
directory is a mount trap only if the filesystem is mounted *direct*
and the root is empty.
Directories created in the root directory are mount traps only if the
filesystem is mounted *indirect* and they are empty.
Directories further down the tree depend on the *maxproto* mount
option and particularly whether it is less than five or not.
When *maxproto* is five, no directories further down the
tree are ever mount traps, they are always regular directories. When
the *maxproto* is four (or three), these directories are mount traps
precisely when they are empty.
So: non-empty (i.e. non-leaf) directories are never mount traps. Empty
directories are sometimes mount traps, and sometimes not depending on
where in the tree they are (root, top level, or lower), the *maxproto*,
and whether the mount was *indirect* or not.
`DCACHE_NEED_AUTOMOUNT`와 `d_automount()`
80-113autofs 구현의 핵심 요소는 Linux VFS가 제공하는 마운트 트랩입니다. 파일시스템이 제공하는 어떤 디렉터리든 트랩으로 지정할 수 있으며, autofs는 서로 협력하는 두 기능을 사용합니다.
dentry에 `DCACHE_NEED_AUTOMOUNT` 플래그가 설정되어 있으면 잠재적인 마운트 트랩입니다. 이 플래그는 inode에 `S_AUTOMOUNT`가 설정될 때 설정되며 직접 설정할 수도 있습니다. 이 디렉터리에 `stat`을 넘어서는 접근이 발생하면 보통 `d_op->d_automount()` dentry 연산이 호출됩니다. 이 메서드는 디렉터리에 마운트할 파일시스템을 찾아 반환하고, VFS가 그 파일시스템의 루트를 실제로 디렉터리에 마운트합니다.
autofs는 파일시스템을 직접 찾지 않고 automount 데몬에 파일시스템을 찾아 마운트하라는 메시지를 보냅니다. autofs의 `d_automount` 메서드는 데몬이 준비 완료를 보고할 때까지 기다린 뒤, 마운트가 이미 이루어졌음을 뜻하는 `NULL`을 반환합니다. VFS는 새로 마운트하지 않고 이미 존재하는 마운트를 따라 내려갑니다.
이 기능만으로도 서버의 마운트 지점을 클라이언트에 반영하기 위해 트랩을 만드는 NFS 같은 사용 사례에는 충분하지만 autofs에는 부족합니다. 디렉터리에 마운트하는 행위 자체가 `stat`을 넘어서는 접근으로 간주되므로, automount 데몬이 트랩에 걸리지 않고 트랩 디렉터리에 파일시스템을 마운트할 방법이 추가로 필요합니다. 이를 위해 두 번째 플래그가 있습니다.
`DCACHE_NEED_AUTOMOUNT`가 실제 마운트로 이어지는 흐름입니다.
Mount Traps
===========
A core element of the implementation of autofs is the Mount Traps
which are provided by the Linux VFS. Any directory provided by a
filesystem can be designated as a trap. This involves two separate
features that work together to allow autofs to do its job.
**DCACHE_NEED_AUTOMOUNT**
If a dentry has the DCACHE_NEED_AUTOMOUNT flag set (which gets set if
the inode has S_AUTOMOUNT set, or can be set directly) then it is
(potentially) a mount trap. Any access to this directory beyond a
"`stat`" will (normally) cause the `d_op->d_automount()` dentry operation
to be called. The task of this method is to find the filesystem that
should be mounted on the directory and to return it. The VFS is
responsible for actually mounting the root of this filesystem on the
directory.
autofs doesn't find the filesystem itself but sends a message to the
automount daemon asking it to find and mount the filesystem. The
autofs `d_automount` method then waits for the daemon to report that
everything is ready. It will then return "`NULL`" indicating that the
mount has already happened. The VFS doesn't try to mount anything but
follows down the mount that is already there.
This functionality is sufficient for some users of mount traps such
as NFS which creates traps so that mountpoints on the server can be
reflected on the client. However it is not sufficient for autofs. As
mounting onto a directory is considered to be "beyond a `stat`", the
automount daemon would not be able to mount a filesystem on the 'trap'
directory without some way to avoid getting caught in the trap. For
that purpose there is another flag.
`DCACHE_MANAGE_TRANSIT`와 REF-walk
114-166dentry에 `DCACHE_MANAGE_TRANSIT`가 설정되면 서로 다르지만 관련된 두 동작이 `d_op->d_manage()` dentry 연산을 통해 실행됩니다.
첫 번째 동작에서는 디렉터리에 파일시스템이 마운트되어 있는지 검사하기 전에 `rcu_walk` 매개변수를 `false`로 두고 `d_manage()`를 호출합니다. 이 호출에는 세 종류의 결과가 있습니다.
0을 반환하면 이 dentry에 특별한 처리가 필요 없으므로 일반적인 마운트 및 automount 검사를 계속합니다. autofs는 보통 0을 반환하지만, 먼저 진행 중인 만료, 즉 마운트된 파일시스템의 자동 언마운트가 끝날 때까지 기다려 경쟁 조건을 피합니다.
`-EISDIR`을 반환하면 VFS는 디렉터리에 있는 마운트를 무시하고 `->d_automount()` 호출도 고려하지 않습니다. 결과적으로 `DCACHE_NEED_AUTOMOUNT`가 비활성화된 것처럼 동작하여 해당 디렉터리는 마운트 트랩으로 취급되지 않습니다.
autofs는 조회를 수행하는 프로세스가 automount 데몬이고 마운트가 요청되었지만 아직 완료되지 않았다고 판단할 때 `-EISDIR`을 반환합니다. 이 판정 방법은 뒤에서 설명합니다. 덕분에 automount 데몬 자체가 마운트 트랩에 걸리지 않습니다.
여기에는 미묘한 예외가 있습니다. 첫 번째 autofs 아래에 두 번째 autofs 파일시스템을 마운트하고 같은 데몬이 둘 다 관리할 수 있습니다. 데몬이 두 번째 파일시스템에 무언가를 마운트하려면 첫 번째 파일시스템을 지나 아래로 걸어갈 수 있어야 합니다. 따라서 `d_manage`는 데몬에 항상 `-EISDIR`을 반환하면 안 되고, 마운트가 요청되었으나 아직 완료되지 않은 경우에만 반환해야 합니다.
dentry가 심볼릭 링크이거나 비어 있지 않아 마운트 트랩이 아니어야 하는 경우에도 `d_manage`는 `-EISDIR`을 반환합니다.
그 밖의 음수 반환값은 오류로 처리되어 호출자에게 전달됩니다. autofs는 데몬이 아무것도 마운트하지 못하면 `-ENOENT`, 메모리가 부족하면 `-ENOMEM`, 만료 완료를 기다리는 동안 신호를 받으면 `-EINTR`, 또는 automount 데몬이 내려보낸 다른 오류를 반환할 수 있습니다.
`rcu_walk=false`일 때 VFS가 결과를 해석하는 방식입니다.
**DCACHE_MANAGE_TRANSIT**
If a dentry has DCACHE_MANAGE_TRANSIT set then two very different but
related behaviours are invoked, both using the `d_op->d_manage()`
dentry operation.
Firstly, before checking to see if any filesystem is mounted on the
directory, d_manage() will be called with the `rcu_walk` parameter set
to `false`. It may return one of three things:
- A return value of zero indicates that there is nothing special
about this dentry and normal checks for mounts and automounts
should proceed.
autofs normally returns zero, but first waits for any
expiry (automatic unmounting of the mounted filesystem) to
complete. This avoids races.
- A return value of `-EISDIR` tells the VFS to ignore any mounts
on the directory and to not consider calling `->d_automount()`.
This effectively disables the **DCACHE_NEED_AUTOMOUNT** flag
causing the directory not be a mount trap after all.
autofs returns this if it detects that the process performing the
lookup is the automount daemon and that the mount has been
requested but has not yet completed. How it determines this is
discussed later. This allows the automount daemon not to get
caught in the mount trap.
There is a subtlety here. It is possible that a second autofs
filesystem can be mounted below the first and for both of them to
be managed by the same daemon. For the daemon to be able to mount
something on the second it must be able to "walk" down past the
first. This means that d_manage cannot *always* return -EISDIR for
the automount daemon. It must only return it when a mount has
been requested, but has not yet completed.
`d_manage` also returns `-EISDIR` if the dentry shouldn't be a
mount trap, either because it is a symbolic link or because it is
not empty.
- Any other negative value is treated as an error and returned
to the caller.
autofs can return
- -ENOENT if the automount daemon failed to mount anything,
- -ENOMEM if it ran out of memory,
- -EINTR if a signal arrived while waiting for expiry to
complete
- or any other error sent down by the automount daemon.
RCU-walk에서의 `d_manage()`
167-200두 번째 사용 사례는 RCU-walk 중에만 발생하므로 `rcu_walk`가 설정되어 있습니다.
RCU-walk는 파일 이름 경로를 따라가는 빠르고 가벼운 절차입니다. 모든 상황을 처리할 수는 없으므로 어려운 상황을 만나면 더 느리지만 견고한 REF-walk로 전환합니다.
RCU-walk는 `->d_automount`를 호출하지 않습니다. 파일시스템이 이미 마운트되어 있어야 하며, 그렇지 않으면 RCU-walk로 해당 경로를 처리할 수 없습니다. 마운트 트랩을 RCU-walk 모드에서 안전하게 통과할 수 있는지 확인하기 위해 `rcu_walk=true`로 `->d_manage()`를 호출합니다.
이 경우 `d_manage()`는 블로킹을 피해야 하고 가능하면 스핀락도 잡지 않아야 합니다. 목적은 마운트된 디렉터리 안으로 안전하게 내려갈 수 있는지 판단하는 것뿐이며, 안전하지 않을 수 있는 이유는 마운트 만료가 진행 중인 경우입니다.
`rcu_walk`의 `d_manage()`는 VFS에 automount가 필요 없는 디렉터리라고 알리기 위해 `-EISDIR`을 반환할 수 없습니다. RCU-walk가 `DCACHE_NEED_AUTOMOUNT`가 설정되었지만 아무것도 마운트되지 않은 dentry를 만나면 반드시 REF-walk로 전환합니다. `d_manage()`는 VFS를 RCU-walk에 남겨 둘 수 없고 `-ECHILD`를 반환해 RCU-walk에서 빠져나오게 할 수만 있습니다.
따라서 `rcu_walk`가 설정된 `d_manage()`는 마운트된 파일시스템으로 들어가는 것이 안전하지 않다고 볼 이유가 조금이라도 있으면 `-ECHILD`, 그렇지 않으면 0을 반환해야 합니다. autofs는 파일시스템 만료가 시작되었거나 검토 중이면 `-ECHILD`, 그 외에는 0을 반환합니다.
마운트 만료 상태만으로 빠른 경로 유지 여부를 정합니다.
The second use case only occurs during an "RCU-walk" and so `rcu_walk`
will be set.
An RCU-walk is a fast and lightweight process for walking down a
filename path (i.e. it is like running on tip-toes). RCU-walk cannot
cope with all situations so when it finds a difficulty it falls back
to "REF-walk", which is slower but more robust.
RCU-walk will never call `->d_automount`; the filesystems must already
be mounted or RCU-walk cannot handle the path.
To determine if a mount-trap is safe for RCU-walk mode it calls
`->d_manage()` with `rcu_walk` set to `true`.
In this case `d_manage()` must avoid blocking and should avoid taking
spinlocks if at all possible. Its sole purpose is to determine if it
would be safe to follow down into any mounted directory and the only
reason that it might not be is if an expiry of the mount is
underway.
In the `rcu_walk` case, `d_manage()` cannot return -EISDIR to tell the
VFS that this is a directory that doesn't require d_automount. If
`rcu_walk` sees a dentry with DCACHE_NEED_AUTOMOUNT set but nothing
mounted, it *will* fall back to REF-walk. `d_manage()` cannot make the
VFS remain in RCU-walk mode, but can only tell it to get out of
RCU-walk mode by returning `-ECHILD`.
So `d_manage()`, when called with `rcu_walk` set, should either return
-ECHILD if there is any reason to believe it is unsafe to enter the
mounted filesystem, otherwise it should return 0.
autofs will return `-ECHILD` if an expiry of the filesystem has been
initiated or is being considered, otherwise it returns 0.
마운트 지점 만료의 배경
201-235VFS에는 dcache에서 사용하지 않는 dentry 정보를 제거하는 것처럼 사용하지 않는 마운트를 자동으로 만료시키는 메커니즘이 있으며, `MNT_SHRINKABLE` 플래그가 이를 안내합니다. 이 방식은 `d_automount()`가 마운트할 파일시스템을 반환해 생성된 마운트에만 적용됩니다. autofs는 파일시스템을 반환하지 않고 automount 데몬이 마운트하게 하므로 언마운트에도 데몬을 참여시켜야 합니다. 그 대신 autofs는 만료를 더 세밀하게 제어할 수 있습니다.
VFS는 `umount` 시스템 호출에 `MNT_EXPIRE` 플래그를 사용한 만료도 지원합니다. `MNT_EXPIRE` 언마운트는 이전 시도가 한 번 있었고 그 이후 파일시스템이 비활성 상태이며 접근되지 않은 경우에만 성공합니다. autofs는 이 기능에 의존하지 않고 파일시스템의 최근 사용 여부를 자체적으로 추적하므로 autofs 디렉터리의 이름별로 따로 만료시킬 수 있습니다.
프로토콜 버전 4에서 automount 데몬은 원하는 시점에 autofs 위에 마운트된 파일시스템을 언마운트하거나 심볼릭 링크 또는 빈 디렉터리를 제거할 수 있습니다. 성공하면 해당 이름은 마운트 또는 생성 전 상태로 돌아가고 다음 접근에서 정상 automount 처리가 다시 시작됩니다. 특히 `rmdir`와 `unlink`는 일반 파일시스템처럼 dcache에 음수 엔트리를 남기지 않으므로, 방금 제거한 객체에 대한 접근도 autofs에 전달됩니다.
버전 5에서는 최상위 디렉터리에서 언마운트하는 경우를 제외하면 이 방식이 안전하지 않습니다. 하위 디렉터리는 마운트 트랩이 아니므로 파일시스템을 언마운트하는 즉시 다른 프로세스가 빈 디렉터리를 볼 수 있습니다. 따라서 일반적으로 뒤에서 설명하는 autofs 만료 프로토콜을 사용하는 편이 가장 안전합니다.
VFS 방식과 autofs 프로토콜의 책임 차이입니다.
Mountpoint expiry
=================
The VFS has a mechanism for automatically expiring unused mounts,
much as it can expire any unused dentry information from the dcache.
This is guided by the MNT_SHRINKABLE flag. This only applies to
mounts that were created by `d_automount()` returning a filesystem to be
mounted. As autofs doesn't return such a filesystem but leaves the
mounting to the automount daemon, it must involve the automount daemon
in unmounting as well. This also means that autofs has more control
over expiry.
The VFS also supports "expiry" of mounts using the MNT_EXPIRE flag to
the `umount` system call. Unmounting with MNT_EXPIRE will fail unless
a previous attempt had been made, and the filesystem has been inactive
and untouched since that previous attempt. autofs does not depend on
this but has its own internal tracking of whether filesystems were
recently used. This allows individual names in the autofs directory
to expire separately.
With version 4 of the protocol, the automount daemon can try to
unmount any filesystems mounted on the autofs filesystem or remove any
symbolic links or empty directories any time it likes. If the unmount
or removal is successful the filesystem will be returned to the state
it was before the mount or creation, so that any access of the name
will trigger normal auto-mount processing. In particular, `rmdir` and
`unlink` do not leave negative entries in the dcache as a normal
filesystem would, so an attempt to access a recently-removed object is
passed to autofs for handling.
With version 5, this is not safe except for unmounting from top-level
directories. As lower-level directories are never mount traps, other
processes will see an empty directory as soon as the filesystem is
unmounted. So it is generally safest to use the autofs expiry
protocol described below.
`last_used`, `strictexpire`, 만료 후보
236-278보통 데몬은 한동안 사용되지 않은 엔트리만 제거하려 합니다. 이를 위해 autofs는 각 디렉터리와 심볼릭 링크에 `last_used` 타임스탬프를 유지합니다. 심볼릭 링크에서는 링크를 사용하거나 따라가 대상을 확인한 마지막 시각을 실제로 기록합니다.
디렉터리에서는 이 필드를 조금 다르게 사용합니다. 마운트 시점, 만료 검사에서 디렉터리가 사용 중이라고 판명된 시점, 그리고 경로 탐색 중에 갱신합니다. 여기서 사용 중이라는 것은 열린 파일 디스크립터가 있거나 프로세스의 작업 디렉터리인 경우를 포함합니다. 경로 탐색 중 갱신은 자주 접근하는 automount가 반복해서 만료된 직후 다시 마운트되는 일을 막습니다.
하지만 GUI가 계속 접근하거나 애플리케이션이 autofs 디렉터리 트리를 자주 스캔하면 실제로 사용하지 않는 마운트가 누적될 수 있습니다. 이 경우 `strictexpire` autofs 마운트 옵션으로 경로 탐색 시 `last_used` 갱신을 막아, 실제로 사용하지 않는 마운트가 만료되지 않는 것처럼 보이는 문제를 피할 수 있습니다.
데몬은 뒤에서 설명하는 `ioctl`을 사용해 만료할 항목이 있는지 autofs에 물을 수 있습니다. *direct* 마운트에서는 전체 마운트 트리를 언마운트할 수 있는지 검토하고, *indirect* 마운트에서는 최상위 디렉터리의 각 이름을 검사해 언마운트하고 정리할 수 있는 항목을 찾습니다.
indirect 마운트에는 최상위 이름 대신 실제로 마운트된 각 리프를 검토하는 옵션도 있습니다. 원래 autofs 버전 4 호환성을 위한 기능이며 Sun 형식 automount map에서는 폐기 예정으로 간주해야 합니다. 다만 amd automounter가 개별 마운트마다 만료 시간 제한을 지정할 수 있으므로, 보통 indirect인 amd 형식 map에서 다시 쓰일 가능성이 있습니다. 이를 위해 필요한 변경에는 몇 가지 어려움이 남아 있습니다.
autofs가 디렉터리를 검토할 때는 `last_used`를 파일시스템 마운트 시 지정한 `timeout`과 비교하지만 일부 경우에는 이 검사를 생략합니다. 또한 해당 디렉터리나 그 아래가 사용 중인지 검사합니다. 심볼릭 링크는 `last_used` 시각만 고려합니다. 시간과 사용 상태가 모두 만료를 허용하면 만료 동작을 시작합니다.
디렉터리와 심볼릭 링크에 적용되는 검사입니다.
Normally the daemon only wants to remove entries which haven't been
used for a while. For this purpose autofs maintains a "`last_used`"
time stamp on each directory or symlink. For symlinks it genuinely
does record the last time the symlink was "used" or followed to find
out where it points to. For directories the field is used slightly
differently. The field is updated at mount time and during expire
checks if it is found to be in use (ie. open file descriptor or
process working directory) and during path walks. The update done
during path walks prevents frequent expire and immediate mount of
frequently accessed automounts. But in the case where a GUI continually
access or an application frequently scans an autofs directory tree
there can be an accumulation of mounts that aren't actually being
used. To cater for this case the "`strictexpire`" autofs mount option
can be used to avoid the "`last_used`" update on path walk thereby
preventing this apparent inability to expire mounts that aren't
really in use.
The daemon is able to ask autofs if anything is due to be expired,
using an `ioctl` as discussed later. For a *direct* mount, autofs
considers if the entire mount-tree can be unmounted or not. For an
*indirect* mount, autofs considers each of the names in the top level
directory to determine if any of those can be unmounted and cleaned
up.
There is an option with indirect mounts to consider each of the leaves
that has been mounted on instead of considering the top-level names.
This was originally intended for compatibility with version 4 of autofs
and should be considered as deprecated for Sun Format automount maps.
However, it may be used again for amd format mount maps (which are
generally indirect maps) because the amd automounter allows for the
setting of an expire timeout for individual mounts. But there are
some difficulties in making the needed changes for this.
When autofs considers a directory it checks the `last_used` time and
compares it with the "timeout" value set when the filesystem was
mounted, though this check is ignored in some cases. It also checks if
the directory or anything below it is in use. For symbolic links,
only the `last_used` time is ever considered.
If both appear to support expiring the directory or symlink, an action
is taken.
만료를 요청하는 두 인터페이스
279-300autofs에 만료를 검토하라고 요청하는 방법은 두 가지입니다. 첫 번째는 `AUTOFS_IOC_EXPIRE` ioctl이며 indirect 마운트에서만 작동합니다. 루트 디렉터리에서 만료할 항목을 찾으면 그 이름을 반환합니다. 이름을 받은 automount 데몬은 해당 이름 아래에 마운트된 파일시스템을 일반 방식으로 언마운트해야 합니다. 앞서 설명했듯 autofs 버전 5에서 최상위가 아닌 마운트에는 안전하지 않으므로 현재 `automount(8)`은 이 ioctl을 사용하지 않습니다.
두 번째는 `AUTOFS_DEV_IOCTL_EXPIRE_CMD` 또는 `AUTOFS_IOC_EXPIRE_MULTI` ioctl을 사용합니다. direct와 indirect 마운트 모두에서 작동합니다. 만료할 객체를 고르면 아래에서 설명하는 알림 메커니즘으로 데몬에 알리고, 데몬이 만료 알림을 확인할 때까지 블로킹합니다. 따라서 `EXPIRE` ioctl은 알림을 처리하는 스레드와 다른 스레드에서 보내야 합니다.
ioctl이 블로킹된 동안 엔트리는 "expiring"으로 표시됩니다. `d_manage`는 데몬이 언마운트와 필요한 디렉터리 제거가 완료되었다고 확인하거나 작업을 중단했다고 알릴 때까지 블로킹합니다.
두 방식의 범위와 동기화 모델입니다.
There are two ways to ask autofs to consider expiry. The first is to
use the **AUTOFS_IOC_EXPIRE** ioctl. This only works for indirect
mounts. If it finds something in the root directory to expire it will
return the name of that thing. Once a name has been returned the
automount daemon needs to unmount any filesystems mounted below the
name normally. As described above, this is unsafe for non-toplevel
mounts in a version-5 autofs. For this reason the current `automount(8)`
does not use this ioctl.
The second mechanism uses either the **AUTOFS_DEV_IOCTL_EXPIRE_CMD** or
the **AUTOFS_IOC_EXPIRE_MULTI** ioctl. This will work for both direct and
indirect mounts. If it selects an object to expire, it will notify
the daemon using the notification mechanism described below. This
will block until the daemon acknowledges the expiry notification.
This implies that the "`EXPIRE`" ioctl must be sent from a different
thread than the one which handles notification.
While the ioctl is blocking, the entry is marked as "expiring" and
`d_manage` will block until the daemon affirms that the unmount has
completed (together with removing any directories that might have been
necessary), or has been aborted.
데몬 판별
301-316automount 데몬과 파일시스템 사이에는 여러 통신 방식이 있습니다. 데몬은 일반 파일시스템 연산으로 디렉터리와 심볼릭 링크를 만들고 제거할 수 있습니다. autofs는 연산을 요청한 프로세스가 데몬인지 프로세스 그룹 ID 번호로 판별합니다. 프로세스 그룹 조회는 `getpgid(1)`을 참고하십시오.
autofs 파일시스템을 마운트할 때 마운트를 수행한 프로세스의 pgid를 기록합니다. 단, `pgrp=` 옵션이 있으면 옵션으로 전달한 번호를 기록합니다. 그 프로세스 그룹에 속한 프로세스의 요청은 모두 데몬이 보낸 것으로 간주합니다. 데몬을 중지했다가 재시작해야 하면 뒤에서 설명하는 ioctl로 새 pgid를 제공할 수 있습니다.
프로세스 그룹으로 트랩 우회 권한을 식별합니다.
Communicating with autofs: detecting the daemon
===============================================
There are several forms of communication between the automount daemon
and the filesystem. As we have already seen, the daemon can create and
remove directories and symlinks using normal filesystem operations.
autofs knows whether a process requesting some operation is the daemon
or not based on its process-group id number (see getpgid(1)).
When an autofs filesystem is mounted the pgid of the mounting
processes is recorded unless the "pgrp=" option is given, in which
case that number is recorded instead. Any request arriving from a
process in that process group is considered to come from the daemon.
If the daemon ever has to be stopped and restarted a new pgid can be
provided through an ioctl as will be described below.
이벤트 파이프와 알림 패킷
317-365autofs 파일시스템을 마운트할 때 파이프의 쓰기 끝을 `fd=` 마운트 옵션으로 전달해야 합니다. autofs는 데몬이 응답해야 하는 알림 메시지를 이 파이프에 기록합니다.
프로토콜 버전 5의 메시지는 `struct autofs_v5_packet`입니다. 헤더 `struct autofs_packet_hdr`, 고유한 `wait_queue_token`, 장치와 inode 번호, 요청자의 UID·GID, PID·TGID, 이름 길이와 `name[NAME_MAX+1]`을 담습니다. 헤더에는 프로토콜 버전과 패킷 형식이 들어갑니다.
패킷 형식은 `autofs_ptype_missing_indirect`, `autofs_ptype_expire_indirect`, `autofs_ptype_missing_direct`, `autofs_ptype_expire_direct` 중 하나입니다. 따라서 메시지는 어떤 이름에 접근했지만 존재하지 않는 missing 사건 또는 해당 이름이 만료 대상으로 선택된 expire 사건을 direct·indirect 형식별로 나타낼 수 있습니다.
파이프는 `pipe2(2)`에 `O_DIRECT`를 전달한 것과 같은 "packet mode"로 설정됩니다. 파이프 읽기 한 번은 최대 한 패킷만 반환하며, 패킷에서 읽지 않은 나머지 부분은 폐기됩니다.
`wait_queue_token`은 확인해야 할 개별 요청을 식별하는 고유 번호입니다. 파이프로 메시지를 보낼 때 영향받는 dentry는 "active" 또는 "expiring"으로 표시되고, 해당 dentry에 대한 다른 접근은 아래의 ioctl 가운데 하나에 관련 `wait_queue_token`을 전달해 메시지를 확인할 때까지 블로킹됩니다.
패킷 필드와 네 가지 사건 형식입니다.
Communicating with autofs: the event pipe
=========================================
When an autofs filesystem is mounted, the 'write' end of a pipe must
be passed using the 'fd=' mount option. autofs will write
notification messages to this pipe for the daemon to respond to.
For version 5, the format of the message is::
struct autofs_v5_packet {
struct autofs_packet_hdr hdr;
autofs_wqt_t wait_queue_token;
__u32 dev;
__u64 ino;
__u32 uid;
__u32 gid;
__u32 pid;
__u32 tgid;
__u32 len;
char name[NAME_MAX+1];
};
And the format of the header is::
struct autofs_packet_hdr {
int proto_version; /* Protocol version */
int type; /* Type of packet */
};
where the type is one of ::
autofs_ptype_missing_indirect
autofs_ptype_expire_indirect
autofs_ptype_missing_direct
autofs_ptype_expire_direct
so messages can indicate that a name is missing (something tried to
access it but it isn't there) or that it has been selected for expiry.
The pipe will be set to "packet mode" (equivalent to passing
`O_DIRECT`) to _pipe2(2)_ so that a read from the pipe will return at
most one packet, and any unread portion of a packet will be discarded.
The `wait_queue_token` is a unique number which can identify a
particular request to be acknowledged. When a message is sent over
the pipe the affected dentry is marked as either "active" or
"expiring" and other accesses to it block until the message is
acknowledged using one of the ioctls below with the relevant
`wait_queue_token`.
루트 디렉터리 ioctl
366-432autofs 파일시스템의 루트 디렉터리는 여러 ioctl에 응답합니다. ioctl을 실행하는 프로세스는 `CAP_SYS_ADMIN` capability가 있거나 automount 데몬이어야 합니다.
`AUTOFS_IOC_READY`는 알림 처리가 완료되었음을 알립니다. 인수는 확인할 알림의 `wait_queue_token`입니다. `AUTOFS_IOC_FAIL`은 같은 방식이지만 `ENOENT` 오류로 실패했음을 알립니다.
`AUTOFS_IOC_CATATONIC`은 autofs를 "catatonic" 모드로 전환해 데몬에 알림 전송을 중지합니다. 파이프 쓰기가 실패해도 이 모드로 들어갑니다.
`AUTOFS_IOC_PROTOVER`는 사용 중인 프로토콜 버전을 반환합니다. `AUTOFS_IOC_PROTOSUBVER`는 실제로 구현 버전 번호인 프로토콜 하위 버전을 반환합니다.
`AUTOFS_IOC_SETTIMEOUT`은 unsigned long을 가리키는 포인터를 받습니다. 전달된 값으로 만료 시간 제한을 설정하고, 기존 시간 제한 값을 같은 포인터를 통해 돌려줍니다.
`AUTOFS_IOC_ASKUMOUNT`는 파일시스템을 언마운트할 수 있으면 포인터가 가리키는 `int`에 1을 반환합니다. 상태는 언제든 변할 수 있으므로 힌트일 뿐이지만, 비용이 큰 전체 언마운트 시도를 피하는 데 사용할 수 있습니다.
`AUTOFS_IOC_EXPIRE`는 앞에서 설명한 대로 만료에 적합한 항목이 있는지 묻습니다. `struct autofs_packet_expire_multi`를 가리키는 포인터가 필요하며, 언마운트하거나 제거할 수 있는 항목의 이름으로 구조체를 채웁니다. 만료할 항목이 없으면 `errno`는 `EAGAIN`입니다. 구조체에 `wait_queue_token`이 있지만 wait queue를 만들지 않으며 확인도 필요하지 않습니다.
`AUTOFS_IOC_EXPIRE_MULTI`는 `AUTOFS_IOC_EXPIRE`와 비슷하지만 데몬에 알림을 보내고 데몬이 확인할 때까지 블로킹합니다. 정수 인수에는 만료 동작을 바꾸는 플래그가 들어갑니다.
`AUTOFS_EXP_IMMEDIATE`는 `last_used`를 무시하여 객체가 사용 중이지만 않으면 만료합니다. `AUTOFS_EXP_FORCED`는 사용 중 상태도 무시하여 객체가 사용 중이어도 만료합니다. 이는 데몬이 언마운트를 수행할 능력이 있어 강제 만료를 요청했다고 가정합니다. `AUTOFS_EXP_LEAVES`는 최상위 이름 대신 리프를 만료 대상으로 고르며, *maxproto*가 4일 때만 안전합니다.
알림 확인, 프로토콜 조회, 만료 제어 명령입니다.
Communicating with autofs: root directory ioctls
================================================
The root directory of an autofs filesystem will respond to a number of
ioctls. The process issuing the ioctl must have the CAP_SYS_ADMIN
capability, or must be the automount daemon.
The available ioctl commands are:
- **AUTOFS_IOC_READY**:
a notification has been handled. The argument
to the ioctl command is the "wait_queue_token" number
corresponding to the notification being acknowledged.
- **AUTOFS_IOC_FAIL**:
similar to above, but indicates failure with
the error code `ENOENT`.
- **AUTOFS_IOC_CATATONIC**:
Causes the autofs to enter "catatonic"
mode meaning that it stops sending notifications to the daemon.
This mode is also entered if a write to the pipe fails.
- **AUTOFS_IOC_PROTOVER**:
This returns the protocol version in use.
- **AUTOFS_IOC_PROTOSUBVER**:
Returns the protocol sub-version which
is really a version number for the implementation.
- **AUTOFS_IOC_SETTIMEOUT**:
This passes a pointer to an unsigned
long. The value is used to set the timeout for expiry, and
the current timeout value is stored back through the pointer.
- **AUTOFS_IOC_ASKUMOUNT**:
Returns, in the pointed-to `int`, 1 if
the filesystem could be unmounted. This is only a hint as
the situation could change at any instant. This call can be
used to avoid a more expensive full unmount attempt.
- **AUTOFS_IOC_EXPIRE**:
as described above, this asks if there is
anything suitable to expire. A pointer to a packet::
struct autofs_packet_expire_multi {
struct autofs_packet_hdr hdr;
autofs_wqt_t wait_queue_token;
int len;
char name[NAME_MAX+1];
};
is required. This is filled in with the name of something
that can be unmounted or removed. If nothing can be expired,
`errno` is set to `EAGAIN`. Even though a `wait_queue_token`
is present in the structure, no "wait queue" is established
and no acknowledgment is needed.
- **AUTOFS_IOC_EXPIRE_MULTI**:
This is similar to
**AUTOFS_IOC_EXPIRE** except that it causes notification to be
sent to the daemon, and it blocks until the daemon acknowledges.
The argument is an integer which can contain two different flags.
**AUTOFS_EXP_IMMEDIATE** causes `last_used` time to be ignored
and objects are expired if the are not in use.
**AUTOFS_EXP_FORCED** causes the in use status to be ignored
and objects are expired even if they are in use. This assumes
that the daemon has requested this because it is capable of
performing the umount.
**AUTOFS_EXP_LEAVES** will select a leaf rather than a top-level
name to expire. This is only safe when *maxproto* is 4.
`/dev/autofs` 장치와 공통 구조체
433-481특히 *direct* 마운트에서는 autofs 파일시스템의 루트를 항상 열 수 있는 것이 아닙니다. automount 데몬이 재시작되면 앞의 통신 채널만으로는 기존 마운트의 제어권을 되찾을 수 없습니다. 이를 해결하기 위해 autofs 파일시스템과 직접 통신하는 "miscellaneous" 문자 장치가 있으며 major 10, minor 235를 사용합니다. 접근에는 `CAP_SYS_ADMIN`이 필요합니다.
이 장치의 ioctl은 별도 문서 `autofs-mount-control.rst`에서 자세히 설명하며 여기서는 간단히 요약합니다. 각 ioctl에는 `autofs_dev_ioctl` 구조체 포인터를 전달합니다.
구조체의 `ver_major`와 `ver_minor`는 인터페이스 버전, `size`는 구조체를 포함해 전달한 전체 데이터 크기, `ioctlfd`는 automount 명령용 파일 디스크립터입니다. union에는 프로토콜 버전, mount 열기, ready/fail, pipe FD, timeout, requester, expire, ask-unmount, is-mountpoint 명령의 매개변수가 있고, 마지막 `char path[]`에는 가변 길이 경로가 옵니다.
`OPEN_MOUNT`와 `IS_MOUNTPOINT`는 `path`로 대상 파일시스템을 식별합니다. 다른 모든 명령은 루트에서 열린 파일 디스크립터인 `ioctlfd`로 파일시스템을 식별하며, 이 디스크립터는 `OPEN_MOUNT`로 얻을 수 있습니다.
`ver_major`와 `ver_minor`는 입출력 매개변수입니다. 요청 버전이 지원되는지 검사하고 커널 모듈이 지원할 수 있는 최대 버전을 보고합니다.
문자 장치 명령이 공유하는 헤더와 매개변수입니다.
Communicating with autofs: char-device ioctls
=============================================
It is not always possible to open the root of an autofs filesystem,
particularly a *direct* mounted filesystem. If the automount daemon
is restarted there is no way for it to regain control of existing
mounts using any of the above communication channels. To address this
need there is a "miscellaneous" character device (major 10, minor 235)
which can be used to communicate directly with the autofs filesystem.
It requires CAP_SYS_ADMIN for access.
The 'ioctl's that can be used on this device are described in a separate
document `autofs-mount-control.rst`, and are summarised briefly here.
Each ioctl is passed a pointer to an `autofs_dev_ioctl` structure::
struct autofs_dev_ioctl {
__u32 ver_major;
__u32 ver_minor;
__u32 size; /* total size of data passed in
* including this struct */
__s32 ioctlfd; /* automount command fd */
/* Command parameters */
union {
struct args_protover protover;
struct args_protosubver protosubver;
struct args_openmount openmount;
struct args_ready ready;
struct args_fail fail;
struct args_setpipefd setpipefd;
struct args_timeout timeout;
struct args_requester requester;
struct args_expire expire;
struct args_askumount askumount;
struct args_ismountpoint ismountpoint;
};
char path[];
};
For the **OPEN_MOUNT** and **IS_MOUNTPOINT** commands, the target
filesystem is identified by the `path`. All other commands identify
the filesystem by the `ioctlfd` which is a file descriptor open on the
root, and which can be returned by **OPEN_MOUNT**.
The `ver_major` and `ver_minor` are in/out parameters which check that
the requested version is supported, and report the maximum version
that the kernel module can support.
문자 장치 명령
482-525`AUTOFS_DEV_IOCTL_VERSION_CMD`는 버전 번호를 검증하고 설정하는 것 외에는 아무 동작도 하지 않습니다.
`AUTOFS_DEV_IOCTL_OPENMOUNT_CMD`는 autofs 파일시스템 루트에서 열린 파일 디스크립터를 반환합니다. 파일시스템은 이름과 `openmount.devid`에 저장된 장치 번호로 식별합니다. 기존 파일시스템의 장치 번호는 `/proc/self/mountinfo`에서 찾을 수 있습니다. `AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD`는 `close(ioctlfd)`와 같습니다.
`AUTOFS_DEV_IOCTL_SETPIPEFD_CMD`는 파일시스템이 catatonic 모드일 때 `setpipefd.pipefd`로 새 파이프의 쓰기 끝을 제공해 데몬과의 통신을 다시 설정합니다. 호출 프로세스의 프로세스 그룹을 데몬 식별에 사용합니다.
`AUTOFS_DEV_IOCTL_REQUESTER_CMD`의 `path`는 파일시스템 안에서 자동 마운트가 이루어진 이름이어야 합니다. 성공하면 `requester.uid`와 `requester.gid`에 해당 마운트를 유발한 프로세스의 UID와 GID가 들어갑니다.
`AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD`는 경로가 특정 형식의 마운트 지점인지 검사합니다. 자세한 내용은 별도 문서를 참고하십시오.
`AUTOFS_DEV_IOCTL_PROTOVER_CMD`, `PROTOSUBVER_CMD`, `READY_CMD`, `FAIL_CMD`, `CATATONIC_CMD`, `TIMEOUT_CMD`, `EXPIRE_CMD`, `ASKUMOUNT_CMD`는 이름이 대응하는 `AUTOFS_IOC` ioctl과 같은 기능을 합니다. 단, `FAIL`은 `ENOENT`를 전제로 하지 않고 `fail.status`에 명시적 오류 번호를 받을 수 있으며, 이 `EXPIRE`는 `AUTOFS_IOC_EXPIRE_MULTI`에 대응합니다.
covered mount 제어를 복구하고 루트 ioctl 기능을 제공합니다.
Commands are:
- **AUTOFS_DEV_IOCTL_VERSION_CMD**:
does nothing, except validate and
set version numbers.
- **AUTOFS_DEV_IOCTL_OPENMOUNT_CMD**:
return an open file descriptor
on the root of an autofs filesystem. The filesystem is identified
by name and device number, which is stored in `openmount.devid`.
Device numbers for existing filesystems can be found in
`/proc/self/mountinfo`.
- **AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD**:
same as `close(ioctlfd)`.
- **AUTOFS_DEV_IOCTL_SETPIPEFD_CMD**:
if the filesystem is in
catatonic mode, this can provide the write end of a new pipe
in `setpipefd.pipefd` to re-establish communication with a daemon.
The process group of the calling process is used to identify the
daemon.
- **AUTOFS_DEV_IOCTL_REQUESTER_CMD**:
`path` should be a
name within the filesystem that has been auto-mounted on.
On successful return, `requester.uid` and `requester.gid` will be
the UID and GID of the process which triggered that mount.
- **AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD**:
Check if path is a
mountpoint of a particular type - see separate documentation for
details.
- **AUTOFS_DEV_IOCTL_PROTOVER_CMD**
- **AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD**
- **AUTOFS_DEV_IOCTL_READY_CMD**
- **AUTOFS_DEV_IOCTL_FAIL_CMD**
- **AUTOFS_DEV_IOCTL_CATATONIC_CMD**
- **AUTOFS_DEV_IOCTL_TIMEOUT_CMD**
- **AUTOFS_DEV_IOCTL_EXPIRE_CMD**
- **AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD**
These all have the same
function as the similarly named **AUTOFS_IOC** ioctls, except
that **FAIL** can be given an explicit error number in `fail.status`
instead of assuming `ENOENT`, and this **EXPIRE** command
corresponds to **AUTOFS_IOC_EXPIRE_MULTI**.
Catatonic 모드
526-549autofs 마운트는 catatonic 모드에 들어갈 수 있습니다. 알림 파이프 쓰기가 실패하거나 ioctl로 명시적으로 요청할 때 이 모드로 전환합니다.
catatonic 모드에 들어가면 파이프를 닫고 대기 중인 모든 알림을 `ENOENT` 오류로 확인 처리합니다.
catatonic 모드에서는 존재하지 않는 이름에 접근하면 `ENOENT`가 발생합니다. 기존 디렉터리에 대한 접근은 데몬에서 온 요청처럼 취급하므로 마운트 트랩이 발동하지 않습니다.
파일시스템을 마운트할 때 디렉터리와 심볼릭 링크의 소유권을 정하는 UID와 GID를 줄 수 있습니다. catatonic 모드에서는 그 UID와 일치하는 프로세스가 루트 디렉터리에 디렉터리나 심볼릭 링크를 만들 수 있지만 다른 디렉터리에는 만들 수 없습니다.
catatonic 모드는 `/dev/autofs`에서 `AUTOFS_DEV_IOCTL_OPENMOUNT_CMD` ioctl을 사용해야만 벗어날 수 있습니다.
데몬 통신 장애 뒤 기존 마운트의 제어권을 회복하는 절차입니다.
Catatonic mode
==============
As mentioned, an autofs mount can enter "catatonic" mode. This
happens if a write to the notification pipe fails, or if it is
explicitly requested by an `ioctl`.
When entering catatonic mode, the pipe is closed and any pending
notifications are acknowledged with the error `ENOENT`.
Once in catatonic mode attempts to access non-existing names will
result in `ENOENT` while attempts to access existing directories will
be treated in the same way as if they came from the daemon, so mount
traps will not fire.
When the filesystem is mounted a _uid_ and _gid_ can be given which
set the ownership of directories and symbolic links. When the
filesystem is in catatonic mode, any process with a matching UID can
create directories or symlinks in the root directory, but not in other
directories.
Catatonic mode can only be left via the
**AUTOFS_DEV_IOCTL_OPENMOUNT_CMD** ioctl on the `/dev/autofs`.
`ignore` 마운트 옵션
550-564`ignore` 마운트 옵션은 마운트 정보를 표시할 때 해당 마운트 엔트리를 무시해야 한다는 일반적인 표시를 애플리케이션에 제공합니다.
autofs를 제공하고 커널 마운트 목록을 바탕으로 사용자 공간에 마운트 목록을 제공하는 다른 운영체제에서는, autofs 파일시스템 사용자가 선택적으로 지정할 수 있는 아무 동작도 하지 않는 마운트 옵션을 허용합니다. 가장 널리 쓰이는 운영체제에서 그 옵션 이름이 `ignore`입니다.
사용자 공간 프로그램은 마운트 목록을 읽을 때 이 옵션을 보고 autofs 마운트를 고려 대상에서 제외할 수 있습니다.
커널 동작을 바꾸는 대신 사용자 공간 목록 처리에 힌트를 줍니다.
The "ignore" mount option
=========================
The "ignore" mount option can be used to provide a generic indicator
to applications that the mount entry should be ignored when displaying
mount information.
In other OSes that provide autofs and that provide a mount list to user
space based on the kernel mount list a no-op mount option ("ignore" is
the one use on the most common OSes) is allowed so that autofs file
system users can optionally use it.
This is intended to be used by user space programs to exclude autofs
mounts from consideration when reading the mounts list.
네임스페이스와 shared 마운트
565-580bind 마운트와 네임스페이스를 사용하면 하나의 autofs 파일시스템이 하나 이상의 파일시스템 네임스페이스에서 여러 위치에 나타날 수 있습니다. 이 구성이 올바르게 작동하려면 autofs 파일시스템을 항상 `shared`로 마운트해야 합니다.
예를 들어 `mount --make-shared /autofs/mount/point`를 실행해 마운트 전파를 shared로 설정합니다.
automount 데몬은 autofs 파일시스템의 단일 마운트 위치만 관리할 수 있습니다. 그 위치의 마운트가 shared가 아니면 다른 위치는 예상대로 작동하지 않습니다. 특히 다른 위치에 접근하면 `ELOOP`, 즉 `Too many levels of symbolic links` 오류가 발생할 가능성이 큽니다.
데몬이 관리하는 위치의 하위 마운트가 다른 표시 위치에도 전달되어야 합니다.
autofs, name spaces, and shared mounts
======================================
With bind mounts and name spaces it is possible for an autofs
filesystem to appear at multiple places in one or more filesystem
name spaces. For this to work sensibly, the autofs filesystem should
always be mounted "shared". e.g. ::
mount --make-shared /autofs/mount/point
The automount daemon is only able to manage a single mount location for
an autofs filesystem and if mounts on that are not 'shared', other
locations will not behave as expected. In particular access to those
other locations will likely result in the `ELOOP` error ::
Too many levels of symbolic links
요약·해설
autofs.rst:1-580autofs는 VFS 마운트 트랩과 사용자 공간 automount 데몬을 결합해 경로를 처음 사용할 때 파일시스템을 마운트하고, 사용하지 않는 마운트를 이름 단위로 안전하게 만료시킵니다. `DCACHE_NEED_AUTOMOUNT`가 마운트 요청을 시작하고 `DCACHE_MANAGE_TRANSIT`와 `d_manage()`가 데몬의 트랩 우회, 만료 경쟁 방지, RCU-walk 전환을 조정합니다.
커널과 데몬은 이벤트 파이프의 v5 패킷과 wait token, 루트 디렉터리 ioctl, `/dev/autofs` 문자 장치 ioctl로 통신합니다. 문자 장치는 direct 또는 covered mount의 루트를 다시 열 수 있어 데몬 재시작 뒤에도 기존 마운트의 제어권을 복구할 수 있습니다.
접근부터 마운트, 사용 추적, 만료와 재연결까지의 핵심 흐름입니다.