文件系统用于控制数据如何被保存和读取。不同的文件系统,其存取的机制不同。

文件系统是指整体目录结构(目录树),用于组织计算机系统中的文件。

即保存的数据(文件、目录等)是如何被组织和管理的。包括如何分配磁盘空间,如何管理元数据。

Linux 中,一切皆文件。

Linux 支持的文件系统:

  • 传统文件系统:EXT2 / minix / MS-DOS / FAT (用 vfat 模块) / iso9660 (光盘)

  • 日志式文件系统: EXT3 / EXT4 / ReiserFS / Windows’ NTFS / IBM’s JFS / SGI’s XFS / ZFS

  • 网络文件系统: NFS / SMBFS

4.1 重要概念

4.1.1 BLOCK

块。

操作系统读取硬盘时,不会一个个扇区地读取,效率太低,而是 一次性连续读取多个扇区,即一次性读取一个块。这种由多个扇区组成的块,是 文件存取的最小单位

每个块通常为 1KB 或 4 KB。

4.1.2 SUPERBLOCK

超级块。

超级块用于记录 文件系统的整体信息,不同的文件系统其超级块保存的信息不尽相同。

4.1.3 DATA BLOCKS

数据块,用于保存文件的实际内容。

4.1.4 INODE

Index Node,索引节点。

对于用户来说,文件系统是目录树的分层结构。对于 Linux 内核来说,文件系统是扁平的,没有层次。

内核使用 Inode 来代表每个文件。每一个文件都有对应的 Inode。

Inode 内容

📕 除了 文件名实际数据内容 之外,文件的所有信息都保存在 Inode 中。

Inode 包含文件的元信息,常见的有:

  • 文件大小

  • 文件拥有者 UID

  • 文件 GID

  • 文件的 RWX 权限

  • 文件的时间戳

    • ctime:Inode 上一次变动时间

    • mtime:文件内容上一次变动时间

    • atime:文件上一次打开时间

  • 链接数:硬链接数,即有多少文件名指向该 Inode

  • 数据块指针:数据块的位置

  • 隐藏属性

Inode 大小

Inode 也会消耗硬盘空间。

格式化分区时,操作系统自动将 硬盘分成两个区域。一个是 数据区,存放文件数据;另一个是 Inode 区(Inode表),存放 Inode 所包含的信息。

每个 Inode 节点的大小通常为 128 Bytes256 Bytes,每 1 KB 或 2 KB 就设置一个 Inode。Inode表通常占文件系统容量的 1% 左右。

在创建某些文件系统时,其 Inode 总数就被固定了,从而 限制了 该文件系统所能容纳的 文件总数

存储设备把 Inode 用光是完全可能的,此时即使仍有可用空间,也无法新建文件。经常发生在拥有大量小文件的服务器上,如邮件服务器。

XFS 文件系统没有该限制,因为它可以动态调整 Inode 的数量。

Inode 编号

每个 Inode 都有一个编号,操作系统用 Inode 编号来识别不同的文件。

移动或重命名文件,只是改变了文件名,Inode 编号不会改变。

例如,使用 vi 来编辑一个文件。当键入 vi filename 时,在 Inode 表中找到 Inode 编号之后,才允许打开该 Inode 。在 vi 的编辑会话期间,更改了该 Inode 中的某些属性,完成操作并键入 :wq 时,将关闭并释放该 Inode 。通过这种方式,如果两个用户试图对同一个文件进行编辑, Inode 已经在第一个编辑会话期间分配给了另一个 UID,因此第二个编辑任务就必须等待,直到该 Inode 释放为止。

Linux 系统内部 不使用文件名,而 使用 Inode 编号来识别文件。对于系统来说,文件名只是 Inode 编号便于识别的别名。

打开文件的过程:
  • 从目录文件中找到文件名对应的 Inode 编号

  • 读取 Inode 节点中的文件元数据

  • 读取数据块

如何记录大文件

如果文件太大, 一个 Inode 不足以记录全部的块。会利用 一层间接三层间接 来记录。

每个 Inode 可记录 12个直接号码,一个间接号码,一个双间接号码,一个三间接号码。

Inode 的特殊作用
  • 文件名包含特殊字符无法正常删除时,可以通过删除 Inode 节点来删除

  • 可以在不结束进程的情况下进行程序升级,无需重启。

因为系统通过 Inode 编号来识别运行中的文件。程序升级时,新版文件虽有相同文件名,但使用新的 Inode,不会影响到运行中的文件。再次运行该程序时,文件名会自动指向新版文件的 Inode,旧版文件的 Inode 则被系统回收。

4.1.5 目录文件

Linux 系统中,目录也是一种文件。打开目录,实际上就是打开目录文件。

目录文件结构

