标签 文件系统 下的文章

本文旨在高屋建瓴地来讨论 Linux 文件系统概念,而不是对某种特定的文件系统,比如 EXT4 是如何工作的进行具体的描述。另外,本文也不是一个文件系统命令的教程。

每台通用计算机都需要将各种数据存储在硬盘驱动器(HDD)或其他类似设备上,比如 USB 存储器。这样做有两个原因。首先,当计算机关闭以后,内存(RAM)会失去存于它里面的内容。尽管存在非易失类型的 RAM,在计算机断电以后还能把数据存储下来(比如采用 USB 闪存和固态硬盘的闪存),但是,闪存和标准的、易失性的 RAM,比如 DDR3 以及其他相似类型的 RAM 相比,要贵很多。

数据需要存储在硬盘驱动上的另一个原因是,即使是标准的 RAM 也要比普通硬盘贵得多。尽管 RAM 和硬盘的价格都在迅速下降,但是 RAM 的价格依旧在以字节为单位来计算。让我们进行一个以字节为单位的快速计算:基于 16 GB 大的 RAM 的价格和 2 TB 大的硬盘驱动的价格。计算显示 RAM 的价格大约比硬盘驱动贵 71 倍。今天,一个典型的 RAM 的价格大约是 0.000000004373750 美元/每字节。

直观的展示一下在很久以前 RAM 的价格,在计算机发展的非常早的时期,其中一种类型的 RAM 是基于在 CRT 屏幕上的点。这种 RAM 非常昂贵,大约 1 美元/每字节。

定义

你可能听过其他人以各种不同和令人迷惑的方式谈论过文件系统。文件系统这个单词本身有多重含义,你需要从一个讨论或文件的上下文中理解它的正确含义。

我将根据我所观察到的在不同情况下使用“文件系统”这个词来定义它的不同含义。注意,尽管我试图遵循标准的“官方”含义,但是我打算基于它的不同用法来定义这个术语(如下)。这就是说我将在本文的后续章节中进行更详细的探讨。

  1. 始于顶层 root(/)目录的整个 Linux 目录结构。
  2. 特定类型的数据存储格式,比如 EXT3、EXT4、BTRFS 以及 XFS 等等。Linux 支持近百种类型的文件系统,包括一些非常老的以及一些最新的。每一种文件系统类型都使用它自己独特的元数据结构来定义数据是如何存储和访问的。
  3. 用特定类型的文件系统格式化后的分区或逻辑卷,可以挂载到 Linux 文件系统的指定挂载点上。

文件系统的基本功能

磁盘存储是文件系统必须的功能,它与之伴生的有一些有趣而且不可或缺的细节。很明显,文件系统是用来为非易失数据的存储提供空间,这是它的基本功能。然而,它还有许多从需求出发的重要功能。

所有文件系统都需要提供一个名字空间,这是一种命名和组织方法。它定义了文件应该如何命名、文件名的最大长度,以及所有可用字符集中可用于文件名中字符集子集。它也定义了一个磁盘上数据的逻辑结构,比如使用目录来组织文件而不是把所有文件聚集成一个单一的、巨大的文件混合体。

定义名字空间以后,元数据结构是为该名字空间提供逻辑基础所必须的。这包括所需数据结构要能够支持分层目录结构,同时能够通过结构来确定硬盘空间中的块是已用的或可用的,支持修改文件或目录的名字,提供关于文件大小、创建时间、最后访问或修改时间等信息,以及位置或数据所属的文件在磁盘空间中的位置。其他的元数据用来存储关于磁盘细分的高级信息,比如逻辑卷和分区。这种更高层次的元数据以及它所代表的结构包含描述文件系统存储在驱动器或分区中的信息,但与文件系统元数据无关,与之独立。

文件系统也需要一个应用程序接口(API),从而提供了对文件系统对象,比如文件和目录进行操作的系统功能调用的访问。API 也提供了诸如创建、移动和删除文件的功能。它也提供了算法来确定某些信息,比如文件存于文件系统中的位置。这样的算法可以用来解释诸如磁盘速度和最小化磁盘碎片等术语。

现代文件系统还提供一个安全模型,这是一个定义文件和目录的访问权限的方案。Linux 文件系统安全模型确保用户只能访问自己的文件,而不能访问其他用户的文件或操作系统本身。

最后一块组成部分是实现这些所有功能所需要的软件。Linux 使用两层软件实现的方式来提高系统和程序员的效率。

图片 1:Linux 两层文件系统软件实现。

这两层中的第一层是 Linux 虚拟文件系统。虚拟文件系统提供了内核和开发者访问所有类型文件系统的的单一命令集。虚拟文件系统软件通过调用特殊设备驱动来和不同类型的文件系统进行交互。特定文件系统的设备驱动是第二层实现。设备驱动程序将文件系统命令的标准集解释为在分区或逻辑卷上的特定类型文件系统命令。

目录结构

作为一个通常来说非常有条理的处女座,我喜欢将东西存储在更小的、有组织的小容器中,而不是存于同一个大容器中。目录的使用使我能够存储文件并在我想要查看这些文件的时候也能够找到它们。目录也被称为文件夹,之所以被称为文件夹,是因为其中的文件被类比存放于物理桌面上。

在 Linux 和其他许多操作系统中,目录可以被组织成树状的分层结构。在 Linux 文件系统层次标准中定义了 Linux 的目录结构(LCTT 译注:可参阅这篇)。当通过目录引用来访问目录时,更深层目录名字是通过正斜杠(/)来连接,从而形成一个序列,比如 /var/log/var/spool/mail 。这些被称为路径。

下表提供了标准的、众所周知的、预定义的顶层 Linux 目录及其用途的简要清单。

目录描述
/ (root 文件系统)root 文件系统是文件系统的顶级目录。它必须包含在挂载其它文件系统前需要用来启动 Linux 系统的全部文件。它必须包含需要用来启动剩余文件系统的全部可执行文件和库。文件系统启动以后,所有其他文件系统作为 root 文件系统的子目录挂载到标准的、预定义好的挂载点上。
/bin/bin 目录包含用户的可执行文件。
/boot包含启动 Linux 系统所需要的静态引导程序和内核可执行文件以及配置文件。
/dev该目录包含每一个连接到系统的硬件设备的设备文件。这些文件不是设备驱动,而是代表计算机上的每一个计算机能够访问的设备。
/etc包含主机计算机的本地系统配置文件。
/home主目录存储用户文件,每一个用户都有一个位于 /home 目录中的子目录(作为其主目录)。
/lib包含启动系统所需要的共享库文件。
/media一个挂载外部可移动设备的地方,比如主机可能连接了一个 USB 驱动器。
/mnt一个普通文件系统的临时挂载点(如不可移动的介质),当管理员对一个文件系统进行修复或在其上工作时可以使用。
/opt可选文件,比如供应商提供的应用程序应该安装在这儿。
/root这不是 root(/)文件系统。它是 root 用户的主目录。
/sbin系统二进制文件。这些是用于系统管理的可执行文件。
/tmp临时目录。被操作系统和许多程序用来存储临时文件。用户也可能临时在这儿存储文件。注意,存储在这儿的文件可能在任何时候在没有通知的情况下被删除。
/usr该目录里面包含可共享的、只读的文件,包括可执行二进制文件和库、man 文件以及其他类型的文档。
/var可变数据文件存储在这儿。这些文件包括日志文件、MySQL 和其他数据库的文件、Web 服务器的数据文件、邮件以及更多。

表 1:Linux 文件系统层次结构的顶层

这些目录以及它们的子目录如表 1 所示,在所有子目录中,粗体的目录组成了 root 文件系统的必需部分。也就是说,它们不能创建为一个分离的文件系统并且在开机时进行挂载。这是因为它们(特别是它们包含的内容)必须在系统启动的时候出现,从而系统才能正确启动。

/media 目录和 /mnt 目录是 root 文件系统的一部分,但是它们从来不包含任何数据,因为它们只是一个临时挂载点。

表 1 中剩下的非粗体的目录不需要在系统启动过程中出现,但会在之后挂载到 root 文件系统上,在开机阶段,它们为主机进行准备,从而执行有用的工作。

请参考官方 Linux 文件系统层次标准(FHS)网页来了解这些每一个目录以及它们的子目录的更多细节。维基百科上也有关于 FHS 的一个很好的介绍。应该尽可能的遵循这些标准,从而确保操作和功能的一致性。无论在主机上使用什么类型的文件系统,该层次目录结构都是相同的。

Linux 统一目录结构

在一些非 Linux 操作系统的个人电脑上,如果有多个物理硬盘驱动器或多个分区,每一个硬盘或分区都会分配一个驱动器号。知道文件或程序位于哪一个硬盘驱动器上是很有必要的,比如 C:D: 。然后,你可以在命令中使用驱动器号,以 D: 为例,为了进入 D: 驱动器,你可以使用 cd 命令来更改工作目录为正确的目录,从而定位需要的文件。每一个硬盘驱动器都有自己单独的、完整的目录树。

Linux 文件系统将所有物理硬盘驱动器和分区统一为一个目录结构。它们均从顶层 root 目录(/)开始。所有其它目录以及它们的子目录均位于单一的 Linux 根目录下。这意味着只有一棵目录树来搜索文件和程序。

因为只有一个文件系统,所以 /home/tmp/var/opt/usr 能够创建在和 root(/)文件系统不同的物理硬盘驱动器、分区或逻辑分区上,然后挂载到一个挂载点(目录)上,从而作为 root 文件系统树的一部分。甚至可移动驱动器,比如 USB 驱动器或一个外接的 USB 或 ESATA 硬盘驱动器均可以挂载到 root 文件系统上,成为目录树不可或缺的部分。

当从 Linux 发行版的一个版本升级到另一个版本或从一个发行版更改到另一个发行版的时候,就会很清楚地看到这样创建到不同分区的好处。通常情况下,除了任何像 Fedora 中的 dnf-upgrade 之类的升级工具,会明智地在升级过程中偶尔重新格式化包含操作系统的硬盘驱动来删除那些长期积累的垃圾。如果 /home 目录是 root 文件系统的一部分(位于同一个硬盘驱动器),那么它也会被格式化,然后需要通过之前的备份恢复。如果 /home 目录作为一个分离的文件系统,那么安装程序将会识别到,并跳过它的格式化。对于存储数据库、邮箱、网页和其它可变的用户以及系统数据的 /var 目录也是这样的。

将 Linux 系统目录树的某些部分作为一个分离的文件系统还有一些其他原因。比如,在很久以前,我还不知道将所有需要的 Linux 目录均作为 root(/)文件系统的一部分可能存在的问题,于是,一些非常大的文件填满了 /home 目录。因为 /home 目录和 /tmp 目录均不是分离的文件系统,而是 root 文件系统的简单子目录,整个 root 文件系统就被填满了。于是就不再有剩余空间可以让操作系统用来存储临时文件或扩展已存在数据文件。首先,应用程序开始抱怨没有空间来保存文件,然后,操作系统也开始异常行动。启动到单用户模式,并清除了 /home 目录中的多余文件之后,终于又能够重新工作了。然后,我使用非常标准的多重文件系统设置来重新安装 Linux 系统,从而避免了系统崩溃的再次发生。

我曾经遇到一个情况,Linux 主机还在运行,但是却不允许用户通过 GUI 桌面登录。我可以通过使用虚拟控制台之一,通过命令行界面(CLI)本地登录,然后远程使用 SSH 。问题的原因是因为 /tmp 文件系统满了,因此 GUI 桌面登录时所需要的一些临时文件不能被创建。因为命令行界面登录不需要在 /tmp 目录中创建文件,所以无可用空间并不会阻止我使用命令行界面来登录。在这种情况下,/tmp 目录是一个分离的文件系统,在 /tmp 所位于的逻辑卷上还有大量的可用空间。我简单地扩展了 /tmp 逻辑卷的容量到能够容纳主机所需要的临时文件,于是问题便解决了。注意,这个解决方法不需要重启,当 /tmp 文件系统扩大以后,用户就可以登录到桌面了。

当我在一家很大的科技公司当实验室管理员的时候,遇到过另外一个故障。开发者将一个应用程序安装到了一个错误的位置(/var)。结果该应用程序崩溃了,因为 /var 文件系统满了,由于缺乏空间,存储于 /var/log 中的日志文件无法附加新的日志消息。然而,系统仍然在运行,因为 root 文件系统和 /tmp 文件系统还没有被填满。删除了该应用程序并重新安装在 /opt 文件系统后,问题便解决了。

文件系统类型

Linux 系统支持大约 100 种分区类型的读取,但是只能对很少的一些进行创建和写操作。但是,可以挂载不同类型的文件系统在同一个 root 文件系统上,并且是很常见的。在这样的背景下,我们所说的文件系统一词是指在硬盘驱动器或逻辑卷上的一个分区中存储和管理用户数据所需要的结构和元数据。能够被 Linux 系统的 fdisk 命令识别的文件系统类型的完整列表在此,你可以感受一下 Linux 系统对许多类型的系统的高度兼容性。

Linux 支持读取这么多类型的分区系统的主要目的是为了提高兼容性,从而至少能够与一些其他计算机系统的文件系统进行交互。下面列出了在 Fedora 中创建一个新的文件系统时的所有可选类型:

  • btrfs
  • cramfs
  • ext2
  • ext3
  • ext4
  • fat
  • gfs2
  • hfsplus
  • minix
  • msdos
  • ntfs
  • reiserfs
  • vfat
  • xfs

其他发行版支持创建的文件系统类型不同。比如,CentOS 6 只支持创建上表中标为黑体的文件系统类型。

挂载

在 Linux 系统上“ 挂载 mount ”文件系统的术语是指在计算机发展的早期,磁带或可移动的磁盘组需要需要物理地挂载到一个合适的驱动器设备上。当通过物理的方式放置到驱动器上以后,操作系统会逻辑地挂载位于磁盘上的文件系统,从而操作系统、应用程序和用户才能够访问文件系统中的内容。

一个挂载点简单的来说就是一个目录,就像任何其它目录一样,是作为 root 文件系统的一部分创建的。所以,比如,home 文件系统是挂载在目录 /home 下。文件系统可以被挂载到其他非 root 文件系统的挂载点上,但是这并不常见。

在 Linux 系统启动阶段的最初阶段,root 文件系统就会被挂载到 root 目录下(/)。其它文件系统在之后通过 SystemV 下的 rc 或更新一些的 Linux 发行版中的 systemd 等 Linux 启动程序挂载。在启动进程中文件系统的挂载是由 /etc/fstab 配置文件管理的。一个简单的记忆方法是,fstab 代表“ 文件系统表 file system table ”,它包含了需要挂载的文件系统的列表,这些文件系统均指定了挂载点,以及针对特定文件系统可能需要的选项。

使用 mount 命令可以把文件系统挂载到一个已有的目录/挂载点上。通常情况下,任何作为挂载点的目录都应该是空的且不包含任何其他文件。Linux 系统不会阻止用户挂载一个已被挂载了文件系统的目录或将文件系统挂载到一个包含文件的目录上。如果你将文件系统挂载到一个已有的目录或文件系统上,那么其原始内容将会被隐藏,只有新挂载的文件系统的内容是可见的。

结论

我希望通过这篇文章,阐明了围绕文件系统这个术语的一些可能的模糊之处。我花费了很长的时间,以及在一个良师的帮助下才真正理解和欣赏到 Linux 文件系统的复杂性、优雅性和功能以及它的全部含义。

如果你有任何问题,请写到下面的评论中,我会尽力来回答它们。

下个月

Linux 的另一个重要概念是:万物皆为文件。这个概念对用户和系统管理员来说有一些有趣和重要的实际应用。当我说完这个理由之后,你可能会想阅读我的文章:万物皆为文件,这篇文章会在我下个月计划写的关于 /dev 目录的文章之前写完。(LCTT 译注,也可参阅这篇

(题图 : wallup.net)


作者简介:

David Both 居住在美国北卡罗纳州的首府罗利,是一个 Linux 开源贡献者。他已经从事 IT 行业 40 余年,在 IBM 教授 OS/2 20 余年。1981 年,他在 IBM 开发了第一个关于最初的 IBM 个人电脑的培训课程。他也曾在 Red Hat 教授 RHCE 课程,也曾供职于 MCI worldcom,Cico 以及北卡罗纳州等。他已经为 Linux 开源社区工作近 20 年。


via: https://opensource.com/life/16/10/introduction-linux-filesystems

作者:David Both 译者:ucasFL 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

让我们大概地从 EXT4 的历史、特性以及最佳实践这几个方面来学习它和之前的几代 EXT 文件系统有何不同。

在之前关于 Linux 文件系统的文章里,我写过一篇 Linux 文件系统介绍 和一些更高级的概念例如 一切都是文件。现在我想要更深入地了解 EXT 文件系统的特性的详细内容,但是首先让我们来回答一个问题,“什么样才算是一个文件系统 ?” 一个文件系统应该涵盖以下所有特点:

  1. 数据存储: 对于任何一个文件系统来说,一个最主要的功能就是能够被当作一个结构化的容器来存储和获取数据。
  2. 命名空间: 命名空间是一个提供了用于命名与组织数据的命名规则和数据结构的方法学。
  3. 安全模型: 一个用于定义访问权限的策略。
  4. API: 操作这个系统的对象的系统功能调用,这些对象诸如目录和文件。
  5. 实现: 能够实现以上几点的软件。

本文内容的讨论主要集中于上述几点中的第一项,并探索为一个 EXT 文件系统的数据存储提供逻辑框架的元数据结构。

EXT 文件系统历史

虽然 EXT 文件系统是为 Linux 编写的,但其真正起源于 Minix 操作系统和 Minix 文件系统,而 Minix 最早发布于 1987,早于 Linux 5 年。如果我们从 EXT 文件系统大家族的 Minix 起源来观察其历史与技术发展那么理解 EXT4 文件系统就会简单得多。

Minix

当 Linux Torvalds 在写最初的 Linux 内核的时候,他需要一个文件系统但是他又不想自己写一个。于是他简单地把 Minix 文件系统 加了进去,这个 Minix 文件系统是由 Andrew S. Tanenbaum 写的,同时它也是 Tanenbaum 的 Minix 操作系统的一部分。Minix 是一个类 Unix 风格的操作系统,最初编写它的原因是用于教育用途。Minix 的代码是自由可用的并有适当的许可协议,所以 Torvalds 可以把它用 Linux 的最初版本里。

Minix 有以下这些结构,其中的大部分位于生成文件系统的分区中:

  • 引导扇区 是硬盘安装后的第一个扇区。这个引导块包含了一个非常小的引导记录和一个分区表。
  • 每一个分区的第一个块都是一个包含了元数据的 超级块 superblock ,这些元数据定义了其他的文件系统结构并将其定位于物理硬盘的具体分区上。
  • 一个 inode 位图块 决定了哪些 inode 是在使用中的,哪一些是未使用的。
  • inode 在硬盘上有它们自己的空间。每一个 inode 都包含了一个文件的信息,包括其所处的数据块的位置,也就是该文件所处的区域。
  • 一个 区位图 用于保持追踪数据区域的使用和未使用情况。
  • 一个 数据区, 这里是数据存储的地方。

对上述了两种位图类型来说,一个 bit 表示一个指定的数据区或者一个指定的 inode。 如果这个位是 0 则表示这个数据区或者这个 inode 是未使用的,如果是 1 则表示正在使用中。

那么,inode 又是什么呢 ? 就是 index-node(索引节点)的简写。 inode 是位于磁盘上的一个 256 字节的块,用于存储和该 inode 对应的文件的相关数据。这些数据包含了文件的大小、文件的所有者和所属组的用户 ID、文件模式(即访问权限)以及三个时间戳用于指定:该文件最后的访问时间、该文件的最后修改时间和该 inode 中的数据的最后修改时间。

同时,这个 inode 还包含了位置数据,指向了其所对应的文件数据在硬盘中的位置。在 Minix 和 EXT 1-3 文件系统中,这是一个数据区和块的列表。Minix 文件系统的 inode 支持 9 个数据块,包括 7 个直接数据块和 2 个间接数据块。如果你想要更深入的了解,这里有一个优秀的 PDF 详细地描述了 Minix 文件系统结构 。同时你也可以在维基百科上对 inode 指针结构 做一个快速了解。

EXT

原生的 EXT 文件系统 (意即 扩展的 extended ) 是由 Rémy Card 编写并于 1992 年与 Linux 一同发行。主要是为了克服 Minix 文件系统中的一些文件大小限制的问题。其中,最主要的结构变化就是文件系统中的元数据。它基于 Unix 文件系统 (UFS),其也被称为伯克利快速文件系统(FFS)。我发现只有很少一部分关于 EXT 文件系统的发行信息是可以被确证的,显然这是因为其存在着严重的问题,并且它很快地被 EXT2 文件系统取代了。

EXT2

EXT2 文件系统 就相当地成功,它在 Linux 发行版中存活了多年。它是我在 1997 年开始使用 Red Hat Linux 5.0 时接触的第一个文件系统。实际上,EXT2 文件系统有着和 EXT 文件系统基本相同的元数据结构。然而 EXT2 更高瞻远瞩,因为其元数据结构之间留有很多供将来使用的磁盘空间。

和 Minix 类似,EXT2 也有一个引导扇区 ,它是硬盘安装后的第一个扇区。它包含了非常小的引导记录和一个分区表。接着引导扇区之后是一些保留的空间,它填充了引导记录和硬盘驱动器上的第一个分区(通常位于下一个柱面)之间的空间。GRUB2 - 也可能是 GRUB1 - 将此空间用于其部分引导代码。

每个 EXT2 分区中的空间被分为 柱面组 cylinder group ,它允许更精细地管理数据空间。 根据我的经验,每一组大小通常约为 8MB。 下面的图 1 显示了一个柱面组的基本结构。 柱面中的数据分配单元是块,通常大小为 4K。

cylindergroup-01_1.png

图 1: EXT 文件系统中的柱面组的结构

柱面组中的第一个块是一个 超级块 superblock ,它包含了元数据,定义了其它文件系统的结构并将其定位于物理硬盘的具体分区上。分区中有一些柱面组还会有备用超级块,但并不是所有的柱面组都有。我们可以使用例如 dd 等磁盘工具来拷贝备用超级块的内容到主超级块上,以达到修复损坏的超级块的目的。虽然这种情况不会经常发生,但是在几年前我的一个超级块损坏了,我就是用这种方法来修复的。幸好,我很有先见之明地使用了 dumpe2fs 命令来备份了我的系统上的分区描述符信息。

以下是 dumpe2fs 命令的一部分输出。这部分输出主要是超级块上包含的一些元数据,同时也是文件系统上的前两个柱面组的数据。

# dumpe2fs /dev/sda1
Filesystem volume name:   boot 
Last mounted on:          /boot 
Filesystem UUID:          79fc5ed8-5bbc-4dfe-8359-b7b36be6eed3 
Filesystem magic number:  0xEF53 
Filesystem revision #:    1 (dynamic) 
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file dir nlink extra_isize 
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl 
Filesystem state:         clean 
Errors behavior:          Continue 
Filesystem OS type:       Linux 
Inode count:              122160 
Block count:              488192 
Reserved block count:     24409 
Free blocks:              376512 
Free inodes:              121690 
First block:              0 
Block size:               4096 
Fragment size:            4096 
Group descriptor size:    64 
Reserved GDT blocks:      238 
Blocks per group:         32768 
Fragments per group:      32768 
Inodes per group:         8144 
Inode blocks per group:   509 
Flex block group size:    16 
Filesystem created:       Tue Feb  7 09:33:34 2017 
Last mount time:          Sat Apr 29 21:42:01 2017 
Last write time:          Sat Apr 29 21:42:01 2017 
Mount count:              25 
Maximum mount count:      -1 
Last checked:             Tue Feb  7 09:33:34 2017 
Check interval:           0 (<none>) 
Lifetime writes:          594 MB 
Reserved blocks uid:      0 (user root) 
Reserved blocks gid:      0 (group root) 
First inode:              11 
Inode size:               256 
Required extra isize:     32 
Desired extra isize:      32 
Journal inode:            8 
Default directory hash:   half_md4 
Directory Hash Seed:      c780bac9-d4bf-4f35-b695-0fe35e8d2d60 
Journal backup:           inode blocks 
Journal features:         journal_64bit 
Journal size:             32M 
Journal length:           8192 
Journal sequence:         0x00000213 
Journal start:            0 

Group 0: (Blocks 0-32767) 
 Primary superblock at 0, Group descriptors at 1-1 
 Reserved GDT blocks at 2-239 
 Block bitmap at 240 (+240) 
 Inode bitmap at 255 (+255) 
 Inode table at 270-778 (+270) 
 24839 free blocks, 7676 free inodes, 16 directories 
 Free blocks: 7929-32767 
 Free inodes: 440, 470-8144 
Group 1: (Blocks 32768-65535) 
 Backup superblock at 32768, Group descriptors at 32769-32769 
 Reserved GDT blocks at 32770-33007 
 Block bitmap at 241 (bg #0 + 241) 
 Inode bitmap at 256 (bg #0 + 256)
 Inode table at 779-1287 (bg #0 + 779) 
 8668 free blocks, 8142 free inodes, 2 directories 
 Free blocks: 33008-33283, 33332-33791, 33974-33975, 34023-34092, 34094-34104, 34526-34687, 34706-34723, 34817-35374, 35421-35844, 35935-36355, 36357-36863, 38912-39935, 39940-40570, 42620-42623, 42655, 42674-42687, 42721-42751, 42798-42815, 42847, 42875-42879, 42918-42943, 42975, 43000-43007, 43519, 43559-44031, 44042-44543, 44545-45055, 45116-45567, 45601-45631, 45658-45663, 45689-45695, 45736-45759, 45802-45823, 45857-45887, 45919, 45950-45951, 45972-45983, 46014-46015, 46057-46079, 46112-46591, 46921-47103, 49152-49395, 50027-50355, 52237-52255, 52285-52287, 52323-52351, 52383, 52450-52479, 52518-52543, 52584-52607, 52652-52671, 52734-52735, 52743-53247 
 Free inodes: 8147-16288 
Group 2: (Blocks 65536-98303) 
 Block bitmap at 242 (bg #0 + 242) 
 Inode bitmap at 257 (bg #0 + 257) 
 Inode table at 1288-1796 (bg #0 + 1288) 
 6326 free blocks, 8144 free inodes, 0 directories 
 Free blocks: 67042-67583, 72201-72994, 80185-80349, 81191-81919, 90112-94207 
 Free inodes: 16289-24432 
Group 3: (Blocks 98304-131071)

<截断>

每一个柱面组都有自己的 inode 位图,用于判定该柱面组中的哪些 inode 是使用中的而哪些又是未被使用的。每一个柱面组的 inode 都有它们自己的空间。每一个 inode 都包含了一个文件的相关信息,包括属于该文件的数据块的位置。而块位图纪录了文件系统中的使用中和非使用中的数据块。请注意,在上面的输出中有大量关于文件系统的数据。在非常大的文件系统上,柱面组的数据可以多达数百页的长度。柱面组的元数据包括组中所有空闲数据块的列表。

EXT 文件系统实现了数据分配策略以确保产生最少的文件碎片。减少文件碎片可以提高文件系统的性能。这些策略会在下面的 EXT4 中描述到。

我所遇见的关于 EXT2 文件系统最大的问题是 fsck (文件系统检查) 程序这一环节占用了很长一段时间来定位和校准文件系统中的所有的不一致性,从而导致在系统 崩溃 crash 后其会花费了数个小时来修复。有一次我的其中一台电脑在崩溃后重新启动时共花费了 28 个小时恢复磁盘,而且并且是在磁盘被检测量只有几百兆字节大小的情况下。

EXT3

EXT3 文件系统是应一个目标而生的,就是克服 fsck 程序需要完全恢复在文件更新操作期间发生的不正确关机而损坏的磁盘结构所需的大量时间。它对 EXT 文件系统的唯一新增功能就是 日志,它将提前记录将对文件系统执行的更改。 EXT3 的磁盘结构的其余部分与 EXT2 中的相同。

除了同先前的版本一样直接写入数据到磁盘的数据区域外,EXT3 上的日志会将文件数据随同元数据写入到磁盘上的一个指定数据区域。一旦这些(日志)数据安全地到达硬盘,它就可以几乎零丢失率地被合并或被追加到目标文件上。当这些数据被提交到磁盘上的数据区域上,这些日志就会随即更新,这样在日志中的所有数据提交之前,系统发生故障时文件系统将保持一致状态。在下次启动时,将检查文件系统的不一致性,然后将仍保留在日志中的数据提交到磁盘的数据区,以完成对目标文件的更新。

日志功能确实降低了数据写入性能,但是有三个可用于日志的选项,允许用户在性能和数据完整性、安全性之间进行选择。 我的个人更偏向于选择安全性,因为我的环境不需要大量的磁盘写入活动。

日志功能将失败后检查硬盘驱动器所需的时间从几小时(甚至几天)减少到了几分钟。 多年来,我遇到了很多导致我的系统崩溃的问题。要详细说的话恐怕还得再写一篇文章,但这里需要说明的是大多数是我自己造成的,就比如不小心踢掉电源插头。 幸运的是,EXT 日志文件系统将启动恢复时间缩短到两三分钟。此外,自从我开始使用带日志记录的 EXT3,我从来没有遇到丢失数据的问题。

EXT3 的日志功能可以关闭,然后其功能就等同于 EXT2 文件系统了。 该日志本身仍然是存在的,只是状态为空且未使用。 只需在 mount 命令中使用文件系统类型参数来重新挂载即可指定为 EXT2。 你可以从命令行执行此操作,但是具体还是取决于你正在使用的文件系统,不过你也可以更改 /etc/fstab 文件中的类型说明符,然后重新启动。 我强烈建议不要将 EXT3 文件系统挂载为 EXT2 ,因为这会有丢失数据和增加恢复时间的潜在可能性。

EXT2 文件系统可以使用如下命令来通过日志升级到 EXT3 。

tune2fs -j /dev/sda1

/dev/sda1 表示驱动器和分区的标识符。同时要注意修改 /etc/fstab 中的文件系统类型标识符并重新挂载分区,或者重启系统以确保修改生效。

EXT4

EXT4 文件系统主要提高了性能、可靠性和容量。为了提高可靠性,它新增了元数据和日志校验和。同时为了满足各种关键任务要求,文件系统新增了纳秒级别的时间戳,并在时间戳字段中添加了两个高位来延缓时间戳的 2038 年问题 ,这样 EXT4 文件系统至少可用到 2446 年。

在 EXT4 中,数据分配从固定块改为 扩展盘区 extent 方式,扩展盘区由硬盘驱动器上的开始和结束位置来描述。这使得可以在单个 inode 指针条目中描述非常长的物理上连续的文件,这可以显著减少描述大文件中所有数据的位置所需的指针数。其它在 EXT4 中已经实施的分配策略可以进一步减少碎片化。

EXT4 通过将新创建的文件散布在磁盘上,使其不会像早期的 PC 文件系统一样全部聚集在磁盘起始位置,从而减少了碎片。文件分配算法尝试在柱面组中尽可能均匀地散布文件,并且当文件(由于太大)需要分段存储时,使不连续的文件扩展盘区尽可能靠近同一文件中的其他部分,以尽可能减少磁头寻道和电机旋转等待时间。当创建新文件或扩展现有文件时,使用其它策略来预先分配额外的磁盘空间。这有助于确保扩展文件时不会自动导致其分段。新文件不会紧挨这现有文件立即分配空间,这也可以防止现有文件的碎片化。

除了磁盘上数据的实际位置外,EXT4 使用诸如延迟分配的功能策略,以允许文件系统在分配空间之前收集到所有正在写入磁盘的数据,这可以提高数据空间连续的可能性。

较旧的 EXT 文件系统(如 EXT2 和 EXT3)可以作为 EXT4 进行 mount ,以使其性能获得较小的提升。但不幸的是,这需要关闭 EXT4 的一些重要的新功能,所以我建议不要这样做。

自 Fedora 14 以来,EXT4 一直是 Fedora 的默认文件系统。我们可以使用 Fedora 文档中描述的 流程 将 EXT3 文件系统升级到 EXT4,但是由于仍然存留的之前的 EXT3 元数据结构,它的性能仍将受到影响。从 EXT3 升级到 EXT4 的最佳方法是备份目标文件系统分区上的所有数据,使用 mkfs 命令将空 EXT4 文件系统写入分区,然后从备份中恢复所有数据。

Inode

之前介绍过的 inode 是 EXT 文件系统中的元数据的关键组件。 图 2 显示了 inode 和存储在硬盘驱动器上的数据之间的关系。 该图是单个文件的目录和 inode,在这种情况下,可能会产生高度碎片化。 EXT 文件系统可以主动地减少碎片,所以不太可能会看到有这么多间接数据块或扩展盘区的文件。 实际上,你在下面将会看到,EXT 文件系统中的碎片非常低,所以大多数 inode 只使用一个或两个直接数据指针,而不使用间接指针。

inodesanddataallocation-01_0.png

图 2 :inode 存储有关每个文件的信息,并使 EXT 文件系统能够查找属于它的所有数据。

inode 不包含文件的名称。通过目录项访问文件,目录项本身就是文件的名称,并包含指向 inode 的指针。该指针的值是 inode 号。文件系统中的每个 inode 都具有唯一的 ID 号,但同一台计算机上的其它文件系统(甚至是相同的硬盘驱动器)中的 inode 可以具有相同的 inode 号。这对 硬链接 存在影响,但是这个讨论超出了本文的范围。

inode 包含有关该文件的元数据,包括其类型和权限以及其大小。 inode 还包含 15 个指针的空位,用于描述柱面组数据部分中数据块或扩展盘区的位置和长度。12 个指针提供对数据扩展盘区的直接访问,应该足以满足大多数文件的需求。然而,对于具有明显分段的文件,需要以间接 节点 node 的形式提供一些额外的容量——从技术上讲,这些不是真正的“inode”,所以为了方便起见我在这里使用这个术语“ 节点 node ”。

间接节点是文件系统中的正常数据块,它仅用于描述数据而不用于存储元数据,因此可以支持超过 15 个条目。例如,4K 的块大小可以支持 512 个 4 字节的间接节点,允许单个文件有 12(直接)+ 512(间接)= 524 个扩展盘区。还支持双重和三重间接节点,但我们大多数人不太可能遇到需要那么多扩展盘区的文件。

数据碎片

对于许多较旧的 PC 文件系统,如 FAT(及其所有变体)和 NTFS,碎片一直是导致磁盘性能下降的重大问题。 碎片整理本身就成为一个行业,有各种品牌的整理软件,其效果范围从非常有效到仅仅是微乎其微。

Linux 的扩展文件系统使用数据分配策略,有助于最小化硬盘驱动器上的文件碎片,并在发生碎片时减少碎片的影响。 你可以使用 EXT 文件系统上的 fsck 命令检查整个文件系统的碎片。 以下示例检查我的主工作站的家目录,只有 1.5% 的碎片。 确保使用 -n 参数,因为它会防止 fsck 对扫描的文件系统采取任何操作。

fsck -fn /dev/mapper/vg_01-home

我曾经进行过一些理论计算,以确定磁盘碎片整理是否会产生任何明显的性能提升。 我做了一些假设条件,我使用的磁盘性能数据来自一个新的 300GB 的西部数字硬盘驱动器,具有 2.0ms 的轨到轨寻道时间。 此示例中的文件数是我在计算的当天的文件系统中存在的实际数。 我假设每天有相当大量的碎片化文件(约 20%)会被用到。

全部文件271,794
碎片率 %5.00%
不连续数13,590
% 每天用到的碎片化文件20% (假设)
额外寻道次数2,718
平均寻道时间10.90 ms
每天全部的额外寻道时间29.63 sec
0.49 min
轨到轨寻道时间2.00 ms
每天全部的额外寻道时间5.44 sec
0.091 min

表 1: 碎片对磁盘性能的理论影响

我对每天的全部的额外寻道时间进行了两次计算,一次是轨到轨寻道时间,这是由于 EXT 文件分配策略而导致大多数文件最可能的情况,一个是平均寻道时间,我假设这是一个合理的最坏情况。

从表 1 可以看出,对绝大多数应用程序而言,碎片化甚至对性能适中的硬盘驱动器上的现代 EXT 文件系统的影响是微乎其微的。您可以将您的环境中的数字插入到您自己的类似电子表格中,以了解你对性能影响的期望。这种类型的计算不一定能够代表实际的性能,但它可以提供一些对碎片化及其对系统的理论影响的洞察。

我的大部分分区的碎片率都在 1.5% 左右或 1.6%,我有一个分区有 3.3% 的碎片,但是这是一个大约 128GB 文件系统,具有不到 100 个非常大的 ISO 映像文件;多年来,我扩展过该分区几次,因为它已经太满了。

这并不是说一些应用的环境并不需要更少的碎片的环境。 EXT 文件系统可以由有经验和知识的管理员小心调整,管理员可以针对特定的工作负载类型调整参数。这个工作可以在文件系统创建的时候或稍后使用 tune2fs 命令时完成。每一次调整变化的结果应进行测试,精心的记录和分析,以确保目标环境的最佳性能。在最坏的情况下,如果性能不能提高到期望的水平,则其他文件系统类型可能更适合特定的工作负载。并记住,在单个主机系统上混用文件系统类型以匹配每个文件系统上的不同负载是常见的。

由于大多数 EXT 文件系统的碎片数量较少,因此无需进行碎片整理。目前,EXT 文件系统没有安全的碎片整理工具。有几个工具允许你检查单个文件的碎片程度或文件系统中剩余可用空间的碎片程度。有一个工具,e4defrag,它可以对允许使用的剩余可用空间、目录或文件系统进行碎片整理。顾名思义,它只适用于 EXT4 文件系统中的文件,并且它还有一其它的些限制。

如果有必要在 EXT 文件系统上执行完整的碎片整理,则只有一种方法能够可靠地工作。你必须将文件系统中的所有要进行碎片整理的文件移动从而进行碎片整理,并在确保安全复制到其他位置后将其删除。如果可能,你可以增加文件系统的大小,以帮助减少将来的碎片。然后将文件复制回目标文件系统。但是其实即使这样也不能保证所有文件都被完全去碎片化。

总结

EXT 文件系统在一些 Linux 发行版本上作为默认文件系统已经超过二十多年了。它们用最少的维护代价提供了稳定性、高可用性、可靠性和性能。我尝试过一些其它的文件系统但最终都还是回归到 EXT。每一个我在工作中使用到 Linux 的地方都使用到了 EXT 文件系统,同时我发现了它们适用于任何主流负载。毫无疑问,EXT4 文件系统应该被用于大部分的 Linux 文件系统上,除非我们有明显需要使用其它文件系统的理由。


作者简介:

David Both - David Both 是一名 Linux 于开源的贡献者,目前居住在北卡罗莱纳州的罗利。他从事 IT 行业有 40 余年并在 IBM 中从事 OS/2 培训约 20 余年。在 IBM 就职期间,他在 1981 年为最早的 IBM PC 写了一个培训课程。他已经为红帽教授了 RHCE 课程,曾在 MCI Worldcom,思科和北卡罗来纳州工作。 他使用 Linux 和开源软件工作了近 20 年。


via: https://opensource.com/article/17/5/introduction-ext4-filesystem

作者:David Both 译者:chenxinlong 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

文件通过文件系统在磁盘及分区上命名、存储、检索以及更新,文件系统是在磁盘上组织文件的方式。

文件系统分为两个部分:用户数据和元数据(文件名、创建时间、修改时间、大小以及目录层次结构中的位置等)。

在本指南中,我们将用 7 种方法来识别你的 Linux 文件系统类型,如 Ext2、Ext3、Ext4、BtrFS、GlusterFS 等等。

1、 使用 df 命令

df 命令报告文件系统磁盘空间利用率,要显示特定的磁盘分区的文件系统类型,像下面那样使用 -T 标志:

$ df -Th
或者
$ df -Th | grep "^/dev"

df Command - Find Filesystem Type

df 命令 – 找出文件系统类型

要更好理解 df 命令,阅读下面的文章:

  1. 12 个有用的 df 命令来检查 Linux 中的磁盘空间
  2. Pydf - 一个替代 df 的命令,用颜色显示磁盘使用率

2、 使用 fsck 命令

fsck 用来检查以及修复 Linux 文件系统,它也可以输出指定磁盘分区的文件系统类型

-N 标志禁用检查文件系统错误,它只是显示会做什么(但是我们只需要文件系统类型):

$ fsck -N /dev/sda3
$ fsck -N /dev/sdb1

fsck - Print Linux Filesystem Type

fsck – 打印 Linux 文件系统类型

3、 使用 lsblk 命令

lsblk 会显示块设备,当使用 -f 选项时,它也会打印分区的文件系统类型:

$ lsblk -f

lsblk - Shows Linux Filesystem Type

lsblk – 显示 Linux 文件系统类型

4、 使用 mount 命令

mount 命令用来在 Linux 中挂载文件系统,它也可以用来挂载一个 ISO 镜像挂载远程 Linux 文件系统等等。

当不带任何参数运行时,它会打印包含文件系统类型在内的磁盘分区的信息

$ mount | grep "^/dev"

Mount - Show Filesystem Type in Linux

Mount – 在 Linux 中显示文件系统类型

5、 使用 blkid 命令

blkid 命令用来找出或打印块设备属性,只要将磁盘分区作为参数就行了:

$ blkid /dev/sda3

blkid - Find Filesystem Type

blkid – 找出文件系统类型

6、 使用 file 命令

file 命令会识别文件类型,使用 -s 标志启用读取块设备或字符设备,-L 启用符号链接跟随:

$ sudo file -sL /dev/sda3

file - Identifies Filesystem Type

file – 识别文件系统类型

7、 使用 fstab 文件

/etc/fstab 是一个静态文件系统信息(比如挂载点、文件系统类型、挂载选项等等)文件:

$ cat /etc/fstab

Fstab - Shows Linux Filesystem Type

fstab – 显示 Linux 文件系统类型

就是这样了!在这篇指南中,我们用 7 种方法来识别你的 Linux 文件系统类型。你还知道这里没有提到的其他方法么?在评论中与我们分享。


作者简介:

Aaron Kili是一名 Linux 和 F.O.S.S 的爱好者,未来的 Linux 系统管理员、网站开发人员,目前是 TecMint 的内容创作者,他喜欢用电脑工作,并乐于分享知识。


via: http://www.tecmint.com/find-linux-filesystem-type/

作者:Aaron Kili 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

探索 /dev 目录可以让您知道如何直接访问到 Linux 中的设备。

Linux 目录结构中有很多有趣的功能,这次我会讲到 /dev 目录一些迷人之处。在继续阅读这篇文章之前,建议你看看我前面的文章。Linux 文件系统一切皆为文件,这两篇文章介绍了一些有趣的 Linux 文件系统概念。请先看看 - 我会等你看完再回来。

……

太好了 !欢迎回来。现在我们可以继续更详尽地探讨 /dev 目录。

设备文件

设备文件也称为设备特定文件。设备文件用来为操作系统和用户提供它们代表的设备接口。所有的 Linux 设备文件均位于 /dev 目录下,是根 (/) 文件系统的一个组成部分,因为这些设备文件在操作系统启动过程中必须可以使用。

关于这些设备文件,要记住的一件重要的事情,就是它们大多不是设备驱动程序。更准确地描述来说,它们是设备驱动程序的门户。数据从应用程序或操作系统传递到设备文件,然后设备文件将它传递给设备驱动程序,驱动程序再将它发给物理设备。反向的数据通道也可以用,从物理设备通过设备驱动程序,再到设备文件,最后到达应用程序或其他设备。

让我们以一个典型命令的数据流程来直观地看看。

dboth-dev-dir_0.png

图 1:一个典型命令的简单数据流程。

在上面的图 1 中,显示一个简单命令的简化数据流程。从一个 GUI 终端仿真器,例如 Konsole 或 xterm 中发出 cat /etc/resolv.conf 命令,它会从磁盘中读取 resolv.conf 文件,磁盘设备驱动程序处理设备的具体功能,例如在硬盘驱动器上定位文件并读取它。数据通过设备文件传递,然后从命令到设备文件,然后到 6 号伪终端的设备驱动,然后在终端会话中显示。

当然, cat 命令的输出可以以下面的方式被重定向到一个文件, cat /etc/resolv.conf > /etc/resolv.bak ,这样会创建该文件的备份。在这种情况下,图 1 左侧的数据流量将保持不变,而右边的数据流量将通过 /dev/sda2 设备文件、硬盘设备驱动程序,然后到硬盘驱动器本身。

这些设备文件使得使用标准流 (STD/IO) 和重定向访问 Linux 或 Unix 计算机上的任何一个设备非常容易。只需将数据流定向到设备文件,即可将数据发送到该设备。

设备文件类别

设备文件至少可以按两种方式划分。第一种也是最常用的分类是根据与设备相关联的数据流进行划分。比如,tty (teletype) 和串行设备被认为是基于字符的,因为数据流的传送和处理是以一次一个字符或字节进行的;而块类型设备(如硬盘驱动器)是以块为单位传输数据,通常为 256 个字节的倍数。

您可以在终端上以一个非 root 用户,改变当前工作目录(PWD)到 /dev ,并显示长目录列表。 这将显示设备文件列表、文件权限及其主、次设备号。 例如,下面的设备文件只是我的 Fedora 24 工作站上 /dev 目录中的几个文件。 它们表示磁盘和 tty 设备类型。 注意输出中每行的最左边的字符。 b 代表是块类型设备,c 代表字符设备。

brw-rw----   1 root disk        8,   0 Nov  7 07:06 sda 
brw-rw----   1 root disk        8,   1 Nov  7 07:06 sda1 
brw-rw----   1 root disk        8,  16 Nov  7 07:06 sdb 
brw-rw----   1 root disk        8,  17 Nov  7 07:06 sdb1 
brw-rw----   1 root disk        8,  18 Nov  7 07:06 sdb2
crw--w----   1 root tty         4,   0 Nov  7 07:06 tty0 
crw--w----   1 root tty         4,   1 Nov  7 07:07 tty1 
crw--w----   1 root tty         4,  10 Nov  7 07:06 tty10 
crw--w----   1 root tty         4,  11 Nov  7 07:06 tty11

识别设备文件更详细和更明确的方法是使用设备主要以及次要号。 磁盘设备主设备号为 8,将它们指定为 SCSI 块设备。请注意,所有 PATA 和 SATA 硬盘驱动器都由 SCSI 子系统管理,因为旧的 ATA 子系统多年前就由于代码质量糟糕而被认为不可维护。造成的结果就是,以前被称为 “hd[a-z]” 的硬盘驱动器现在被称为 “sd[a-z]”。

你大概可以从上面的示例中推出磁盘驱动器次设备号的模式。次设备号 0、 16、 32 等等,直到 240,是整个磁盘的号。所以主/次 8/16 表示整个磁盘 /dev/sdb , 8/17 是第一个分区的设备文件,/dev/sdb1。数字 8/34 代表 /dev/sdc2

在上面列表中的 tty 设备文件编号更简单一些,从 tty0 到 tty63 。

Kernel.org 上的 Linux 下的已分配设备文件是设备类型和主次编号分配的正式注册表。它可以帮助您了解所有当前定义的设备的主要/次要号码。

趣味设备文件

让我们花几分钟时间,执行几个有趣的实验,演示 Linux 设备文件的强大和灵活性。 大多数 Linux 发行版都有 1 到 7 个虚拟控制台,可用于使用 shell 接口登录到本地控制台会话。 可以使用 Ctrl-Alt-F1(控制台 1),Ctrl-Alt-F2(控制台 2)等键盘组合键来访问。

请按 Ctrl-Alt-F2 切换到控制台 2。在某些发行版,登录显示的信息包括了与此控制台关联的 tty 设备,但大多不包括。它应该是 tty2,因为你是在控制台 2 中。

以非 root 用户身份登录。 然后你可以使用 who am i 命令 — 是的,就是这个命令,带空格 — 来确定哪个 tty 设备连接到这个控制台。

在我们实际执行此实验之前,看看 /dev 中的 tty2 和 tty3 的设备列表。

ls -l /dev/tty[23]

有大量的 tty 设备,但我们不关心他们中的大多数,只注意 tty2 和 tty3 设备。 作为设备文件,它们没什么特别之处。它们都只是字符类型设备。我们将使用这些设备进行此实验。 tty2 设备连接到虚拟控制台 2,tty3 设备连接到虚拟控制台 3。

Ctrl-Alt-F3 切换到控制台 3。再次以同一非 root 用户身份登录。 现在在控制台 3 上输入以下命令。

echo "Hello world" > /dev/tty2

Ctrl-Alt-f2 键以返回到控制台 2。字符串 “Hello world”(没有引号)将显示在控制台 2。

该实验也可以使用 GUI 桌面上的终端仿真器来执行。 桌面上的终端会话使用 /dev 中的伪终端设备,如 /dev/pts/1。 使用 Konsole 或 Xterm 打开两个终端会话。 确定它们连接到哪些伪终端,并使用一个向另一个发送消息。

现在继续实验,使用 cat 命令,试试在不同的终端上显示 /etc/fstab 文件。

另一个有趣的实验是使用 cat 命令将文件直接打印到打印机。 假设您的打印机设备是 /dev/usb/lp0,并且您的打印机可以直接打印 PDF 文件,以下命令将在您的打印机上打印 test.pdf 文件。

cat test.pdf > /dev/usb/lp0

/dev 目录包含一些非常有趣的设备文件,这些文件是硬件的入口,人们通常不认为这是硬盘驱动器或显示器之类的设备。 例如,系统存储器 RAM 不是通常被认为是“设备”的东西,而 /dev/mem 是通过其可以实现对存储器的直接访问的入口。 下面的例子有一些有趣的结果。

dd if=/dev/mem bs=2048 count=100

上面的 dd 命令提供比简单地使用 cat 命令 dump 所有系统的内存提供了更多的控制。 它提供了指定从 /dev/mem 读取多少数据的能力,还允许指定从存储器哪里开始读取数据。虽然读取了一些内存,但内核响应了以下错误,在 /var/log/messages 中可以看到。

Nov 14 14:37:31 david kernel: usercopy: kernel memory exposure attempt detected from ffff9f78c0010000 (dma-kmalloc-512) (2048 bytes)

这个错误意味着内核正在通过保护属于其他进程的内存来完成它的工作,这正是它应该工作的方式。 所以,虽然可以使用 /dev/mem 来显示存储在 RAM 内存中的数据,但是访问的大多数内存空间是受保护的并且会导致错误。 只可以访问由内核内存管理器分配给运行 dd 命令的 BASH shell 的虚拟内存,而不会导致错误。 抱歉,但你不能窥视不属于你的内存,除非你发现了一个可利用的漏洞。

/dev 中还有一些非常有趣的设备文件。 设备文件 nullzerorandomurandom 不与任何物理设备相关联。

例如,空设备 /dev/null 可以用作来自 shell 命令或程序的输出重定向的目标,以便它们不显示在终端上。 我经常在我的 BASH 脚本中使用这个,以防止向用户展示可能会让他们感到困惑的输出。 /dev/null 设备可用于产生一个空字符串。 使用如下所示的 dd 命令查看 /dev/null 设备文件的一些输出。

# dd if=/dev/null  bs=512 count=500 | od -c     
0+0 records in
0+0 records out
0 bytes copied, 1.5885e-05 s, 0.0 kB/s
0000000

注意,因为空字符什么也没有所以确实没有可见的输出。 注意看看字节数。

/dev/random/dev/urandom 设备也很有趣。 正如它们的名字所暗示的,它们都产生随机输出,不仅仅是数字,而是任何字节组合。 /dev/urandom 设备产生的是确定性的随机输出,并且非常快。 这意味着输出由算法确定,并使用种子字符串作为起点。 结果,如果原始种子是已知的,则黑客可以再现输出,尽管非常困难,但这是有可能的。 使用命令 cat /dev/urandom 可以查看典型的输出,使用 Ctrl-c 退出。

/dev/random 设备文件生成非确定性的随机输出,但它产生的输出更慢一些。 该输出不是由依赖于先前数字的算法确定的,而是由击键动作和鼠标移动而产生的。 这种方法使得复制特定系列的随机数要困难得多。使用 cat 命令去查看一些来自 /dev/random 设备文件输出。尝试移动鼠标以查看它如何影响输出。

正如其名字所暗示的,/dev/zero 设备文件产生一个无止境的零作为输出。 注意,这些是八进制零,而不是ASCII字符零(0)。 使用如下所示的 dd 查看 /dev/zero 设备文件中的一些输出

# dd if=/dev/zero  bs=512 count=500 | od -c
0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
500+0 records in
500+0 records out
256000 bytes (256 kB, 250 KiB) copied, 0.00126996 s, 202 MB/s
0764000

请注意,此命令的字节数不为零。

创建设备文件

在过去,在 /dev 中的设备文件都是在安装时创建的,导致一个目录中有几乎所有的设备文件,尽管大多数文件永远不会用到。 在不常发生的情况,例如需要新的设备文件,或意外删除后需要重新创建设备文件,可以使用 mknod 程序手动创建设备文件。 前提是你必须知道设备的主要和次要号码。

CentOS 和 RHEL 6、7,以及 Fedora 的所有版本——可以追溯到至少 Fedora 15,使用较新的创建设备文件的方法。 所有设备文件都是在引导时创建的。 这是因为 udev 设备管理器在设备添加和删除发生时会进行检测。这可实现在主机启动和运行时的真正的动态即插即用功能。 它还在引导时执行相同的任务,通过在引导过程的很早的时期检测系统上安装的所有设备。 Linux.com 上有一篇很棒的对 udev 的描述

回到 /dev 中的文件列表,注意文件的日期和时间。 所有文件都是在上次启动时创建的。 您可以使用 uptime 或者 last 命令来验证这一点。在上面我的设备列表中,所有这些文件都是在 11 月 7 日上午 7:06 创建的,这是我最后一次启动系统。

当然, mknod 命令仍然可用, 但新的 MAKEDEV (是的,所有字母大写,在我看来是违背 Linux 使用小写命令名的原则的) 命令提供了一个创建设备文件的更容易的界面。 在当前版本的 Fedora 或 CentOS 7 中,默认情况下不安装 MAKEDEV 命令;它安装在 CentOS 6。您可以使用 YUM 或 DNF 来安装 MAKEDEV 包。

结论

有趣的是,我很久没有创建一个设备文件的需要了。 然而,最近我遇到一个有趣的情况,其中一个我常使用的设备文件没有创建,我不得不创建它。 之后该设备再没出过问题。所以丢失设备文件的情况仍然可以发生,知道如何处理它可能很重要。

设备文件有无数种,您遇到的设备文件我可能没有涵盖到。 这些信息在所下面引用的资源中有大量的细节信息可用。 关于这些文件的功能和工具,我希望我已经给您一些基本的了解,下一步您自己可以探索更多。

资源


via: https://opensource.com/article/16/11/managing-devices-linux

作者:David Both 译者:erlinux 校对:jasminepeng

本文由 LCTT 组织编译,Linux中国 荣誉推出

如果你一直关注苹果最新版的 macOS 的消息,你可能已经注意到苹果文件系统 APFS。这是不太让人感冒的话题之一。然而,它是支撑了操作系统用户体验的核心结构。APFS 将在 2017 年之前完成,不过你现在可以在 Sierra(最新版的 macOS) 上面体验一番开发者预览版。

特色与改进

先快速科普一下,文件系统是操作系统用于存储和检索数据的基本结构,不同的文件系统采用不同的方式来实现这个任务。随着计算机变得越来越快,新生代的文件系统已经从计算机速度的提升中获益,以提供新功能和适应现代存储需求。

HFS+,作为今天新一代 Mac 的附带文件系统,已经 18 岁了。它的祖先 HFS 比 Tom Cruise 的兄弟情影片“壮志凌云”还要老。它有点像一辆老丰田。它仍然可以工作(也许惊人的好),但是它不再得到人们的嘉奖。

APFS 不完全是 HFS+ 的升级版,因为相对现在而言,它是一个大幅度的飞跃。虽然这对苹果用户来说是一个重大的升级,但似乎这看起来更像是苹果赶上了其它系统,而不是超越了它们。然而,更新还进展得非常慢。

克隆和数据完整性

APFS 使用称为写时复制(copy-on-write)的方案来生成重复文件的即时克隆。在 HFS+ 下,当用户复制文件的时候,每一个比特(二进制中的“位”)都会被复制。而 APFS 则通过操作元数据并分配磁盘空间来创建克隆。但是,在修改复制的文件之前都不会复制任何比特。当克隆体与原始副本分离的时候,那些改动(并且只有那些改动)才会被保存。

写时复制还提高了数据的完整性。在其它系统下,如果你卸载卷导致覆写操作挂起的话,你可能会发现你的文件系统有一部分与其它部分不同步。写时复制则通过将改动写入到可用的磁盘空间而不是覆盖旧文件来避免这个问题。直到写入操作成功完成前,旧文件都是正式版本。只有当新文件被成功复制时,旧文件才会被清除。

系统快照

快照是写时复制架构给你带来的一个主要的升级。快照是文件系统在某个时间点的一个只读的可装载映像。随着文件系统发生改动,只有改动的比特会被更改。这可以让备份更简单,更可靠。考虑到时间机器(一个苹果出品的备份工具)已经成为硬链接的痛点,这可能是一个重大的升级。

输入/输出的服务质量(QoS)

你可能已经在你的路由器说明书看到了服务质量(QoS)这个名词。QoS 优先分配带宽使用以避免降低优先任务的速度。在你的路由器上,它采用用户定义的规则来为指定任务提供最大的带宽。据报道,苹果的 QoS 会优先考虑用户操作,例如活跃窗口。而诸如时间机器备份这些后台任务将会被降级。所以,这意味着更少的闲暇时光了?

本地加密

在后斯诺登时代,加密成为众所关注的了。越来越多的苹果产品正在强调其系统安全性。内置强大的加密机制并不让人感到意外。包括 APFS 在内,苹果正在采用更加细致入微的加密方案,要么不加密,要么就将加密进行到底。用户可以使用单个密钥来为所有数据加密,或者使用多个加密密钥分别锁定单个文件和文件夹。当然,你也可以不加密,只要你对坏蛋无所忌惮。

固态硬盘和闪存优化

闪存优化已经被列为 APFS 的一个亮点功能,不过它的实现并没有那么振奋人心。苹果选择将一些典型的固态硬盘芯片的处理功能迁移到操作系统,而没有深度系统集成的优势。这更像是让文件系统感知固态硬盘,而不是为它们做优化。

动态分区调整

APFS 驱动器的逻辑分区可以动态调整自身大小。用户只需指定所需分区的数量,然后文件系统会在运行时进行磁盘分配。每个分区只占用其用于存储文件的磁盘空间。剩余的磁盘空间会由任何分区获取。这种设计很整洁,不过比起其它文件系统,这更像是元文件夹。

结论

这是否重要?对于开发者和高级用户来说真是棒极了。对于一般的 Mac 用户应该没有太多的外部差异。虽然升级是重大的举措,但仍然存在一些缺失的部分。本地压缩显然还没有,对用户数据进行的校验也没有。当然,2017 年还没到,一切皆有可能,让我们拭目以待。


编译自: https://www.maketecheasier.com/apple-file-system-better-than-hfs/

作者:Alexander Fox 译者:OneNewLife 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

写这篇文章的主要目的就是提供一步一步的指导,关于如何使用 SSHFS 通过 SSH 挂载远程的 Linux 文件系统或目录。

这篇文章对于那些无论出于什么目的,希望在他们本地的系统中挂载远程的文件系统的用户或者系统管理员有帮助。我们通过 Linux 系统中的一个安装了 SSHFS 客户端进行实际测试,并且成功的挂载了远程的文件系统。

在我们进一步安装之前,让我们了解一下 SSHFS 的相关内容,以及它是如何工作的。

Sshfs 挂载远程的 Linux 文件系统或者目录

什么是 SSHFS?

SSHFS(Secure SHell FileSystem)是一个客户端,可以让我们通过 SSH 文件传输协议(SFTP)挂载远程的文件系统并且在本地机器上和远程的目录和文件进行交互。

SFTP 是一种通过 SSH 协议提供文件访问、文件传输和文件管理功能的安全文件传输协议。因为 SSH 在网络中从一台电脑到另一台电脑传输文件的时候使用数据加密通道,并且 SSHFS 内置在 FUSE(用户空间的文件系统)内核模块,允许任何非特权用户在不修改内核代码的情况下创建他们自己的文件系统。

在这篇文章中,我们将会向你展示在任意 Linux 发行版上如何安装并且使用 SSHFS 客户端,在本地 Linux 机器上挂载远程的 Linux 文件系统或者目录。

步骤 1:在 Linux 系统上安装 SSHFS

默认情况下,sshfs 包不存在所有的主流 Linux 发行版中,你需要在你的 Linux 系统中启用 epel 仓库,在 Yum 命令行的帮助下安装 SSHFS 及其依赖。

# yum install sshfs
# dnf install sshfs              【在 Fedora 22+ 发行版上】
$ sudo apt-get install sshfs     【基于 Debian/Ubuntu 的系统】

步骤 2:创建 SSHFS 挂载目录

当你安装 SSHFS 包之后,你需要创建一个挂载点目录,在这儿你将要挂载你的远程文件系统。例如,我们在 /mnt/tecmint 下创建挂载目录。

# mkdir /mnt/tecmint
$ sudo mkdir /mnt/tecmint     【基于 Debian/Ubuntu 的系统】

步骤 3:使用 SSHFS 挂载远程的文件系统

当你已经创建你的挂载点目录之后,现在使用 root 用户运行下面的命令行,在 /mnt/tecmint 目录下挂载远程的文件系统。视你的情况挂载目录可以是任何目录。

下面的命令行将会在本地的 /mnt/tecmint 目录下挂载一个叫远程的一个 /home/tecmint 目录。(不要忘了使用你的 IP 地址和挂载点替换 x.x.x.x)。

# sshfs [email protected]:/home/tecmint/ /mnt/tecmint
$ sudo sshfs -o allow_other [email protected]:/home/tecmint/ /mnt/tecmint      【基于 Debian/Ubuntu 的系统】

如果你的 Linux 服务器配置为基于 SSH 密钥授权,那么你将需要使用如下所示的命令行指定你的公共密钥的路径。

# sshfs -o IdentityFile=~/.ssh/id_rsa [email protected]:/home/tecmint/ /mnt/tecmint
$ sudo sshfs -o allow_other,IdentityFile=~/.ssh/id_rsa [email protected]:/home/tecmint/ /mnt/tecmint     【基于 Debian/Ubuntu 的系统】

步骤 4:验证远程的文件系统挂载成功

如果你已经成功的运行了上面的命令并且没有任何错误,你将会看到挂载在 /mnt/tecmint 目录下的远程的文件和目录的列表

# cd /mnt/tecmint
# ls
[root@ tecmint]# ls
12345.jpg                       ffmpeg-php-0.6.0.tbz2                Linux                                           news-closeup.xsl     s3.jpg
cmslogs                         gmd-latest.sql.tar.bz2               Malware                                         newsletter1.html     sshdallow
epel-release-6-5.noarch.rpm     json-1.2.1                           movies_list.php                                 pollbeta.sql
ffmpeg-php-0.6.0                json-1.2.1.tgz                       my_next_artical_v2.php                          pollbeta.tar.bz2

步骤 5:使用 df -hT 命令检查挂载点

如果你运行 df -hT命令,你将会看到远程文件系统的挂载点。

# df -hT

样本输出:

Filesystem                          Type        Size  Used Avail Use% Mounted on
udev                                devtmpfs    730M     0  730M   0% /dev
tmpfs                               tmpfs       150M  4.9M  145M   4% /run
/dev/sda1                           ext4         31G  5.5G   24G  19% /
tmpfs                               tmpfs       749M  216K  748M   1% /dev/shm
tmpfs                               tmpfs       5.0M  4.0K  5.0M   1% /run/lock
tmpfs                               tmpfs       749M     0  749M   0% /sys/fs/cgroup
tmpfs                               tmpfs       150M   44K  150M   1% /run/user/1000
[email protected]:/home/tecmint fuse.sshfs  324G   55G  253G  18% /mnt/tecmint

步骤 6:永久挂载远程文件系统

为了永久的挂载远程的文件系统,你需要修改一个叫 /etc/fstab 的文件。照着做,使用你最喜欢的编辑器打开文件。

# vi /etc/fstab
$ sudo vi /etc/fstab     【基于 Debian/Ubuntu 的系统】         

移动到文件的底部并且添加下面的一行,保存文件并退出。下面条目表示使用默认的设置挂载远程的文件系统。

sshfs#[email protected]:/home/tecmint/ /mnt/tecmint fuse.sshfs defaults 0 0

确保服务器之间允许 SSH 无密码登录,这样系统重启之后才能自动挂载文件系统。

如果你的服务器配置为基于 SSH 密钥的认证方式,请加入如下行:

sshfs#[email protected]:/home/tecmint/ /mnt/tecmint fuse.sshfs IdentityFile=~/.ssh/id_rsa defaults 0 0

接下来,你需要更新 fstab 文件使修改生效。

# mount -a
$ sudo mount -a   【基于 Debian/Ubuntu 的系统】

步骤 7:卸载远程的文件系统

为了卸载远程的文件系统,只需要发出以下的命令即可。

# umount /mnt/tecmint

目前为止就这样了,如果你在挂载远程文件系统的时候遇到任何问题或者需要任何帮助,请通过评论联系我们,如果你感觉这篇文章非常有用,请分享给你的朋友们。


via: http://www.tecmint.com/sshfs-mount-remote-linux-filesystem-directory-using-ssh/

作者:Ravi Saive 译者:yangmingming 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出