盘点Linux下分区管理方式
2015-10-26 13:59:15 阿炯

Linux在2.6之后引入了比较多的磁盘分区方式,在没有第三方磁盘管理硬件时,由内核自动分配磁盘分区编号,与主板所在的接口相关。目前主流的分区管理方式有:UUIDs、Labels、Hardware IDs、sysfs Paths,建议使用前两者,它们用以在不同的使用环境中的不同使用,比如:在软件阵列中如果更换了磁盘在主板sata接口位置,而内核是按接口分配分区编号,传统的分区就解决不了这个问题,而上面的方式是可以的。


On modern udev installations, there are symbolic links to storage media in subdirectories of /dev/disk, that let you look up a disk or a partition by serial number (/dev/disk/by-id/), by UUID (/dev/disk/by-uuid), by filesystem label (/dev/disk/by-label/) or by hardware connectivity (/dev/disk/by-path/).

Under Linux 2.6, each disk and disk-like device has an entry in /sys/block. Under Linux since the dawn of time, disks and partitions are listed in /proc/partitions.

Linux also provides the lsblk utility which displays a nice tree view of the storage volumes (since util-linux 2.19, not present on embedded devices with BusyBox).


从Debian 7开始,系统开始使用uuid作为根目录的挂载方式,如果之前使用的默认的分区名,当插入另一块硬盘时且改变了之前系统硬盘位置时,操作系统会将fstab文件中的分区名改为uuid。

Persistent device naming for block devices has been made possible by the introduction of udev and has some advantages over the use of traditional bus-based names such as /dev/hda1 or /dev/sda2.
为块设备设定固定设备名已经成为可能,通过udev引入和在使用传统的一些优势总线名称,如/dev/hda1或/dev/sda2。

While Linux distributions and udev are evolving and hardware detection is becoming more reliable, there are also a number of new problems and changes:
尽管各种Linux发行版引入udev后让硬件检测变得更加可靠,但还有一些新问题和变化:

1、If you have more than one disk controller (IDE or especially SCSI/SATA), or even if you just have variable numbers of removable USB/firewire storage devices attached from day to day, the order in which they are detected may not be deterministic. The result is that device names like /dev/sda1 and /dev/sdb1 may switch around randomly on each boot. Persistent naming allows you not to worry about this at all.

2、For machines with IDE controllers (including for instance machines with all-SATA hard drives and just one IDE cdrom drive), the switch to a standard Squeeze kernel may cause trouble: with the introduction of the new libata PATA support, your IDE hdX devices will become sdX devices. Again, if you have persistent naming in place, you won't even notice. (The postinst for the package linux-base includes code to assist with the changeover, but it makes sense to get it sorted out and verified as working in advance.)

3、Big machines, with many fast CPUs, and many Fiber Channel Host Bus Adapters, variable load/latency FC switches, SCSI controllers, and/or high-performance network cards, may have asynchronous timing issues when dealing with udev and multipath I/O, with almost unpredictable device detection order and automatic assignment of names during boot.

There are more reasons, but these are the most critical ones now and in the near future. That's why Debian encourages you to change your setup to persistent naming schemes, unless you are using LVM. LVM logical volumes should always be identified by logical volume name (/dev/mapper/name).

但在不久的将来这些是最重要的原因。这就是为什么Debian鼓励你改变设置固定的命名方案,当然除非你使用LVM。LVM逻辑卷应该总是被设置为逻辑卷名(/dev/mapper/name)。

The Four Different Schemes for Persistent Naming
四种不同固定命名方案

UUIDs


UUID stands for Universally Unique Identifier and is a mechanism to give each filesystem a unique identifier. All Linux filesystems support filesystem UUIDs; FAT and NTFS filesystems don't support true UUIDs, but are still listed in /dev/disk/by-uuid with a unique identifier:

UUID代表全局惟一标识符和一个机制来给每个文件系统的一个独特的标识符。所有Linux文件系统支持文件系统uuid,FAT和NTFS文件系统不支持真正意义上的uuid,但仍在/dev/disk/by-uuid上有一个惟一的标识符:

# ls -l /dev/disk/by-uuid/
总用量 0
lrwxrwxrwx 1 root root 10 Oct 16 10:27 2d781b26-0285-421a-b9d0-d4a0d3b55680 -> ../../sda1
lrwxrwxrwx 1 root root 10 Oct 16 10:27 31f8eb0d-612b-4805-835e-0e6d8b8c5591 -> ../../sda7
lrwxrwxrwx 1 root root 10 Oct 16 10:27 3FC2-3DDB -> ../../sda6
lrwxrwxrwx 1 root root 10 Oct 16 10:27 5090093f-e023-4a93-b2b6-8a9568dd23dc -> ../../sda2
lrwxrwxrwx 1 root root 10 Oct 16 10:27 912c7844-5430-4eea-b55c-e23f8959a8ee -> ../../sda5
lrwxrwxrwx 1 root root 10 Oct 16 10:27 B0DC1977DC193954 -> ../../sdb1
lrwxrwxrwx 1 root root 10 Oct 16 10:27 bae98338-ec29-4beb-aacf-107e44599b2e -> ../../sdb2