目录文件是由多个目录项组成的列表:

  • 目录项: 文件名 + Inode 编号

目录文件的权限

目录文件的读权限和写权限,都是针对目录文件本身。

  • 权限:允许 读取 目录文件中的 文件名

  • 权限:允许 修改 目录文件中的 目录项

  • 执行 权限:允许借由 Inode 编号 读取 Inode 节点中的所有 元数据,从而访问文件真实数据

新建文件的过程
  1. 确定用户对目录有 w x 权限

  2. 依据 Inode 位图找到可用 Inode,在其中写入新文件的权限和属性

  3. 根据块位图找到可用的块,写入文件数据,更新 Inode 的数据块指针

  4. 同步更新 Inode 位图、块位图、超级块

4.1.6 链接文件

一般情况下,文件名和 Inode 编号是 “一一对应” 关系,每个 Inode 编号对应一个文件名。

硬链接

硬链接原理
硬链接概念

多个文件名指向同一个 Inode 编号

源文件与目标文件的 Inode 编号相同,都指向同一个 Inode。

硬链接特点
  • 可以用不同的文件名访问同一文件

  • 对文件内容进行的修改,会 影响到所有文件名

  • 删除一个文件名,不影响另一个文件名的访问

  • Inode 中不保存硬链接名称。

  • 不能跨文件系统

  • 不能链接目录

链接数

Inode 信息中有一项叫做链接数,即该文件的 硬链接数,用于记录指向该 Inode 的文件名总数。

  • 为文件创建新的硬链接时,链接数会加 1。

  • 删除一个文件名,链接数减 1

  • 链接数减到 0 时,表明不再有文件名指向该 Inode,系统会回收该 Inode 编号及其对应的数据块

链接数减到 0 时意味着该文件已被删除,其占用的空间将变成可用。但实际上,要等到 所有打开该文件的进程都不再访问时,才会真正执行删除

  • 目录文件的链接数为 2 + 子目录数

创建目录时,默认会生成两个目录项:”.” 和 “..”。. 的 Inode 编号就是当前目录的 Inode 编号,等同于当前目录的 “硬链接”;.. 的 Inode 编号是当前目录的父目录的 Inode 编号,等同于父目录的 “硬链接”。

  • 新建子目录时,其上级目录的链接数会加 1

  • 删除子目录时,其上级目录的链接数会减 1

符号链接

Symbolic Link,又叫软链接。

软链接原理
符号链接概念

文件 A 和文件 B 的 Inode 编号虽然不一样,但是文件 A 的内容是文件 B 的路径。读取文件 A 时,系统会自动将访问者导向文件 B。因此,无论打开哪一个文件,最终读取的都是文件 B。文件 A 就称为文件 B 的符号链接。

  • 符号链接依赖于原始文件而存在,如果删除了原始文件,打开链接文件就会报错:”No such file or directory”。

软硬链接的区别

软硬链接区别
  软链接 硬链接
删除链接后 目标不受影响 链接数减 1,到 0 时删除
删除目标后 失效 有效
跨文件系统 支持 不支持
链接到文件 支持 支持
链接到目录 支持 不支持

4.2 Linux 文件系统的特点

Linux 使用 异步 处理的方式来 避免频繁 的磁盘读写导致的低效。

4.2.1 异步更新

当系统加载一个文件到内存后,如果文件没被改过,在内存区段的文件数据被设置为 Clean。如果被修改了,被设置为 Dirty。此时所有的动作都还在内存中执行,并没有写入到磁盘中,系统会 不定时 的将内存中设置为 Dirty 的数据 写回磁盘,以 保持磁盘与内存数据的一致

  • 可以用 sync 命令来强制把内存数据写入磁盘,即 强制更新

4.2.2 文件系统与内存

  • 常用的文件放到内存的 缓冲区,以加速文件系统的读写

  • 实体 内存 将被 完全占用

  • 可以手动 sync

  • 关机命令会 自动执行 sync

  • 非正常关机 重启后,要花 很久 做磁盘 校验,甚至导致 文件系统损坏

4.3 索引式文件系统

索引式文件系统

使用 inode 与 block 能够高效读取全部数据, 读写的性能好。极少需要碎片整理。EXT 系列均属索引式文件系统。

  • FAT 文件系统
非索引文件系统

没有 inode,每个块编号都记录在前一个块中,读取性能很差,有时需要整理磁盘碎片,以便把同一个文件所属的 blocks 聚集在一起。

4.4 日志式文件系统

Journaling File System

EXT 3 以后的版本,以及 XFS,均属于日志式文件系统。

4.4.1 文件系统不一致

Inconsistent

对文件系统进行修改时,如果操作被异常中断,可能会造成文件系统出现不一致。

