mount
Attach a filesystem to a directory, and see what is attached
mount attaches a filesystem to a directory, and that directory's contents are whatever the
filesystem holds for as long as it stays attached. Anything that was in the directory beforehand is
hidden rather than deleted, and comes back when the filesystem is unmounted.
Run with no arguments it lists what is mounted, which on a desktop is dozens of kernel filesystems
you did not attach and are not looking for. findmnt is the better reader: it takes the same
information from /proc/self/mountinfo, prints it as a tree or a table, and accepts a path so you
can ask about one mount rather than filtering the lot. findmnt --target somefile answers which
filesystem a given file is actually on, which is the question behind most uses of df.
The device can be named three ways. /dev/sda1 is the direct one and the one that moves when a
disk is added; LABEL= and UUID= are looked up through blkid and stay right
across a reboot that renumbers the disks. Use one of the latter two in
/etc/fstab, where a wrong answer stops the machine booting.
Options are the part worth reading twice. -o ro,noexec,nosuid,nodev is the set that makes a
filesystem safe to look at rather than to run, and findmnt -o OPTIONS prints what is actually in
force rather than what was asked for. A remount changes them without detaching anything, which is
how a filesystem goes read-only under a running service.
A umount that reports the target is busy is not a failure to fix with -f. Something has a file
open on it or a working directory inside it, and fuser -m or
lsof will say what. umount -l detaches the filesystem from the tree and lets
the last user finish with it, which is the right answer when the holder cannot be stopped.
Sample files used on this page
Every example below was run against these files. Recreate them to follow along.
two disk images a container's real filesystems belong to whoever is running it, so this page brings its own. data.img holds a 32M ext4 labelled tipsdata with a pinned UUID, containing notes.txt and backups/site.tar; blank.img is 16M of zeros with no filesystem on it at all. Neither is attached to a loop device until an example attaches it, so losetup --find always answers /dev/loop0.
total 20912
-rw-r--r-- 1 root root 16777216 Jun 15 10:00 blank.img
-rw-r--r-- 1 root root 33554432 Jun 15 10:00 data.img
Attaching a filesystem
A filesystem in a file needs a loop device standing in for a disk. losetup makes one, or mount -o loop makes one and mounts it in a single step. On real hardware the device is /dev/sda1 or similar and neither step is needed.
Attach a disk image to a loop device
losetup --find --show /srv/images/data.img
--find takes the first unused loop device and --show prints which one it took. Without --show the command succeeds silently and you are left guessing.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
/dev/loop0
Mount an attached device
loop=$(losetup --find --show /srv/images/data.img)
mount "$loop" /mnt/data
ls /mnt/data
The directory now shows the filesystem's contents. lost+found is not something anyone put there: mkfs.ext4 creates it, and fsck puts recovered files in it.
Show output
backups
lost+found
notes.txt
Attach and mount in one step
mount -o loop /srv/images/data.img /mnt/data
findmnt /mnt/data
-o loop sets up the loop device itself, which is the form worth remembering for an ISO or a disk image. The device it chose shows up in the SOURCE column.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
TARGET SOURCE FSTYPE OPTIONS
/mnt/data /dev/loop0 ext4 rw,relatime
Create the mount point as you mount
mount -o loop --mkdir /srv/images/data.img /mnt/archive
findmnt -no TARGET /mnt/archive
ls -ld /mnt/archive
--mkdir makes the directory if it is missing, which saves the mkdir that otherwise precedes half the mount commands anyone types. The mode it gives the new directory comes from the mounted filesystem's root, not from the umask.
Show output
/mnt/archive
drwxr-xr-x 4 root root 1024 Jun 15 10:00 /mnt/archive
Mount by label instead of device
losetup --find --show /srv/images/data.img >/dev/null
mount LABEL=tipsdata /mnt/data
findmnt -no SOURCE,TARGET /mnt/data
The label is looked up through blkid, so the device name never appears. It keeps an /etc/fstab entry right after a disk is added and everything renumbers.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
/dev/loop0 /mnt/data
Mount by UUID
losetup --find --show /srv/images/data.img >/dev/null
mount UUID=4f6b2c18-9a3d-4e07-b5c1-2d8e7a904f31 /mnt/data
findmnt -no SOURCE,TARGET /mnt/data
A UUID is generated when the filesystem is made and two of them never collide, whereas nothing stops two disks carrying the label backup. It is the identifier to use where being wrong is expensive.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
/dev/loop0 /mnt/data
Say which filesystem type it is
mount -o loop -t ext4 /srv/images/data.img /mnt/data
findmnt -no FSTYPE /mnt/data
-t skips the probe and insists on a type. Worth giving in a script, where a wrong guess about an unfamiliar device is better refused than acted on.
Show output
ext4
Keep the loop device after unmounting
loop=$(losetup --find --show /srv/images/data.img)
mount "$loop" /mnt/data
umount /mnt/data
losetup -j /srv/images/data.img
Attached by hand, so umount leaves it attached and only losetup -d releases it. A script that loops over images and forgets this runs out of loop devices rather than failing anywhere obvious. -j asks about one backing file, where losetup -a would answer about every loop device on the machine.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached, and the two numbers after it are the backing file's device and inode
/dev/loop3: [0053]:460583 (/srv/images/data.img)
Detach the loop device with the filesystem
mount -o loop /srv/images/data.img /mnt/data
umount /mnt/data
echo "still attached: $(losetup -j /srv/images/data.img | wc -l)"
umount releases a loop device that mount -o loop set up, which is the difference from the example above. The count is of loop devices backed by this one image, so it answers about the page's own disk rather than about everything the machine has attached.
Show output
still attached: 0
Seeing what is mounted
findmnt reads the same table mount prints and is easier to ask a question of. -n drops the header, -o picks columns and --target takes a path anywhere inside a filesystem rather than the mount point itself.
Look at one mount
mount -o loop /srv/images/data.img /mnt/data
mount | grep /mnt/data
mount on its own lists every filesystem including the kernel's own, so a grep is nearly always attached to it. Note the source it reports: the image file, rather than the loop device findmnt names.
Show output
/srv/images/data.img on /mnt/data type ext4 (rw,relatime)
Pick out the columns you want
mount -o loop /srv/images/data.img /mnt/data
findmnt -no SOURCE,FSTYPE,OPTIONS /mnt/data
-n drops the header and -o names the columns, which between them make the output safe to read in a script. The column names are the ones findmnt prints with no arguments.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
/dev/loop0 ext4 rw,relatime
Find which filesystem a file is on
mount -o loop /srv/images/data.img /mnt/data
findmnt --target /mnt/data/backups -no SOURCE,TARGET
--target accepts any path and walks up to the filesystem holding it. This is the question people reach df for, and findmnt answers it without the size columns in the way.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
/dev/loop0 /mnt/data
See the space as well as the mount
mount -o loop /srv/images/data.img /mnt/data
findmnt -D /mnt/data
-D adds the columns df would give, so one command answers both what is mounted and how full it is. The size is under the image's 32M because the journal and the inode tables are already spent.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
SOURCE FSTYPE SIZE USED AVAIL USE% TARGET
/dev/loop0 ext4 25.2M 68K 22.9M 0% /mnt/data
Ask whether a path is a mount point at all
mountpoint /mnt/data; echo "exit $?"
mount -o loop /srv/images/data.img /mnt/data
mountpoint /mnt/data; echo "exit $?"
mountpoint answers the one question and nothing else. The directory exists in both cases, which is why ls cannot tell them apart and a backup script writing to an unmounted target fills the root filesystem instead.
Show output
/mnt/data is not a mountpoint
exit 32
/mnt/data is a mountpoint
exit 0
Guard a script on the mount being up
if mountpoint -q /mnt/data; then echo "backup target is mounted"; else echo "not mounted, refusing to write"; fi
mount -o loop /srv/images/data.img /mnt/data
if mountpoint -q /mnt/data; then echo "backup target is mounted"; else echo "not mounted, refusing to write"; fi
-q silences the message and leaves the exit status, which is the form to put at the top of anything that writes to a mounted disk. Two lines of guard against filling the root filesystem with a backup nobody can find.
Show output
not mounted, refusing to write
backup target is mounted
Find the mount by its device
loop=$(losetup --find --show /srv/images/data.img)
mount "$loop" /mnt/data
findmnt -S "$loop"
-S selects by source where a bare path selects by target. Useful in the other direction from usual: you have a device name out of dmesg or lsblk and want to know where, if anywhere, it ended up.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
TARGET SOURCE FSTYPE OPTIONS
/mnt/data /dev/loop0 ext4 rw,relatime
Read the kernel's own copy of the table
mount -o loop /srv/images/data.img /mnt/data
grep /mnt/data /proc/mounts
/proc/mounts is where both commands get their answer, in the same five fields /etc/fstab uses. Worth knowing for a recovery shell with neither mount nor findmnt on the path.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
/dev/loop0 /mnt/data ext4 rw,relatime 0 0
Check the device behind a mount
loop=$(losetup --find --show /srv/images/data.img)
mount "$loop" /mnt/data
lsblk "$loop"
lsblk names the device rather than the filesystem, and its MOUNTPOINTS column closes the loop. Give it a device: run bare in a container it lists the host's block devices, which is nothing you can act on.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 32M 0 loop /mnt/data
List the files on a mounted filesystem
mount -o loop /srv/images/data.img /mnt/data
ls -l /mnt/data
An ordinary directory listing, which is the point: once mounted there is nothing special about the path. lost+found is 12K because mkfs preallocates its directory blocks.
Show output
total 14
drwxr-xr-x 2 root root 1024 Jun 15 10:00 backups
drwx------ 2 root root 12288 Jun 15 10:00 lost+found
-rw-r--r-- 1 root root 26 Jun 1 09:00 notes.txt
Options
-o takes a comma-separated list and no spaces. findmnt -o OPTIONS prints what ended up in force, which is not always what was asked for: the kernel adds its own defaults and refuses some combinations outright.
Mount read-only
mount -o loop,ro /srv/images/data.img /mnt/data
touch /mnt/data/new.txt; echo "exit $?"
ro is enforced by the kernel rather than by permissions, so root is refused as well. The form to use on anything you are inspecting after a failure, where writing to it would destroy the evidence.
Show output
touch: cannot touch '/mnt/data/new.txt': Read-only file system
exit 1
Refuse to run anything on it
mount -o loop,noexec /srv/images/data.img /mnt/data
cp /bin/true /mnt/data/prog
/mnt/data/prog; echo "exit $?"
noexec stops the kernel executing a file from this filesystem whatever its mode bits say. Status 126 is the shell's code for found but not runnable, which is worth telling apart from 127 for not found at all.
Show output
bash: line 3: /mnt/data/prog: Permission denied
exit 126
Apply the whole untrusted-media set
mount -o loop,nosuid,nodev,noexec /srv/images/data.img /mnt/data
findmnt -no OPTIONS /mnt/data
nosuid ignores the setuid bit, nodev ignores device nodes and noexec refuses execution. Together they are what to give a USB stick or a disk image of unknown provenance before looking inside it.
Show output
rw,nosuid,nodev,noexec,relatime
Change the options without unmounting
mount -o loop /srv/images/data.img /mnt/data
mount -o remount,ro /mnt/data
findmnt -no OPTIONS /mnt/data
remount alters a live mount in place, so open files stay open. A filesystem that goes read-only by itself has been remounted this way by the kernel after an I/O error, and the service on top of it usually notices second.
Show output
ro,relatime
Add an option to a mount that is already up
mount -o loop /srv/images/data.img /mnt/data
mount -o remount,noexec /mnt/data
findmnt -no OPTIONS /mnt/data
A remount replaces the option list rather than merging into it, so anything you want kept has to be named again. Here relatime survives because the kernel applies it by default, not because it was carried over.
Show output
rw,noexec,relatime
Find the remount that is refused
mount -o loop,ro /srv/images/data.img /mnt/data
mount -o remount,rw /mnt/data
-o loop,ro marks the loop device itself write-protected, not just the mount, and no remount can undo that from above. Detach and reattach without the ro instead.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
mount: /mnt/data: cannot remount /dev/loop0 read-write, is write-protected.
dmesg(1) may have more information after failed mount system call.
Ask the filesystem to go read-only on error
mount -o loop,errors=remount-ro /srv/images/data.img /mnt/data
findmnt -no OPTIONS /mnt/data
grep /mnt/data /proc/mounts
An ext4 option rather than a general one, and the setting behind a filesystem that turns read-only by itself after a disk error. The alternatives are continue, which carries on over a filesystem it knows is damaged, and panic.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
rw,relatime,errors=remount-ro
/dev/loop0 /mnt/data ext4 rw,relatime,errors=remount-ro 0 0
Write through instead of caching
mount -o loop,sync /srv/images/data.img /mnt/data
findmnt -no OPTIONS /mnt/data
sync makes every write reach the device before the call returns. It is slow enough to be worth avoiding on anything but removable media, where the alternative is a stick pulled out with half a file still in memory.
Show output
rw,relatime,sync
Stop recording access times
mount -o loop,noatime /srv/images/data.img /mnt/data
findmnt -no OPTIONS /mnt/data
relatime is the default and already writes an access time at most once a day. noatime drops the last of it, which is worth having on a filesystem full of small files being read constantly and worth nothing anywhere else.
Show output
rw,noatime
Tell the mount options from the filesystem options
mount -o loop /srv/images/data.img /mnt/data
findmnt -no FS-OPTIONS /mnt/data
OPTIONS is everything, FS-OPTIONS only what the filesystem driver itself took. The distinction matters when a mount reports ro and you need to know whether the kernel set it or the command line asked for it.
Show output
rw
Bind mounts and tmpfs
Not every mount comes from a device. A bind mount makes one directory appear at a second path, and tmpfs makes a filesystem out of memory. Both are ordinary entries in the same table.
Make a directory appear somewhere else
mount -o loop /srv/images/data.img /mnt/data
mount --bind /mnt/data/backups /mnt/backup
findmnt -no SOURCE,TARGET,FSTYPE /mnt/backup
ls /mnt/backup
The SOURCE column names the device and the subdirectory inside it in brackets. A bind mount is the way to expose one directory to a service that is confined to a different path, without copying anything or following a symlink.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
/dev/loop0[/backups] /mnt/backup ext4
site.tar
Make a bind mount read-only
mount -o loop /srv/images/data.img /mnt/data
mount --bind /mnt/data/backups /mnt/backup
mount -o remount,bind,ro /mnt/backup
findmnt -no TARGET,OPTIONS /mnt/backup
touch /mnt/backup/x; echo "exit $?"
--bind -o ro in one command does not work: the bind is made first and the options are applied to the original mount, so the copy comes up writable. The remount afterwards sets it, and the original at /mnt/data stays writable throughout.
Show output
/mnt/backup ro,relatime
touch: cannot touch '/mnt/backup/x': Read-only file system
exit 1
Mount a filesystem that lives in memory
mount -t tmpfs -o size=8M,mode=1777 tmpfs /mnt/backup
findmnt -no SOURCE,FSTYPE,SIZE /mnt/backup
stat -c "%A %n" /mnt/backup
tmpfs has no device, so the first argument is a name that shows up in the listing and means nothing else. size= is a cap rather than an allocation: nothing is taken from memory until something is written, and mode=1777 gives the mount point the sticky, world-writable permissions /tmp has.
Show output
tmpfs tmpfs 8M
drwxrwxrwt /mnt/backup
See how big a tmpfs really is
mount -t tmpfs -o size=8M tmpfs /mnt/backup
df -h /mnt/backup | tail -1
The full 8M is available, with none of the overhead an on-disk filesystem spends on journals and inode tables. Without size= a tmpfs defaults to half of RAM, which is rarely what anyone intends.
Show output
tmpfs 8.0M 0 8.0M 0% /mnt/backup
Move a mount to a different path
mount -o loop /srv/images/data.img /mnt/data
mount --move /mnt/data /mnt/backup
findmnt -no TARGET,SOURCE /mnt/backup
findmnt /mnt/data; echo "old path: $?"
--move relocates a live mount without unmounting it, so open files stay open and nothing notices. The old path goes back to being an empty directory.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
/mnt/backup /dev/loop0
old path: 1
Unmount a tree of mounts together
mount -o loop /srv/images/data.img /mnt/data
mount --bind /mnt/data /mnt/backup
umount -R /mnt/backup; echo "exit $?"
findmnt /mnt/backup; echo "gone $?"
-R unmounts everything underneath the path as well as the path itself. A bind mount nested inside another filesystem is the usual reason a plain umount reports the target is busy when nothing has a file open.
Show output
exit 0
gone 1
fstab
/etc/fstab holds the mounts the machine makes at boot, in six fields: what, where, type, options, dump and pass. An entry there also means mount /mnt/data works with no other arguments, which is the quickest way to test one before rebooting on it.
Mount using an entry from fstab
printf '/srv/images/data.img /mnt/data ext4 loop,ro 0 0\n' >> /etc/fstab
mount /mnt/data
findmnt -no SOURCE,TARGET,OPTIONS /mnt/data
The path is the only argument, because everything else came from the file. Always test an entry this way before rebooting: a filesystem that fails to mount at boot drops the machine to an emergency shell.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
/dev/loop0 /mnt/data ro,relatime
Read back the file you just added to
printf '/srv/images/data.img /mnt/data ext4 loop 0 0\n' >> /etc/fstab
cat /etc/fstab
Whitespace-separated fields, six of them. The trailing zeros are the dump flag, which nothing modern uses, and the fsck pass order, where 0 means never check, 1 is the root filesystem and 2 is everything else.
Show output
# /etc/fstab: static file system information.
/srv/images/data.img /mnt/data ext4 loop 0 0
Mount everything fstab asks for
printf '/srv/images/data.img /mnt/data ext4 loop 0 0\n' >> /etc/fstab
mount -a
findmnt -no TARGET,FSTYPE /mnt/data
mount -a is what the boot sequence runs, and running it by hand mounts anything in the file that is not already up. It skips entries marked noauto, which is how a rarely-used filesystem stays in the file without being mounted.
Show output
/mnt/data ext4
Check an fstab entry without acting on it
printf 'LABEL=tipsdata /mnt/data ext4 loop 0 0\n' >> /etc/fstab
findmnt --verify --verbose 2>/dev/null
--verify reads the file and reports what would go wrong, which is the check to run before a reboot you cannot easily undo. Here the label is unreachable at boot, because nothing attaches the loop device carrying it. The per-entry detail goes to standard output and the count of problems to standard error, so one of the two has to be redirected before the order they arrive in is settled.
Show output
/mnt/data
[ ] target exists
[ ] userspace options: loop
[E] unreachable on boot required source: LABEL=tipsdata
See the warning an entry earns without being wrong
printf '/srv/images/data.img /mnt/data ext4 loop 0 0\n' >> /etc/fstab
findmnt --verify 2>/dev/null; echo "exit $?"
A [W] rather than an [E]: this entry works, and --verify is pointing out that the source is a file rather than a block device. Worth reading the warnings as well as the errors, since a typo in a path produces one of each depending on whether the path exists.
Show output
/mnt/data
[W] non-bind mount source /srv/images/data.img is a directory or regular file
exit 0
When it will not mount, or will not unmount
mount gives the same message for several different problems, and umount gives one that is usually about a process rather than about the filesystem. Both are worth recognising on sight.
Mount something that has no filesystem on it
mount -o loop /srv/images/blank.img /mnt/data
blank.img is 16M of zeros. This is also the message for a filesystem type the kernel has no driver for, for a corrupted superblock and for an option the driver rejected, so it narrows nothing down on its own; blkid answering nothing is the quickest way to tell the first case from the rest.
Show output
Your output will differ: the loop device number depends on what else on this machine has one attached
mount: /mnt/data: wrong fs type, bad option, bad superblock on /dev/loop0, missing codepage or helper program, or other error.
dmesg(1) may have more information after failed mount system call.
Mount onto a directory that is not there
mount -o loop /srv/images/data.img /mnt/nowhere
mount does not create the mount point. A missing directory is worth ruling out first, since the message for it is clear where the one above is not.
Show output
mount: /mnt/nowhere: mount point does not exist.
dmesg(1) may have more information after failed mount system call.
Mount the same image twice
mount -o loop /srv/images/data.img /mnt/data
mount -o loop /srv/images/data.img /mnt/data
Refused, and the exit status is 1 rather than the 32 the failures above give. Mounting the same filesystem at a second path is allowed; mounting it twice at the same one is not.
Show output
mount: /mnt/data: /srv/images/data.img is already mounted.
Unmount by device instead of by path
loop=$(losetup --find --show /srv/images/data.img)
mount "$loop" /mnt/data
umount "$loop"; echo "exit $?"
Either name works, and the device is the one to use when the mount point has been renamed out from under the mount. umount takes no -t, so there is no way to unmount everything of one type.
Show output
exit 0
Unmount something that was never mounted
umount /mnt/data; echo "exit $?"
Status 32 again, the same one a busy target gives, so a script cannot tell the two apart from the status alone. mountpoint -q first is the way to make the difference visible.
Show output
umount: /mnt/data: not mounted.
exit 32
Find out why a umount says the target is busy
mount -o loop /srv/images/data.img /mnt/data
exec 3< /mnt/data/notes.txt
umount /mnt/data; echo "exit $?"
fuser -mv /mnt/data 2>&1 >/dev/null
A single open file descriptor is enough. fuser -m names what is holding the filesystem, and lsof will too; -f on the umount is not the answer and does not apply to a local filesystem at all.
Show output
umount: /mnt/data: target is busy.
exit 32
USER PID ACCESS COMMAND
/mnt/data: root mount /mnt/data
root f.... bash
Detach a busy filesystem anyway
mount -o loop /srv/images/data.img /mnt/data
exec 3< /mnt/data/notes.txt
umount -l /mnt/data; echo "exit $?"
findmnt /mnt/data; echo "findmnt exit $?"
-l takes the filesystem out of the directory tree immediately and cleans it up when the last user lets go. The holder keeps its descriptor and notices nothing, so this frees the mount point without freeing the device.
Show output
exit 0
findmnt exit 1
Unmount with the working directory inside
mount -o loop /srv/images/data.img /mnt/data
cd /mnt/data
umount /mnt/data; echo "exit $?"
A shell sitting in the directory counts as a user of it, and this is the commonest cause of the message by a long way. cd out and try again before looking for anything more interesting.
Show output
umount: /mnt/data: target is busy.
exit 32