6 of 8

Linux FilesystemLesson 6 of 8

Mounts: attach and detach filesystems

See how disks join the tree, then build, mount, remount, bind and unmount filesystems safely on a file-backed disk.

  • findmnt
  • lsblk
  • blkid
  • mount
  • umount
  • mkfs.ext4
  • losetup
  • fstab

40 min6 exercises

After this lesson you can

  • Read the mount table and say which device and options back any path.
  • Create a filesystem inside a file and mount it, read-only or read-write.
  • Use tmpfs and bind mounts, and unmount a busy target.
  • Write an /etc/fstab entry and verify it before the next boot.

Disks join the tree at a mount point

There are no drive letters. A filesystem (the structure on a disk that holds directories and files) is attached to a directory in the existing tree. That directory is the mount point. After mounting, the directory shows the root of the attached filesystem; everything below the mount point, including what was in the directory before, is hidden until you unmount.

Three words are easy to mix up:

TermMeaningExample
DeviceSomething that stores blocks/dev/sda2
FilesystemThe format on itext4, xfs, btrfs
Mount pointThe directory it appears at/, /home, /mnt/data

Read the mount table

findmnt shows what is mounted, as a tree:

findmnt --real
TARGET       SOURCE     FSTYPE OPTIONS
/            /dev/sda2  ext4   rw,relatime,errors=remount-ro
└─/boot/efi  /dev/sda1  vfat   rw,relatime,fmask=0077,dmask=0077

--real hides kernel pseudo-filesystems such as /proc and /sys. Ask about one path to learn what backs it:

findmnt /home
TARGET SOURCE    FSTYPE OPTIONS
/      /dev/sda2 ext4   rw,relatime,errors=remount-ro

findmnt reports the mount that contains the path. Here /home is not a separate mount, so the answer is /.

mountpoint answers yes or no, which is handy in scripts:

mountpoint /
mountpoint /tmp
/ is a mountpoint
/tmp is not a mountpoint

Devices

lsblk lists block devices and how they nest:

lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
NAME   SIZE TYPE FSTYPE MOUNTPOINTS
sda    238G disk
├─sda1 512M part vfat   /boot/efi
└─sda2 237G part ext4   /

blkid prints the identity of a filesystem, including the UUID that fstab should use:

sudo blkid /dev/sda2
/dev/sda2: UUID="a1f2c3d4-5b6e-4f70-8a91-0b2c3d4e5f60" BLOCK_SIZE="4096" TYPE="ext4"

A safe place to practise

Mounting is the part of this skill that can lose data, because the commands that format and mount take a device name and do exactly what they are told. Here you never touch a real disk. You make a file act as a disk.

Make a 64 MiB file and format it:

cd ~/lab
truncate -s 64M disk.img
mkfs.ext4 -q -L labdisk disk.img

Mount it. The loop option attaches the file to a loop device, which makes a file look like a disk:

sudo mkdir -p /mnt/labdisk
sudo mount -o loop disk.img /mnt/labdisk
findmnt /mnt/labdisk
TARGET       SOURCE     FSTYPE OPTIONS
/mnt/labdisk /dev/loop0 ext4   rw,relatime
df -h /mnt/labdisk
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0       56M   24K   52M   1% /mnt/labdisk

Of the 64 MiB, 56M is usable: the rest is the filesystem’s own structures. A new ext4 filesystem always contains a lost+found directory that only root can open:

ls -la /mnt/labdisk
total 24
drwxr-xr-x 3 root root  4096 Nov  3 10:50 .
drwxr-xr-x 7 root root  4096 Nov  3 10:50 ..
drwx------ 2 root root 16384 Nov  3 10:50 lost+found

The mount point is owned by root, so you need sudo to write there. That is a property of the filesystem’s root directory, and it goes with the filesystem wherever it is mounted.

sudo touch /mnt/labdisk/hello
sudo mkdir /mnt/labdisk/data

The loop device behind it:

losetup -j ~/lab/disk.img
/dev/loop0: [65024]:795186 (/home/alex/lab/disk.img)

Mount options

Options change how the filesystem behaves, and -o takes a comma-separated list.