As you can see, the FAT and NTSF filesystems have shorter names (sda6 and sdb1), but are still listed by UUID. The point of the 32-digit base-62 strings is to make collisions astronomically unlikely; if it happened that sda1 and sda2 had the same UUID the system would fail to boot.

正如你所看到的,FAT和NTSF文件系统(sda6和sdb1)使用的是短名称,但仍然有UUID。32-digit base-62字符串碰撞不太可能,如果碰巧sda1和sda2有相同的UUID则会导致系统无法启动。

LVM snapshots will result in duplicate UUIDs, however.

然而LVM快照将导致重复的uuid。

Linux取得磁盘分区的uuid

新版本的debian的fstab文件中都采用了uuid的方式,以防止在多硬盘时发生错乱。In /dev/disk/by-uuid there are symlinks mapping each drive's UUID to its entry in /dev (e.g. /dev/sda1)

取得某一分区的uuid:
blkid /dev/sdb1

Show UUID data for all partitions:
blkid

Show UUID data for all partitions in easier to read format: (Note: in newer releases, blkid -L has a different meaning, and blkid -o list should be used instead)
blkid -L

Show just the UUID for /dev/sda1 and nothing else:
blkid -s UUID -o value /dev/sda1

To get the UUIDs for all partitions
for v in /dev/disk/by-uuid/* ; do echo "`readlink $v`: $v" ; done


Find UUID of Storage Devices in Linux

1)、blkid
blkid命令在大多数现代Linux发行版上默认可用,使用blkid命令可以找到Linux系统上所有磁盘分区的UUID:
# blkid
# blkid /dev/sda1
# blkid /dev/sd*

2)、ls
在Linux中,包括存储设备在内的所有设备都表示为文件。可以使用ls命令列出所有这些文件,列出所有分区及其uuid:
$ ls -l /dev/disk/by-uuid

3)、lsblk
使用lsblk命令来列出分区的UUID:
# lsblk -f
# lsblk -o uuid
# lsblk -o +uuid,name

# lsblk -fs(列出分区信息而非硬盘信息,无大小等)
# lsblk -o name,fssize,fsavail,fsused,fsuse% /dev/sda


Labels

Almost every filesystem type can also have a label. All those that have one are listed in the /dev/disk/by-label directory:

几乎每一个文件系统类型有一个标签。所有那些可从/dev/disk/by-label目录中列出:

$ ls -l /dev/disk/by-label
lrwxrwxrwx 1 root root 10 Oct 16 10:27 data -> ../../sdb2
lrwxrwxrwx 1 root root 10 Oct 16 10:27 data2 -> ../../sda2
lrwxrwxrwx 1 root root 10 Oct 16 10:27 fat -> ../../sda6
lrwxrwxrwx 1 root root 10 Oct 16 10:27 home -> ../../sda7
lrwxrwxrwx 1 root root 10 Oct 16 10:27 root -> ../../sda1
lrwxrwxrwx 1 root root 10 Oct 16 10:27 swap -> ../../sda5
lrwxrwxrwx 1 root root 10 Oct 16 10:27 windows -> ../../sdb1

While recognisable words may be used as labels, you need to exercise caution to prevent name collisions; consider the possibility that you might have random USB/firewire drives plugged in at reboot. LVM snapshots will also result in duplicate labels.

当使用单词用作标签时,需要特别小心以防止名称冲突;考虑一下这种可能性,你可能会随机USB或firewire驱动器插在重新启动。另外LVM快照也会导致重复的标签。

You can change the labels of your filesystems using these commands:

你可以使用下面这些命令来改变文件系统分区的标签:

Type    Command    Notes

EXT3:
e2label /dev/XXX <label>
also applies to EXT2/EXT4

FAT/VFAT:
dosfslabel /dev/XXX <label>
bug #506786 in Lenny; or mlabel in mtools

JFS:
jfs_tune -L <label> /dev/XXX

NTFS:
ntfslabel /dev/XXX <label>
or change it under Windows

ReiserFS:
reiserfstune -l <label> /dev/XXX

swap:
mkswap -L <label> /dev/XXX
but see below on swapoff/swapon procedure

XFS:
xfs_admin -L <label> /dev/XXX

Hardware IDs

by-id creates a unique name depending on the hardware serial number. These are intended to be immutable for a given hardware configuration.

by-id可创建一个唯一的名称,当然这取决于硬件序列号。这些对于一个给定的硬件配置都是不可变的。

# ls -l /dev/disk/by-id/
total 0
lrwxrwxrwx 1 root root  9 10月 26 09:39 ata-HGST_HUS724040ALA640_PN2338P4H8R18B -> ../../sdc
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-HGST_HUS724040ALA640_PN2338P4H8R18B-part1 -> ../../sdc1
lrwxrwxrwx 1 root root  9 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK -> ../../sda
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK-part4 -> ../../sda4
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK-part5 -> ../../sda5
lrwxrwxrwx 1 root root  9 10月 26 09:39 ata-WDC_WD10PURX-64D85Y0_WD-WCC4J6JTSASK -> ../../sdb
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-WDC_WD10PURX-64D85Y0_WD-WCC4J6JTSASK-part1 -> ../../sdb1
lrwxrwxrwx 1 root root  9 10月 26 09:39 scsi-SATA_HGST_HUS724040A_PN2338P4H8R18B -> ../../sdc
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_HGST_HUS724040A_PN2338P4H8R18B-part1 -> ../../sdc1
lrwxrwxrwx 1 root root  9 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK -> ../../sda
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK-part4 -> ../../sda4
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK-part5 -> ../../sda5
lrwxrwxrwx 1 root root  9 10月 26 09:39 scsi-SATA_WDC_WD10PURX-64_WD-WCC4J6JTSASK -> ../../sdb
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_WDC_WD10PURX-64_WD-WCC4J6JTSASK-part1 -> ../../sdb1
lrwxrwxrwx 1 root root  9 10月 26 13:07 usb-Linux_File-CD_Gadget_0123456789-0:0 -> ../../sdd
lrwxrwxrwx 1 root root  9 10月 26 13:07 usb-Linux_File-CD_Gadget_0123456789-0:1 -> ../../sr0
lrwxrwxrwx 1 root root  9 10月 26 13:07 usb-Linux_File-CD_Gadget_0123456789-0:2 -> ../../sde
lrwxrwxrwx 1 root root  9 10月 26 09:39 wwn-0x5000c50077d41ff1 -> ../../sda
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000c50077d41ff1-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000c50077d41ff1-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000c50077d41ff1-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000c50077d41ff1-part4 -> ../../sda4
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000c50077d41ff1-part5 -> ../../sda5
lrwxrwxrwx 1 root root  9 10月 26 09:39 wwn-0x5000cca249d20d31 -> ../../sdc
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000cca249d20d31-part1 -> ../../sdc1
lrwxrwxrwx 1 root root  9 10月 26 09:39 wwn-0x50014ee2606c3855 -> ../../sdb
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x50014ee2606c3855-part1 -> ../../sdb1

sysfs Paths

by-path creates a unique name depending on the shortest physical path (according to sysfs). Both contain strings to indicate which subsystem they belong to and thus are not suitable for solving the problems mentioned in the beginning of this article. They won't be discussed any further here.

by-path依据最短的物理路径(根据sysfs)创建一个唯一的名称,包含字符串来表示它们属于哪个子系统(主板上的总线的位置),因此不适合在这篇文章开始提到的问题,所有不会进一步讨论。

Preparing for Persistent Naming(准备固定命名)

You can get a basic overview of which devices are associated with which persistent names simply by invoking

你可以通过简单地调用得到设备的基本的概述与持久的名字

$ ls -lR /dev/disk
# ls -lR /dev/disk
/dev/disk:
总用量 0
drwxr-xr-x 2 root root 640 10月 26 09:38 by-id
drwxr-xr-x 2 root root  80 10月 26 09:38 by-label
drwxr-xr-x 2 root root 240 10月 26 09:38 by-path
drwxr-xr-x 2 root root 160 10月 26 09:38 by-uuid

/dev/disk/by-id:
lrwxrwxrwx 1 root root  9 10月 26 09:39 ata-HGST_HUS724040ALA640_PN2338P4H8R18B -> ../../sdc
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-HGST_HUS724040ALA640_PN2338P4H8R18B-part1 -> ../../sdc1
lrwxrwxrwx 1 root root  9 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK -> ../../sda
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK-part4 -> ../../sda4
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-ST500DM002-1BD142_W3T8Y1BK-part5 -> ../../sda5
lrwxrwxrwx 1 root root  9 10月 26 09:39 ata-WDC_WD10PURX-64D85Y0_WD-WCC4J6JTSASK -> ../../sdb
lrwxrwxrwx 1 root root 10 10月 26 09:39 ata-WDC_WD10PURX-64D85Y0_WD-WCC4J6JTSASK-part1 -> ../../sdb1
lrwxrwxrwx 1 root root  9 10月 26 09:39 scsi-SATA_HGST_HUS724040A_PN2338P4H8R18B -> ../../sdc
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_HGST_HUS724040A_PN2338P4H8R18B-part1 -> ../../sdc1
lrwxrwxrwx 1 root root  9 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK -> ../../sda
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK-part4 -> ../../sda4
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_ST500DM002-1BD1_W3T8Y1BK-part5 -> ../../sda5
lrwxrwxrwx 1 root root  9 10月 26 09:39 scsi-SATA_WDC_WD10PURX-64_WD-WCC4J6JTSASK -> ../../sdb
lrwxrwxrwx 1 root root 10 10月 26 09:39 scsi-SATA_WDC_WD10PURX-64_WD-WCC4J6JTSASK-part1 -> ../../sdb1
lrwxrwxrwx 1 root root  9 10月 26 09:39 wwn-0x5000c50077d41ff1 -> ../../sda
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000c50077d41ff1-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000c50077d41ff1-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000c50077d41ff1-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000c50077d41ff1-part4 -> ../../sda4
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000c50077d41ff1-part5 -> ../../sda5
lrwxrwxrwx 1 root root  9 10月 26 09:39 wwn-0x5000cca249d20d31 -> ../../sdc
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x5000cca249d20d31-part1 -> ../../sdc1
lrwxrwxrwx 1 root root  9 10月 26 09:39 wwn-0x50014ee2606c3855 -> ../../sdb
lrwxrwxrwx 1 root root 10 10月 26 09:39 wwn-0x50014ee2606c3855-part1 -> ../../sdb1

/dev/disk/by-label:
lrwxrwxrwx 1 root root 10 10月 26 09:39 backup -> ../../sdb1
lrwxrwxrwx 1 root root 10 10月 26 09:39 hstorage -> ../../sdc1

/dev/disk/by-path:
lrwxrwxrwx 1 root root  9 10月 26 09:39 pci-0000:00:1f.2-scsi-0:0:0:0 -> ../../sda
lrwxrwxrwx 1 root root 10 10月 26 09:39 pci-0000:00:1f.2-scsi-0:0:0:0-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 10月 26 09:39 pci-0000:00:1f.2-scsi-0:0:0:0-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 10月 26 09:39 pci-0000:00:1f.2-scsi-0:0:0:0-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 10月 26 09:39 pci-0000:00:1f.2-scsi-0:0:0:0-part4 -> ../../sda4
lrwxrwxrwx 1 root root 10 10月 26 09:39 pci-0000:00:1f.2-scsi-0:0:0:0-part5 -> ../../sda5
lrwxrwxrwx 1 root root  9 10月 26 09:39 pci-0000:00:1f.2-scsi-1:0:0:0 -> ../../sdb
lrwxrwxrwx 1 root root 10 10月 26 09:39 pci-0000:00:1f.2-scsi-1:0:0:0-part1 -> ../../sdb1
lrwxrwxrwx 1 root root  9 10月 26 09:39 pci-0000:00:1f.2-scsi-2:0:0:0 -> ../../sdc
lrwxrwxrwx 1 root root 10 10月 26 09:39 pci-0000:00:1f.2-scsi-2:0:0:0-part1 -> ../../sdc1

/dev/disk/by-uuid:
lrwxrwxrwx 1 root root 10 10月 26 09:39 408c4817-69c8-4854-8956-b0e1c7932c3c -> ../../sda5
lrwxrwxrwx 1 root root 10 10月 26 09:39 491466e4-b7d6-415f-8c3f-7f03e3d1abb9 -> ../../sda1
lrwxrwxrwx 1 root root 10 10月 26 09:39 5990d215-f397-403e-8a34-1db4cb981d5f -> ../../sda2
lrwxrwxrwx 1 root root 10 10月 26 09:39 631f4ae8-9d5c-4920-ab49-12d746beae84 -> ../../sdc1
lrwxrwxrwx 1 root root 10 10月 26 09:39 9f034f49-fc67-4c0b-92f0-9e1503d42d39 -> ../../sdb1
lrwxrwxrwx 1 root root 10 10月 26 09:39 cbfd88d9-bccb-4621-9ef9-b317c41d9758 -> ../../sda3

but there's also a handy new blkid command (which is in /sbin, but doesn't require root privileges). It gives various kinds of useful output, the simplest being:

但有一个方便的新blkid命令(在/sbin下,不需要root特权)。它有许多的输出,最简单的是:

$ /sbin/blkid
/dev/sda3: UUID="cbfd88d9-bccb-4621-9ef9-b317c41d9758" TYPE="swap"
/dev/sda1: UUID="491466e4-b7d6-415f-8c3f-7f03e3d1abb9" TYPE="ext2"
/dev/sda2: UUID="5990d215-f397-403e-8a34-1db4cb981d5f" TYPE="xfs"
/dev/sdb1: LABEL="backup" UUID="9f034f49-fc67-4c0b-92f0-9e1503d42d39" TYPE="xfs"
/dev/sda5: UUID="408c4817-69c8-4854-8956-b0e1c7932c3c" TYPE="xfs"
/dev/sdc1: LABEL="hstorage" UUID="631f4ae8-9d5c-4920-ab49-12d746beae84" TYPE="xfs"

As you can see, the swap partition here does not have a UUID or label; the Debian Lenny installer used a version of partman that did not set these for swap partitions. However, swap partitions can be given persistent names via mkswap.

正如你所见,这里的交换分区没有一个UUID或标签;Debian Lenny安装程序使用partman没有设置交换分区。然而通过mkswap交换分区可以设置固定的名字。

Assigning Persistent Names to Swap Partitions(分配固定名字交换分区)

First, make quite sure you've correctly identified the swap partition (see /proc/swaps)! Then (as root) safely deactivate the current swap, reinitialise it (optionally adding a label), and reactivate it:

首先,确保确定了交换分区(见/proc/swaps)!然后使用root用户安全禁用当前交换分区,reinitialise它添加一个标签(可选),并激活它:

# swapoff /dev/sda3
# mkswap -L Swap /dev/sda3
Setting up swapspace version 1, size = 1998737 kB
LABEL=Swap, UUID=cbfd88d9-bccb-4621-9ef9-b317c41d9758
# swapon /dev/sda3

You can verify the results as a normal user:

您可以作为一个普通用户来验证结果:

$ /sbin/blkid
/dev/sda2: LABEL=Swap UUID="cbfd88d9-bccb-4621-9ef9-b317c41d9758" TYPE="swap"
...

Using Persistent Naming(使用固定命称)

Having chosen which naming method you'd like to use, let's now enable persistent naming for your system:

在选择想使用的命名方法,现在让我们使固定的系统命名:

In fstab

Enabling persistent naming in /etc/fstab is easy; for each filesystem in your fstab file, just replace the device name in the first column (where it says something like /dev/sda7) with the new persistent name. This can be achieved by substituting in the appropriate path under /dev/disk, such as:

使用固定命名挂载很容易,为每个文件系统分区在fstab文件中,只替换第一列的设备名称(好像说/dev/sda7)为新的固定名字。这可以通过替换/dev/disk下在适当的路径,例如:

/dev/disk/by-label/home
or
/dev/disk/by-uuid/31f8eb0d-612b-4805-835e-0e6d8b8c5591

However, instead of giving an explicit /dev/disk path, the method usually recommended is to indicate how the filesystem is to be mounted by writing LABEL=<label> or UUID=<uuid> - for example:

当然也可以不是给一个明确的/dev/disk路径,通常的文件系统的挂载写法,即如何写LABEL=<label>或UUID=<uuid>——例如:

LABEL=home
or
UUID=31f8eb0d-612b-4805-835e-0e6d8b8c5591

参考来源:
Part-UUID
Linux中fstab文件详解



上面盘点了分区挂载管理的一些方式,接下来再对这些方式从侧面进行分析:比如分区的使用情况、所在硬盘介质信息、内核如何组织管理这些信息等。

不借用于df来取得每分区的使用比,当然最全的灵感来源还是其本身。

还是先盘点系统中相关的二进制指令

查看挂载点:mount -l

要验证一个目录是否被用于挂载点,可以使用mount、mountpoint和findmnt命令,或通过读取/proc/mounts来实现。

mountpoint:Check whether a directory or file is a mountpoint.

用法:
mountpoint [-qd] /path/to/directory
mountpoint -x /dev/device

选项:
 -q, --quiet        quiet mode - don't print anything
 -d, --fs-devno     print maj:min device number of the filesystem
 -x, --devno        print maj:min device number of the block device

取得挂载点主次设备号
mountpoint  -d /boot
252:1
mountpoint  -x /dev/vda1
252:1

设备与挂载点

使用mount指令
mount | awk '{if ($3 == "/mnt/freeoa") { exit 0}} ENDFILE{exit -1}' || mount /dev/sdc1 /mnt/freeoa
mount | awk '{if ($3 == "/mnt/freeoa") { exit 0}} ENDFILE{exit -1}' && echo "/mnt/freeoa already mounted"

使用mountpoint指令
mountpoint -q /mnt/freeoa || mount /dev/sdc1 /mnt/freeoa
mountpoint -q /mnt/freeoa && echo "/mnt/freeoa already mounted."

使用findmnt也可以做同样的事情
findmnt /mnt/freeoa >/dev/null || mount /dev/sdc1 /mnt/freeoa
findmnt /mnt/freeoa >/dev/null && echo "/mnt/freeoa already mounted"

分析/proc/mounts文件
awk '{if ($2 == "/mnt/freeoa") { exit 0}} ENDFILE{exit -1}' < /proc/mounts || mount /dev/sdc1 /mnt/freeoa
awk '{if ($2 == "/mnt/freeoa") { exit 0}} ENDFILE{exit -1}' < /proc/mounts && echo "/mnt/freeoa already mounted"


关于findmnt

展示Linux中当前所挂载的文件系统,是一个简单的命令行实用程序,用于显示当前挂载的文件系统列表,它或在/etc/fstab、/etc/mtab或/proc/self/mountinfo中搜索所挂载的文件系统信息。

其输出主要有4列:
TARGET(挂载点,日常用的最多的方式): This column shows the mount point.
SOURCE(被挂载设备的信息): In this column, you can see the mounted device.
FSTYPE(文件系统类型): Here is described the file system.
OPTIONS(相关的参数设置): This column shows mount point options, such as Read-Only or Writable.

它会以树状目录来展示这些信息,如果只想以简单的二维表示,可使用'-l'参数;使用'-t'参数可只展示指定格式的文件系统,下为以fstasb文件内容的方式展示相关信息:
findmnt --fstab -t xfs

'--verbose'参数可展示更多的挂载细节,使用'-o'参数还可以定制输出显示指定的信息列。

findmnt -n -o TARGET,SOURCE
findmnt -n -o TARGET --target /path/to/FILE


内置stat(env stat)来分析设备的使用信息

使用stat指令来查看挂载点所对应的块设备的使用情况,获取文件与文件系统的信息,使用mount point或device file。


# df -h
Filesystem               Size  Used Avail Use% Mounted on
...
/dev/sda1                194M  127M   58M  69% /boot

# env stat /dev/sda1
  File: ‘/dev/sda1’
  Size: 0             Blocks: 0          IO Block: 4096   block special file
Device: 5h/5d    Inode: 1699        Links: 1     Device type: 8,1
Access: (0660/brw-rw----)  Uid: (    0/    root)   Gid: (    6/    disk)
Access: 2022-08-15 17:57:52.254845084 +0800
Modify: 2022-07-08 08:13:23.852000000 +0800
Change: 2022-07-08 08:13:23.852000000 +0800
Birth: -

# env stat /boot/
  File: ‘/boot/’
  Size: 3072          Blocks: 8          IO Block: 1024   directory
Device: 801h/2049d    Inode: 2           Links: 6
Access: (0555/dr-xr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2022-09-05 23:12:51.000000000 +0800
Modify: 2021-01-10 20:30:19.000000000 +0800
Change: 2021-01-10 20:30:19.000000000 +0800
Birth: -


由于stat命令返回一个“设备(Device)”字段,想知道如何使用符合POSIX编程的方式以获取底层stat()库调用所返回的信息。可以参考这段C代码:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>

int main (int argc, const char *argv[]) {
    struct stat info;
    stat(argv[1], &info);
    printf("min: %d maj: %d\n",minor(info.st_dev),major(info.st_dev));
    return 0;
}

将给出命令行(argv[1])上列出的文件的设备的主要和次要设备ID。不幸的是:major()和minor()不是POSIX标准,尽管手册页声称它们“存在于GNU/linux之外的许多其他系统上”。然后可以从/proc/diskstats中获取设备主/次编号和设备节点之间的对应关系,通过/etc/mtab映射到/proc/mounts中的挂载点。


内核从/proc/mounts文件中检索该信息,也可以通过该文件以检索相同的信息。

此三个挂载信息相关的文件关系:
/etc/mtab -> ../proc/self/mounts
/proc/mounts -> self/mounts
-r--r--r-- 1 root root 0 8-24 15:21 /proc/self/mounts

其信息的分析读取:
#include <stdio.h>
#include <stdlib.h>
#include <mntent.h>

int main(void){
  struct mntent *ent;
  FILE *aFile;

  aFile = setmntent("/proc/mounts", "r");
  if (aFile == NULL) {
    perror("setmntent");
    exit(1);
  }
  while (NULL != (ent = getmntent(aFile))) {
    printf("%s %s\n", ent->mnt_fsname, ent->mnt_dir);
  }
  endmntent(aFile);
}

可以在getmnent libc库调用中分析/etc/mtab来获取文件系统列表;否则就要使用/proc/mounts或/proc/self/mountinfo中的一个(现在建议使用/proc/mount)。

在/proc/filesystems记录了本机可能会用到的文件系统类型(内容有两列,以空格分隔),伪文件系统其首例为nodev,无类型指定即为本地文件系统,如下:
nodev    sysfs
nodev    rootfs
nodev    ramfs
nodev    bdev
nodev    proc
nodev    cgroup
nodev    cpuset
nodev    tmpfs
nodev    devtmpfs
nodev    debugfs
nodev    securityfs
nodev    sockfs
nodev    pipefs
nodev    anon_inodefs
nodev    configfs
nodev    devpts
nodev    hugetlbfs
nodev    autofs
nodev    pstore
nodev    mqueue
nodev    selinuxfs
    ext3
    ext2
    ext4
nodev    binfmt_misc
    iso9660
    fuseblk
nodev    fuse
nodev    fusectl

而/proc/mounts中记录了本机所有的文件系统挂载信息,其第二列就为常见的挂载点目录。
rootfs / rootfs rw 0 0
sysfs /sys sysfs rw,seclabel,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
devtmpfs /dev devtmpfs rw,seclabel,nosuid,size=32891936k,nr_inodes=8222984,mode=755 0 0
securityfs /sys/kernel/security securityfs rw,nosuid,nodev,noexec,relatime 0 0
tmpfs /dev/shm tmpfs rw,seclabel,nosuid,nodev 0 0
devpts /dev/pts devpts rw,seclabel,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /run tmpfs rw,seclabel,nosuid,nodev,mode=755 0 0
tmpfs /sys/fs/cgroup tmpfs ro,seclabel,nosuid,nodev,noexec,mode=755 0 0
cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0
pstore /sys/fs/pstore pstore rw,nosuid,nodev,noexec,relatime 0 0
cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,relatime,net_prio,net_cls 0 0
cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
cgroup /sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pids 0 0
cgroup /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0
cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0
cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
configfs /sys/kernel/config configfs rw,relatime 0 0
/dev/mapper/centos-root / ext4 rw,seclabel,relatime,data=ordered 0 0
selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0
systemd-1 /proc/sys/fs/binfmt_misc autofs rw,relatime,fd=30,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=13083 0 0
debugfs /sys/kernel/debug debugfs rw,relatime 0 0
hugetlbfs /dev/hugepages hugetlbfs rw,seclabel,relatime 0 0
mqueue /dev/mqueue mqueue rw,seclabel,relatime 0 0
/dev/vda1 /boot ext4 rw,seclabel,relatime,data=ordered 0 0
/dev/mapper/vg01-lv_apps /apps ext4 rw,seclabel,relatime,data=ordered 0 0
/dev/mapper/vg01-lv_data /data ext4 rw,seclabel,relatime,data=ordered 0 0
binfmt_misc /proc/sys/fs/binfmt_misc binfmt_misc rw,relatime 0 0
tmpfs /run/user/1000 tmpfs rw,seclabel,nosuid,nodev,relatime,size=6580580k,mode=700,uid=1000,gid=1000 0 0
fusectl /sys/fs/fuse/connections fusectl rw,relatime 0 0
mfs#172.16.13.26:9421 /mnt fuse rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other 0 0
tmpfs /run/user/0 tmpfs rw,seclabel,nosuid,nodev,relatime,size=6580580k,mode=700 0 0

即/proc/filesystems的第2列等于/proc/mounts的第3列,/proc/mounts的第2列就是常说的挂载点。

/proc/partitions
major minor  #blocks  name
 252        0  104857600 vda
 252        1     487424 vda1
 252        2  104369152 vda2
 252       16  209715200 vdb
 252       17  209714176 vdb1
 253        0   87588864 dm-0
 253        1   16777216 dm-1
 253        2   52424704 dm-2
 253        3  157286400 dm-3

可以使用/proc/partitions和/etc/mtab来获取分区列表,然后在每个分区之间循环执行statfs。可以取得挂载点的分区使用比,其底层调用了statvfs()与fstatvfs()的相关实现。


Linux 内核官方文档关于块设备
/sys/block/DEV-NAME/queue下记录了相关的定义类大小或开关字段


在/sys/block目录下查证哪些存储设备是机械硬盘(HDD)

块设备是否为真正的HDD,可以从man sd和man 4 hd中记录的与硬盘驱动器相对应的主要设备编号来参考得出:
SCSI and SATA disks have major 8, old IDE disks 3 or 22.

不过,此种方法在新的内核下不再那么有效了。

从/proc/devices中或解析/sys/block/*/dev 下的相关文件:
cd /sys/block; grep -lE '^(8|3|22):' */dev | sed 's-/dev--'
sda
sdb


