DevOps.Academy
CoursesCurriculumPricing

    Loading…

    ↑ ↓ move · ↵ open · Ctrl K anywhere

    ◔My learningSign in
    DevOps.Academy

    Free, hands-on DevOps lessons. Made with care in India.

    Learn

    All coursesLinux roadmapCurriculumMy learning

    Academy

    PricingCertificates

    Legal

    PrivacyTermsContact

    devops.rajeev.pro

    Linux & BashLesson 11 of 16
    Your progress · 0%
    On this page
    1. The storage stack
    2. Filesystems and inodes
    3. Adding a new disk
    4. Mounting: now and at every boot
    5. LVM: storage you can grow
    6. Swap
    7. Checking and repairing
    ↖ Course roadmap
    Lesson 11 · Disks & filesystems

    Disks and filesystems: add, mount, grow and repair

    How disks, partitions, filesystems and mount points fit together, how to add a new disk and mount it permanently with fstab, grow storage with LVM, add swap, and check a filesystem safely.

    40 min read · intermediate · hands-on

    By the end of this lesson you'll be able to

    0 of 6 complete

    The storage stack

    Linux storage is layers. Once you can name the layer you're looking at, every command makes sense:

    Disk, partition, (LVM), filesystem, mount point. Most problems live at one layer.© Diagram: DevOps Academy

    Disk, partition, (LVM), filesystem, mount point. Most problems live at one layer.© Diagram: DevOps Academy
    $ lsblk                                  # disks and partitions, as a tree
    NAME         MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
    nvme0n1      259:0    0   40G  0 disk
    ├─nvme0n1p1  259:1    0 39.9G  0 part /
    └─nvme0n1p15 259:2    0  106M  0 part /boot/efi
    nvme1n1      259:3    0   50G  0 disk
    $ lsblk -f                               # plus filesystem type and UUID
    $ df -Th                                 # mounted filesystems: type, size, use
    $ findmnt /                              # how one mount point is mounted, with options
    TARGET SOURCE         FSTYPE OPTIONS
    /      /dev/nvme0n1p1 ext4   rw,relatime,discard,errors=remount-ro
    
    df -Th
    • dfdisk space per filesystem

    Here nvme1n1 is a new, empty 50 GB disk: no partitions, nothing mounted. Disk names are sda, sdb on many machines, vda on some VMs and nvme0n1 on newer hardware and cloud instances.

    Filesystems and inodes

    A filesystem organises a partition into files and folders. The two you'll meet on servers:

    ext4XFS
    Default onUbuntu, DebianRHEL, Rocky, Amazon Linux
    Grow while mountedyesyes
    Shrinkyes (unmounted)no
    Check / repaire2fsck (fsck)xfs_repair
    Tunetune2fsxfs_admin

    Every file has an inode: a record of its owner, permissions, size and where its data is. Its name lives in the folder; the inode holds the rest (you saw inode numbers with ls -i in the Working with files lesson). On ext4 the number of inodes is fixed when the filesystem is made:

    $ df -i /
    Filesystem      Inodes  IUsed   IFree IUse% Mounted on
    /dev/nvme0n1p1 2621440 2621440       0  100% /
    
    df -i /
    • dfdisk space per filesystem

    That's a disk that is "full" with gigabytes free: millions of tiny files (sessions, cache, mail) used every inode. Find the folders holding the most entries:

    $ sudo du --inodes -x / 2>/dev/null | sort -n | tail -5    # inode use per folder, biggest last
    
    sudo du --inodes -x / 2>/dev/null | sort -n | tail -5
    • sudorun the next command as root
    • dudisk space used by files
    • |pipe: send output to the next command
    • sortsort lines
    • -nsort as numbers
    • tailshow the last lines

    Adding a new disk

    $ sudo parted /dev/nvme1n1 --script mklabel gpt mkpart data ext4 0% 100%   # one partition, whole disk
    $ lsblk /dev/nvme1n1
    NAME      MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
    nvme1n1   259:3    0  50G  0 disk
    └─nvme1n1p1 259:4  0  50G  0 part
    $ sudo mkfs.ext4 -L data /dev/nvme1n1p1     # create the filesystem (-L sets a label)
    $ sudo mkdir -p /data
    $ sudo mount /dev/nvme1n1p1 /data           # mount it now
    $ df -h /data
    
    sudo parted /dev/nvme1n1 --script mklabel gpt mkpart data ext4 0% 100%
    • sudorun the next command as root
    sudo mkdir -p /data
    • mkdirmake a directory
    • -pcreate missing parents, no error if it exists
    df -h /data
    • dfdisk space per filesystem
    • -hhuman-readable sizes

    fdisk (MBR or GPT) and gdisk (GPT) do the same job interactively. Use GPT for new disks: MBR can't handle disks over 2 TB.

    Check the disk name twice

    mkfs and parted destroy whatever is on the device you name. Run lsblk first, confirm the size and that nothing is mounted, and copy the exact name. Formatting nvme0n1p1 instead of nvme1n1p1 erases the operating system.

    Mounting: now and at every boot

    mount lasts until the next reboot. To mount at every boot, add a line to /etc/fstab, using the filesystem's UUID (device names can change when disks are added):

    $ sudo blkid /dev/nvme1n1p1
    /dev/nvme1n1p1: LABEL="data" UUID="3f9c2a1e-8b7d-4c1a-9e2f-6a5b4c3d2e1f" BLOCK_SIZE="4096" TYPE="ext4"
    
    sudo blkid /dev/nvme1n1p1
    • sudorun the next command as root
    # /etc/fstab
    # <what>                                    <where>  <type>  <options>          <dump> <fsck order>
    UUID=3f9c2a1e-8b7d-4c1a-9e2f-6a5b4c3d2e1f   /data    ext4    defaults,nofail    0      2
    
    FieldMeans
    whatUUID=… (or LABEL=data)
    wherethe mount point folder
    typeext4, xfs, swap…
    optionsdefaults; nofail boots even if this disk is missing; noatime saves writes
    dump0 (nobody uses dump any more)
    fsck order1 for /, 2 for other filesystems, 0 never check
    $ sudo umount /data
    $ sudo mount -a                  # mount everything in fstab now: errors show here, not at boot
    $ sudo findmnt --verify          # check fstab for mistakes
    $ findmnt /data
    
    sudo umount /data
    • sudorun the next command as root
    In production: never reboot on an untested fstab

    A wrong /etc/fstab line can stop the boot and drop the server into emergency mode, which on a cloud VM often means no SSH at all. Always run sudo mount -a and findmnt --verify after editing it, and use nofail for data disks, so a missing disk doesn't block the boot.

    umount fails with "target is busy" while something uses the mount: find what with sudo lsof +D /data or sudo fuser -vm /data, and stop it first.

    LVM: storage you can grow

    With plain partitions, a full disk means moving data. LVM (Logical Volume Manager) adds a flexible layer: disks become physical volumes (PV), pooled into a volume group (VG), from which you cut logical volumes (LV). Need more space? Add a disk to the group and grow the volume, while it's mounted.

    $ sudo pvcreate /dev/nvme1n1                  # 1. make the disk a physical volume
    $ sudo vgcreate data /dev/nvme1n1             # 2. a volume group called data
    $ sudo lvcreate -n app -L 20G data            # 3. a 20 GB logical volume: /dev/data/app
    $ sudo mkfs.ext4 /dev/data/app && sudo mount /dev/data/app /srv/app
    $ sudo pvs && sudo vgs && sudo lvs            # what you have, layer by layer
    $ sudo lvextend -r -L +10G /dev/data/app      # later: grow by 10 GB, filesystem included
    $ sudo vgextend data /dev/nvme2n1             # out of room? add another disk to the group
    
    sudo pvcreate /dev/nvme1n1
    • sudorun the next command as root
    sudo mkfs.ext4 /dev/data/app && sudo mount /dev/data/app /srv/app
    • &&run the next command only if this one worked

    -r on lvextend resizes the filesystem in the same step; without it, the volume grows but the filesystem doesn't, and df shows no change. Cloud disks often grow without LVM too: resize the disk in the console, then sudo growpart /dev/nvme0n1 1 and sudo resize2fs /dev/nvme0n1p1 (xfs_growfs / for XFS).

    Swap

    Swap is disk space used as overflow memory. It's slow, but it lets a server survive a memory spike instead of having the kernel kill a process. A small swap file is enough for most servers:

    $ sudo fallocate -l 2G /swapfile
    $ sudo chmod 600 /swapfile                    # only root may read it: it holds memory contents
    $ sudo mkswap /swapfile && sudo swapon /swapfile
    $ swapon --show
    NAME      TYPE SIZE USED PRIO
    /swapfile file   2G   0B   -2
    $ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab   # keep it after reboot
    
    sudo fallocate -l 2G /swapfile
    • sudorun the next command as root
    sudo chmod 600 /swapfile
    • chmodchange permissions
    sudo mkswap /swapfile && sudo swapon /swapfile
    • &&run the next command only if this one worked
    echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
    • echoprint text
    • |pipe: send output to the next command
    • teewrite input to a file and pass it on
    • -aappend

    Constant swapping (free -h showing swap use growing, high %wa in top) means the server needs more RAM or a lighter workload, not more swap.

    Checking and repairing

    $ sudo umount /data                            # never check a mounted filesystem
    $ sudo e2fsck -f /dev/nvme1n1p1                # ext4 (fsck picks the right tool too)
    $ sudo xfs_repair /dev/data/app                # XFS
    $ sudo tune2fs -l /dev/nvme1n1p1 | grep -i "mount count\|state"   # ext4 health info
    
    sudo umount /data
    • sudorun the next command as root
    sudo tune2fs -l /dev/nvme1n1p1 | grep -i "mount count\|state"
    • |pipe: send output to the next command
    • grepfind lines that match a pattern
    • -iignore upper/lower case

    Filesystems mounted at boot (/) are checked automatically when needed. For a damaged root filesystem you boot from a rescue image, or on a cloud VM attach the disk to another instance and check it there. dmesg and journalctl -k show disk errors (I/O error, EXT4-fs error): on physical hardware, that's often the disk itself failing, and the fix is a backup and a new disk.

    ⌘
    Mini mission

    Add a data disk the safe way

    A new empty disk is attached to the server for the app's uploads. Create a filesystem on it, mount it at /data so it survives reboots, and prove the fstab line works before any reboot. Practise on a file-backed disk so nothing real is at risk.

    Input: A Linux VM where you have sudoOutput: /data mounted from /etc/fstab
    Reveal one safe solution
    $ truncate -s 1G ~/disk.img                          # a fake 1 GB disk, safe to practise on
    $ LOOP=$(sudo losetup -f --show ~/disk.img) && echo $LOOP
    /dev/loop0
    $ sudo mkfs.ext4 -q -L data $LOOP
    $ UUID=$(sudo blkid -s UUID -o value $LOOP) && echo $UUID
    3f9c2a1e-8b7d-4c1a-9e2f-6a5b4c3d2e1f
    $ sudo mkdir -p /data
    $ echo "UUID=$UUID /data ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab
    $ sudo mount -a && sudo findmnt --verify && findmnt /data
    TARGET SOURCE     FSTYPE OPTIONS
    /data  /dev/loop0 ext4   rw,relatime
    $ echo "uploads work" | sudo tee /data/test.txt
    
    LOOP=$(sudo losetup -f --show ~/disk.img) && echo $LOOP
    • &&run the next command only if this one worked
    • echoprint text
    sudo mkfs.ext4 -q -L data $LOOP
    • sudorun the next command as root
    sudo mkdir -p /data
    • mkdirmake a directory
    • -pcreate missing parents, no error if it exists
    echo "UUID=$UUID /data ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab
    • |pipe: send output to the next command
    • teewrite input to a file and pass it on
    • -aappend

    mount -a mounting /data from the fstab line is your proof it will work at boot. On a real disk, skip truncate and losetup and use its name from lsblk instead. To clean up the practice: sudo umount /data, remove the line from /etc/fstab, and sudo losetup -d /dev/loop0.

    Try it yourself

    0 of 6 steps done

    Run each task in your own account or terminal, then tick it off.

    Knowledge check

    Quick check

    Question 1 of 5

    Why put UUID=… instead of /dev/sdb1 in /etc/fstab?

    Go deeper

    Official reading for this lesson

    • Docslsblk(8) manualUbuntu manpages ↗
    • Docsfstab(5): the format of /etc/fstabUbuntu manpages ↗
    • Docslvm(8): an overview of LVMUbuntu manpages ↗
    • Docslvextend(8): grow a logical volumeUbuntu manpages ↗
    • GuideLPIC-1 objectives 102.1, 104.1, 104.2 and 104.3Linux Professional Institute ↗

    Or get every quiz answer right and it completes itself.

    ← PreviousPackages: install, update and trust softwareNext lesson →How Linux boots, and what to do when it does not