Chapter 4. Filesystem Maintenance
Using Disks and Filesystems
|
Display available space on mounted filesystems. |
|
List disks and other block devices. |
|
Make a disk partition accessible. |
|
Unmount a disk partition (make it inaccessible). |
|
Check a disk partition for errors. |
Linux systems can have multiple disks or partitions. In casual conversation, these are variously called devices, filesystems, volumes, even directories. I’ll try to be more precise.
A disk is a mass storage device, which may be divided into partitions that act as independent devices. Disks and partitions are represented on Linux systems as special files in the directory /dev. For example, /dev/sda7 could be a partition on your hard drive. Some common devices in /dev are:
sda |
First block device, such as SCSI, SATA, or USB hard drives; partitions are sda1, sda2, …. |
sdb |
Second block device; partitions are sdb1, sdb2, …. Likewise for sdc, sdd, etc. |
md0 |
First RAID device; partitions are md0p1, md0p2, …. Likewise for md1, md2, etc. |
nvme0n1 |
First NVMe SSD device; partitions are nvme0n1p1, nvme0n1p2, …. Likewise for nvme1n1, nvme2n1, etc. The second integer, like the 1 in nvme0n1p2, is called the namespace ID, and most users can ignore it. |
Before a partition can hold files, it is formatted by a program that creates a filesystem on it (see “Creating and Modifying Filesystems”). A filesystem defines how files are represented; examples are ext4 (a Linux journaling filesystem) and NTFS (a Microsoft Windows filesystem). Formatting is generally done for you when you install Linux.
After creating a filesystem, make it available by mounting its partition on an empty directory.1 For example, if you mount a Windows filesystem on a directory /mnt/win, it becomes part of your system’s directory tree, and you can create and edit files like /mnt/win/myfile.txt. Mounting generally happens automatically at boot time. You can also unmount partitions to make them inaccessible via the filesystem for maintenance.
df |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
df [options] [disk devices | files | directories] |
The df
(disk free) command shows you the size, used space, and free
space on a given disk partition. If you supply a file or directory,
df
describes the disk device on which that file or directory
resides. With no arguments, df
reports on all mounted
filesystems:
→ df Filesystem 1k-blocks Used Avail Use% Mounted on /dev/sda 1011928 225464 735060 24% / /dev/sda9 521748 249148 246096 51% /var /dev/sda8 8064272 4088636 3565984 54% /usr /dev/sda10 8064272 4586576 3068044 60% /home
The df
command may list all sorts of devices besides disks. To limit
the display to disks, try these options (and create an alias if it’s
helpful):
→ df -h -x tmpfs -x devtmpfs -x squashfs
Useful options
|
List sizes in KB (the default). |
|
List sizes in MB. |
|
Display sizes in blocks of N bytes. (Default = 1024) |
|
Print human-readable output and choose the most appropriate unit for each size. For example, if your two disks have 1 gigabyte and 25 KB free, respectively, |
|
Display only local filesystems, not networked filesystems. |
|
Include the filesystem type ( |
|
Display only filesystems of the given type. |
|
Don’t display filesystems of the given type. |
|
Inode mode. Display total, used, and free inodes for each filesystem, instead of disk blocks. When all inodes on a filesystem are used, the filesystem is “full” even if free disk space remains. |
lsblk |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
lsblk [options] [devices] |
The lsblk
command lists the mass storage devices,
known as block devices, available on a Linux system, such as
hard disks, SSDs, and RAM disks.
→ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 20G 0 disk ├─sda1 8:1 0 1M 0 part ├─sda2 8:2 0 513M 0 part /boot/efi ├─sda3 8:3 0 19.5G 0 part / sdb 8:80 0 7.6G 0 disk └─sdb1 8:81 1 7.6G 0 part /mnt/usb-key
The output shows a hard drive at /dev/sda with three partitions, and
a USB thumb drive at /dev/sdb with a single partition. lsblk
has a
ton of formatting options and can limit itself to particular devices.
→ lsblk -o NAME,SIZE /dev/sda NAME SIZE sda 20G ├─sda1 1M ├─sda2 513M └─sda3 19.5G
Useful options
|
Display a simple list instead of a tree. |
|
Show all block devices, including those normally hidden. |
|
Add information about the filesystems on each device. |
|
Print only the given columns, which you provide as a comma-separated list. View the available columns with |
|
Print the list in JSON format for easy processing by programs. |
mount |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
mount [options] [device | directory] |
The mount
command makes a partition accessible. Most commonly it
handles disk drives (say, /dev/sda1) and removable media (e.g., USB
keys), making them accessible via an existing directory (say,
/mnt/mydir):
→ sudo mkdir /mnt/mydir → ls /mnt/mydir→ sudo mount /dev/sda1 /mnt/mydir → ls /mnt/mydir file1 file2 file3
Notice it’s empty
→ df /mnt/mydir Filesystem 1K-blocks Used Avail Use% Mounted on /dev/sda1 1011928 285744 674780 30% /mnt/mydir
Files on the mounted partition
mount
has many uses; I discuss only the most basic. In most
common cases, mount
reads the file /etc/fstab (filesystem table,
pronounced “F S tab”) to learn how to
mount a desired disk. For example, if you run mount /usr
, the
mount
command looks up “/usr” in /etc/fstab, whose line might look
like this:
/dev/sda8 /usr ext4 defaults 1 2
Here mount
learns that device /dev/sda8 should be mounted on
/usr as a Linux ext4-formatted filesystem with default options.
Mount it with either of these commands:
→ sudo mount /dev/sda8→ sudo mount /usr
By device
By directory
mount
is run typically by the superuser, but common removable
devices like USB keys and DVDs often can be mounted and unmounted by
any user.
Useful options
|
Specify the type of filesystem, such as |
|
List all mounted filesystems; works with |
|
Mount all filesystems listed in /etc/fstab. Ignores entries that include the |
|
Mount the filesystem read-only (see the manpage for disclaimers). |
umount |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
umount [options] [device | directory] |
umount
does the opposite of mount
: it makes a
disk partition unavailable via the filesystem.2 For instance, if you’ve mounted
a USB thumb drive, umount it before you unplug it:
→ umount "/media/smith/My Vacation Photos"
Always unmount any removable medium before ejecting it, particularly if it’s writable, or you risk damage to its filesystem. To unmount all mounted devices:
→ sudo umount -a
Don’t unmount a filesystem that’s in use; in fact, the umount
command refuses to do so for safety reasons.
fsck |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
fsck [options] [devices] |
The fsck
(filesystem check) command validates a Linux
disk filesystem and, if requested, repairs errors found on it. fsck
runs automatically when your system boots, or manually. In general,
unmount a device before checking it, so no other programs are
operating on it at the same time:
→ sudo umount /dev/sda10 → sudo fsck -f /dev/sda10 Pass 1: Checking inodes, blocks, and sizes Pass 2: Checking directory structure Pass 3: Checking directory connectivity Pass 4: Checking reference counts Pass 5: Checking group summary information /home: 172/1281696 files (11.6% non-contiguous), ...
You cannot use fsck
to fix your root filesystem while your system is
running normally. Boot first on a Linux USB thumb drive or other
rescue media, then run fsck
.
fsck
is a frontend for a set of filesystem-checking commands found
in /sbin, with names beginning “fsck”. Only certain types of
filesystems are supported; list them with the command:
→ ls /sbin/fsck.* | cut -d. -f2 | column cramfs ext3 fat hfsplus msdos ext2 ext4 hfs minix vfat
Useful options
|
Check all disks listed in /etc/fstab, in order. |
|
Force |
|
Print a description of the checking that would be done, but exit without performing any checking. |
|
Fix errors interactively, prompting before each fix. |
|
Fix errors automatically (use only if you really know what you’re doing; if not, you can seriously mess up a filesystem). |
Creating and Modifying Filesystems
|
Format (create a filesystem on) a disk partition. |
|
Grow or shrink a disk partition. |
|
Change the volume label on a disk partition. |
Disk-related operations like partitioning and formatting can be
complex at the command line. In general, for
anything more complicated than formatting a single partition, I
recommend using a graphical application such as gparted
. Honestly, it’s easier and less error-prone.
Nevertheless, I still run a few operations at the command line that
are quick and easy. One is listing the partitions of a storage device
like /dev/sda with fdisk
:
→ sudo fdisk -l /dev/sda Disk /dev/sda: 20 GiB, 21474836480 bytes, ... ⋮ Device Start End Sectors Size Type /dev/sda1 2048 4095 2048 1M BIOS boot /dev/sda2 4096 1054719 1050624 513M EFI System /dev/sda3 1054720 41940991 40886272 19.5G Linux
→ sudo parted /dev/sda -- print
Another is exporting the partition table of a storage device for safekeeping. (Store it on a USB thumb drive or other device, not the disk you’re working on!)
→ sudo sfdisk -d /dev/sda > /mnt/thumb/sda.txt
Later, if you mess up a risky partitioning operation, you can restore the partition table (but be careful to specify the correct disk device or you’ll overwrite the wrong partition table):
→ sudo sfdisk /dev/device < /mnt/thumb/sda.txt
The commands that follow are also relatively basic operations on disks and filesystems without graphical tools.
mkfs |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
mke2fs [options] device |
||||||
mkfs.ext3 [options] device |
||||||
mkfs.ext4 [options] device |
||||||
mkntfs [options] device |
||||||
mkfs.ntfs [options] device ...and many other variations... |
The mkfs
family of commands formats a Linux storage device for a
variety of filesystems. The storage device is usually a partition,
such as /dev/sdb1.
Examples:
→ sudo mkfs.ext4 /dev/device→ sudo mke2fs /dev/device
Standard Linux filesystem
→ sudo mkfs.ntfs /dev/device
Standard Linux filesystem
→ sudo mkntfs /dev/device
Microsoft Windows filesystem
Microsoft Windows filesystem
As you can see, most of the command names are “mkfs” followed by a dot
and a filesystem type, like mkfs.ext4
. They may also have alternate
names (links) with the filesystem type embedded in the middle of
“mkfs”, such as mke2fs
for an “ext” filesystem. To list all such
commands installed on your system, run:
→ ls /usr/*bin/mkfs.* /usr/sbin/mkfs.ext2 /usr/sbin/mkfs.hfs /usr/sbin/mkfs.ext3 /usr/sbin/mkfs.minix /usr/sbin/mkfs.ext4 /usr/sbin/mkfs.msdos /usr/sbin/mkfs.fat /usr/sbin/mkfs.ntfs
Useful options
|
Dry-run mode: don’t format anything. Just display what would be done. |
|
Label the formatted volume with the given name, which can be up to 16 bytes long. |
|
Set the block size to N bytes. |
resize2fs |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
resize2fs [options] device [size] |
The resize2fs
command grows or shrinks a
standard Linux filesystem of type ext2, ext3, or ext4. To enlarge a
filesystem:
-
Confirm that the device has enough free space immediately following the current partition.
-
Unmount the filesystem.
-
Enlarge its disk partition with
gparted
or similar program. (This requires free space just after the current partition.) -
Check the filesystem with
fsck
. -
Run
resize2fs
with appropriate arguments. In modern kernels, the filesystem may be mounted during resizing.
-
Confirm with
df
that the data in the filesystem (the “Used” column) will fit within the proposed new size. -
Unmount the filesystem.
-
Run
resize2fs
with appropriate arguments.
-
Shrink its disk partition with
gparted
or a similar program. -
Check the filesystem with
fsck
.
To resize a filesystem on /dev/sda1, assuming you’ve already completed
any checking and partitioning, run resize2fs
either with or without
a size:
→ sudo resize2fs /dev/sda1 100G→ sudo resize2fs /dev/sda1
Resize to 100 GB
Resize to the partition size
Sizes can be an absolute number of blocks, like 12345690, or a size
followed by K
(KB), M
(MB), G
(GB), T
(terabytes), or s
(512-byte sectors). The values are powers of two,
so 1K
means 1024, not 1000, and so on.
If you resize filesystems often, make your life easier with logical volume management (LVM), as explained in “Logical Volumes for Flexible Storage”, or a more modern filesystem, as in “ZFS: A Modern, Do-It-All Filesystem”.
Useful options
|
Force the resizing operation, even if |
|
Display the progress of the operation as it runs. |
e2label |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
e2label device [label] |
A label is a nickname for a filesystem. The
e2label
command sets or prints the label of a
standard Linux filesystem of type ext2, ext3, or ext4. Filesystems
don’t require labels, but they’re convenient for referring to
filesystems in /etc/fstab.
→ sudo e2label /dev/sdb1 backups→ sudo e2label /dev/sdb1
Assign a label
backups
Print a label
RAID Arrays for Redundancy
|
RAID (Redundant Array of Independent Disks) is a technique that distributes a computer’s data across multiple disks, transparently, while acting like a single disk. Usually, RAID is for redundancy—if one disk dies, your files are still intact. Other types of RAID increase the performance of storage.
A bunch of disks in a RAID arrangement is called a RAID array. The type of RAID, called the RAID level, determines how many drive failures the array can tolerate and still guarantee the data’s safety. Some standard RAID levels are RAID-0, RAID-1, RAID-5, RAID-10, and others you can explore on the web.
Let’s create a minimal RAID-1 array using the most common RAID
software for Linux, mdadm
. RAID-1 adds redundancy
simply by mirroring data from one drive to the others in the array. As
long as one drive is still operating, the data is safe. For this
example, I start with two disks, /dev/sdf and /dev/sdg, each of
which has a 10 GB partition, /dev/sdf1 and /dev/sdg1. The steps I
show are largely the same for other RAID levels and additional
devices. For full details, visit the
Linux Raid Wiki.
Warning
RAID operations can wipe out filesystems without confirmation. Practice the commands on spare drives or a virtual machine for safety.
Create a RAID Array
First, show that no RAID setup exists yet:
→ cat /proc/mdstat
Personalities : No RAID types listed
Create the RAID-1 array /dev/md1, from the two partitions:
→ sudo mdadm --create /dev/md1 --level 1 \ --raid-devices 2 /dev/sdf1 /dev/sdg1
View /proc/mdstat again. The Personalities line now shows that RAID-1 is in use, and the next line shows the new array, md1, which is being built:
→ cat /proc/mdstat Personalities : [raid1] md1 : active raid1 sdg1[1] sdf1[0] 10474496 blocks super 1.2 [2/2] [UU] [=========>...........] resync = 45.8% ... finish=0.4min ...
Optionally, wait for the build (“resync”) to complete:
→ cat /proc/mdstat Personalities : [raid1] md1 : active raid1 sdg1[1] sdf1[0] 10474496 blocks super 1.2 [2/2] [UU]
However, you don’t have to wait. The array is usable immediately. Format and mount it like any other storage device:
→ sudo mke2fs /dev/md1→ sudo mkdir /mnt/raid
Format the array
→ sudo mount /dev/md1 /mnt/raid → df -h /mnt/raid
Mount it
Filesystem Size Used Avail Use% Mounted on /dev/md1 9.9G 24K 9.4G 1% /mnt/raid
View it
Run lsblk
to illustrate the RAID configuration:
→ lsblk ⋮ sdf 8:80 0 10G 0 disk └─sdf1 8:81 0 10G 0 part └─md1 9:1 0 10G 0 raid1 /mnt/raid sdg 8:96 0 10G 0 disk └─sdg1 8:97 0 10G 0 part └─md1 9:1 0 10G 0 raid1 /mnt/raid
Run mdadm
to see more details about the array:
→ sudo mdadm --detail /dev/md1 dev/md1: ⋮ Creation Time : Thu Jul 20 13:15:08 2023 Raid Level : raid1 Array Size : 10474496 (9.99 GiB 10.73 GB) Raid Devices : 2 State : clean Working Devices : 2 ⋮ Number Major Minor RaidDevice State 0 8 81 0 active sync /dev/sdf1 1 8 97 1 active sync /dev/sdg1
When you’re satisfied with the array, save its configuration so it will survive reboots and mount itself. Don’t skip any steps.
-
Save the RAID configuration to a file:
→ sudo mdadm --detail --scan --verbose > /tmp/raid → cat /tmp/raid ARRAY /dev/md1 level=raid1 num-devices=2 ...
-
Use a text editor to append the contents of /tmp/raid to the configuration file /etc/mdadm/mdadm.conf, replacing any previous RAID configuration.
-
Run this command to update the Linux kernel:
→ sudo update-initramfs -u
-
Reboot. Check that your RAID array survived by mounting it by hand:3
→ sudo mount /dev/md1 /mnt/raid
-
If everything worked, add this line to /etc/fstab so your RAID array mounts at boot time:
/dev/md1 /mnt/raid ext4 defaults 0 2
Warning
Don’t update /etc/fstab too early. If your RAID configuration has a problem and you reboot, the computer might hang. Instead, test the configuration first by rebooting and mounting the array by hand, as I have.
Replace a Device in a RAID Array
So, your RAID array is up and running. What happens when a device dies
and needs replacement? First, the failure is visible in
/proc/mdstat. The failed device, /dev/sdf1, is marked with (F)
,
and the uptime indicator, which should read [UU]
(two devices up),
reads [U_]
(first device up, second device down).
→ cat /proc/mdstat Personalities : [raid1] md1 : active raid1 sdf1[1](F) sdg1[0] 10474496 blocks super 1.2 [2/1] [U_]
mdadm
also shows the array as “degraded” and the device as “faulty”:
→ sudo mdadm --detail /dev/md1 /dev/md1: ⋮ Raid Devices : 2 State : clean, degraded Working Devices : 1 Failed Devices : 1 ⋮ Number Major Minor RaidDevice State 1 8 97 - faulty /dev/sdf1
To replace device /dev/sdf1, mark it as failed (if it isn’t already) and remove it from the RAID array:
→ sudo mdadm --manage /dev/md1 --fail /dev/sdf1 → sudo mdadm --manage /dev/md1 --remove /dev/sdf1
Shut down the computer, unplug the power cable, and physically swap the failed storage device for a new one of the same size or larger. I’ll call it by a nonexistent name /dev/NEW to clearly distinguish it in my instructions because the following commands are destructive, and you don’t want to mix up your drives. Substitute the correct device name on your system.
Boot the computer, identify a good drive in the RAID array (in our
case, /dev/sdg), and copy its partition table onto the new device
with the sgdisk
command.
→ sudo sgdisk -R /dev/NEW /dev/sdg→ sudo sgdisk -G /dev/NEW
Copy from sdg to NEW
Randomize GUIDs
The device /dev/NEW now has a 10 GB partition, /dev/NEW1. Add it to the array:
→ sudo mdadm --manage /dev/md1 --add /dev/NEW1 mdadm: added /dev/NEW1
The array immediately begins rebuilding itself, mirroring data onto the new device:
→ cat /proc/mdstat ⋮ [==========>..........] recovery = 51.5% ... finish=0.4min ...
When mirroring is complete, the new device /dev/NEW1 has replaced the faulty device /dev/sdf1:
→ cat /proc/mdstat Personalities : [raid1] md1 : active raid1 NEW1[1] sdg1[0] 10474496 blocks super 1.2 [2/2] [UU]
Destroy a RAID Array
Should you ever want to destroy the RAID array and use the partitions for other purposes, run these commands, assuming your device names are /dev/sdg1 and /dev/sdh1:
→ sudo umount /mnt/raid → sudo mdadm --stop /dev/md1 mdadm: stopped /dev/md1 → sudo mdadm --zero-superblock /dev/sdg1 /dev/sdh1
Finally, update /etc/fstab and /etc/mdadm/mdadm.conf to remove the RAID array /dev/md1, and inform the kernel that the array is gone:
→ sudo update-initramfs -u
Logical Volumes for Flexible Storage
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Logical volume management (LVM) solves two annoying problems with disk storage:
-
Limited size. When a disk fills up, you have to delete files or replace it with a larger disk.
-
Fixed partitions. When you partition a disk, you guess how much space each partition will require, and if you’re wrong, it’s time-consuming to change.
LVM solves these problems by wrapping a layer of abstraction around
physical storage. It collects together a bunch of physical disks of
any sizes, called physical volumes, to simulate one big disk,
which it calls a volume group. The volume group becomes a
playground for creating simulated partitions, called logical
volumes, that can grow and shrink on demand. Figure 4-1 shows the
relationship between physical volumes (PVs), the volume group (VG) that
contains them, and logical volumes (LVs) that you carve out of the total space. If the VG runs out
of space, simply add another physical volume and the VG grows. If a
partition (LV) is the wrong size, just change it. Existing files are
preserved. Any mass storage devices can be part of a volume group,
even RAID arrays created with mdadm
(see “RAID Arrays for Redundancy”).
The most popular LVM software for Linux is called lvm2. It
includes over 50 commands, which might seem like a lot, but their
names follow a simple pattern: pv
, vg
, or lv
, followed by a verb
like create
, remove
, or display
. So vgcreate
creates a volume
group, and pvdisplay
prints information about a physical volume.
Warning
LVM operations can wipe out filesystems without confirmation. Practice the commands on spare drives or a virtual machine for safety.
Also, LVM provides no inherent redundancy. If one physical volume dies, you lose the whole volume group. For more safety, run LVM on top of RAID; see “RAID Arrays for Redundancy”.
I now present examples of using the most common lvm2 commands, using three empty 10 GB disk partitions, /dev/sdb1, /dev/sdc1, and /dev/sdd1.4 lvm2 has dozens more commands, however. For a full list, view the manpage of any lvm2 command and jump to the end or visit sourceware.org/lvm2.
Create a First Logical Volume
This sequence of steps sets up two physical volumes, groups them into a 20 GB volume group, myvg, and creates a 15 GB logical volume, stuff:
→ sudo pvcreate /dev/sdb1 /dev/sdc1Physical volume "/dev/sdb1" successfully created. Physical volume "/dev/sdc1" successfully created. → sudo vgcreate myvg /dev/sdb1 /dev/sdc1
Create two PVs
Volume group "myvg" successfully created → sudo lvcreate -L 15G -n stuff myvg
Create a VG
Logical volume "stuff" created. → sudo pvs
Create the LV
PV VG Fmt Attr PSize PFree /dev/sdb1 myvg lvm2 a-- <10.00g 0 /dev/sdc1 myvg lvm2 a-- <10.00g 5.34g
View the PVs
The logical volume stuff is usable like any other storage device. Format and mount it:
→ sudo mke2fs /dev/myvg/stuff→ sudo mkdir /mnt/stuff
Format the LV
→ sudo mount /dev/myvg/stuff /mnt/stuff → df -h /mnt/stuff
Mount it
Filesystem Size Used Avail Use% Mounted on /dev/mapper/myvg-stuff 15G 24K 1.4G 1% /mnt/stuff
View it
When your LV is ready, add this line to /etc/fstab to mount it at boot time:
/dev/mapper/myvg-stuff /mnt/stuff ext4 defaults 0 2
View LVM Details
The pvdisplay
, vgdisplay
, and lvdisplay
commands print
details about physical volumes, volume groups, and logical volumes,
respectively. The commands pvs
, vgs
, and lvs
print helpful summaries of that
information.
→ sudo pvdisplay→ sudo pvdisplay /dev/sdb1
Show all PVs
→ sudo pvs
Show selected PVs
→ sudo vgdisplay
Summarize PVs
→ sudo vgdisplay myvg
Show all VGs
→ sudo vgs
Show selected VGs
→ sudo lvdisplay
Summarize VGs
→ sudo lvdisplay myvg/stuff
Show all LVs
→ sudo lvs
Show selected LVs
Summarize LVs
Add a Logical Volume
Let’s run lvcreate
again to add a 2 GB logical
volume called tiny to our volume group:
→ sudo lvcreate -L 2G -n tiny myvg Logical volume "tiny" created. → sudo mke2fs /dev/myvg/tiny→ sudo mkdir /mnt/tiny
Format
→ sudo mount /dev/myvg/tiny /mnt/tiny → df -h /mnt/tiny
Mount
Filesystem Size Used Avail Use% Mounted on /dev/mapper/myvg-tiny 2.0G 24K 1.9G 1% /mnt/tiny
View
Add Disks to a Volume Group
The vgextend
command adds physical volumes to
a volume group. Suppose you want to increase the size of stuff by
10 GB (to 25 GB), but there’s only 3 GB of space left in volume group
myvg. Enlarge your VG by adding a third physical volume, /dev/sdd1,
increasing the VG’s total size to 30 GB:
→ sudo pvcreate /dev/sdd1→ sudo vgextend myvg /dev/sdd1
Create another PV
Grow the VG
At this point, the LVM setup looks like Figure 4-1. Run lsblk
to
illustrate the LVM configuration:
→ lsblk /dev/sdb /dev/sdc /dev/sdd NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sdb 8:16 0 10G 0 disk └─sdb1 8:17 0 10G 0 part └─myvg-stuff 253:0 0 15G 0 lvm /mnt/stuff sdc 8:32 0 10G 0 disk └─sdc1 8:33 0 10G 0 part ├─myvg-stuff 253:0 0 15G 0 lvm /mnt/stuff └─myvg-tiny 253:1 0 2G 0 lvm /mnt/tiny sdd 8:48 0 10G 0 disk └─sdd1 8:49 0 10G 0 part
Enlarge a Logical Volume
The lvresize
command grows or shrinks a
logical volume.5 Let’s enlarge the LV stuff to 25
GB:
→ sudo lvresize --resizefs --size 25G /dev/myvg/stuff → df -h /mnt/stuff Filesystem Size Used Avail Use% Mounted on /dev/mapper/myvg-stuff 25G 24K 24G 1% /mnt/stuff
Shrink a Logical Volume
It turns out the LV stuff doesn’t need to be so large. Shrink it to 8 GB (making sure first that it has less than 8 GB in use):
→ sudo lvresize --resizefs --size 8G /dev/myvg/stuff Do you want to unmount "/mnt/stuff" ? [Y|n] y ⋮ Logical volume myvg/stuff successfully resized. → df -h /mnt/stuff Filesystem Size Used Avail Use% Mounted on /dev/mapper/myvg-stuff 7.9G 24K 7.5G 1% /mnt/stuff
Delete a Logical Volume
The lvremove
command deletes a logical
volume. Let’s get rid of the LV tiny:
→ sudo umount /mnt/tiny→ sudo lvremove /dev/myvg/tiny
First unmount the LV
Do you really want to remove and DISCARD active logical volume myvg/tiny? [y/n]: y Logical volume "tiny" successfully removed
Remove the LV
Delete a Volume Group
The vgremove
command removes a volume group
and deletes any logical volumes it contains:
→ sudo vgremove myvg Do you really want to remove volume group "myvg" containing 1 logical volumes? [y/n]: y Do you really want to remove and DISCARD active logical volume myvg/stuff? [y/n]: y Logical volume "stuff" successfully removed Volume group "myvg" successfully removed
ZFS: A Modern, Do-It-All Filesystem
|
|
|
Warning
ZFS operations can wipe out filesystems without confirmation. Practice the commands on spare drives or a virtual machine for safety.
ZFS (Zettabyte File System) packs advanced features like RAID, logical
volume management, encryption, and compression into one convenient
package. If you’re accustomed to traditional Linux filesystems like
ext4, ZFS may seem like an alien world. It has its own terminology
with “pools” and “vdevs.” It doesn’t use /etc/fstab or the mount
command. You don’t even need to partition or format your disks explicitly.
A ZFS vdev, short for “virtual device,” is a group of physical disks that work together. They might divide the data among themselves as if they were one big disk, like a RAID-0 “disk striping” setup. They might mirror each other for redundancy, like a RAID-1 setup. They might operate as a disk cache; and there are other possibilities.
A collection of vdevs is called a pool. A pool acts
like one big storage device. You can carve it up into units that are
sort of like partitions, called datasets, and
you can change their size limits and other attributes flexibly.
Dataset names look like Linux paths without a leading slash. For
example, a pool named mypool
with a dataset named stuff
would be
named mypool/stuff
. (Datasets can contain other datasets too, like
mypool/stuff/important
.) Add a leading slash, and you get the
dataset’s default Linux mount point, like /mypool/stuff.
ZFS isn’t the only filesystem with advanced capabilities—another popular one is Btrfs—but it’s among the easiest to configure.
Note
I discuss only the minimal ZFS functionality to do interesting things. Real ZFS systems need careful configuration, tuning, and plenty of RAM; read the docs at https://oreil.ly/-t5Fu.
To demonstrate ZFS with both mirroring and striping, I use two pairs of disks, as in Figure 4-2. Each pair is a vdev with mirroring (RAID-1). ZFS then stripes across the two vdevs (RAID-0), effectively creating a RAID-10 setup. This redundant pool can tolerate one failed drive in each vdev and keep the data safe.
Create a ZFS Pool
Use the zpool
command to construct the pool of
two pairs of mirrored drives. I create a pool
called mypool
from four 10 GB disk devices, /dev/sdb, /dev/sdc,
/dev/sdd, and /dev/sde:
→ sudo zpool create mypool \ mirror /dev/sdb /dev/sdc \ mirror /dev/sdd /dev/sde
Warning
The simple device names in my examples, like /dev/sdb, can change after a reboot. For a more robust setup, use names that are guaranteed not to change, like the symbolic links found in /dev/disk/by-id or /dev/disk/by-uuid.
Also, on real systems, be sure to set an appropriate alignment shift
value with -o ashift
on creation; see the docs.
Use zpool status
to view the results.
→ zpool status pool: mypool state: ONLINE config: NAME STATE READ WRITE CKSUM mypool ONLINE 0 0 0mirror-0 ONLINE 0 0 0
The pool
sdb ONLINE 0 0 0 sdc ONLINE 0 0 0 mirror-1 ONLINE 0 0 0
First vdev
sdd ONLINE 0 0 0 sde ONLINE 0 0 0
Second vdev
Create a ZFS Dataset
Traditional filesystems have partitions of fixed size that you mount
in the file /etc/fstab. ZFS has datasets of arbitrary size that it mounts
automatically. Create a dataset named data
in pool mypool
, mounted
at the directory /mypool/data:
→ sudo zfs create -o mypool/data
Move the mount point if you like, to /mnt/stuff:
→ sudo zfs set mountpoint=/mnt/stuff mypool/data
View the results with either of these commands:
→ zfs mount mypool /mypoolmypool/data /mnt/stuff
The whole pool
→ zfs get mountpoint mypool/data NAME PROPERTY VALUE SOURCE mypool/data mountpoint /mnt/stuff local
Your dataset
Now use the dataset like any other mounted partition:
→ sudo cp /etc/hosts /mnt/stuff → cd /mnt/stuff → ls hosts
Create an Encrypted ZFS Dataset
By adding a few options, you can create a dataset that’s encrypted and
requires a passphrase before mounting. Create an encrypted dataset
named mypool/cryptic
:
→ zfs create \ -o encryption=on \ -o keylocation=prompt \ -o keyformat=passphrase \ mypool/cryptic Enter new passphrase: xxxxxxxx Re-enter new passphrase: xxxxxxxx
Use the dataset normally. When you reboot or otherwise need to mount the dataset, run:
→ sudo zfs mount -l mypool/cryptic
Set Size Limits on ZFS Datasets
By default, a ZFS dataset is the same size as the pool. Limit its size by setting a quota, which you may change anytime:
→ sudo zfs set quota=15g mypool/data
→ zfs list
NAME USED AVAIL REFER MOUNTPOINT
mypool 312K 18.4G 25K /mypool
mypool/data 24K 15.0G 24K /mnt/stuff 15 GB limit
Enable Compression on ZFS Datasets
ZFS can automatically compress data as it’s written and uncompress it when read. It supports various compression algorithms; here I use gzip compression and view how effectively files are being compressed (the compression ratio):
→ sudo zfs set compression=gzip mypool/data → cp hugefile /mnt/stuff→ zfs get compressratio
Store a big file
NAME PROPERTY VALUE SOURCE mypool compressratio 122.66x - mypool/data compressratio 126.12x -
See the compression ratio
After enabling compression, only new data is compressed; existing files are not. To turn off compression:
→ sudo zfs set compression=off mypool/data
Snapshot a ZFS Dataset
ZFS supports snapshots:
storing the state of a dataset so you can easily return to that state
(roll back) later. Before performing a risky change on your files, for
example, take a snapshot, and if something goes wrong, you can revert
the change with a single command. Snapshots occupy very little disk
space, and you can send them efficiently to other zpools or hosts
(with zfs send
and zfs recv
). Create a snapshot of mypool/data
named safe
:
→ sudo zfs snapshot mypool/data@safe
List your snapshots:
→ zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT mypool/data@safe 0B - 24K -
If you can’t list snapshots, set listsnapshots=on
and try again:
→ sudo zpool set listsnapshots=on mypool
Try changing some files in mypool/data
. Then roll back to the
snapshot safe
and see that your changes are gone:
→ sudo zfs rollback mypool/data@safe
Backups and Remote Storage
|
Efficiently copy a set of files, even across a network. |
|
Sync files with various cloud providers. |
|
Low-level copying of data. |
|
Burn a DVD or Blu-ray disc. |
You can back up your precious Linux files in various ways:
-
Copy them to a remote machine.
-
Copy them to a backup medium like an external drive.
-
Burn them onto a disc.
I present a few popular Linux commands for backups, but there are
others. Some users prefer cpio
for its
flexibility, and some long-time administrators swear by dump
and restore
as the only reliable way
to back up and restore every type of file. See the manpages for these
commands if you are interested in them.
rsync |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
rsync [options] source destination |
The rsync
command copies a set of files. It can make an exact copy,
including file permissions and other attributes (called mirroring),
or it can just copy the data. It can run over a network or on a single
machine. rsync
has many uses and over 50 options; I present just
a few common cases relating to backups.
To mirror the directory mydir and its contents into another directory mydir2 on a single machine:
→ rsync -a mydir mydir2
rsync
is finicky about how you specify the first directory. If you
write “mydir” as in the example here, that directory is copied into
mydir2, creating the subdirectory mydir2/mydir. If instead, you’d
rather have only the contents of mydir copied into mydir2,
append a slash onto “mydir”:
→ rsync -a mydir/ mydir2
rsync
can mirror a directory over a network to another host,
securing the connection with SSH to prevent eavesdropping. Here I copy directory mydir to the
account “smith” on remote host server.example.com, in a directory
D2:
→ rsync -a mydir smith@server.example.com:D2
If you like rsync
but also want to have incremental backups and
manage them efficiently, try rsnapshot
(https://oreil.ly/VNfb-).
Useful options
rclone |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
rclone subcommand [options] [arguments] |
The rclone
command connects your Linux system to
popular cloud storage providers to copy files conveniently. It works
with Dropbox, Google Drive, Microsoft OneDrive, Amazon S3, and about
50 other destinations. To get started, run rclone config
and follow
the prompts to set up a connection with your cloud provider of choice,
which rclone
calls a remote. Visit
rclone.org/docs for detailed instructions on
configuration.
After choosing a name for your remote, such as myremote
, refer to
remote files with the syntax myremote:
path, where path is a
Linux-style file path. For example, a file photo.jpg in a remote
directory Photos would be myremote:Photos/photo.jpg
.
Backups are usually done with the rclone sync
command, which
synchronizes a local directory and a remote directory so they contain
the same content, adding or deleting as necessary. It works much like
the rsync --delete
command. You can synchronize in either direction,
from your local machine to the remote, or from the remote to your
local machine. You can even set up client-side encryption, so files
are transparently encrypted before they’re copied to the remote and
decrypted when they’re copied back to your local system (see the
docs).
Some common operations for backups include:
|
List files on the remote recursively (append |
|
List only directories on the remote. |
|
Display a long listing like |
|
Copy a local file to the remote. |
|
Copy a remote file to your local system. |
|
Move a local file to the remote. |
|
Move a remote file to your local system. |
|
Delete a remote file. |
|
Synchronize local files onto the remote. |
|
Synchronize remote files onto your local system. |
Run rclone help
for a complete list of subcommands. Note that you
can access fancier paths on the remote than my earlier examples show:
→ rclone copy remote:Photos/Vacation/picture.jpg .
Useful options
|
Dry-run mode: don’t actually copy. Just display what would be done. |
|
Run interactively so you’re prompted before changes. |
dd |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
dd [options] |
dd
is a low-level copier of bits and bytes. It can copy data from
one file to another, say, from myfile to /tmp/mycopy:
→ dd if=myfile of=/tmp/mycopy 2+1 records in 2+1 records out 1168 bytes (1.2 kB) copied, 0.000174074 s, 6.7 MB/s
It can even convert data while copying, like changing characters to uppercase while copying from myfile to /tmp/mycopy:
→ dd if=myfile of=/tmp/mycopy conv=ucase
dd
does much more than copy files. It can copy raw data directly
from one disk device to another. Here’s a command to clone a hard
disk:
→ sudo dd if=/dev/device1 of=/dev/device2 bs=512 \ conv=noerror,sync OVERWRITES /dev/device2
Or, copy an entire disk device to create an ISO file. Make sure the output file is on a different disk device and has sufficient free space.
→ sudo dd if=/dev/device of=disk_backup.iso
Warning
dd
, when run as the superuser, can wipe out your hard drive in
seconds if you’re not careful. Always double-check that the output
file (the argument of=
) is the one you intend. Back up your computer
and keep a Linux “live” distro on hand for emergencies (see
“What’s in This Book?”) before experimenting with dd
as root.
For some great advice on sophisticated uses of dd
, visit
https://oreil.ly/R3krx. My
favorite tip is backing up a disk’s master boot record (MBR), which is
512 bytes long, to a file called mbr.txt:
→ sudo dd if=/dev/device of=mbr.txt bs=512 count=1
Useful options
growisofs |
stdin |
stdout |
- file |
-- opt |
--help |
--version |
growisofs [options] tracks |
The growisofs
command burns a writable CD, DVD, or Blu-ray disc. To
burn the contents of a Linux directory onto a disc readable on Linux,
Windows, and macOS systems:
-
Locate your disc writer devices by running:
→ grep "^drive name:" /proc/sys/dev/cdrom/info drive name: sr1 sr0
The available devices here are /dev/sr1 and /dev/sr0.
-
Put the files you want to burn into a directory, say, dir. Arrange them exactly as you’d like on the disc. The directory dir itself is not copied to the disc, just its contents.
-
Use the
mkisofs
command to create an ISO (disc) image file, and burn it onto a disc usinggrowisofs
, assuming your device is /dev/sr1:→ mkisofs -R -l -o $HOME/mydisk.iso dir → growisofs -dvd-compat -Z /dev/sr1=$HOME/mydisk.iso → rm $HOME/mydisk.iso
To burn audio CDs, use a friendly graphical program like k3b
.
1 You can mount a filesystem on a nonempty directory, but the directory’s contents become inaccessible until you unmount.
2 Notice the spelling is “umount,” not “unmount.”
3 If your RAID array mysteriously renames itself /dev/md127, you forgot to run update-initramfs
in the previous step.
4 Operate on partitions rather than whole disks.
5 Old-timers may resize an LV by running lvextend
, umount
, fsck
, resize2fs
, and mount
in sequence. lvresize
is easier.
Get Linux Pocket Guide, 4th Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.