一般来说,/proc包含了有关进程的信息,而不是文件系统的信息。如上所述,需要解析来自statfs()系统调用的结果。df就是使用了此规范的shell实用程序。

如果对指令输出这么多列数据不感兴趣,可以使用'--output'来指定输出(这同样对指令的版本有所要求):
df -h --output=target,avail


Tools to Monitor Linux Disk Partitions and Usage in Linux
fdisk (fixed disk)
sfdisk (scriptable fdisk)
cfdisk (curses fdisk)
Parted
lsblk (list block)
blkid (block id)
hwinfo (hardware info):hwinfo --short --block
df (disk filesystem)
pydf (python df):(Python Disk File System) is an advanced command line tool and a good alternative to Linux 'df comand'. It is used to display the amount of used and available disk space on a Linux file systems, same like df command, but in different colours. The output of the pydf command can be customizable according to your needs. Which on github too.


Linux下查看磁盘类型

方式1--/sys/block/
方式2--lsblk
方式3--fdisk
方法4--smartctl

方式1–/sys/block/

从/sys/block/DISK/queue/rotational的返回值(其中为硬盘设备名称,例如sda等等),如果返回1则表示磁盘可旋转,那么就是HDD了;反之如果返回0,则表示磁盘不可以旋转,那么就有可能是SSD了。

