AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 459249
Accepted
Nht_e0
Nht_e0
Asked: 2018-07-30 18:33:07 +0800 CST2018-07-30 18:33:07 +0800 CST 2018-07-30 18:33:07 +0800 CST

磁盘被访问了多少次?

  • 772

这是关于通用 UFS。

据我了解,当给出绝对路径(例如/home/userU/file.txt:)时,每个目录和文件都会访问磁盘。因此,在这种情况下,磁盘被访问 4 次

1 为/, 1 为home/, 1 为/userU, 1 为file.txt

我的问题是

  1. 如果给出一个硬链接/hL,指向上面文件的inode,访问磁盘的顺序是什么?
  2. 如果给出一个软链接/sL,指向上面的文件,访问磁盘的顺序是什么?

假设在所有三种情况下最初都没有缓存任何 inode 或任何其他数据。

path hard-link
  • 2 2 个回答
  • 798 Views

2 个回答

  • Voted
  1. Best Answer
    slm
    2018-07-30T22:03:25+08:002018-07-30T22:03:25+08:00

    背景

    假设我们有以下目录设置:

    $ ll
    total 0
    -rw-r--r-- 2 root root 0 Jul 29 23:36 afile.txt
    -rw-r--r-- 2 root root 0 Jul 29 23:36 hL
    lrwxrwxrwx 1 root root 9 Jul 30 01:22 sL -> afile.txt
    

    现在让我们看看你的2个问题。


    问题

    1. 如果给出一个硬链接/hL,指向上面文件的inode,访问磁盘的顺序是什么?

    对于硬链接,它们拥有与它们指向的原始文件/目录相同的 inode 引用。所以没有额外的硬盘访问来读取它们。

    例如:

    $ stat hL | head -3
      File: ‘hL’
      Size: 0           Blocks: 0          IO Block: 4096   regular empty file
    Device: fd00h/64768d    Inode: 667668      Links: 2
    

    对比

    $ stat afile.txt | head -3
      File: ‘afile.txt’
      Size: 0           Blocks: 0          IO Block: 4096   regular empty file
    Device: fd00h/64768d    Inode: 667668      Links: 2
    

    这两个之间的唯一区别是名称。因此,任一路径都会产生相同数量的 HDD 访问。

    1. 如果给出一个软链接/sL,指向上面的文件,访问磁盘的顺序是什么?

    然而,对于软链接,还有一个额外的 HDD 访问。这种额外的访问将针对文件sL所在目录的元数据。然后这将返回详细信息,说明该文件实际上是一个符号链接,并且它指向另一个文件/目录。

    例如:

    $ stat sL | head -3
      File: ‘sL’ -> ‘afile.txt’
      Size: 9           Blocks: 0          IO Block: 4096   symbolic link
    Device: fd00h/64768d    Inode: 681295      Links: 1
    

    在这里,我们可以看到它的类型为“符号链接”,并且指向afile.txt. 还要注意它有一个不同的 inode(681295 与 667668),进一步证明它需要额外读取。

    那么什么是读命令呢?

    如果您使用strace针对这些文件/目录运行命令的 Bash shell 本身,您可以了解事情是如何工作的。

    [pid 18098] stat("/tmp/adir/hL", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
    [pid 18098] open("/tmp/adir/hL", O_RDONLY) = 3
    [pid 18098] fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
    

    这是命令的输出more /tmp/adir/hL。

    对于/tmp/adir/hL:

    • stat/open (/) → stat/open (tmp) → stat/open (adir) → stat/open (hL)

    对于/tmp/adir/sL:

    • stat/open (/) → stat/open (tmp) → stat/open (adir) → stat/open (sL) → stat/open (afile.txt)

    更多详细信息

    符号链接上的维基百科页面也避开了所有这些:

    尽管将链接值存储在 inode 中节省了磁盘块和磁盘读取,但操作系统仍然需要解析链接中的路径名,这总是需要读取额外的 inode,并且通常需要读取其他的,可能还有很多目录,处理文件列表和每个文件的索引节点,直到找到与链接的路径组件匹配的内容。只有当链接指向同一目录中的文件时,“快速符号链接”才能提供比其他符号链接更好的性能。

    参考

    • 符号链接 - 维基百科
    • 1
  2. Bob
    2018-07-30T23:11:52+08:002018-07-30T23:11:52+08:00

    这两个问题其实都是一个问题:“How path_resolutionworks?”,所以从这个角度来看整个过程。

    从PATH_RESOLUTION(7)我们读到:

    文件名(或路径名)解析如下。

    然后我们看到第一步对于硬链接和符号链接都是通用的(系统决定路径解析的起点是什么:根目录/、chrooted 目录或当前目录)。

    如果路径名以“/”字符开头,则起始查找目录是调用进程的根目录。(进程从其父进程继承其根目录。通常这将是文件层次结构的根目录。进程可能会通过使用 chroot(2) 系统调用获得不同的根目录。进程可能会获得完全私有的挂载命名空间,以防它(或其祖先之一)是通过调用设置了 CLONE_NEWNS 标志的 clone(2) 系统调用启动的。)这将处理路径名的“/”部分。

    如果路径名不以“/”字符开头,则解析进程的起始查找目录是进程的当前工作目录。(这也是从父级继承的。它可以通过使用 chdir(2) 系统调用来更改。)

    以“/”字符开头的路径名称为绝对路径名。不以“/”开头的路径名称为相对路径名。

    正如我们看到的硬链接和符号链接之间的起点没有区别。但是,当开始走这条路时,下一步确实会出现差异:

    将当前查找目录设置为起始查找目录。现在,对于路径名的每个非最终组件,其中组件是由“/”字符分隔的子字符串,在当前查找目录中查找该组件。

    如果进程在当前查找目录上没有搜索权限,则返回 EACCES 错误(“权限被拒绝”)。

    如果未找到该组件,则返回 ENOENT 错误(“没有这样的文件或目录”)。如果找到该组件,但它既不是目录也不是符号链接,则返回 ENOTDIR 错误(“不是目录”)。

    如果找到该组件并且是一个目录,我们将当前查找目录设置为该目录,然后转到下一个组件。

    正如描述所示,文件和硬链接的路径解析没有区别 - 过程是相同的。那么符号链接呢?我们进一步阅读:

    如果找到该组件并且是符号链接(symlink),我们首先解析这个符号链接(以当前查找目录为起始查找目录)。发生错误时,将返回该错误。如果结果不是目录,则返回 ENOTDIR 错误。如果符号链接解析成功并返回一个目录,我们将当前查找目录设置为该目录,然后转到下一个组件。请注意,如果路径名的前缀 ('dirname') 组件包含一个文件名,该文件名是解析到目录的符号链接,则此处的解析过程可能涉及递归(该目录的前缀组件可能包含符号链接,因此上)。为了保护内核免受堆栈溢出,以及防止拒绝服务,最大递归深度和跟随的符号链接的最大数量有限制。超过最大值时返回 ELOOP 错误(“符号链接级别太多”)。

    如上所述,符号链接解析需要额外的磁盘访问操作,所以回答这两个问题:

    如果给出一个硬链接/hL,指向上面文件的inode,访问磁盘的顺序是什么?

    和

    如果给出一个软链接/sL,指向上面的文件,访问磁盘的顺序是什么?

    我们可以得出结论,硬链接访问与普通文件访问没有区别,但符号链接解析需要额外的磁盘访问操作,即符号链接解析。

    补充阅读:

    • PATH_RESOLUTION(7)
    • 打开(2)
    • 链接(2)
    • 符号链接(2)
    • 统计(2)
    • 1

相关问题

  • `update-alternatives --config somecommand` 如何找到 `somecommand` 的符号链接?

  • ln 中带有硬链接和软链接的路径

  • 使用 linux 终端默认在 openmpi 和 mpich 之间切换

  • 如何将命令应用于带有空格的 $PATH 文件?

  • 什么情况下路径中最先找到的可执行文件不会被使用

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve