stat von /sys-Dateien

stat von /sys-Dateien

Ich habe ein Bash-Skript, das rsynczum Sichern von Dateien in Archlinux verwendet wird. Mir ist aufgefallen, dass rsyncdas Kopieren einer Datei von fehlgeschlagen ist /sys, während cpes problemlos funktioniert hat:

# 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

Ich frage mich, warum das rsyncfehlschlägt und ob es möglich ist, die Datei damit zu kopieren?

Antwort1

Zunächst einmal /sysist einPseudodateisystem. Wenn Sie sich das ansehen, /proc/filesystemsfinden Sie eine Liste registrierter Dateisysteme, bei denen ziemlich viele nodev vorne stehen. Das zeigt an, dass siePseudodateisysteme. Das bedeutet, dass sie auf einem laufenden Kernel als RAM-basiertes Dateisystem existieren. Außerdem benötigen sie kein Blockgerät.

$ cat /proc/filesystems
nodev   sysfs
nodev   rootfs
nodev   bdev
...

Beim Booten mountet der Kernel dieses System und aktualisiert die Einträge bei Bedarf. Zum Beispiel wenn während des Bootens oder durch neue Hardware gefunden wird udev.

/etc/mtabNormalerweise finden Sie die Halterung hier :

sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0

Einen guten Artikel zu diesem Thema finden Sie hier: Patric Mochel – Das sysfs-Dateisystem.


stat von /sys-Dateien

Wenn Sie in ein Verzeichnis unter gehen /sysund ein ausführen, ls -lwerden Sie feststellen, dass alle Dateien die gleiche Größe haben. Normalerweise 4096 Bytes. Dies wird von gemeldet 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
...

Außerdem können Sie eine statDatei ausführen und ein weiteres deutliches Merkmal feststellen: Sie belegt 0 Blöcke. Außerdem ist der Inode von Root (stat /sys) 1. /stat/fsNormalerweise hat er Inode 2 usw.

rsync im Vergleich zu cp

Die einfachste Erklärung für das Fehlschlagen der Synchronisierung von Pseudodateien mit rsync ist vielleicht ein Beispiel.

Angenommen, wir haben eine Datei mit dem Namen address18 Bytes. Ein lsOR statder Datei meldet 4096 Bytes.


rsync

  1. Öffnet den Dateideskriptor fd.
  2. Verwendet fstat(fd), um Informationen wie die Größe abzurufen.
  3. Legen Sie fest, dass Sie size bytes lesen möchten, also 4096. Das wäreZeile 253des Codes, der durch@mattdm.read_size == 4096
    1. Fragen; gelesen: 4096 Bytes.
    2. Es wird ein kurzer String gelesen, also 18 Bytes.nread == 18
    3. read_size = read_size - nread (4096 - 18 = 4078)
    4. Fragen; gelesen: 4078 Bytes
    5. 0 Bytes gelesen (da beim ersten Lesen alle Bytes in der Datei verbraucht wurden).
    6. nread == 0,Zeile 255
    7. Bytes können nicht gelesen werden 4096. Puffer auf Null setzen.
    8. Fehler festlegen ENODATA.
    9. Zurückkehren.
  4. Fehler melden.
  5. Erneut versuchen. (Oben genannte Schleife).
  6. Scheitern.
  7. Fehler melden.
  8. BUSSGELD.

Während dieses Vorgangs wird tatsächlich die gesamte Datei gelesen. Da jedoch keine Größe verfügbar ist, kann das Ergebnis nicht validiert werden. Daher ist ein Fehler die einzige Option.