# grep ^ /sys/block/*/queue/rotational
/sys/block/dm-0/queue/rotational:1
/sys/block/dm-1/queue/rotational:1
...
/sys/block/dm-6/queue/rotational:1
/sys/block/sda/queue/rotational:1
/sys/block/sdb/queue/rotational:1
/sys/block/sdc/queue/rotational:1
/sys/block/sdd/queue/rotational:1
/sys/block/sde/queue/rotational:1
/sys/block/sr0/queue/rotational:1

# more /sys/block/sda/queue/rotational
1

这种方法有个问题,那就是/sys/block/下面不只有硬盘,还可能有别的块设备,它们都在干扰你的判断。

方式2–lsblk

使用lsblk命令进行判断,参数-d表示显示设备名称,参数-o表示仅显示特定的属性列。
# lsblk -o name,rota | grep sda
sda    1
├─sda1    1
├─sda2    1
└─sda3    1

方式3–fdisk

可以通过fdisk命令查看,参数-l表示列出磁盘详情。在输出结果中,以Disk开头的行表示磁盘简介,下面是一些详细参数,可以试着在这些参数中寻找一些HDD特有的关键字,比如:heads(磁头),track(磁道)和cylinders(柱面)。下面分别是HDD和SSD的输出结果,HDD拷贝自网络。

