為什麼 rsync 在 Linux 中無法從 /sys 複製文件?
我有一個用於
rsync
在 Archlinux 中備份文件的 bash 腳本。我注意到rsync
無法從中復製文件/sys
,但cp
工作得很好:# rsync /sys/class/net/enp3s1/address /tmp rsync: read errors mapping "/sys/class/net/enp3s1/address": No data available (61) rsync: read errors mapping "/sys/class/net/enp3s1/address": No data available (61) ERROR: address failed verification -- update discarded. rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1052) [sender=3.0.9] # cp /sys/class/net/enp3s1/address /tmp ## this works
我想知道為什麼會
rsync
失敗,是否可以用它複製文件?
Rsync 具有專門檢查文件在讀取期間是否被截斷並給出此錯誤的程式碼
ENODATA
- . 我不知道為什麼其中的文件/sys
有這種行為,但由於它們不是真正的文件,我想這並不奇怪。似乎沒有辦法告訴 rsync 跳過這個特定的檢查。我認為你最好不要 rsync
/sys
並使用特定的腳本來挑選你想要的特定資訊(比如網卡地址)。
首先
/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 的 – The sysfs Filesystem。
/sys 文件的統計資訊
如果您進入一個目錄
/sys
並執行 als -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塊。根 (stat /sys) 的 inode 也是 1。/stat/fs
通常具有 inode 2。等等。rsync 與 cp
同步偽文件的 rsync 失敗的最簡單解釋可能是通過範例。
假設我們有一個名為
address
18 字節的文件。一個ls
或stat
的文件報告 4096 字節。rsync
- 打開文件描述符 fd。
- 使用 fstat(fd) 獲取大小等資訊。
- 開始讀取 size 字節,即 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
具有零塊的報告文件,它被歸類為稀疏。 4. 嘗試通過 extent-copy 讀取文件(一種複制普通 稀疏文件的更有效方法),但失敗。 5. 通過稀疏複製進行複制。
- 從 MAXINT 的最大讀取大小開始。
通常18446744073709551615
是 32 位系統上的字節。- 問; 讀取 4096 字節。(根據統計資訊在記憶體中分配的緩衝區大小。)
- 讀取一個短字元串,即 18 個字節。
- 檢查是否需要一個孔,不。
- 將緩衝區寫入目標。
- 從最大讀取大小中減去 18。
- 問; 讀取 4096 字節。
- 第一次讀取時消耗了 0 個字節。
- 返回成功。
- 一切都好。更新文件的標誌。
- 美好的。