例如:删除文件时,先要从目录树中移除文件的标示,然后收回文件占用的空间。如果在这两步之间操作被打断,文件占用的空间就无法收回。文件系统认为它是被占用的,但实际上目录树中已经找不到使用它的文件了。

在非日志文件系统中,要检查并修复类似的错误就必须对整个文件系统的数据结构进行检查。一般在挂载文件系统前,操作系统会检查它上次是否被成功卸载,如果没有,就会对其进行检查。如果文件系统很大或者 I/O 带宽有限,这个操作可能会花费很长时间。

4.4.2 日志式文件系统

为了避免这样的问题,日志文件系统分配了一个称为日志(journal)的区域,来提前记录要对文件系统做的更改。系统崩溃以后,只要读取日志重新执行未完成的操作,文件系统就可以恢复一致。

  1. 准备:把 准备写入的信息 记录到日志

  2. 写入:写入文件的权限与数据,更新元数据;

  3. 结束:完成该文件的记录。

需要时检查日志记录,就可以知道哪个文件发生了问题,便于 快速修复

4.5 SWAP

4.5.1 交换的概念

Swapping,交换。

Linux 把其物理内存 RAM 分成一些内存区块,称为页面(PAGES),此时 就成了针对 SWAP 的量词。

把一页内存复制到硬盘中预分配的空间中,这一过程就叫做交换,Swapping。预分配的硬盘空间称为交换空间,交换的目的是释放该页的内存。物理内存加上交换空间,合起来就是 可用虚拟内存 的大小。

4.5.2 使用交换的原因

系统需要更多的可用内存

内核把不常使用的页面交换出去,把内存交给当前迫切需要的应用

清理初始化页面

大量的被应用程序占用的页面,往往是为了其初始化,而仅在程序启动时使用,之后便再也不用。非常有必要清理掉这部分页面,给需要的程序。

休眠

如果主机支持休眠,交换空间用来 记录 运行中的程序状态,以便据此 “唤醒” 主机。

4.5.3 SWAP 的缺点

与内存相比,硬盘的读取速度更慢。发生的交换越多,系统越慢。

当系统需要频繁地进行交换时,说明系统急需增加物理内存。

4.5.4 SWAP 的形式

交换分区

单独用于交换的独立分区,不能保存其它文件。

交换文件

交换文件是一种特殊文件。

4.5.5 创建 SWAP

创建交换分区

新建分区

gdisk /dev/vda

swap 的 Hex code 8200

格式化

mkswap /dev/vda6

挂载

swapon [-d] [-f] [-p priority] [-v] specialfile...

swapon /dev/vda6   挂载该交换分区

swapon -s    列出当前所有交换设备

UUID="6b17e4ab-9bf9-43d6-88a0-73ab47855f9d" swap swap defaults 0 0 添加 FSTAB 条目

因为不是文件系统,所以 没有挂载点,故文件系统和挂载点均用 swap 代替。

创建交换文件

创建伪文件

dd if=/dev/zero of=/tmp/swap bs=1M count=128

格式化

mkswap /tmp/swap

挂载

swapon /tmp/swap

自启动

/tmp/swap swap swap defaults 0 0 创建 FSTAB 条目

UUID 只能用来查询块设备,而无法查询文件,所以挂载文件不能使用 UUID。

4.6 Linux VFS

VFS,Virtual Filesystem Switch,或 Virtual File System

整个 Linux 的系统都是通过 VFS 的内核功能去读取文件系统的。

VFS 是实体文件系统上面的一个抽象层。其目的是允许客户端程序以统一的方式,来访问不同类型的实体文件系统。

VFS 可用于透明地访问本地或网络存储设备,而客户端程序几乎察觉不到其区别。同样也可以用于连接 Windows,Mac OS,Unix 的文件系统,应用程序无需了解各文件系统的不同,便可以在本地文件系统访问不同的资源。

VFS

4.7 创建文件系统

创建文件系统的一般流程:

  1. 对磁盘进行 分区

  2. 格式化分区,以 创建文件系统

  3. 创建 挂载点,将其挂载到系统

4.7.1 创建设备文件

mknod 命令用于创建特殊设备文件。

mknod 设备文件名 [bcp] [Major] [Minor]

设备种类

.. b 块设备文件

.. c 字符设备文件

.. p FIFO 文件

Major 主要设备代码;

Minor 次要设备代码;

设备代码

设备文件的属性中,有一对数字,MajorMinor,这两个数字会 映射 到内核已经加载的某个 驱动程序 上,内核通过这种方式来确定哪个设备文件该使用哪个驱动程序来访问。

    ls -l /dev/sda*

    brw-rw----. 1 root disk 8, 0 Jun 24 02:30 /dev/sda
    brw-rw----. 1 root disk 8, 1 Jun 24 02:30 /dev/sda1
    brw-rw----. 1 root disk 8, 2 Jun 15 23:43 /dev/sda2

