ホームページ  >  記事  >  運用・保守  >  lsof から始めて、Linux 仮想ファイル システムを深く理解します。

lsof から始めて、Linux 仮想ファイル システムを深く理解します。

Linux中文社区
Linux中文社区転載
2023-08-04 16:15:491618ブラウズ

バックグラウンド

ディスク容量がいっぱいであることが時々発生しますが、ディスクをチェックするとき、特定のディスクをチェックするとき、ファイルの占有状況を確認したところ、ディスクにまだ多くの空き領域があることがわかりました。
1. <span style="font-size: 15px;">df</span> コマンドを実行してディスク使用量を確認し、ディスクがいっぱいであることを確認します。
-bash-4.2$ df -ThFilesystem     Type      Size  Used Avail Use% Mounted on/dev/vda1      ext4       30G    30G 0         100% /devtmpfs       devtmpfs  489M     0  489M   0% /devtmpfs          tmpfs     497M     0  497M   0% /dev/shmtmpfs          tmpfs     497M   50M  447M  11% /runtmpfs          tmpfs     497M     0  497M   0% /sys/fs/cgroup


2. du コマンドを実行して、各ディレクトリのディスク使用量を確認し、各ディレクトリ内のファイルのサイズを合計すると、ディスクは占有されていませんが、10 G を超えるスペースが何らかの理由で不足しています。


-bash-4.2$ du -h --max-depth=1 /home16M    /home/logs11G    /home/serverdog11G    /home

###
3.为何会出现这样的情况呢?
因为虽然文件已被删除,但是一些进程仍然打开这些文件,因此其占用的磁盘空间并没有被释放。执行<span style="font-size: 15px;">lsof</span> 命令显示打开已删除的文件。将有问题的进程重启(或,清空),磁盘空间就会得到释放。
-bash-4.2# lsof | grep deletemysqld     2470         mysql    4u      REG              253,1           0     523577 /var/tmp/ibfTeQFn (deleted)mysqld     2470         mysql    5u      REG              253,1           0     523579 /var/tmp/ibaHcIdW (deleted)mysqld     2470         mysql    6u      REG              253,1           0     523581 /var/tmp/ibLjiALu (deleted)mysqld     2470         mysql    7u      REG              253,1           0     523585 /var/tmp/ibCFnzTB (deleted)mysqld     2470         mysql   11u      REG              253,1           0     523587 /var/tmp/ibCjuqva (deleted)

那么,Linux 的文件系统,到底为什么这么设计呢?要了解这些,就要先弄清楚并不容易,下面将从一些基本概念入手,一步步将这些梳理清楚:
  • 什么是虚拟文件系统(VFS:virtual filesystem)?

  • 什么是通用文件模型?

    • 超级块对象(superblock object)

    • 索引节点对象(inode object)

    • 文件对象(file object)

    • 目录项对象(dentry object)

    • 文件的概念

  • 文件的表达

    • 内存表达

    • 磁盘表达

  • 目录树的构建

    • ソフト リンクとハード リンク

  • ファイルとディスクの管理

    • インデックス ノードのステータス

  • ファイルとプロセスの管理

    • 操作:

      開いて削除

仮想ファイル システム

下の図は基本的なものを示していますLinux オペレーティング システムでファイル管理を担当するコンポーネント。上半分の領域がユーザーモード、下半分の領域がカーネルモードです。アプリケーションは標準ライブラリ libc を使用してファイルにアクセスし、ライブラリはカーネル モードに入るために要求をシステム コールにマップします。

lsof から始めて、Linux 仮想ファイル システムを深く理解します。

すべてのファイル関連操作のエントリ ポイントは、特定のファイル システム (Ext3、ReiserFS、NFS など) ではなく、仮想ファイル システム (VFS) です。 VFS は、システム ライブラリと特定のファイル システム間のインターフェイスを提供します。したがって、VFS は抽象化レイヤーとして機能するだけでなく、さまざまな実装で使用および拡張できるファイル システムの基本実装を実際に提供します。したがって、ファイル システムがどのように機能するかを理解するには、まず VFS について理解する必要があります。

