The mount() and umount() system calls allow a privileged (CAP_SYS_ADMIN
) process to mount and unmount file systems. Most UNIX implementations provide versions of these system calls. However, they are not standardized by SUSv3, and their operation varies both across UNIX implementations and across file systems.
Before looking at these system calls, it is useful to know about three files that contain information about the file systems that are currently mounted or can be mounted:
A list of the currently mounted file systems can be read from the Linux-specific /proc/mounts
virtual file. /proc/mounts
is an interface to kernel data structures, so it always contains accurate information about mounted file systems.
The mount(8) and umount(8) commands automatically maintain the file /etc/mtab
, which contains information that is similar to that in /proc/mounts
, but slightly more detailed. In particular, /etc/mtab
includes file system–specific options given to mount(8), which are not shown in /proc/mounts
. However, because the mount() and umount() system calls don’t update /etc/mtab
, this file may be inaccurate if some application that mounts or unmounts devices fails to update it.
The /etc/fstab
file, maintained manually by the system administrator, contains descriptions of all of the available file systems on a system, and is used by the mount(8), umount(8), and fsck(8) commands.
The /proc/mounts
, /etc/mtab
, and /etc/fstab
files share a common format, described in the fstab(5) manual page. Here is an example of a line from the /proc/mounts
file:
/dev/sda9 /boot ext3 rw 0 0
This line contains six fields:
The name of the mounted device.
The file-system type.
Mount flags. In the above example, rw indicates that the file system was mounted read-write.
A number used to control the operation of file-system backups by dump(8). This field and the next are used only in the /etc/fstab
file; for /proc/mounts
and /etc/mtab
, these fields are always 0.
A number used to control the order in which fsck(8) checks file systems at system boot time.
The getfsent(3) and getmntent(3) manual pages document functions that can be used to read records from these files.
The mount() system call mounts the file system contained on the device specified by source under the directory (the mount point) specified by target.
#include <sys/mount.h>
int mount
(const char *source, const char *target, const char *fstype,
unsigned long mountflags, const void *data);
Returns 0 on success, or -1 on error
The names source and target are used for the first two arguments because mount() can perform other tasks than mounting a disk file system under a directory.
The fstype argument is a string identifying the type of file system contained on the device, such as ext4 or btrfs.
The mountflags argument is a bit mask constructed by ORing (|
) zero or more of the flags shown in Table 14-1, which are described in more detail below.
The final mount() argument, data, is a pointer to a buffer of information whose interpretation depends on the file system. For most file-system types, this argument is a string consisting of comma-separated option settings. A full list of these options can be found in the mount(8) manual page (or the documentation for the file system concerned, if it is not described in mount(8)).
Table 14-1. mountflags values for
mount()
Flag | Purpose |
---|---|
| Create a bind mount (since Linux 2.4) |
| Make directory updates synchronous (since Linux 2.6) |
| Permit mandatory locking of files |
| Atomically move mount point to new location |
| |
| Don’t allow access to devices |
| Don’t update last access time for directories |
| Don’t allow programs to be executed |
| Disable set-user-ID and set-group-ID programs |
| Read-only mount; files can’t be created or modified |
| Recursive mount (since Linux 2.6.20) |
| Update last access time only if older than last modification time or last status change time (since Linux 2.4.11) |
| Remount with new mountflags and data |
| Always update last access time (since Linux 2.6.30) |
| Make all file and directory updates synchronous |
The mountflags argument is a bit mask of flags that modify the operation of mount(). Zero or more of the following flags can be specified in mountflags:
MS_BIND
(since Linux 2.4)Create a bind mount. We describe this feature in Bind Mounts. If this flag is specified, then the fstype, mountflags, and data arguments are ignored.
MS_DIRSYNC
(since Linux 2.6)Make directory updates synchronous. This is similar to the effect of the open() O_SYNC
flag (Controlling Kernel Buffering of File I/O), but applies only to directory updates. The MS_SYNCHRONOUS
flag described below provides a superset of the functionality of MS_DIRSYNC
, ensuring that both file and directory updates are performed synchronously. The MS_DIRSYNC
flag allows an application to ensure that directory updates (e.g., open(pathname, O_CREAT), rename(), link(), unlink(), symlink(), and mkdir()) are synchronized without incurring the expense of synchronizing all file updates. The FS_DIRSYNC_FL
flag (I-node Flags (ext2 Extended File Attributes)) serves a similar purpose to MS_DIRSYNC
, with the difference that FS_DIRSYNC_FL
can be applied to individual directories. In addition, on Linux, calling fsync() on a file descriptor that refers to a directory provides a means of synchronizing directory updates on a per-directory basis. (This Linux-specific fsync() behavior is not specified in SUSv3.)
MS_MANDLOCK
Permit mandatory record locking on files in this file system. We describe record locking in Chapter 55.
MS_MOVE
Atomically move the existing mount point specified by source to the new location specified by target. This corresponds to the —move option to mount(8). This is equivalent to unmounting the subtree and then remounting at a different location, except that there is no point in time when the subtree is unmounted. The source argument should be a string specified as a target in a previous mount() call. When this flag is specified, the fstype, mountflags, and data arguments are ignored.
MS_NOATIME
Don’t update the last access time for files in this file system. The purpose of this flag, as well as the MS_NODIRATIME
flag described below, is to eliminate the extra disk access required to update the file i-node each time a file is accessed. In some applications, maintaining this timestamp is not critical, and avoiding doing so can significantly improve performance. The MS_NOATIME
flag serves a similar purpose to the FS_NOATIME_FL
flag (I-node Flags (ext2 Extended File Attributes)), with the difference that FS_NOATIME_FL
can be applied to single files. Linux also provides similar functionality via the O_NOATIME
open() flag, which selects this behavior for individual open files ().
MS_NODEV
Don’t allow access to block and character devices on this file system. This is a security feature designed to prevent users from doing things such as inserting a removable disk containing device special files that would allow arbitrary access to the system.
MS_NODIRATIME
Don’t update the last access time for directories on this file system. (This flag provides a subset of the functionality of MS_NOATIME
, which prevents updates to the last access time for all file types.)
MS_NOEXEC
Don’t allow programs (or scripts) to be executed from this file system. This is useful if the file system contains non-Linux executables.
MS_NOSUID
Disable set-user-ID and set-group-ID programs on this file system. This is a security feature to prevent users from running set-user-ID and set-group-ID programs from removable devices.
MS_RDONLY
Mount the file system read-only, so that no new files can be created and no existing files can be modified.
MS_REC
(since Linux 2.4.11)This flag is used in conjunction with other flags (e.g., MS_BIND
) to recursively apply the mount action to all of the mounts in a subtree.
MS_RELATIME
(since Linux 2.6.20)Update the last access timestamp for files on this file system only if the current setting of this timestamp is less than or equal to either the last modification or the last status change timestamp. This provides some of the performance benefits of MS_NOATIME
, but is useful for programs that need to know if a file has been read since it was last updated. Since Linux 2.6.30, the behavior provided by MS_RELATIME
is the default (unless the MS_NOATIME
flag is specified), and the MS_STRICTATIME
flag is required to obtain classical behavior. In addition, since Linux 2.6.30, the last access timestamp is always updated if its current value is more than 24 hours in the past, even if the current value is more recent than the last modification and last status change timestamps. (This is useful for certain system programs that monitor directories to see whether files have recently been accessed.)
MS_REMOUNT
Alter the mountflags and data for a file system that is already mounted (e.g., to make a read-only file system writable). When using this flag, the source and target arguments should be the same as for the original mount() call, and the fstype argument is ignored. This flag avoids the need to unmount and remount the disk, which may not be possible in some cases. For example, we can’t unmount a file system if any process has files open on, or its current working directory located within, the file system (this will always be true of the root file system). Another example of where we need to use MS_REMOUNT
is with tmpfs (memory-based) file systems (A Virtual Memory File System: tmpfs), which can’t be unmounted without losing their contents. Not all mountflags are modifiable; see the mount(2) manual page for details.
MS_STRICTATIME
(since Linux 2.6.30)Always update the last access timestamp when files on this file system are accessed. This was the default behavior before Linux 2.6.30. If MS_STRICTATIME
is specified, then MS_NOATIME
and MS_RELATIME
are ignored if they are also specified in mountflags.
MS_SYNCHRONOUS
Make all file and directory updates on this file system synchronous. (In the case of files, this is as though files were always opened with the open() O_SYNC
flag.)
Starting with kernel 2.6.15, Linux provides four new mount flags to support the notion of shared subtrees. The new flags are MS_PRIVATE
, MS_SHARED
, MS_SLAVE
, and MS_UNBINDABLE
. (These flags can be used in conjunction with MS_REC
to propagate their effects to all of the submounts under a mount subtree.) Shared subtrees are designed for use with certain advanced file-system features, such as per-process mount namespaces (see the description of CLONE_NEWNS
in ), and the Filesystem in Userspace (FUSE) facility. The shared subtree facility permits file-system mounts to be propagated between mount namespaces in a controlled fashion. Details on shared subtrees can be found in the kernel source code file Documentation/filesystems/sharedsubtree.txt
and [Viro & Pai, 2006].
The program in Example 14-1 provides a command-level interface to the mount(2) system call. In effect, it is a crude version of the mount(8) command. The following shell session log demonstrates the use of this program. We begin by creating a directory to be used as a mount point and mounting a file system:
$su
Need privilege to mount a file system Password: #mkdir /testfs
#./t_mount -t ext2 -o bsdgroups /dev/sda12 /testfs
#cat /proc/mounts | grep sda12
Verify the setup /dev/sda12 /testfs ext3 rw 0 0 Doesn't show bsdgroups #grep sda12 /etc/mtab
We find that the preceding grep command produces no output because our program doesn’t update /etc/mtab
. We continue, remounting the file system read-only:
#./t_mount -f Rr /dev/sda12 /testfs
#cat /proc/mounts | grep sda12
Verify change /dev/sda12 /testfs ext3 ro 0 0
The string ro in the line displayed from /proc/mounts
indicates that this is a read-only mount.
Finally, we move the mount point to a new location within the directory hierarchy:
#mkdir /demo
#./t_mount -f m /testfs /demo
#cat /proc/mounts | grep sda12
Verify change /dev/sda12 /demo ext3 ro 0
Example 14-1. Using mount()
filesys/t_mount.c
#include <sys/mount.h> #include "tlpi_hdr.h" static void usageError(const char *progName, const char *msg) { if (msg != NULL) fprintf(stderr, "%s", msg); fprintf(stderr, "Usage: %s [options] source target\n\n", progName); fprintf(stderr, "Available options:\n"); #define fpe(str) fprintf(stderr, " " str) /* Shorter! */ fpe("-t fstype [e.g., 'ext2' or 'reiserfs']\n"); fpe("-o data [file system-dependent options,\n"); fpe(" e.g., 'bsdgroups' for ext2]\n"); fpe("-f mountflags can include any of:\n"); #define fpe2(str) fprintf(stderr, " " str) fpe2("b - MS_BIND create a bind mount\n"); fpe2("d - MS_DIRSYNC synchronous directory updates\n"); fpe2("l - MS_MANDLOCK permit mandatory locking\n"); fpe2("m - MS_MOVE atomically move subtree\n"); fpe2("A - MS_NOATIME don't update atime (last access time)\n"); fpe2("V - MS_NODEV don't permit device access\n"); fpe2("D - MS_NODIRATIME don't update atime on directories\n"); fpe2("E - MS_NOEXEC don't allow executables\n"); fpe2("S - MS_NOSUID disable set-user/group-ID programs\n"); fpe2("r - MS_RDONLY read-only mount\n"); fpe2("c - MS_REC recursive mount\n"); fpe2("R - MS_REMOUNT remount\n"); fpe2("s - MS_SYNCHRONOUS make writes synchronous\n"); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { unsigned long flags; char *data, *fstype; int j, opt; flags = 0; data = NULL; fstype = NULL; while ((opt = getopt(argc, argv, "o:t:f:")) != -1) { switch (opt) { case 'o': data = optarg; break; case 't': fstype = optarg; break; case 'f': for (j = 0; j < strlen(optarg); j++) { switch (optarg[j]) { case 'b': flags |= MS_BIND; break; case 'd': flags |= MS_DIRSYNC; break; case 'l': flags |= MS_MANDLOCK; break; case 'm': flags |= MS_MOVE; break; case 'A': flags |= MS_NOATIME; break; case 'V': flags |= MS_NODEV; break; case 'D': flags |= MS_NODIRATIME; break; case 'E': flags |= MS_NOEXEC; break; case 'S': flags |= MS_NOSUID; break; case 'r': flags |= MS_RDONLY; break; case 'c': flags |= MS_REC; break; case 'R': flags |= MS_REMOUNT; break; case 's': flags |= MS_SYNCHRONOUS; break; default: usageError(argv[0], NULL); } } break; default: usageError(argv[0], NULL); } } if (argc != optind + 2) usageError(argv[0], "Wrong number of arguments\n"); if (mount(argv[optind], argv[optind + 1], fstype, flags, data) == -1) errExit("mount"); exit(EXIT_SUCCESS); }filesys/t_mount.c
The umount() system call unmounts a mounted file system.
#include <sys/mount.h>
int umount
(const char *target);
Returns 0 on success, or -1 on error
The target argument specifies the mount point of the file system to be unmounted.
On Linux 2.2 and earlier, the file system can be identified in two ways: by the mount point or by the name of the device containing the file system. Since kernel 2.4, Linux doesn’t allow the latter possibility, because a single file system can now be mounted at multiple locations, so that specifying a file system for target would be ambiguous. We explain this point in further detail in Mounting a File System at Multiple Mount Points.
It is not possible to unmount a file system that is busy; that is, if there are open files on the file system, or a process’s current working directory is somewhere in the file system. Calling umount() on a busy file system yields the error EBUSY
.
The umount2() system call is an extended version of umount(). It allows finer control over the unmount operation via the flags argument.
#include <sys/mount.h>
int umount2
(const char *target, int flags);
Returns 0 on success, or -1 on error
This flags bit-mask argument consists of zero or more of the following values ORed together:
MNT_DETACH
(since Linux 2.4.11)Perform a lazy unmount. The mount point is marked so that no process can make new accesses to it, but processes that are already using it can continue to do so. The file system is actually unmounted when all processes cease using the mount.
MNT_EXPIRE
(since Linux 2.6.8)Mark the mount point as expired. If an initial umount2() call is made specifying this flag, and the mount point is not busy, then the call fails with the error EAGAIN
, but the mount point is marked to expire. (If the mount point is busy, then the call fails with the error EBUSY
, and the mount point is not marked to expire.) A mount point remains expired as long as no process subsequently makes use of it. A second umount2() call specifying MNT_EXPIRE
will unmount an expired mount point. This provides a mechanism to unmount a file system that hasn’t been used for some period of time. This flag can’t be specified with MNT_DETACH
or MNT_FORCE
.
MNT_FORCE
Force an unmount even if the device is busy (NFS mounts only). Employing this option can cause data loss.
UMOUNT_NOFOLLOW
(since Linux 2.6.34)Don’t dereference target if it is a symbolic link. This flag is designed for use in certain set-user-ID-root programs that allow unprivileged users to perform unmounts, in order to avoid the security problems that could occur if target is a symbolic link that is changed to point to a different location.