常见的磁盘文件对应的设备代码如下所示:

磁盘文件名 Major Minor
/dev/sda 8 0-15
/dev/sdb 8 16-31
/dev/loop0 7 0
/dev/loop1 7 1

范例

  • 创建块设备

mknod /dev/vda10 b 252 10

  • 创建 FIFO 设备

mknod /tmp/testpipe p

4.7.2 格式化

格式化的目的是在某个设备上 创建文件系统

MKFS

make filesystem,是个 综合 的命令,可以调用不同的文件系统格式化工具。

MKFS.xfs

mkfs.xfs [-b bsize] [-d parms] [-i parms] [-l parms] [-L label] [-f] [-r parms] 设备名称

单位:扇区 s,块(默认) b,字节 kmgtpe

-b 块大小,512 ~ 64k,Linux 最大限制 4k

-f 忽略设备现有文件系统,强制格式化

-L 卷标

-d 数据区参数:

.. agcount AG数量,与 CPU 有关

.. agsize AG 大小,agcount/agsize 只选一个设置即可

.. file 格式化的设备是文件而不是设备

.. size 数据区大小

.. su RAID 中 stripe 值

.. sw RAID 中用于保存数据的磁盘数量(扣除备份盘与备用盘)

.. sunit 与 su 相当,单位是扇区

.. swidth su*sw,单位是扇区

-i Inode 设置:

.. size Inode 大小,256 Bytes ~ 2k,一般 256

.. internal 日志设备是否为内置,1 内置(默认),0 外置

.. logdev 指定外置日志设备

.. size 日志设备大小,至少 512 blocks,最好大于 2M

-r realtime section 设置:

.. extsize extent 大小,一般不须设置。有 RAID 时,最好设置与 swidth 的数值相同, 4K ~ 1G

范例
  • mkfs.xfs /dev/sda4

用默认值(xfs, Linux filesystem)

  • 根据 CPU 数量来确定 AG 数量

mkfs.xfs -f -d agcount=2 /dev/sda4

  • 格式化伪设备

mkfs.xfs -f /srv/loopdev

MKFS.ext4

mkfs.ext4 -b size -L label 设备名称

-b block 大小,1K, 2K, 4K

-L 设备卷标

MKFS.其他

mkfs.btrfs mkfs.cramfs mkfs.ext2 mkfs.ext3 mkfs.ext4

mkfs.fat mkfs.minix mkfs.msdos mkfs.vfat mkfs.xfs

mkfs -t vfat /dev/vda5

4.7.3 挂载

挂载就是把一个 目录 当做 接入点,把磁盘 分区 的数据放置在该目录下。

接入点的目录称为 挂载点,该目录为进入该文件系统的入口。

挂载点的概念

文件系统挂载原则

  • 一个文件系统不能同时挂载在不同的挂载点中

  • 一个目录不能同时挂载多个文件系统

  • 作为挂载点的目录,理论上应该都是空目录

如果挂载点目录不是空的,当挂载上新分区时,目录会显示新分区内的数据,而把目录中原来的文件 暂时隐藏 起来,等新分区卸载之后,目录中原来保存的文件可以被再次访问。

MOUNT

mount -t 文件系统 UUID='' 挂载点

mount -t 文件系统 LABEL='' 挂载点

mount -t 文件系统 设备文件名 挂载点

-a 依据 /etc/fstab 挂载所有设备

-l 显示卷标

-t 指定挂载的文件系统类型,xfs, ext3, ext4, vfat, nfs, iso9660, cifs, reiserfs, smbfs

-n 挂载的信息不会写入 /etc/mtab,常用于只读文件系统

-o 额外参数,用逗号分隔:

.. async, sync 内存机制为同步还是异步,默认为异步

.. atime, noatime 是否更新文件的访问时间

.. ro, rw 挂载文件系统成为只读或可写

.. auto, noauto 允许被 mount -a 自动挂载

.. dev, nodev 允许此文件系统上创建设备文件

.. suid, nosuid 是否支持 suid/sgid

.. exec, noexec 是否允许可执行文件的存在

.. user, nouser 是否允许普通用户运行 mount

.. defaults 使用默认值(rw, suid, dev, exec, auto, nouser, async)

.. remount 重新挂载

.. loop Loop 设备,一种伪设备,使文件可以作为块设备被访问

自动检测文件系统类型

挂载时,即使不指定文件系统类型,Linux 也会根据 /etc/filesystems 文件中的优先顺序,来逐个测试。

通过分析 超级块,结合各自驱动程序来测试挂载,如果匹配成功,则使用该类型的文件系统挂载。

挂载各种文件系统范例