共通ファイル モデル

VFS の主なアイデアは、共通ファイル モデルを導入することです。一般的なファイル モデルは、次のオブジェクト タイプで構成されます。

スーパーブロック オブジェクト

メモリ: インストール中に作成されるファイル システムファイルシステムに関する情報を保存します
ディスク: ディスク上に保存されるファイルシステム制御ブロック (ファイルシステム制御ブロック) に対応します

インデックスノードオブジェクト (inode オブジェクト)

メモリ: アクセス時に作成され、特定のファイルに関する一般情報を保存します (inode 構造)
ディスク: ファイル コントロールに保存されているファイルに対応しますディスク上のブロック
各 inode オブジェクトには、ファイル システム内でファイルを一意に識別する i ノード番号があります

ファイル オブジェクト (ファイル オブジェクト)

メモリ: ファイルを開くときに作成され、開いているファイルとファイル間のやり取りを保存します。 process (ファイル構造 ) に関する情報
オープン ファイル情報は、プロセスがファイルにアクセスしている間のみカーネル メモリに存在します。

ディレクトリ オブジェクト (dentry オブジェクト)

メモリ: ディレクトリ エントリがメモリに読み込まれると、VFS 変換されます。 dentry 構造のディレクトリ エントリ オブジェクトに変換します。
ディスク: 特定のファイル システムが特定の方法でディスクに保存されます。
対応するファイルにリンクされたディレクトリ エントリ (つまり、ファイル名) を保存します。情報

ディレクトリ ツリー

要約すると、Linux のルート ファイル システム (システムのルート ファイル システム) は、カーネルがシステムを起動するために最初に使用するものです。マウント ファイル システム。カーネル コード イメージ ファイルはルート ファイル システムに保存され、システム ブート プログラムは、ルート ファイル システムのマウント後に実行するために、いくつかの基本的な初期化スクリプトとサービスをメモリにロードします (ファイル システムとカーネルは完全に独立した 2 つの部分です) )。その後、スクリプトまたはコマンドを使用して、ファイル システムがインストールされているディレクトリに他のファイル システムがサブファイル システムとしてインストールされ、最終的にディレクトリ ツリー全体が形成されます。

start_kernel   vfs_caches_init     mnt_init       init_rootfs     // 注册rootfs文件系统      init_mount_tree // 挂载rootfs文件系统   …   rest_init   kernel_thread(kernel_init, NULL, CLONE_FS);

就单个文件系统而言,在文件系统安装时,创建超级块对象;沿树查找文件时,总是首先从初识目录的中查找匹配的目录项,以便获取相应的索引节点,然后读取索引节点的目录文件,转化为dentry对象,再检查匹配的目录项,反复执行以上过程,直至找到对应的文件的索引节点,并创建索引节点对象。

软链接 vs 硬链接

软链接是一个普通的文件,其中存放的是另外一个文件的路径名。硬链接则指向同一个索引节点,硬链接数记录在索引节点对象的 i_nlink 字段。当<span style="font-size: 15px;color: rgb(68, 68, 68);">i_nlink</span>字段为零时,说明没有硬链接指向该文件。

文件 & 进程管理

下图是一个简单示例,说明进程是怎样与文件进行交互。三个不同进程打开同一个文件,每个进程都有自己的文件对象,其中两个进程使用同一个硬链接(每个硬链接对应一个目录对象),两个目录项对象都指向同一个 索引节点对象。

lsof から始めて、Linux 仮想ファイル システムを深く理解します。

索引节点的数据又由两部分组成:内存数据和磁盘数据。Linux 使用 Write back 作为索引节点的数据一致性策略。对于索引节点的数据,当文件被打开时,才会加载索引节点到内存;当不再被进程使用,则从内存踢出;如果中间有更新,则需要把数据写回磁盘。
*  "in_use" - valid inode, i_count > 0, i_nlink > 0*  "dirty"  - as "in_use" but also dirty*  "unused" - valid inode, i_count = 0