OptionEffect
ro / rwRead-only or read-write
noexecPrograms on it cannot be run
nosuidSetuid bits are ignored
nodevDevice files are ignored
noatimeDo not update access times (fewer writes)
remountChange the options of an existing mount

noexec,nosuid,nodev is the usual hardening for /tmp and for removable media.

remount changes options without unmounting, which is how you protect a disk while you inspect it:

sudo mount -o remount,ro /mnt/labdisk
sudo touch /mnt/labdisk/x
touch: cannot touch '/mnt/labdisk/x': Read-only file system
sudo mount -o remount,rw /mnt/labdisk

tmpfs and bind mounts

Two kinds of mount need no disk at all.

tmpfs is a filesystem in memory. Fast, size-limited, and empty after a reboot:

sudo mkdir -p /mnt/ram
sudo mount -t tmpfs -o size=8m tmpfs /mnt/ram
df -h /mnt/ram
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           8.0M     0  8.0M   0% /mnt/ram

A bind mount shows an existing directory at a second location. Both paths are the same files:

sudo mkdir -p /srv/view
sudo mount --bind /mnt/labdisk/data /srv/view
findmnt /srv/view
TARGET    SOURCE                FSTYPE OPTIONS
/srv/view /dev/loop0[/data]     ext4   rw,relatime

The [/data] shows that only the data directory is exposed, not the whole device. This is how containers get access to a host directory.

sudo touch /srv/view/inside
ls /mnt/labdisk/data
inside

Unmount

sudo umount /srv/view
sudo umount /mnt/labdisk

umount takes the mount point (or the device) and flushes pending writes first. Always unmount before you remove a disk or delete its image.

It refuses when something is using the filesystem. A shell whose working directory is inside it counts:

cd /mnt/ram
sudo umount /mnt/ram
umount: /mnt/ram: target is busy.

Find who is holding it:

cd ~
sudo fuser -vm /mnt/ram

Move your shell out, close or stop what fuser reports, and try again. umount -l (lazy) detaches the mount from the tree immediately and cleans up later. It hides the problem rather than solving it, so use it as a last resort.

Detach the loop device if it is still attached (umount normally does this for you):

sudo losetup -d /dev/loop0

Make a mount permanent: /etc/fstab

Mounts made by hand vanish at reboot. /etc/fstab lists the ones to recreate. Each line has six fields:

# source                                   target       type  options            dump pass
UUID=a1f2c3d4-5b6e-4f70-8a91-0b2c3d4e5f60  /            ext4  errors=remount-ro  0    1
UUID=9C4F-2A71                             /boot/efi    vfat  umask=0077         0    1
/home/alex/lab/disk.img                    /mnt/labdisk ext4  loop,noauto,nofail 0    0
FieldMeaning
1What to mount. Prefer UUID= over /dev/sdb1, because device names can change between boots
2Where to mount it
3Filesystem type
4Options, comma-separated
5dump backup flag, almost always 0
6Order of fsck at boot: 1 for /, 2 for other disks, 0 to skip

Two options protect you from a broken fstab:

  • nofail lets the boot continue if the disk is missing. Without it, a missing data disk can drop the machine to an emergency shell.
  • noauto skips the mount at boot. You mount it explicitly with mount /mnt/labdisk.
findmnt --verify
/mnt/labdisk
   [W] non-bind mount source /home/alex/lab/disk.img is a directory or regular file

0 parse errors, 0 errors, 1 warning

A warning is fine here: a regular file is exactly what a loop image is. With the entry in place, the short form works:

sudo mount /mnt/labdisk

mount looks the target up in fstab and fills in the rest.

Clean up

sudo umount /mnt/ram
sudo umount /mnt/labdisk
sudo sed -i '\|/mnt/labdisk|d' /etc/fstab
rm ~/lab/disk.img

The sed command deletes the line containing /mnt/labdisk from fstab. Check the file afterwards with cat /etc/fstab.

Practice

0 of 6 done