挂载光盘镜像

mount -o loop /tmp/CentOS-DVD.iso /data/dvd

挂载伪设备

mount -o loop UUID="7dd97bd2-4446-48fd-9d23-a8b03ffdd5ee" /mnt

挂载 xfs/ext4/vfat 等文件系统

mount UUID="e0a6af55-26e7-4cb7-a515-826a8bd29e90" /data/xfs

挂载光盘

mount /dev/sr0 /data/cdrom

挂载 U 盘

mount -o codepage=950,iocharset=utf8 UUID=""35BC-6D6B"" /data/usb

挂载目录

mount --bind /where /data/elsewhere

重新挂载根目录

当系统进入单人维护模式时,根目录常会被系统挂载为只读,在不重启的情况下重新挂载根目录:

mount -o remount,rw,auto /

UMOUNT

卸载设备

umount -fn 设备文件名或挂载点

-f 强制卸载,可用于NFS无法读取的情况

-l 立刻卸载文件系统,比 -f 还强

-n 卸载后不更新 /etc/mtab

4.7.4 设置启动挂载

系统挂载的原则

  • 根目录是必须挂载的﹐且要先于其它挂载点挂载

  • 其它挂载点必须为已创建的目录,需遵守 FHS

  • 所有挂载点在同一时间之内﹐只能挂载一次。

  • 所有分区在同一时间之内﹐只能挂载一次。

  • 卸载前须将工作目录 移出挂载点

FSTAB

/etc/fstab 用来决定启动时自动挂载哪些设备。

使用 mount 命令挂载设备时,系统会把所有的选项和参数都写入 /etc/fstab 中。

语法

[设备] [挂载点] [文件系统类型] [文件系统参数] [dump] [fsck]

  • 设备:设备文件名、UUID、卷标均可

  • 文件系统参数:包括特定文件系统专有参数 以及 通用的参数

通用参数:

参数 内容意义
async/sync 默认为异步,性能较好
auto/noauto 是否会被 mount -a 自动挂载。默认为 auto。
dev, nodev 允许此文件系统上创建设备文件
rw/ro 把分区以读写或只读方式挂载
exec/noexec 文件系统内是否允许可执行程序运行。
user/nouser 是否允许用户使用 mount 命令来挂载
suid/nosuid 是否允许 SUID
defaults async, auto, dev, rw, exec, nouser, suid
  • dump

dump 备份命令对其是否起作用,设置为 0 表示不用。

  • fsck

是否需要使用 fsck 在启动时校验文件系统的完整性(clean)。

xfs 文件系统不适用,因为 xfs 会自己进行校验,不需要额外操作,因此设置为 0。

编辑 FSTAB

把需要自动挂载的设备加入 /etc/fstab 配置文件中。

UUID=84f7aabf-238f-4561-808d-8414f522c62b /boot xfs defaults 0 0 挂载启动分区

/srv/loopdev /data/file xfs defaults,loop 0 0 挂载伪设备

UUID="6b17e4ab-9bf9-43d6-88a0-73ab47855f9d" swap swap defaults 0 0 挂载交换分区

测试是否会被自动挂载:

mount -a

df /data/xfs

如果因编辑 /etc/fstab 时格式错误,而导致无法启动,而进入单人维护模式时,可以使用 mount -n -o remount,rw / 重新加载根目录。

4.8 文件系统的校验

系统非正常关机会导致文件系统出现数据不一致的情况,需要在系统启动时执行文件系统校验。

如果在系统启动以后进行校验,必须提前 卸载分区

4.8.1 XFS_REPAIR

xfs_repair 用于修复损坏的 xfs 文件系统。修复前必须卸载文件系统,否则可能导致数据不一致或损坏。

xfs_repair [options] 设备名称

设备名称可以为分区或磁盘。

-f 修复普通文件,而非设备

-n 仅检查

-d 单人维护模式,针对根目录进行检查与修复,很危险!

根目录无法被卸载,出问题要进入 单人维护或修复模式,然后通过 -d 选项来处理。加入 -d,系统会 强制校验 该设备,校验完毕后会 自动重启

4.8.2 FSCK

fsck 实际上是一套前端软件,后端为各类文件系统的修复程序。包括:

fsck.ext2fsck.ext3fsck.ext4fsck.msdosfsck.nfsfsck.vfatfsck.xfs 等。

  • fsck.ext4

fsck.ext4 实际程序为 e2fsck,用于修复 EXT 家族文件系统,需先卸载挂载点。

fsck.ext4 -pf -b 超级块 设备名称

设备名称可以是设备文件、挂载点、UUDI、卷标。

-p 修复时,对提问自动回复 y

-f 强制检查

-D 对文件系统的目录进行最优配置。

-b 指定 超级块 的位置

通过 -b 这个参数即可在主 超级块 损坏时,尝试用备份的 超级块 修复。1K 的块其 超级块 备份在 8193,2K 的块在 16384,4K块在 32768。可以先用 mke2fs -n /dev/sda5 命令来检查备份 superblcok 的位置。

4.9 修改文件系统参数

修改文件系统卷标、UUID等参数。

XFS_ADMIN

xfs_admin 用于修改 XFS 的参数,需要先卸载分区。

xfs_admin [-lu] [-L label] [-U uuid] 设备文件名

-l 查看设备卷标

-L 设置设备卷标

-u 查看设备 UUID

-U 设置设备 UUID

  • 修改卷标

xfs_admin -L vbird_xfs /dev/vda4

  • 修改 UUID

xfs_admin -U e0fa7252-b374-4a06-987a-3cb14f415488 /dev/vda4

TUNE2FS

修改 EXT 的卷标与 UUID

tune2fs -l -L Label -U uuid 设备文件名

-l 读取 超级块 中的数据

-L 修改卷标

-U 修改 UUID

tune2fs -L vbird_ext4 /dev/vda5

4.10 磁盘配额

Disk Quota,磁盘配额。

4.10.1 Quota 简介

磁盘配额是由系统管理员设定的,针对文件系统各要素的一个 限额

磁盘配额旨在合理分配有限的磁盘空间。

4.10.2 Quota 类型

  • Block Quota:限制块数量,从而限制可用磁盘空间
  • Inode Quota:限制 Inode 数量,从而限制可用文件数量

4.10.3 Quota 级别

  • Soft Quota:柔性限额,超过此限额后,用户会收到警告信息
  • Hard Quota:硬性限额,超过此限额后,用户无法创建新文件

宽限期

为了给当前用户一些时间来减少其文件占用,可以配置宽限期。在超过柔性限额,未到刚性限额时,用来为用户或组设定一个期限。

4.10.4 Quota 应用对象

在 XFS 中,可以针对以下对象设定配额:

  • 用户
  • 目录

组限制与目录限制无法并存。

4.10.5 Quota 用途

  • WWW server:限制每人的网站空间
  • mail server:限制每人的邮件空间
  • file server:限制每人最大可用空间
  • 针对组的磁盘配额
  • 针对用户的磁盘配额
  • 针对目录的磁盘配额

4.10.6 EXT 与 XFS 使用配额的区别

EXT 家族仅支持对 整个文件系统 做磁盘配额,即对 挂载点 进行配置。xfs 可以针对 特定项目 进行配额,即对指定的 目录 来配置。

XFS 的配额是 整合到文件系统 中的,并非由外部程序管理。通过配额直接统计磁盘使用率,更快速。如 du 为第三方工具,它会重新计算目录下的磁盘使用率,但 xfs_quota 则无需计算,可以直接显示特定目录的磁盘使用率,快很多。

XFS 与 EXT 配额使用对照

设置流程项目 XFS 文件系统 EXT 家族
/etc/fstab参数设置 usrquota/grpquota/prjquota usrquota/grpquota
配额配置文件 不需要 quotacheck
设置用户/群组限制值 xfs_quota -x -c “limit…” edquota 或setquota
设置宽限时间 xfs_quota -x -c “timer…” edquota
设置目录限制值 xfs_quota -x -c “limit…”
查看报告 xfs_quota -x -c “report…” repquota 或quota
启动与关闭配额限制 xfs_quota -x -c “[disable\| enable]…” quotaoff, quotaon
发送警告信给用户 目前版本尚未支持 warnquota

4.10.7 Quota 的限制

  • 在 EXT 上,仅能针对整个文件系统,无法针对目录。
  • 内核必须支持 quota
  • 只对普通用户有效
  • 若启用 SELinux,仅能针对 /home 进行设置。要想设置其他目录,需解除 SELinux 限制。

4.10.8 XFS_QUOTA

语法

xfs_quota 用于生成配额的详细报告,设置各种配额参数。

xfs_quota -x -c "子命令" [挂载点]

-x 专家模式,用于接 -c 子命令

-c子命令

子命令
用户子命令

print 查看当前主机内的文件系统、对应的路径

df 与 df 功能相同,可以加上 -b(block)-i(inode)-h(加上单位)

report 列出目前的配额项目,可接 -ugr (user/group/project) 及 -bi 等参数

state 查看当前具体的配额设置

管理员子命令

disable 暂时禁用配额的限制。其实系统还是在计算配额,只是没有管制。

enable 启用配额限制,恢复正常管制。

off 针对文件系统完全关闭某类配额的限制。只有卸载、重新挂载才能再次启用配额。

remove 清除所有配额设置,必须在 off 状态下进行。