HDD磁盘

Disk /dev/sda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00074f7d

nvme磁盘

Disk /dev/nvme0n1: 238.5 GiB, 256060514304 bytes, 500118192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xad91c214

方法4–smartctl

第三方专业工具,其结果展示比较直观,但是需要单独安装smarttools软件包。
smartctl  -a /dev/sdf | grep Rotation

ssd 会输出如下结果
Rotation Rate:Solid State Device

hdd 会输出如下结果
Rotation Rate:7200 rpm


命令查看看dm-N设备映射

该设备是由使用LVM方式的文件分区代号。
# lvdisplay|awk '/LV Name/{n=$3} /Block device/{d=$3; sub(".*:","dm-",d); print d,n;}'
dm-0 /dev/datavg/datalv
dm-1 /dev/freeoa-vg/root
dm-2 /dev/freeoa-vg/swap_1


使用Perl来分析/proc/filesystems与/proc/mounts来取得主机上的非虚拟文件挂载情况

use v5.16;
use Data::Dumper;
use Fcntl qw(:DEFAULT :flock);

#22-09-11,从/proc的虚拟文件系统中取得本地块设备(block)的设备文件与挂载点信息

my @locrfs=('fuse');#本地块设备的文件系统类型:xfs,ext2+,etc

#先查出非虚拟的文件系统类型
sysopen(FS, "/proc/filesystems",O_RDONLY);
while(<FS>){
   chomp($_);
   my @fst = split(/\t+/,$_);
   push @locrfs,$fst[1] unless($fst[0]);
}
close(FS) || die "FS文件无法关闭...";

#从挂载信息中查看上述文件系统类型的挂载信息
sysopen(MNT,"/proc/mounts",O_RDONLY);
while(<MNT>){
    chomp($_);
    my @mnt = split(/\s+/,$_);
    say "$mnt[0]:$mnt[1]:$mnt[2]" if(grep { $_ eq $mnt[2] } @locrfs);
}

close(MNT) || die "MNT文件无法关闭...";

脚本除了输出本地真实的文件挂载信息外,还附加了'fuse'类型的信息:
/dev/mapper/centos-root:/:ext4
/dev/vda1:/boot:ext4
/dev/mapper/vg01-lv_apps:/apps:ext4
/dev/mapper/vg01-lv_data:/data:ext4
mfs#172.16.17.26:9421:/mnt:fuse



该文章最后由 阿炯 于 2022-09-11 21:38:08 更新,目前是第 2 版。