首先/sys
是伪文件系统。如果您看一下,/proc/filesystems
将会发现已注册文件系统的列表,其中很多都nodev
位于前面。这表明它们是伪文件系统。这意味着它们作为基于RAM的文件系统存在于运行的内核中。此外,它们不需要块设备。
$ cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev bdev
...
在启动时,内核会挂载该系统并在适合时更新条目。例如,在引导过程中或通过查找新硬件udev
。
在/etc/mtab
通常情况下,您可以通过以下方式找到挂载:
sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0
有关该主题的出色论文,请阅读
Patric Mochel的- sysfs文件系统。
/ sys文件的状态
如果您进入一个目录/sys
并在其中执行操作,ls -l
您会注意到所有文件都有一个大小。通常为4096个字节。据报道sysfs
。
:/sys/devices/pci0000:00/0000:00:19.0/net/eth2$ ls -l
-r--r--r-- 1 root root 4096 Apr 24 20:09 addr_assign_type
-r--r--r-- 1 root root 4096 Apr 24 20:09 address
-r--r--r-- 1 root root 4096 Apr 24 20:09 addr_len
...
此外,您可以stat
对文件进行处理,并注意到另一个独特的功能。它占了0块。根(状态/ sys)的/stat/fs
inode也为1。通常具有inode2。依此类推。
rsync与cp
同步伪文件的rsync失败最简单的解释可能是示例。
假设我们有一个名为address
18个字节的文件。文件中的ls
或stat
报告4096个字节。
同步
- 打开文件描述符fd。
- 使用fstat(fd)获取信息,例如大小。
- 设置为读取大小字节,即4096。这是@mattdm链接的代码的第253行。
read_size == 4096
- 问; 读取:4096字节。
- 读取一个短字符串,即18个字节。
nread == 18
read_size = read_size - nread (4096 - 18 = 4078)
- 问; 读取:4078字节
- 读取0个字节(第一次读取消耗了文件中的所有字节)。
nread == 0
,第255行
- 无法读取
4096
字节。归零缓冲区。
- 设置错误
ENODATA
。
- 返回。
- 报告错误。
- 重试。(以上循环)。
- 失败。
- 报告错误。
- 精细。
在此过程中,它实际上会读取整个文件。但是,由于没有可用的大小,因此无法验证结果-因此失败只是选择。
cp
- 打开文件描述符fd。
- 使用fstat(fd)获取诸如st_size之类的信息(还使用lstat和stat)。
检查文件是否可能稀疏。那是文件有洞等。
copy.c:1010
/* Use a heuristic to determine whether SRC_NAME contains any sparse
* blocks. If the file has fewer blocks than would normally be
* needed for a file of its size, then at least one of the blocks in
* the file is a hole. */
sparse_src = is_probably_sparse (&src_open_sb);
由于stat
报表文件的块为零,因此分类为稀疏。
尝试通过扩展区复制(一种更有效的方法来复制普通
稀疏文件)读取文件,但失败。
- 通过稀疏复制进行复制。
- 从最大读取大小MAXINT开始。
通常
18446744073709551615
是32位系统上的字节。
- 问; 读取4096个字节。(根据统计信息在内存中分配的缓冲区大小。)
- 读取一个短字符串,即18个字节。
- 检查是否需要打孔,不。
- 将缓冲区写入目标。
- 从最大读取大小中减去18。
- 问; 读取4096个字节。
- 第一次读取时消耗了0个字节。
- 返回成功。
- 一切都好。更新文件标志。
- 精细。
/sys/
?