范例

暂时禁用配额

xfs_quota -x -c "disable -up" /home

重新恢复配额

xfs_quota -x -c "enable -up" /home

关闭文件系统项目配额限制

xfs_quota -x -c "off -p" /home

此时查看发现用户配额限制正常,但项目配额消失。卸载挂载点,重新挂载后项目配额恢复。

清除某类配额

要先使用 off 子命令来关闭该类配额,然后再用 remove 清除。

xfs_quota -x -c "off -u" /home 关闭用户配额限制

xfs_quota -x -c "remove -u" /home 清除用户配额设置

umount /home; mount -a 重新挂载

再次检查发现用户配额设置全部清除,项目配额还在

remove 会清除所有用户或所有项目的配额,无法针对特定用户或项目单独清除。

4.11 Linux 目录结构

4.11.1 目录树

  • 目录树的启始点为根目录;

  • 每一个目录不仅能使用本地分区的文件系统,也可以使用 网络文件系统。可以用 NFS 服务器挂载特定目录。

  • 每一个文件在此目录树中的文件名(包含完整路径)都是独一无二的。

目录树

根据 FHS 的定义,建议把 /var 分区 独立 出来, 利于保护系统数据。

4.11.2 FHS

Filesystem Hierarchy Standard,文件系统结构层次标准

FHS 的重点在于规范每个特定的目录下应放置什么数据。

  可共享 不可共享
静态数据 /usr /etc
静态数据 /opt /boot
变化数据 /var/mail /var/run
变化数据 /var/spool/news /var/lock
  • 可共享:可被其他操作系统挂载的目录

  • 不可共享:设备文件、socket 文件

  • 静态数据:函数库、文件说明文档、主机服务配置文件

  • 变化数据:日志、用户邮件

FHS 规范

必选
目录 用途
/bin 可执行文件 cat, chmod, chown, date, mv, mkdir, cp, bash
/boot 系统启动所需文件 vmlinuz, grub2
/dev 设备文件 /null, /zero, /tty , /loop*, /sd*
/etc 系统配置文件 /modprobe.d/, /passwd, /fstab, /issue, /opt
/lib 函数库 /modules
/media 可移除的设备 /floppy, /cdrom
/mnt 临时挂载设备  
/opt 第三方程序  
/run 系统启动后产生的数据  
/sbin 启动、修复、还原系统所需程序 fdisk, fsck, ifconfig, mkfs
/srv 网络服务数据 /srv/www/
/tmp 普通用户或运行中程序临时文件  
/usr 发行版自带程序  
/var 变化的数据 log等
可选
目录 用途
/home 用户家目录
/lib64 64位程序的函数库
/root root用户家目录,与根目录同一分区
其它
目录 用途
/lost+found EXT 文件系统专用,当文件系统发生错误时,将一些丢失的片段放到该目录
/proc 虚拟文件系统,目录中的文件实际在内存中,不占硬盘空间
/sys 虚拟文件系统,记录当前已载入的内核模块,内核检测到的硬件设备等,不占硬盘空间

根目录

所有的目录都由根目录衍生出来,同时根目录也与 启动、还原、系统修复 有关。

根目录所在分区越小越好,不要与应用程序放在同一个分区,以保证系统的高性能,高稳定性。

/usr 目录

Unix Software Resource,保存系统内置程序,可共享、不可变。

FHS 建议软件开发者将数据分别保存到 usr 的子目录,不要创建独立的目录,以利管理。

必选
子目录 用途
/usr/bin/ 普通用户可用程序
/usr/lib/ 与 /lib 功能相同
/usr/local/ 系统管理员在本机安装自己下载的软件,建议安装到此目录。
/usr/sbin/ 扩展系统功能的系统命令。网络服务器软件的服务命令等。
/usr/share/ 只读架构的数据文件,包括共享文件。几乎都是文本文件/usr/share/man:线上说明文档/usr/share/doc:软件杂项的文件说明/usr/share/zoneinfo:与时区有关的时区文件
可选
子目录 用途
/usr/games/ 游戏
/usr/include/ c/c++等程序语言的header与include
/usr/libexec/ 不常用的脚本或可执行文件
/usr/lib64/ 64位程序函数库
/usr/src/ 源代码

/var 目录

/var 是在系统运行后才会渐渐占用硬盘空间的目录,主要针对常态性变化的文件,包括高速缓存、日志等。

必选
子目录 用途  
/var/cache/ 应用程序运行中产生的缓存文件  
/var/lib/ 程序执行过程中用到的数据文件 /var/lib/mysql/,/var/lib/rpm
/var/lock/ 锁定设备文件,以确保该设备同时只给一个软件使用 链接到 /run/lock 中
/var/log/ 日志文件 /var/log/messages,/var/log/wtmp
/var/mail/ 电子邮件 链接到 /var/spool/mail/
/var/run/ 某些程序或者是服务启动后,将他们的 PID 放在这里 链接到 /run
/var/spool/ 通常放置一些队列数据* *

