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
なぜ失敗するのか、ファイルのコピーに使用できるのか知りたいのですが。
答え1
最初/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
aをすると、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
さらに、ファイルを操作するとゼロブロックを占めるというもう1つの明確な機能が見つかります。また、ルートノード(stat / sys)のinodeは1です。/stat/fs
通常、inode 2があります。など。
rsyncとcp
おそらく、rsyncの疑似ファイル同期失敗の最も簡単な説明は、例を通してです。
address
18バイトというファイルがあるとしましょう。ファイルはls
4096バイトを報告します。stat
同期
- ファイル記述子fdを開きます。
- サイズやその他の情報を取得するには、fstat(fd)を使用してください。
- 4096のsizeバイトの読み取りを開始します。そうだろう253号線リンクされたコード@mattdem。
read_size == 4096
- Q;読み取り: 4096 バイトです。
- 18バイトの短い文字列を読み込みます。
nread == 18
read_size = read_size - nread (4096 - 18 = 4078)
- Q;読み取り:4078バイト
- ゼロバイトを読み取ります(最初の読み取りでファイルのすべてのバイトを消費するため)。
nread == 0
、255番国道- バイトを読み取れません
4096
。バッファをゼロにします。 - 設定エラーです
ENODATA
。 - 返品。
- エラーを報告してください。
- やり直しより。 (上のループ).
- 失敗する。
- エラーを報告してください。
- 美しい。
このプロセスの間、実際にファイル全体を読み込みます。ただし、使用可能なディメンションがないため、結果を確認できないため、失敗は唯一のオプションです。
CP
- ファイル記述子fdを開きます。
- st_sizeなどの情報を取得するには、fstat(fd)を使用します(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から始まります。通常32ビットシステムの
バイトです。18446744073709551615
- Q;4096バイトを読みました。 (統計に基づいてメモリに割り当てられたバッファサイズ。)
- 18バイトの短い文字列を読み込みます。
- 掘削が必要であることを確認してください。
- 宛先にバッファを書き込みます。
- 最大読み取りサイズから18を減算します。
- Q;4096バイトを読みました。
- 最初の読み取りですべて消費されるため、0バイトです。
- リターン成功。
- 最大読み取りサイズMAXINTから始まります。通常32ビットシステムの
- すべてがうまくいった。ファイルフラグを更新します。
- 美しい。
答え2
再同期はパスワード特に読み込み中にファイルが切り捨てられていることを確認し、次のエラーを表示しますENODATA
。全然知らないなぜのファイルには/sys
これらの動作がありますが、実際のファイルではないので、それは驚くべきことではありません。 rsyncにこの特定のチェックをスキップするように指示する方法はないようです。
/sys
rsyncを実行せずに特定のスクリプトを使用して必要な特定の情報(ネットワークカードアドレスなど)を選択する方が良いと思います。
答え3
関連している可能性がありますが、拡張属性呼び出しはsysfsで失敗します。
[root@hypervisor eth0]# lsattr アドレス
lsattr:アドレスからフラグを読み取るときにデバイスの不適切なioctl
[ルート@ハイパーバイザーeth0]#
私のstraceを見ると、rsyncがデフォルトで拡張属性を取得しようとしているようです。
22964 <... getxattr Recovery> , 0x7fff42845110, 132) = -1 ENODATA(利用可能なデータなし)
拡張属性をスキップすると、問題が解決することを確認するためにrsyncを提供するフラグを見つけようとしましたが、何も見つかりませんでした--xattrs
。存在する目的地に到達)。
答え4
Rsyncは通常、ファイル情報を読み取り、ファイルの内容またはデルタをターゲットディレクトリの一時ファイルに転送し、検証した後、ファイルデータの名前をターゲットファイルの名前に変更します。
私の考えでは、sysfsの問題は、すべてのファイルが4k(メモリ1ページ)に見えますが、数バイトしか含めることができないということです。潜在的に破損する可能性のあるファイルがターゲットにコピーされるのを防ぐために、rsyncはファイルのメタデータが実際にコピーされたものと一致しないことを検出するとコピーをキャンセルします。
少なくともrsync v3.0.6では、--inplace
スイッチを使用してこの動作を防ぐことができます。 Rsyncは依然としてエラーを検出しますが、検出時にターゲットファイルを上書きしたため、潜在的に破損したファイルはそのまま残ります。
これの副作用は、ファイルが4kでゼロで埋められることです。なぜなら、rsyncがファイルのサイズを考えるサイズだからです。ほとんどの場合、ヌルバイトは通常無視されるため、何の効果もありません。