Linuxでrsyncが/ sysからファイルをコピーできないのはなぜですか?


12

rsyncArchlinuxのファイルのバックアップに使用するbashスクリプトがあります。うまく動作している間に、rsyncからファイルをコピーできなかったことに気付きました。/syscp

# 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失敗するのだろうか、それでファイルをコピーすることは可能ですか?


4
なぜコピーしたいの/sys/ですか?
frostschutz

1
@frostschutz OPのコマンドを使用して、ネットワークカードのMACアドレスを(ファイルとして)コピーします
Eugene Yarmash

@eugeneyでは、なぜMACアドレスが設定されている設定ファイルをバックアップするだけでは十分ではないのでしょうか?
13

@eugeney書き込みも可能/sys/class/net/*/addressですか(試してみると「許可が拒否されました」)?そうでない場合は、復元できないため、実際/有用なバックアップを作成していません。
13

回答:


12

Rsyncには、読み取り中にファイルが切り捨てられたかどうかを具体的にチェックし、このエラーを返すコードがあります— ENODATA。ファイルにこの動作がある理由はわかりません/sysが、実際のファイルではないので、それほど驚くことではないと思います。この特定のチェックをスキップするようにrsyncに指示する方法はないようです。

おそらく、rsync /sysを使用せず、特定のスクリプトを使用して、必要な特定の情報(ネットワークカードアドレスなど)を選択する方が良いと思います。


Pfft、特にrsyncが失敗する理由がわからないのはどこですか?
ブラッチリー

すみません、はっきりしませんでした。Rsyncは、読み取り中に切り捨てられたファイルを特にチェックし、このエラーをスローします。
mattdm

4
あなたが実際にそれらを読むまで、「そこにある」ものは絶対に確実ではないので、私は彼らがこの挙動を持っていると思います。読み取りは、実際にはカーネルからの動的情報の要求です。そのため、カーネルは事前にファイルサイズなどに正確な詳細WRTを提供しようとはせず、指摘するように、rsyncはそのような矛盾を悪い兆候と見なします。
goldilocks

11

まずは/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's – The sysfs Filesystemをお読みください 。


/ sysファイルの統計

以下のディレクトリに移動すると、すべてのファイルのサイズが1つで/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ブロックを占有します。また、ルートのiノード(stat / sys)は1です。/stat/fs通常、iノードは2です。など。

rsyncとcp

擬似ファイルの同期のrsync失敗の最も簡単な説明は、おそらく例です。

address18バイトの名前のファイルがあるとします。ファイルの1 lsstatは4096バイトを報告します。


rsync

  1. ファイル記述子fdを開きます。
  2. fstat(fd)を使用して、サイズなどの情報を取得します。
  3. サイズのバイト、つまり4096を読み込むように設定します。これは@mattdmによってリンクされたコードの253行です。read_size == 4096
    1. 尋ねる; 読み取り:4096バイト。
    2. 短い文字列、つまり18バイトが読み取られます。 nread == 18
    3. read_size = read_size - nread (4096 - 18 = 4078)
    4. 尋ねる; 読み取り:4078バイト
    5. 0バイトの読み取り(最初の読み取りではファイル内のすべてのバイトが消費されたため)。
    6. nread == 0255行目
    7. 4096バイトを読み取れません。ゼロアウトバッファ。
    8. エラーを設定しますENODATA
    9. 戻ります。
  4. エラーを報告します。
  5. リトライ。(ループの上)。
  6. 不合格。
  7. エラーを報告します。
  8. ファイン。

このプロセス中に、実際にファイル全体を読み取ります。しかし、使用可能なサイズがないと、結果を検証できません。したがって、失敗は唯一の選択肢です。

cp

  1. ファイル記述子fdを開きます。
  2. fstat(fd)を使用して、st_sizeなどの情報を取得します(lstatおよびstatも使用します)。
  3. ファイルがスパースである可能性が高いかどうかを確認してください。つまり、ファイルには穴などがあります。

    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. エクステントコピー(通常の スパースファイルをコピーするより効率的な方法)でファイルを読み取ろうとして失敗します。

  5. スパースコピーでコピーします。
    1. MAXINTの最大読み取りサイズで開始します。
      通常 18446744073709551615、32ビットシステムのバイト。
    2. 尋ねる; 4096バイトを読み取ります。(統計情報からメモリに割り当てられたバッファサイズ。)
    3. 短い文字列、つまり18バイトが読み取られます。
    4. いいえ、穴が必要かどうかを確認してください。
    5. ターゲットにバッファを書き込みます。
    6. 最大読み取りサイズから18を引きます。
    7. 尋ねる; 4096バイトを読み取ります。
    8. 最初の読み取りですべてが消費されたため、0バイト。
    9. 成功を返します。
  6. 大丈夫。ファイルの更新フラグ。
  7. ファイン。

2

関連する可能性がありますが、sysfsでは拡張属性呼び出しは失敗します。

[root @ hypervisor eth0]#lsattrアドレス

lsattr:アドレスのフラグを読み取り中のデバイスの不適切なioctl

[root @ hypervisor eth0]#

私のstraceを見ると、rsyncはデフォルトで拡張属性を引き込もうとしているようです:

22964 <... getxattr resumed>、0x7fff42845110、132)= -1 ENODATA(利用可能なデータなし)

拡張属性をスキップすると問題が解決するかどうかを確認するためにrsyncを指定するフラグを見つけよう--xattrsとしましたが、何も見つけることができませんでした(宛先でそれらをオンにします)。


0

Rsyncは通常、ファイルの情報を読み取り、ファイルの内容またはデルタを宛先ディレクトリの一時ファイルに転送し、ファイルのデータを確認した後、宛先ファイル名に名前を変更します。

sysfsの問題は、すべてのファイルが4k(1メモリページ)として表示されるのに、数バイトしか含まれない可能性があることだと思います。破損の可能性があるファイルを宛先にコピーしないように、ファイルのメタデータと実際にコピーされたものとの不一致が見つかった場合、rsyncはコピーをキャンセルします。

少なくともrsync v3.0.6では、この動作は--inplaceスイッチを使用して回避できます。Rsyncは引き続きエラーを検出しますが、宛先ファイルは既に上書きされているため、破損している可能性のあるファイルをそこに残します。

ただし、副作用として、ファイルが4kにゼロで埋められることになります。これは、rsyncがファイルを認識するサイズであるためです。nullバイトは通常無視されるため、ほとんどの場合、違いはありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.