/proc/ 目录

proc 是 Linux 系统很重要的目录。与 /etc/home 等目录不同,它不是一个真正的文件系统,而是一个 虚拟 的文件系统。它不存在于磁盘,而存在于系统 内存 中。所以用 ls -al /proc 查看时,会看到目录下文件的大小都为 0 字节。proc 以文件系统的方式 为访问系统内核的操作提供接口

很多 系统信息 都可以通过查看 /proc 下的对应文件来获得。proc 文件系统是 动态 从系统内核读出所需信息的。

当前主机上各进程的 PID 都以 目录 的形式保存在 /proc

/proc 目录中常见内容:

文件名 文件内容
/proc/cmdline 载入内核时所运行的命令与参数,查看此文件,可了解命令是如何启动的
/proc/cpuinfo 本机的 CPU 信息,包含频率、类型与运算功能等
/proc/devices 主要设备
/proc/filesystems 系统已载入的文件系统
/proc/interrupts 系统当前 IRQ 分配
/proc/ioports 系统各设备的 I/O 位址
/proc/kcore 内存的大小
/proc/loadavg 平均负载
/proc/meminfo 内存信息
/proc/modules 已载入的模块,即驱动程序
/proc/mounts 挂载的数据
/proc/swaps 用于计量交换空间及使用情况
/proc/partitions 所有分区
/proc/uptime 运行时间
/proc/version 核心的版本
/proc/bus/* 总线设备,USB 设备

其它

CentOS 7 目录结构有所变化。以前版本的根目录中的某些目录,被转移到 /usr 里了,并链接过去。

  • /bin  –  /usr/bin

  • /sbin  –  /usr/sbin

  • /lib  –  /usr/lib

  • /lib64  –  /usr/lib64

  • /var/lock  –  /run/lock

  • /var/run  –  /run

4.12 目录与路径

4.12.1 相对路径与绝对路径

  • 绝对路径:相对根目录而言的路径。

  • 相对路径:相对当前所在位置的路径。

4.12.2 目录操作

路径表示方法

. 当前目录

.. 上级目录

- 前一个工作目录

~ 当前用户的家目录

~account 指定用户的家目录

📕 所有目录中都存在两个目录:...,自己和上层目录。

cd

Change the current directory to … 切换目录

cd ~neo到 neo 的家目录

cd ~到自己的家目录

cd到自己的家目录

cd ..到上层目录

cd -到刚才的目录

cd /var/spool/mail绝对路径

cd ../postfix相对路径

pwd

Print Working Directory 查看当前工作目录

pwd -P

-P 显示真实路径,而非链接路径。

mkdir

创建目录

mkdir -mp 目录名

-m 设置文件夹权限

-p 递归创建

rmdir

删除空目录

rmdir -p 递归删除空目录

4.12.3 $PATH 变量

环境变量之一。

系统会按照 PATH 的设置来查找可执行文件,如果一个文件同时存在 PATH 定义的多个目录中,则执行 第一个 找到的文件。

PATH 变量由一堆目录组成,每个目录中间用冒号(:)隔开,按 优先级 排序。

  • 如果要运行的命令所处的目录不在 PATH 变量中,有两个办法可以使用该命令:

    • 用绝对路径 /root/ls ,用起来比较麻烦

    • 把该命令的路径加入 PATH 变量,PATH="${PATH}:/root",这样就可以只用命令名来执行了

  • 安全起见,不建议将当前目录 . 加入 PATH 变量中。

  • 不同用户其默认的 PATH 不同,默认能够随意执行的命令也不同

  • PATH 是可以修改的

  • 命令应该要放置到正确的目录下,执行才会比较方便

6.4 文件系统占用的空间

df

查看 文件系统 磁盘空间用量。

df [OPTION]... [FILE]...

-a 所有的文件系统,包括系统特有的 /proc 等文件系统;

-k 以 KBytes 为单位

-m 以 MBytes 为单位

-h 人性化的单位显示

-H 用 M=1000K 替换 M=1024K

-T 显示文件系统类型

-i 不用磁盘容量,而用 inode 的数量

📕 df 命令是通过读取 超级块 来获取信息的。

du

查看 目录或文件 所占空间

du [OPTION]... [FILE]...

-a 不只目录,也包括所有的文件

-h 人性化显示

-s 只显示总计

-S 不显示子目录

由于 du 默认会显示所有文件以及子目录的大小,加上 -S 可以 避免重复计算

-k 以 KBytes 为单位

-m 以 MBytes 为单位