Do these on your own system. They get harder. Check each result, then tick it off.

  1. Warm-up

    What backs the root directory?

    Print the source device, filesystem type and mount options of / on one line, with no column headings.

    Check your result

    One line such as:

    /dev/sda2 ext4 rw,relatime,errors=remount-ro
    Hint

    findmnt can select columns with -o and drop the header with -n.

    Solution
    findmnt -n -o SOURCE,FSTYPE,OPTIONS /
  2. Warm-up

    Map disks to mount points

    List the block devices on your system with their size, type, filesystem and mount points. Identify which partition is mounted at /.

    Check your result

    A tree such as sda (type disk) with children sda1 and sda2 (type part). The row whose MOUNTPOINTS is / is your root filesystem. On a virtual machine the device may be vda.

    Hint

    lsblk -o takes a list of column names.

    Solution
    lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
  3. Practice

    Build and mount a disk

    Create a 64 MiB file ~/lab/disk.img, put an ext4 filesystem labelled labdisk in it, and mount it at /mnt/labdisk. Create a file on it, show its usage with df, and unmount it. Leave nothing mounted and no loop device attached.

    Check your result

    While mounted:

    df -h /mnt/labdisk
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/loop0       56M   24K   52M   1% /mnt/labdisk

    After unmounting, findmnt /mnt/labdisk prints nothing, and losetup -j ~/lab/disk.img prints nothing.

    Hint

    truncate makes the file, mkfs.ext4 formats it, and mount -o loop attaches it to a loop device for you.

    Solution
    truncate -s 64M ~/lab/disk.img
    mkfs.ext4 -q -L labdisk ~/lab/disk.img
    sudo mkdir -p /mnt/labdisk
    sudo mount -o loop ~/lab/disk.img /mnt/labdisk
    sudo touch /mnt/labdisk/hello
    df -h /mnt/labdisk
    sudo umount /mnt/labdisk
  4. Practice

    Switch a mounted disk to read-only

    With labdisk mounted, remount it read-only without unmounting. Prove that a write is refused, then put it back to read-write and prove a write works.

    Check your result
    touch: cannot touch '/mnt/labdisk/x': Read-only file system

    After the second remount the same touch succeeds silently.

    Hint

    mount -o remount,ro TARGET.

    Solution
    sudo mount -o remount,ro /mnt/labdisk
    sudo touch /mnt/labdisk/x
    sudo mount -o remount,rw /mnt/labdisk
    sudo touch /mnt/labdisk/x
  5. Practice

    Show a directory in two places

    Create ~/lab/shared/data and an empty ~/lab/view. Make ~/lab/view show the contents of ~/lab/shared/data. Create a file through view and confirm it appears in data. Then undo the mount.

    Check your result
    ls ~/lab/shared/data
    inside
    Hint

    A bind mount takes an existing directory as its source: mount --bind SOURCE TARGET.

    Solution
    mkdir -p ~/lab/shared/data ~/lab/view
    sudo mount --bind ~/lab/shared/data ~/lab/view
    touch ~/lab/view/inside
    ls ~/lab/shared/data
    sudo umount ~/lab/view
  6. Challenge

    Make the mount reproducible

    Add one line to /etc/fstab so that sudo mount /mnt/labdisk works with no other arguments, using your image file. The entry must not try to mount at boot and must not stop the boot if it fails. Check it with the tool that validates fstab, mount it by that short command, unmount it, and finally remove the line again.

    Check your result
    sudo mount /mnt/labdisk
    findmnt /mnt/labdisk
    TARGET       SOURCE     FSTYPE OPTIONS
    /mnt/labdisk /dev/loop0 ext4   rw,relatime

    findmnt --verify may warn that the source is a regular file. That is expected for an image.

    Hint

    Six fields: source, target, type, options, dump, pass. The options loop, noauto and nofail do what you need.

    Solution
    echo "$HOME/lab/disk.img /mnt/labdisk ext4 loop,noauto,nofail 0 0" | sudo tee -a /etc/fstab
    findmnt --verify
    sudo mount /mnt/labdisk
    findmnt /mnt/labdisk
    sudo umount /mnt/labdisk
    sudo sed -i '\|/mnt/labdisk|d' /etc/fstab