インデックス ノードがまだ使用されているかどうかは、<span style="font-size: 15px;">open()</span>## によって決まります。 #close ()<span style="font-size: 15px;"></span> この操作では、ファイル オブジェクトが作成および破棄されます。ファイル オブジェクトは、iget<span style="font-size: 15px;"></span>## を通じてインデックス ノードによって提供されます。 # および iput<span style="font-size: 15px;"></span> インデックス ノードの i_count フィールドを更新して、使用数カウントを完了します。オープン操作では i_count が 1 つ増加し、クローズ操作では i_count が 1 つ減少します。クローズ操作中にインデックス ノードが解放されるかどうかを決定します。i_count = 0 の場合は、プロセス参照がなくなり、メモリから解放されることを意味します。
ファイルとディスクの管理

ファイルとディスクの管理に最も密接に関連する操作は

touch <span style="font-size: 15px;"></span> 操作と #rm<span style="font-size: 15px;"> 操作、特に後者が最も重要です。 strace (または dtruss) を使用して、rm</span> の実際のシステム コールを表示します。

# dtruss rm tmp...geteuid(0x0, 0x0, 0x0)         = 0 0ioctl(0x0, 0x4004667A, 0x7FFEE06F09C4)         = 0 0lstat64("tmp\0", 0x7FFEE06F0968, 0x0)         = 0 0access("tmp\0", 0x2, 0x0)         = 0 0unlink("tmp\0", 0x0, 0x0)         = 0 0

可以发现 rm 实际是通过 unlink 完成的。unlink代表删除目录项,以及减少其索引节点的计数。由通用文件模型可知,父目录本身同样是一个文件,也就意味着目录项是其文件数据的一部分。删除目录项等价于从父目录的文件中删除数据,也就意味着首先要打开父目录的文件。那么,删除操作即可理解为:

  1. 删除命令(一个进程)使用 open 操作获得父目录文件对象

  2. 通过 <span style="font-size: 15px;color: rgb(68, 68, 68);">iget</span> 增加 目录文件的索引节点对象计数

  3. 读取目录文件数据

  • 将目录文件数据转化为目录项对象

  • 由于目录项包含文件的索引节点,类似的,需要通过 iget 增加文件的索引节点对象计数

  • 删除目录的目录项

  • 减少文件索引节点对象的硬链接计数i_nlink

  • 通过 <span style="font-size: 15px;color: rgb(68, 68, 68);">iput</span> 结束对文件索引节点对象的操作,使用计数 i_count 减一

    • 判断i_count是否为零,如果为零,则释放内存

    • 然后,判断i_nlink是否为零,如果为零,则释放磁盘空间

  • 通过 iput 结束对目录索引节点对象的操作。

  • 概要

    遭遇した問題を振り返ると、実際には次の 2 つの角度から問題を理解できます。

    インデックスとデータ

    ファイル システムとファイル、ディスク管理とファイル、プロセス管理とファイル、中心となるのはファイルのデータではなく、ファイルのインデックスです。データとインデックスを分離することは、ファイル システムを理解するための鍵です。


    lsof から始めて、Linux 仮想ファイル システムを深く理解します。

    ##キャッシュ戦略

    オペレーティング システムはライト バックを使用するためこの戦略は、メモリが最初に解放された場合にのみディスクを解放できることを意味します。

    なぜ lsof なのか ?

    上記のモデルから明確に理解できます。これは、ディレクトリにはファイルのインデックスが作成されなくなりましたが、ファイルを開くときには引き続きインデックスが作成されるためです。ファイルが削除されるため、ディスク領域をすぐに解放することはできません。
    なぜ lsof は削除されたファイルや未公開のファイルを見つけることができるのでしょうか?
    lsof は、その名前が示すように、開いているファイルのリストを表示します。このコマンドの原理は、開いているファイルのリストを検索することで、削除されたが解放されていないファイルを見つけることができます。

以上がlsof から始めて、Linux 仮想ファイル システムを深く理解します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はLinux中文社区で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。