cp

  1. Öffnet den Dateideskriptor fd.
  2. Verwendet fstat(fd), um Informationen wie st_size zu erhalten (verwendet auch lstat und stat).
  3. Überprüfen Sie, ob die Datei wahrscheinlich spärlich ist. Das heißt, die Datei hat Löcher usw.

    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);
    

    Da statdie Berichtsdatei keine Blöcke enthält, wird sie als spärlich kategorisiert.

  4. Versucht, die Datei per Extent-Copy zu lesen (eine effizientere Methode zum Kopierennormal Sparse-Dateien) und schlägt fehl.

  5. Kopie durch Sparse-Kopie.
    1. Beginnt mit der maximalen Lesegröße von MAXINT.
      Normalerweise 18446744073709551615Bytes auf einem 32-Bit-System.
    2. Fragen; 4096 Bytes lesen. (Puffergröße im Speicher aus Statistikinformationen zugewiesen.)
    3. Es wird ein kurzer String gelesen, also 18 Bytes.
    4. Überprüfen Sie, ob ein Loch erforderlich ist. Nein.
    5. Schreibpuffer zum Ziel.
    6. Subtrahieren Sie 18 von der maximalen Lesegröße.
    7. Fragen; 4096 Bytes lesen.
    8. 0 Bytes, da alles beim ersten Lesen verbraucht wurde.
    9. Rückgabe erfolgreich.
  6. Alles OK. Flags für Datei aktualisieren.
  7. BUSSGELD.

Antwort2

Rsync hatCodedas speziell prüft, ob eine Datei beim Lesen abgeschnitten wird und diesen Fehler ausgibt — ENODATA. Ich weiß nichtWarumdie Dateien in /syszeigen dieses Verhalten, aber da es keine echten Dateien sind, ist das wohl nicht allzu überraschend. Es scheint keine Möglichkeit zu geben, rsync anzuweisen, diese spezielle Prüfung zu überspringen.

Ich denke, es ist wahrscheinlich besser, auf Rsync zu verzichten /sysund stattdessen bestimmte Skripte zu verwenden, um gezielt die gewünschten Informationen herauszupicken (wie etwa die Adresse der Netzwerkkarte).

Antwort3

Könnte damit zusammenhängen, aber erweiterte Attributaufrufe schlagen auf Sysfs fehl:

[root@hypervisor eth0]# lsattr-Adresse

lsattr: Unangemessenes ioctl für Gerät beim Lesen von Flags an der Adresse

[root@hypervisor eth0]#

Wenn ich mir mein Strace anschaue, sieht es so aus, als ob rsync standardmäßig versucht, erweiterte Attribute einzubinden:

22964 <... getxattr resumed> , 0x7fff42845110, 132) = -1 ENODATA (Keine Daten verfügbar)

Ich habe versucht, ein Flag zu finden, das ich rsync geben kann, um zu sehen, ob das Überspringen erweiterter Attribute das Problem löst, konnte aber nichts finden ( --xattrsmacht sieAnam Zielort).

Antwort4

Normalerweise liest Rsync die Dateiinformationen, überträgt Dateiinhalte oder Deltas in eine temporäre Datei im Zielverzeichnis und benennt sie dann nach der Überprüfung der Dateidaten in den Zieldateinamen um.

Ich glaube, das Problem mit sysfs besteht darin, dass alle Dateien als 4 KB (eine Speicherseite) angezeigt werden, obwohl sie möglicherweise nur wenige Bytes enthalten. Um das Kopieren einer möglicherweise beschädigten Datei in das Ziel zu vermeiden, bricht rsync den Kopiervorgang ab, wenn es eine Nichtübereinstimmung zwischen den Metadaten der Datei und dem, was tatsächlich kopiert wurde, feststellt.

Zumindest bei rsync v3.0.6 kann dieses Verhalten mit dem --inplaceSchalter vermieden werden. Rsync erkennt zwar immer noch Fehler, aber da die Zieldateien zu diesem Zeitpunkt bereits überschrieben wurden, verbleiben die möglicherweise beschädigten Dateien dort.

Beachten Sie jedoch, dass ein Nebeneffekt davon darin besteht, dass Dateien mit Nullen auf 4 KB aufgefüllt werden, da dies die Größe ist, die rsync für die Dateien hält. In den meisten Fällen sollte dies keinen Unterschied machen, da Nullbytes normalerweise ignoriert werden.

verwandte Informationen